public override void Emit(CodeGen cg) { Slot tempContext = cg.ContextSlot; Slot newContext = cg.GetLocalTmp(typeof(CodeContext)); _scope.Emit(cg); //Locals dictionary cg.EmitCodeContext(); //CodeContext //cg.EmitBoolean(true); //Visible = true cg.EmitCall(typeof(RuntimeHelpers), "CreateNestedCodeContext"); newContext.EmitSet(cg); cg.ContextSlot = newContext; _body.Emit(cg); cg.ContextSlot = tempContext; }
public override void Emit(CodeGen cg) { Nullable <Label> firstTime = null; Label eol = cg.DefineLabel(); Label breakTarget = cg.DefineLabel(); Label continueTarget = cg.DefineLabel(); if (_increment != null) { firstTime = cg.DefineLabel(); cg.Emit(OpCodes.Br, firstTime.Value); } if (_header.IsValid) { //cg.EmitPosition(Start, _header); } cg.MarkLabel(continueTarget); if (_increment != null) { _increment.EmitAs(cg, typeof(void)); cg.MarkLabel(firstTime.Value); } if (_test != null) { _test.Emit(cg); cg.Emit(OpCodes.Brfalse, eol); } cg.PushTargets(breakTarget, continueTarget, this); _body.Emit(cg); cg.Emit(OpCodes.Br, continueTarget); cg.PopTargets(); cg.MarkLabel(eol); if (_else != null) { _else.Emit(cg); } cg.MarkLabel(breakTarget); }
private void Emit(CodeGen cg, int count) { for (int index = 0; index < count; index++) { Expression current = _expressions[index]; // Emit the expression current.Emit(cg); // If we don't want the expression just emitted as the result, // pop it off of the stack, unless it is a void expression. if (index != _valueIndex && current.Type != typeof(void)) { cg.Emit(OpCodes.Pop); } } }
private static void EmitArgument(CodeGen cg, Expression argument, Type type) { //if (argument.Type != type && (argument.Type.IsValueType || type.IsValueType)) if (!type.IsAssignableFrom(argument.Type) || (argument.Type != type && (argument.Type.IsValueType || type.IsValueType))) { argument = Ast.Convert(argument, type); } if (type.IsByRef) { argument.EmitAddress(cg, type.GetElementType()); } else { argument.Emit(cg); } }
public override void Emit(CodeGen cg) { Label eoi = cg.DefineLabel(); Label next = cg.DefineLabel(); _test.Emit(cg); //cg.EmitSequencePointNone(); //cg.Emit(OpCodes.Nop); cg.Emit(OpCodes.Brfalse, next); _true.Emit(cg); //cg.EmitSequencePointNone(); //cg.Emit(OpCodes.Nop); cg.Emit(OpCodes.Br, eoi); cg.MarkLabel(next); _false.Emit(cg); //cg.EmitSequencePointNone(); //cg.Emit(OpCodes.Nop); cg.MarkLabel(eoi); }
public override void Emit(CodeGen cg) { Label startTarget = cg.DefineLabel(); Label breakTarget = cg.DefineLabel(); Label continueTarget = cg.DefineLabel(); cg.MarkLabel(startTarget); cg.PushTargets(breakTarget, continueTarget, this); _body.Emit(cg); cg.MarkLabel(continueTarget); // TODO: Check if we need to emit position somewhere else also. //cg.EmitPosition(Start, _header); _test.Emit(cg); cg.Emit(OpCodes.Brtrue, startTarget); cg.PopTargets(); cg.MarkLabel(breakTarget); }
public override void Emit(CodeGen cg) { //_value.Emit(cg); // Save the expression value - order of evaluation is different than that of the Stelem* instruction //Slot temp = cg.GetLocalTmp(_elementType); //temp.EmitSet(cg); // Emit the array reference _array.Emit(cg); // Emit the index (as integer) _index.Emit(cg); // Emit the value _value.EmitAs(cg, _elementType); //temp.EmitGet(cg); // Store it in the array EmitLocation(cg); cg.EmitStoreElement(_elementType); //temp.EmitGet(cg); //DO NOT WANT!!! //cg.FreeLocalTmp(temp); }
internal override void EmitAddress(CodeGen cg, Type asType) { for (int index = 0; index < _expressions.Count; index++) { Expression current = _expressions[index]; // Emit the expression if (index == _valueIndex) { current.EmitAddress(cg, asType); } else { current.Emit(cg); // If we don't want the expression just emitted as the result, // pop it off of the stack, unless it is a void expression. if (current.Type != typeof(void)) { cg.Emit(OpCodes.Pop); } } } }
public virtual void EmitSet(CodeGen cg, Expression value) { value.Emit(cg); EmitSet(cg); }
public override void Emit(CodeGen cg) { // TODO: Improve the following to direct call: Callable.Call(Callable.Create(...)) //EmitLocation(cg); if (_instance != null && !cg.IsDynamicMethod) // damn DM! // go away! // this dangerous too for now { if (!IsParamsMethod()) { if (_instance is CodeBlockExpression) { CodeBlockExpression cbe = (CodeBlockExpression)_instance; Debug.Assert(_arguments.Count == _parameterInfos.Length); for (int arg = 0; arg < _parameterInfos.Length; arg++) { Expression argument = _arguments[arg]; Type type = _parameterInfos[arg].ParameterType; EmitArgument(cg, argument, type); } EmitLocation(cg); if (tailcall) { // TODO: Remove tail calls from list of known non-recursive methods //Console.WriteLine(cbe.Block.Name); tailcall = true; } cbe.EmitDirect(cg, tailcall); if (ScriptDomainManager.Options.LightweightDebugging && !tailcall && Span.IsValid) { cg.EmitConstant(SpanToLong(Span)); cg.EmitCall(Debugging.DebugMethods.ExpressionOut); } return; } } else // 'params' { } } if (_method == BuiltinsIsTrue) { EmitLocation(cg); var arg = Unwrap(_arguments[0]); if (arg.Type == typeof(bool)) { arg.Emit(cg); } else if (arg.Type == typeof(object)) { Label next = cg.DefineLabel(); Label end = cg.DefineLabel(); arg.Emit(cg); cg.Emit(OpCodes.Dup); cg.Emit(OpCodes.Isinst, typeof(bool)); cg.Emit(OpCodes.Brfalse, next); cg.EmitUnbox(typeof(bool)); cg.Emit(OpCodes.Br, end); cg.MarkLabel(next); cg.Emit(OpCodes.Pop); cg.EmitConstant(true); cg.MarkLabel(end); } else { cg.EmitConstant(true); } return; } var ii = _instance; ii = Unwrap(ii); BoundExpression.Emitter fixup = null; bool varargs = false; var pttt = Array.ConvertAll(_parameterInfos, x => x.ParameterType); if (ii is BoundExpression) { var be = ii as BoundExpression; if (BoundExpression.Fixups.ContainsKey(be.Variable.Name)) { fixup = BoundExpression.Fixups[be.Variable.Name]; pttt = BoundExpression.FixupTypes[be.Variable.Name]; } else { CodeGen rcg; CodeGenDescriptor[] cgd; if (CodeGen._codeBlockLookup.TryGetValue(be.Variable.Name, out rcg)) { var lpttt = pt.GetValue(rcg.MethodInfo) as Type[]; if (_arguments.Count == lpttt.Length) { _method = rcg.MethodInfo; pttt = lpttt; } } else if (CodeGen._codeBlockLookupX.TryGetValue(be.Variable.Name, out rcg)) { var lpppt = pt.GetValue(rcg.MethodInfo) as Type[]; if (lpppt.Length - 1 > _arguments.Count) { } else if (AllArgsAreObject(_arguments)) { _method = rcg.MethodInfo; pttt = lpppt; varargs = true; } else if (_arguments.Count == 1 && lpppt.Length == 1 && _arguments[0].Type == typeof(object[]) && _arguments[0] is MethodCallExpression && ((MethodCallExpression)_arguments[0])._method.Name == "ListToVector") { _arguments[0] = Unwrap(((MethodCallExpression)_arguments[0]).Arguments[0]); _method = rcg.MethodInfo; pttt = lpppt; } } else if (CodeGen._codeBlockLookupN.TryGetValue(be.Variable.Name, out cgd)) { if (AllArgsAreObject(_arguments)) { foreach (var i in cgd) { if (i.arity == _arguments.Count) { _method = i.cg.MethodInfo; pttt = pt.GetValue(_method) as Type[]; break; } } } } } } // Emit instance, if calling an instance method if (!_method.IsStatic) { Type type = _method.DeclaringType; if (type.IsValueType) { _instance.EmitAddress(cg, type); } else { if (fixup == null) { _instance.Emit(cg); } } } if (varargs) { int arg = 0; for (; arg < pttt.Length - 1; arg++) { Expression argument = _arguments[arg]; Type type = pttt[arg]; EmitArgument(cg, argument, type); } // make tail var tailargs = new List <Expression>(); for (; arg < _arguments.Count; arg++) { tailargs.Add(_arguments[arg]); } var tailarr = tailargs.ToArray(); var tail = Ast.ComplexCallHelper(MakeList(tailarr, true), tailarr); EmitArgument(cg, tail, typeof(object)); } else { // Emit arguments // we cant really complain here or show error... Debug.Assert(_arguments.Count == pttt.Length); for (int arg = 0; arg < pttt.Length && arg < _arguments.Count; arg++) { Expression argument = _arguments[arg]; Type type = pttt[arg]; EmitArgument(cg, argument, type); } } // check for possible conversion/boxing needed, disabled tail call if (tailcall) { if (ShouldTailCallBeRemoved(cg)) { //Console.WriteLine("Removing tail call: {0} in {1}", cg.MethodBase, cg.TypeGen.AssemblyGen.AssemblyBuilder); tailcall = false; } } EmitLocation(cg); // Emit the actual call if (fixup == null) { cg.EmitCall(_method, tailcall); } else { fixup(cg, tailcall); } if (ScriptDomainManager.Options.LightweightDebugging && !tailcall && Span.IsValid) { cg.EmitConstant(SpanToLong(Span)); cg.EmitCall(Debugging.DebugMethods.ExpressionOut); } }
public override void Emit(CodeGen cg) { _expression.Emit(cg); cg.EmitConvert(_expression.Type, _conversion); }
public override void Emit(CodeGen cg) { _expression.Emit(cg); }
internal void Allocate(CodeGen cg) { Debug.Assert(cg.Allocator.Block == Block); switch (_kind) { case VariableKind.Local: if (_block.IsGlobal) { // Local on global level, simply allocate the storage _storage = cg.Allocator.LocalAllocator.AllocateStorage(_name, _type); if (_defaultValue != null) { Slot slot = CreateSlotForVariable(cg); _defaultValue.Emit(cg); slot.EmitSet(cg); } } else { Slot slot; // If lifting local into closure, allocate in the environment if (_lift) { // allocate space in the environment and set it to Uninitialized slot = AllocInEnv(cg); } else { // Allocate the storage _storage = cg.Allocator.LocalAllocator.AllocateStorage(_name, _type); // No access slot for local variables, pass null. slot = _storage.CreateSlot(_storage.RequireAccessSlot ? cg.Allocator.GetScopeAccessSlot(_block) : null); MarkLocal(slot); } if (_uninitialized || _defaultValue != null) { // Emit initialization (environments will be initialized all at once) if (_defaultValue != null) { _defaultValue.Emit(cg); slot.EmitSet(cg); } else if (_type == typeof(object)) { // Only set variables of type object to "Uninitialized" //throw new UnInitializedUsageException(this, "Attempted to use uninitialized variable"); slot.EmitSetUninitialized(cg); } } } break; case VariableKind.Parameter: // Lifting parameter into closure, allocate in env and move. if (_lift) { Slot slot = AllocInEnv(cg); Slot src = GetArgumentSlot(cg); // Copy the value from the parameter (src) into the environment (slot) slot.EmitSet(cg, src); } else { Debug.Assert(cg.Allocator.Block == Block); // Nothing to do here } break; case VariableKind.Global: if (_defaultValue is UnboundExpression || cg.Allocator.Parent.Parent.Parent != null) { _storage = cg.Allocator.GlobalAllocator.AllocateStorage(_name, _type); } else { _storage = cg.Allocator.Parent.LocalAllocator.AllocateStorage(_name, _type); } Debug.Assert(_storage != null); break; case VariableKind.Temporary: // Nothing to do here break; case VariableKind.GeneratorTemporary: // Do the work in CreateSlot break; } }
public override void Emit(CodeGen cg) { //if (NodeType == AstNodeType.Convert && _operand is BoundExpression) //{ // var be = _operand as BoundExpression; // var tv = be.Variable.GetTypedVariable(Type); // if (tv != null) // { // tv. // return; // } //} if (NodeType == AstNodeType.Convert && _operand is ConstantExpression && _operand.Type == typeof(bool) && _type == typeof(object)) { _operand.EmitAs(cg, typeof(object)); } else { _operand.Emit(cg); EmitLocation(cg); switch (NodeType) { case AstNodeType.Convert: if (_type != _operand.Type && _type.Name == "Callable" && Converter != null) { cg.EmitCall(Converter); } else { cg.EmitCast(_operand.Type, _type); } break; case AstNodeType.Not: if (_operand.Type == typeof(bool)) { cg.Emit(OpCodes.Ldc_I4_0); cg.Emit(OpCodes.Ceq); } else { cg.Emit(OpCodes.Not); } break; case AstNodeType.Negate: cg.Emit(OpCodes.Neg); break; case AstNodeType.OnesComplement: cg.Emit(OpCodes.Not); break; default: throw new NotImplementedException(); } } }