Esempio n. 1
0
 /// <summary>
 /// Creates reference to variable and resolves to it's type
 /// </summary>
 public static RppId StaticId(RppVar rppVar)
 {
     RppId classParamInput = Id(rppVar.Name);
     SymbolTable symbolTable = new SymbolTable();
     symbolTable.AddLocalVar(rppVar.Name, rppVar.Type.Value, rppVar);
     classParamInput.Analyze(symbolTable, new Diagnostic());
     return classParamInput;
 }
Esempio n. 2
0
        private static void LoadValFromRef(RppVar node, ILGenerator body, Dictionary<LocalBuilder, Tuple<FieldBuilder, Type>> capturedVars)
        {
            Type varType = node.Type.Value.NativeType;

            body.Emit(OpCodes.Ldfld, GetRefElemField(GetRefType(varType)));
            if (varType.IsClass)
            {
                Type varTypeInClosureContext = capturedVars == null ? varType : capturedVars[node.Builder].Item2;
                body.Emit(OpCodes.Castclass, varTypeInClosureContext);
            }
        }
Esempio n. 3
0
 public static void Load(RppVar node, ILGenerator body, Dictionary<LocalBuilder, Tuple<FieldBuilder, Type>> capturedVars)
 {
     if (node.IsCaptured)
     {
         LoadRef(node, body, capturedVars);
         LoadValFromRef(node, body, capturedVars);
     }
     else
     {
         body.Emit(OpCodes.Ldloc, node.Builder);
     }
 }
Esempio n. 4
0
        /// <summary>
        /// If var is primitive, then instance of <c>Ref&lt;primitiveType&gt;</c> is created. If
        /// var is class, then <c>Ref&lt;object&gt;</c> is created because <c>Reflection.Emit</c> doesn't let
        /// me create instance of generic type with type builder as parameters (or actually it let's me create
        /// but I can't get constructors). So we have to cast everytime we load value from <c>elem</c>.
        /// </summary>
        private static void Declare(RppVar node, ILGenerator body, bool initialize)
        {
            Type varType = node.Type.Value.NativeType;

            if (node.IsCaptured)
            {
                Type elementType = varType;
                varType = GetRefType(varType);
                ConstructorInfo constructor = initialize ? GetSpecificConstructor(varType, elementType) : varType.GetConstructor(Type.EmptyTypes);
                Debug.Assert(constructor != null, "constructor != null");

                body.Emit(OpCodes.Newobj, constructor);

                initialize = true;
            }

            node.Builder = body.DeclareLocal(varType);
            node.Builder.SetLocalSymInfo(node.Name);

            if (initialize)
            {
                body.Emit(OpCodes.Stloc, node.Builder);
            }
        }
Esempio n. 5
0
 public override void Visit(RppVar node)
 {
     if (!(node.InitExpr is RppEmptyExpr) && !(node.InitExpr is RppDefaultExpr))
     {
         node.InitExpr.Accept(this);
         ClrVarCodegen.DeclareAndInitialize(node, _body);
     }
     else
     {
         ClrVarCodegen.Declare(node, _body);
     }
 }
Esempio n. 6
0
 private static void LoadRef(RppVar node, ILGenerator body, Dictionary<LocalBuilder, Tuple<FieldBuilder, Type>> capturedVars)
 {
     if (capturedVars != null)
     {
         FieldBuilder field = capturedVars[node.Builder].Item1;
         body.Emit(OpCodes.Ldarg_0);
         body.Emit(OpCodes.Ldfld, field);
     }
     else
     {
         // When we access captured variable not from a closure, we need to load it almost as if we would do it from a closure
         body.Emit(OpCodes.Ldloc, node.Builder);
     }
 }
Esempio n. 7
0
 public static void DeclareAndInitialize(RppVar node, ILGenerator body)
 {
     Declare(node, body, true);
 }
Esempio n. 8
0
        public static void Store(RppVar node, ILGenerator body, Dictionary<LocalBuilder, Tuple<FieldBuilder, Type>> capturedVars)
        {
            if (node.IsCaptured)
            {
                // TODO this is not very optimal, we save what's on stack to local var, loading this.refField and then
                // loading temp var and storing then to this.refField.elem
                // This is needed because clr want's to have this, field, value -> on stack
                Type varType = node.Type.Value.NativeType;
                LocalBuilder tempVar = body.DeclareLocal(varType);
                body.Emit(OpCodes.Stloc, tempVar);

                LoadRef(node, body, capturedVars);

                body.Emit(OpCodes.Ldloc, tempVar);

                body.Emit(OpCodes.Stfld, GetRefElemField(GetRefType(varType)));
            }
            else
            {
                body.Emit(OpCodes.Stloc, node.Builder);
            }
        }
Esempio n. 9
0
 public static void Declare(RppVar node, ILGenerator body)
 {
     Declare(node, body, false);
 }