Inheritance: AbstractLocalEntity, ITypedEntity, ILocalEntity, IInternalEntity
        void PropagateByRefParameterChanges(Method call, IParameter[] parameters, InternalLocal[] temporaries)
        {
            int byRefIndex = 0;
            for (int i=0; i<parameters.Length; ++i)
            {
                if (!parameters[i].IsByRef) continue;

                SlicingExpression slice = CodeBuilder.CreateSlicing(
                                            CodeBuilder.CreateReference(call.Parameters[0]),
                                            i);
                call.Body.Add(
                    CodeBuilder.CreateAssignment(
                        slice,
                        CodeBuilder.CreateReference(temporaries[byRefIndex])));
                ++byRefIndex;
            }
        }
        void ImplementByRefICallableCall(
            Method call,
            InternalCallableType type,
            ClassDefinition node,
            CallableSignature signature,
            int byRefCount)
        {
            MethodInvocationExpression mie = CreateInvokeInvocation(type);
            IParameter[] parameters = signature.Parameters;
            ReferenceExpression args = CodeBuilder.CreateReference(call.Parameters[0]);
            InternalLocal[] temporaries = new InternalLocal[byRefCount];

            int byRefIndex = 0;
            for (int i=0; i<parameters.Length; ++i)
            {
                SlicingExpression slice = CodeBuilder.CreateSlicing(args.CloneNode(), i);

                IParameter parameter = parameters[i];
                if (parameter.IsByRef)
                {
                    IType tempType = parameter.Type;
                    if (tempType.IsByRef)
                    {
                        tempType = tempType.ElementType;
                    }
                    temporaries[byRefIndex] = CodeBuilder.DeclareLocal(call,
                                "__temp_" + parameter.Name,
                                tempType);

                    call.Body.Add(
                        CodeBuilder.CreateAssignment(
                        CodeBuilder.CreateReference(temporaries[byRefIndex]),
                            CodeBuilder.CreateCast(
                                tempType,
                                slice)));

                    mie.Arguments.Add(
                        CodeBuilder.CreateReference(
                            temporaries[byRefIndex]));

                    ++byRefIndex;
                }
                else
                {
                    mie.Arguments.Add(slice);
                }
            }

            if (TypeSystemServices.VoidType == signature.ReturnType)
            {
                call.Body.Add(mie);
                PropagateByRefParameterChanges(call, parameters, temporaries);
            }
            else
            {
                InternalLocal invokeReturnValue = CodeBuilder.DeclareLocal(call,
                            "__returnValue", signature.ReturnType);
                call.Body.Add(
                    CodeBuilder.CreateAssignment(
                        CodeBuilder.CreateReference(invokeReturnValue),
                        mie));
                PropagateByRefParameterChanges(call, parameters, temporaries);
                call.Body.Add(
                    new ReturnStatement(
                        CodeBuilder.CreateReference(invokeReturnValue)));
            }
        }
 Expression CloneOrAssignToTemp(InternalLocal temp, Expression operand)
 {
     return null == temp
         ? operand.CloneNode()
         : CodeBuilder.CreateAssignment(
             CodeBuilder.CreateReference(temp),
             operand.CloneNode());
 }
        private Expression CreateSideEffectAwareSlicingOperation(LexicalInfo lexicalInfo, BinaryOperatorType binaryOperator, SlicingExpression lvalue, Expression rvalue, InternalLocal returnValue)
        {
            MethodInvocationExpression eval = CodeBuilder.CreateEvalInvocation(lexicalInfo);
            if (HasSideEffect(lvalue.Target))
            {
                InternalLocal temp = AddInitializedTempLocal(eval, lvalue.Target);
                lvalue.Target = CodeBuilder.CreateReference(temp);
            }

            foreach (Slice slice in lvalue.Indices)
            {
                Expression index = slice.Begin;
                if (HasSideEffect(index))
                {
                    InternalLocal temp = AddInitializedTempLocal(eval, index);
                    slice.Begin = CodeBuilder.CreateReference(temp);
                }
            }

            BinaryExpression addition = CodeBuilder.CreateBoundBinaryExpression(
                GetExpressionType(lvalue),
                binaryOperator,
                CloneOrAssignToTemp(returnValue, lvalue),
                rvalue);
            Expression expansion = CodeBuilder.CreateAssignment(
                lvalue.CloneNode(),
                addition);
            // Resolve operator overloads if any
            BindArithmeticOperator(addition);
            if (eval.Arguments.Count > 0 || null != returnValue)
            {
                eval.Arguments.Add(expansion);
                if (null != returnValue)
                {
                    eval.Arguments.Add(CodeBuilder.CreateReference(returnValue));
                }
                BindExpressionType(eval, GetExpressionType(lvalue));
                expansion = eval;
            }
            return expansion;
        }
Beispiel #5
0
        void SetLocal(BinaryExpression node, InternalLocal tag, bool leaveValueOnStack)
        {
            node.Right.Accept(this); // leaves type on stack

            IType typeOnStack = null;

            if (leaveValueOnStack)
            {
                typeOnStack = PeekTypeOnStack();
                _il.Emit(OpCodes.Dup);
            }
            else
            {
                typeOnStack = PopType();
            }
            EmitAssignment(tag, typeOnStack);
        }
 protected virtual IEntity DeclareLocal(Node sourceNode, string name, IType localType, bool privateScope)
 {
     Local local = new Local(name, privateScope);
     local.LexicalInfo = sourceNode.LexicalInfo;
     InternalLocal entity = new InternalLocal(local, localType);
     local.Entity = entity;
     _currentMethod.Method.Locals.Add(local);
     return entity;
 }
 private ReferenceExpression CreateReference(InternalLocal enteredLoop)
 {
     return CodeBuilder().CreateReference(enteredLoop);
 }
Beispiel #8
0
 void EmitAssignment(InternalLocal tag, IType typeOnStack)
 {
     // todo: assignment result must be type on the left in the
     // case of casting
     LocalBuilder local = tag.LocalBuilder;
     EmitCastIfNeeded(tag.Type, typeOnStack);
     _il.Emit(OpCodes.Stloc, local);
 }
Beispiel #9
0
 public InternalLocal DeclareLocal(Method node, string name, IType type)
 {
     Local local = new Local(node.LexicalInfo, name);
     InternalLocal entity = new InternalLocal(local, type);
     local.Entity = entity;
     node.Locals.Add(local);
     return entity;
 }
Beispiel #10
0
 public ReferenceExpression CreateReference(InternalLocal local)
 {
     return CreateLocalReference(local.Name, local);
 }
Beispiel #11
0
 public ReferenceExpression CreateLocalReference(string name, InternalLocal entity)
 {
     return CreateTypedReference(name, entity);
 }
Beispiel #12
0
 public Expression CreateInitValueType(LexicalInfo li, InternalLocal local)
 {
     MethodInvocationExpression mie = CreateBuiltinInvocation(li, BuiltinFunction.InitValueType);
     mie.Arguments.Add(CreateReference(local));
     return mie;
 }
Beispiel #13
0
 public Expression CreateDefaultInitializer(LexicalInfo li, InternalLocal local)
 {
     if (local.Type.IsValueType)
     {
         return CreateInitValueType(li, local);
     }
     return CreateAssignment(
             li,
             CreateReference(local),
             CreateNullLiteral());
 }