public static void CloseCompilerGeneratedBlock(EmitContext ec) { if (symwriter != null) { int offset = symwriter.GetILOffset (ec.ig); symwriter.CloseCompilerGeneratedBlock (offset); } }
public override void Emit(EmitContext ec) { if (Value) ec.Emit (OpCodes.Ldc_I4_1); else ec.Emit (OpCodes.Ldc_I4_0); }
public override Expression DoResolve (EmitContext ec) { // // We are born fully resolved // return this; }
public override bool Resolve (EmitContext ec) { expr = expr.Resolve (ec); if (expr == null) return false; Report.Debug (64, "RESOLVE YIELD #1", this, ec, expr, expr.GetType (), ec.CurrentAnonymousMethod, ec.CurrentIterator); if (!CheckContext (ec, loc)) return false; Iterator iterator = ec.CurrentIterator; if (expr.Type != iterator.OriginalIteratorType) { expr = Convert.ImplicitConversionRequired ( ec, expr, iterator.OriginalIteratorType, loc); if (expr == null) return false; } if (!ec.CurrentBranching.CurrentUsageVector.IsUnreachable) unwind_protect = ec.CurrentBranching.AddResumePoint (this, loc, out resume_pc); return true; }
public override void Emit (EmitContext ec) { // // Emits null pointer // ec.Emit (OpCodes.Ldc_I4_0); ec.Emit (OpCodes.Conv_U); }
public override void Emit (EmitContext ec) { if (args != null) Invocation.EmitArguments (ec, mi, args); ec.ig.Emit (OpCodes.Call, mi); return; }
public override void Emit(EmitContext ec) { if (statement != null) { statement.EmitStatement (ec); ec.Emit (OpCodes.Ret); return; } base.Emit (ec); }
public override void Emit (EmitContext ec) { ec.ig.Emit (OpCodes.Ldnull); #if GMCS_SOURCE // Only to make verifier happy if (TypeManager.IsGenericParameter (type)) ec.ig.Emit (OpCodes.Unbox_Any, type); #endif }
public override void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type t, bool expl) { if (TypeManager.IsGenericParameter (t)) { Report.Error(403, loc, "Cannot convert null to the type parameter `{0}' because it could be a value " + "type. Consider using `default ({0})' instead", t.Name); } else { Report.Error(37, loc, "Cannot convert null to `{0}' because it is a value type", TypeManager.CSharpName(t)); } }
public override void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type target, bool expl) { if (!expl && IsLiteral && (TypeManager.IsPrimitiveType (target) || type == TypeManager.decimal_type) && (TypeManager.IsPrimitiveType (type) || type == TypeManager.decimal_type)) { Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", AsString (), TypeManager.CSharpName (target)); } else { base.Error_ValueCannotBeConverted (ec, loc, target, expl); } }
protected override void DoEmit(EmitContext ec) { if (statement != null) { statement.EmitStatement (ec); if (unwind_protect) ec.Emit (OpCodes.Leave, ec.CreateReturnLabel ()); else { ec.Emit (OpCodes.Ret); } return; } base.DoEmit (ec); }
public override Expression CreateExpressionTree (EmitContext ec) { if (expr_tree != null) return expr_tree (ec, mg); ArrayList args = new ArrayList (arguments.Count + 1); args.Add (new Argument (new NullLiteral (loc))); args.Add (new Argument (mg.CreateExpressionTree (ec))); foreach (Argument a in arguments) { args.Add (new Argument (a.Expr.CreateExpressionTree (ec))); } return CreateExpressionFactoryCall ("Call", args); }
static public Expression MakeSimpleCall (EmitContext ec, MethodGroupExpr mg, Expression e, Location loc) { ArrayList args; MethodBase method; args = new ArrayList (1); args.Add (new Argument (e, Argument.AType.Expression)); method = Invocation.OverloadResolve (ec, (MethodGroupExpr) mg, args, loc); if (method == null) return null; return new StaticCallExpr ((MethodInfo) method, args, loc); }
protected override Parameters ResolveParameters (EmitContext ec, TypeInferenceContext tic, Type delegateType) { if (!TypeManager.IsDelegateType (delegateType)) return null; AParametersCollection d_params = TypeManager.GetDelegateParameters (delegateType); if (HasExplicitParameters) { if (!VerifyExplicitParameters (delegateType, d_params, ec.IsInProbingMode)) return null; return Parameters; } // // If L has an implicitly typed parameter list we make implicit parameters explicit // Set each parameter of L is given the type of the corresponding parameter in D // if (!VerifyParameterCompatibility (delegateType, d_params, ec.IsInProbingMode)) return null; Type [] ptypes = new Type [Parameters.Count]; for (int i = 0; i < d_params.Count; i++) { // D has no ref or out parameters if ((d_params.FixedParameters [i].ModFlags & Parameter.Modifier.ISBYREF) != 0) return null; Type d_param = d_params.Types [i]; #if MS_COMPATIBLE // Blablabla, because reflection does not work with dynamic types if (d_param.IsGenericParameter) d_param = delegateType.GetGenericArguments () [d_param.GenericParameterPosition]; #endif // // When type inference context exists try to apply inferred type arguments // if (tic != null) { d_param = tic.InflateGenericArgument (d_param); } ptypes [i] = d_param; ((ImplicitLambdaParameter) Parameters.FixedParameters [i]).Type = d_param; } Parameters.Types = ptypes; return Parameters; }
public override bool GetAttributableValue (EmitContext ec, Type value_type, out object value) { if (value_type == TypeManager.object_type) { value = GetTypedValue (); return true; } Constant c = ImplicitConversionRequired (ec, value_type, loc); if (c == null) { value = null; return false; } value = c.GetTypedValue (); return true; }
protected override Expression CreateExpressionTree (EmitContext ec, Type delegate_type) { if (ec.IsInProbingMode) return this; Expression args = Parameters.CreateExpressionTree (ec, loc); Expression expr = Block.CreateExpressionTree (ec); if (expr == null) return null; ArrayList arguments = new ArrayList (2); arguments.Add (new Argument (expr)); arguments.Add (new Argument (args)); return CreateExpressionFactoryCall ("Lambda", new TypeArguments (new TypeExpression (delegate_type, loc)), arguments); }
/// <summary> /// We already know that the statement is unreachable, but we still /// need to resolve it to catch errors. /// </summary> public virtual bool ResolveUnreachable (EmitContext ec, bool warn) { // // This conflicts with csc's way of doing this, but IMHO it's // the right thing to do. // // If something is unreachable, we still check whether it's // correct. This means that you cannot use unassigned variables // in unreachable code, for instance. // if (warn) Report.Warning (162, 2, loc, "Unreachable code detected"); ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc); bool ok = Resolve (ec); ec.KillFlowBranching (); return ok; }
public static bool CheckContext (EmitContext ec, Location loc) { for (Block block = ec.CurrentBlock; block != null; block = block.Parent) { if (!block.Unsafe) continue; Report.Error (1629, loc, "Unsafe code may not appear in iterators"); return false; } // // We can't use `ec.InUnsafe' here because it's allowed to have an iterator // inside an unsafe class. See test-martin-29.cs for an example. // if (!ec.CurrentAnonymousMethod.IsIterator) { Report.Error (1621, loc, "The yield statement cannot be used inside " + "anonymous method blocks"); return false; } return true; }
public void EmitStatement(EmitContext ec, MethodSpec method, Arguments Arguments, Location loc) { EmitPredefined(ec, method, Arguments, true, loc); }
public override void Emit(EmitContext ec) { throw new NotImplementedException(); }
protected override void DoEmit(EmitContext ec) { state_machine.EmitMoveNext(ec); }
void EmitMoveNext(EmitContext ec) { move_next_ok = ec.DefineLabel(); move_next_error = ec.DefineLabel(); if (resume_points == null) { EmitMoveNext_NoResumePoints(ec); return; } current_pc = ec.GetTemporaryLocal(ec.BuiltinTypes.UInt); ec.EmitThis(); ec.Emit(OpCodes.Ldfld, storey.PC.Spec); ec.Emit(OpCodes.Stloc, current_pc); // We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit ec.EmitThis(); ec.EmitInt((int)IteratorStorey.State.After); ec.Emit(OpCodes.Stfld, storey.PC.Spec); Label[] labels = new Label[1 + resume_points.Count]; labels[0] = ec.DefineLabel(); bool need_skip_finally = false; for (int i = 0; i < resume_points.Count; ++i) { ResumableStatement s = resume_points[i]; need_skip_finally |= s is ExceptionStatement; labels[i + 1] = s.PrepareForEmit(ec); } if (need_skip_finally) { skip_finally = ec.GetTemporaryLocal(ec.BuiltinTypes.Bool); ec.EmitInt(0); ec.Emit(OpCodes.Stloc, skip_finally); } var async_init = this as AsyncInitializer; if (async_init != null) { ec.BeginExceptionBlock(); } ec.Emit(OpCodes.Ldloc, current_pc); ec.Emit(OpCodes.Switch, labels); ec.Emit(async_init != null ? OpCodes.Leave : OpCodes.Br, move_next_error); ec.MarkLabel(labels[0]); iterator_body_end = ec.DefineLabel(); block.EmitEmbedded(ec); ec.MarkLabel(iterator_body_end); if (async_init != null) { var catch_value = LocalVariable.CreateCompilerGenerated(ec.Module.Compiler.BuiltinTypes.Exception, block, Location); ec.BeginCatchBlock(catch_value.Type); catch_value.EmitAssign(ec); ec.EmitThis(); ec.EmitInt((int)IteratorStorey.State.After); ec.Emit(OpCodes.Stfld, storey.PC.Spec); ((AsyncTaskStorey)async_init.Storey).EmitSetException(ec, new LocalVariableReference(catch_value, Location)); ec.Emit(OpCodes.Leave, move_next_ok); ec.EndExceptionBlock(); } ec.Mark(Block.Original.EndLocation); ec.EmitThis(); ec.EmitInt((int)IteratorStorey.State.After); ec.Emit(OpCodes.Stfld, storey.PC.Spec); EmitMoveNextEpilogue(ec); ec.MarkLabel(move_next_error); if (ReturnType.Kind != MemberKind.Void) { ec.EmitInt(0); ec.Emit(OpCodes.Ret); } ec.MarkLabel(move_next_ok); if (ReturnType.Kind != MemberKind.Void) { ec.EmitInt(1); ec.Emit(OpCodes.Ret); } }
public override void EmitStatement(EmitContext ec) { var stmt = new If(condition, new StatementExpression(invoke), new StatementExpression(assign), loc); stmt.Emit(ec); }
public void Release(EmitContext ec) { ec.FreeTemporaryLocal(builder, type); builder = null; }
public override Expression EmitToField(EmitContext ec) { return(child.EmitToField(ec)); }
// // Initializes all hoisted variables // public void EmitStoreyInstantiation (EmitContext ec, ExplicitBlock block) { // There can be only one instance variable for each storey type if (Instance != null) throw new InternalErrorException (); // // Create an instance of this storey // ResolveContext rc = new ResolveContext (ec.MemberContext); rc.CurrentBlock = block; var storey_type_expr = CreateStoreyTypeExpression (ec); var source = new New (storey_type_expr, null, Location).Resolve (rc); // // When the current context is async (or iterator) lift local storey // instantiation to the currect storey // if (ec.CurrentAnonymousMethod is StateMachineInitializer && (block.HasYield || block.HasAwait)) { // // Unfortunately, normal capture mechanism could not be used because we are // too late in the pipeline and standart assign cannot be used either due to // recursive nature of GetStoreyInstanceExpression // var field = ec.CurrentAnonymousMethod.Storey.AddCompilerGeneratedField ( LocalVariable.GetCompilerGeneratedName (block), storey_type_expr, true); field.Define (); field.Emit (); var fexpr = new FieldExpr (field, Location); fexpr.InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, Location); fexpr.EmitAssign (ec, source, false, false); Instance = fexpr; } else { var local = TemporaryVariableReference.Create (source.Type, block, Location); if (source.Type.IsStruct) { local.LocalInfo.CreateBuilder (ec); } else { local.EmitAssign (ec, source); } Instance = local; } EmitHoistedFieldsInitialization (rc, ec); // TODO: Implement properly //SymbolWriter.DefineScopeVariable (ID, Instance.Builder); }
public void AddressOf(EmitContext ec, AddressOp mode) { throw new NotImplementedException(); }
protected void EmitCall(EmitContext ec, Expression binder, Arguments arguments, bool isStatement) { // // This method generates all internal infrastructure for a dynamic call. The // reason why it's quite complicated is the mixture of dynamic and anonymous // methods. Dynamic itself requires a temporary class (ContainerX) and anonymous // methods can generate temporary storey as well (AnonStorey). Handling MVAR // type parameters rewrite is non-trivial in such case as there are various // combinations possible therefore the mutator is not straightforward. Secondly // we need to keep both MVAR(possibly VAR for anon storey) and type VAR to emit // correct Site field type and its access from EmitContext. // int dyn_args_count = arguments == null ? 0 : arguments.Count; int default_args = isStatement ? 1 : 2; var module = ec.Module; bool is_invoke = ((MemberAccess)((Invocation)binder).Exp).Name.StartsWith("Invoke"); TypeSpec callSite; TypeSpec callSiteGeneric; if (isPlayScriptAotMode) { callSite = module.PredefinedTypes.AsCallSite.TypeSpec; callSiteGeneric = module.PredefinedTypes.AsCallSiteGeneric.TypeSpec; } else { callSite = module.PredefinedTypes.CallSite.TypeSpec; callSiteGeneric = module.PredefinedTypes.CallSiteGeneric.TypeSpec; } bool has_ref_out_argument = false; var targs = new TypeExpression[dyn_args_count + default_args]; targs[0] = new TypeExpression(callSite, loc); TypeExpression[] targs_for_instance = null; TypeParameterMutator mutator; var site_container = ec.CreateDynamicSite(); if (context_mvars != null) { TypeParameters tparam; TypeContainer sc = site_container; do { tparam = sc.CurrentTypeParameters; sc = sc.Parent; } while (tparam == null); mutator = new TypeParameterMutator(context_mvars, tparam); if (!ec.IsAnonymousStoreyMutateRequired) { targs_for_instance = new TypeExpression[targs.Length]; targs_for_instance[0] = targs[0]; } } else { mutator = null; } for (int i = 0; i < dyn_args_count; ++i) { Argument a = arguments[i]; if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref) { has_ref_out_argument = true; } var t = a.Type; // Convert any internal type like dynamic or null to object if (t.Kind == MemberKind.InternalCompilerType) { t = ec.BuiltinTypes.Object; } // PlayScript AOT mode - Convert all types to object if they are not basic AS types or this is an invocation. if (isPlayScriptAotMode && !IsValidPlayScriptAotType(t, is_invoke)) // Always box to Object for invoke argument lists { t = ec.BuiltinTypes.Object; arguments[i] = new Argument(new BoxedCast(a.Expr, ec.BuiltinTypes.Object)); } if (targs_for_instance != null) { targs_for_instance[i + 1] = new TypeExpression(t, loc); } if (mutator != null) { t = t.Mutate(mutator); } targs[i + 1] = new TypeExpression(t, loc); } // Always use "object" as return type in AOT mode. var ret_type = type; if (isPlayScriptAotMode && !isStatement && !IsValidPlayScriptAotType(ret_type, is_invoke)) { ret_type = ec.BuiltinTypes.Object; } TypeExpr del_type = null; TypeExpr del_type_instance_access = null; if (!has_ref_out_argument) { string d_name = isStatement ? "Action" : "Func"; TypeExpr te = null; Namespace type_ns = module.GlobalRootNamespace.GetNamespace("System", true); if (type_ns != null) { te = type_ns.LookupType(module, d_name, dyn_args_count + default_args, LookupMode.Normal, loc); } if (te != null) { if (!isStatement) { var t = ret_type; if (t.Kind == MemberKind.InternalCompilerType) { t = ec.BuiltinTypes.Object; } if (targs_for_instance != null) { targs_for_instance[targs_for_instance.Length - 1] = new TypeExpression(t, loc); } if (mutator != null) { t = t.Mutate(mutator); } targs[targs.Length - 1] = new TypeExpression(t, loc); } del_type = new GenericTypeExpr(te.Type, new TypeArguments(targs), loc); if (targs_for_instance != null) { del_type_instance_access = new GenericTypeExpr(te.Type, new TypeArguments(targs_for_instance), loc); } else { del_type_instance_access = del_type; } } } // // Create custom delegate when no appropriate predefined delegate has been found // Delegate d; if (del_type == null) { TypeSpec rt = isStatement ? ec.BuiltinTypes.Void : ret_type; Parameter[] p = new Parameter[dyn_args_count + 1]; p[0] = new Parameter(targs[0], "p0", Parameter.Modifier.NONE, null, loc); var site = ec.CreateDynamicSite(); int index = site.Containers == null ? 0 : site.Containers.Count; if (mutator != null) { rt = mutator.Mutate(rt); } for (int i = 1; i < dyn_args_count + 1; ++i) { p[i] = new Parameter(targs[i], "p" + i.ToString("X"), arguments[i - 1].Modifier, null, loc); } d = new Delegate(site, new TypeExpression(rt, loc), Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED, new MemberName("Container" + index.ToString("X")), new ParametersCompiled(p), null); d.CreateContainer(); d.DefineContainer(); d.Define(); d.PrepareEmit(); site.AddTypeContainer(d); del_type = new TypeExpression(d.CurrentType, loc); if (targs_for_instance != null) { del_type_instance_access = null; } else { del_type_instance_access = del_type; } } else { d = null; } var site_type_decl = new GenericTypeExpr(callSiteGeneric, new TypeArguments(del_type), loc); var field = site_container.CreateCallSiteField(site_type_decl, loc); if (field == null) { return; } if (del_type_instance_access == null) { var dt = d.CurrentType.DeclaringType.MakeGenericType(module, context_mvars.Types); del_type_instance_access = new TypeExpression(MemberCache.GetMember(dt, d.CurrentType), loc); } var instanceAccessExprType = new GenericTypeExpr(callSiteGeneric, new TypeArguments(del_type_instance_access), loc); if (instanceAccessExprType.ResolveAsType(ec.MemberContext) == null) { return; } bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired; TypeSpec gt; if (inflate_using_mvar || context_mvars == null) { gt = site_container.CurrentType; } else { gt = site_container.CurrentType.MakeGenericType(module, context_mvars.Types); } // When site container already exists the inflated version has to be // updated manually to contain newly created field if (gt is InflatedTypeSpec && site_container.AnonymousMethodsCounter > 1) { var tparams = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes; var inflator = new TypeParameterInflator(module, gt, tparams, gt.TypeArguments); gt.MemberCache.AddMember(field.InflateMember(inflator)); } FieldExpr site_field_expr = new FieldExpr(MemberCache.GetMember(gt, field), loc); BlockContext bc = new BlockContext(ec.MemberContext, null, ec.BuiltinTypes.Void); Arguments args = new Arguments(1); args.Add(new Argument(binder)); StatementExpression s = new StatementExpression(new SimpleAssign(site_field_expr, new Invocation(new MemberAccess(instanceAccessExprType, "Create"), args))); using (ec.With(BuilderContext.Options.OmitDebugInfo, true)) { if (s.Resolve(bc)) { Statement init = new If(new Binary(Binary.Operator.Equality, site_field_expr, new NullLiteral(loc)), s, loc); init.Emit(ec); } args = new Arguments(1 + dyn_args_count); args.Add(new Argument(site_field_expr)); if (arguments != null) { int arg_pos = 1; foreach (Argument a in arguments) { if (a is NamedArgument) { // Name is not valid in this context args.Add(new Argument(a.Expr, a.ArgType)); } else { args.Add(a); } if (inflate_using_mvar && a.Type != targs[arg_pos].Type) { a.Expr.Type = targs[arg_pos].Type; } ++arg_pos; } } Expression target; if (isPlayScriptAotMode && !isStatement && type != ret_type) { // PlayScript: If doing an invoke, we have to cast the return type to the type expected by the expression.. target = new Cast(new TypeExpression(type, loc), new DelegateInvocation(new MemberAccess(site_field_expr, "Target", loc).Resolve(bc), args, loc), loc).Resolve(bc); } else { target = new DelegateInvocation(new MemberAccess(site_field_expr, "Target", loc).Resolve(bc), args, loc).Resolve(bc); } if (target != null) { target.Emit(ec); } } }
public override void EmitStatement(EmitContext ec) { EmitCall(ec, binder_expr, arguments, true); }
public override void Emit(EmitContext ec) { EmitCall(ec, binder_expr, arguments, false); }
public void EmitAssign(EmitContext ec, Expression source, bool leave_copy, bool isCompound) { throw new NotImplementedException(); }
public void Emit(EmitContext ec, bool leave_copy) { throw new NotImplementedException(); }
void Emit(EmitContext ec, bool is_statement) { IAssignMethod t = (IAssignMethod)target; t.EmitAssign(ec, source, !is_statement, this is CompoundAssign); }
protected virtual void EmitHoistedParameters (EmitContext ec, List<HoistedParameter> hoisted) { foreach (HoistedParameter hp in hoisted) { // // Parameters could be proxied via local fields for value type storey // if (hoisted_local_params != null) { var local_param = hoisted_local_params.Find (l => l.Parameter.Parameter == hp.Parameter.Parameter); var source = new FieldExpr (local_param.Field, Location); source.InstanceExpression = new CompilerGeneratedThis (CurrentType, Location); hp.EmitAssign (ec, source, false, false); continue; } hp.EmitHoistingAssignment (ec); } }
public void Emit(EmitContext ec, bool conditionalAccess) { Label NullOperatorLabel; Nullable.Unwrap unwrap; if (conditionalAccess && Expression.IsNeverNull(instance)) { conditionalAccess = false; } if (conditionalAccess) { NullOperatorLabel = ec.DefineLabel(); unwrap = instance as Nullable.Unwrap; } else { NullOperatorLabel = new Label(); unwrap = null; } IMemoryLocation instance_address = null; bool conditional_access_dup = false; if (unwrap != null) { unwrap.Store(ec); unwrap.EmitCheck(ec); ec.Emit(OpCodes.Brtrue_S, NullOperatorLabel); } else { if (conditionalAccess && addressRequired) { // // Don't allocate temp variable when instance load is cheap and load and load-address // operate on same memory // instance_address = instance as VariableReference; if (instance_address == null) { instance_address = instance as LocalTemporary; } if (instance_address == null) { EmitLoad(ec, false); ec.Emit(OpCodes.Dup); ec.EmitLoadFromPtr(instance.Type); conditional_access_dup = true; } else { instance.Emit(ec); } } else { EmitLoad(ec, !conditionalAccess); if (conditionalAccess) { conditional_access_dup = !ExpressionAnalyzer.IsInexpensiveLoad(instance); if (conditional_access_dup) { ec.Emit(OpCodes.Dup); } } } if (conditionalAccess) { if (instance.Type.Kind == MemberKind.TypeParameter) { ec.Emit(OpCodes.Box, instance.Type); } ec.Emit(OpCodes.Brtrue_S, NullOperatorLabel); if (conditional_access_dup) { ec.Emit(OpCodes.Pop); } } } if (conditionalAccess) { if (!ec.ConditionalAccess.Statement) { var t = ec.ConditionalAccess.Type; if (t.IsNullableType) { Nullable.LiftedNull.Create(t, Location.Null).Emit(ec); } else { ec.EmitNull(); if (t.IsGenericParameter) { ec.Emit(OpCodes.Unbox_Any, t); } } } ec.Emit(OpCodes.Br, ec.ConditionalAccess.EndLabel); ec.MarkLabel(NullOperatorLabel); if (instance_address != null) { instance_address.AddressOf(ec, AddressOp.Load); } else if (unwrap != null) { unwrap.Emit(ec); if (addressRequired) { var tmp = ec.GetTemporaryLocal(unwrap.Type); ec.Emit(OpCodes.Stloc, tmp); ec.Emit(OpCodes.Ldloca, tmp); ec.FreeTemporaryLocal(tmp, unwrap.Type); } } else if (!conditional_access_dup) { instance.Emit(ec); } } }
public void EmitPredefined(EmitContext ec, MethodSpec method, Arguments Arguments, bool statement = false, Location?loc = null) { Expression instance_copy = null; if (!HasAwaitArguments && ec.HasSet(BuilderContext.Options.AsyncBody)) { HasAwaitArguments = Arguments != null && Arguments.ContainsEmitWithAwait(); if (HasAwaitArguments && InstanceExpressionOnStack) { throw new NotSupportedException(); } } OpCode call_op; LocalTemporary lt = null; if (method.IsStatic) { call_op = OpCodes.Call; } else { call_op = IsVirtualCallRequired(InstanceExpression, method) ? OpCodes.Callvirt : OpCodes.Call; if (HasAwaitArguments) { instance_copy = InstanceExpression.EmitToField(ec); var ie = new InstanceEmitter(instance_copy, IsAddressCall(instance_copy, call_op, method.DeclaringType)); if (Arguments == null) { ie.EmitLoad(ec, true); } } else if (!InstanceExpressionOnStack) { var ie = new InstanceEmitter(InstanceExpression, IsAddressCall(InstanceExpression, call_op, method.DeclaringType)); ie.Emit(ec, ConditionalAccess); if (DuplicateArguments) { ec.Emit(OpCodes.Dup); if (Arguments != null && Arguments.Count != 0) { lt = new LocalTemporary(ie.GetStackType(ec)); lt.Store(ec); instance_copy = lt; } } } } if (Arguments != null && !InstanceExpressionOnStack) { EmittedArguments = Arguments.Emit(ec, DuplicateArguments, HasAwaitArguments); if (EmittedArguments != null) { if (instance_copy != null) { var ie = new InstanceEmitter(instance_copy, IsAddressCall(instance_copy, call_op, method.DeclaringType)); ie.Emit(ec, ConditionalAccess); if (lt != null) { lt.Release(ec); } } EmittedArguments.Emit(ec); } } if (call_op == OpCodes.Callvirt && (InstanceExpression.Type.IsGenericParameter || InstanceExpression.Type.IsStructOrEnum)) { ec.Emit(OpCodes.Constrained, InstanceExpression.Type); } if (loc != null) { // // Emit explicit sequence point for expressions like Foo.Bar () to help debugger to // break at right place when LHS expression can be stepped-into // ec.MarkCallEntry(loc.Value); } // // Set instance expression to actual result expression. When it contains await it can be // picked up by caller // InstanceExpression = instance_copy; if (method.Parameters.HasArglist) { var varargs_types = GetVarargsTypes(method, Arguments); ec.Emit(call_op, method, varargs_types); } else { // // If you have: // this.DoFoo (); // and DoFoo is not virtual, you can omit the callvirt, // because you don't need the null checking behavior. // ec.Emit(call_op, method); } // // Pop the return value if there is one and stack should be empty // if (statement && method.ReturnType.Kind != MemberKind.Void) { ec.Emit(OpCodes.Pop); } }
// // Emits a list of resolved Arguments // public void Emit(EmitContext ec) { Emit(ec, false, false); }
public override void EmitStatement(EmitContext ec) { Emit(ec, true); }
public override void Emit(EmitContext ec) { child.Emit(ec); }
public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound) { GetFieldExpression (ec).EmitAssign (ec, source, leave_copy, false); }
public override void Emit(EmitContext ec) { // Don't create sequence point DoEmit(ec); }
protected override void DoEmit(EmitContext ec) { machine_initializer.InjectYield(ec, expr, resume_pc, unwind_protect, resume_point); }
public override void Emit (EmitContext ec) { ResolveContext rc = new ResolveContext (ec.MemberContext); Expression e = hv.GetFieldExpression (ec).CreateExpressionTree (rc, false); // This should never fail e = e.Resolve (rc); if (e != null) e.Emit (ec); }
public void EmitAssign(EmitContext ec, Expression source, bool leave_copy, bool isCompound) { EmitCall(ec, setter, setter_args, !leave_copy); }
public void Emit (EmitContext ec) { GetFieldExpression (ec).Emit (ec); }
// // Creates field access expression for hoisted variable // protected virtual FieldExpr GetFieldExpression (EmitContext ec) { if (ec.CurrentAnonymousMethod == null || ec.CurrentAnonymousMethod.Storey == null) { if (cached_outer_access != null) return cached_outer_access; // // When setting top-level hoisted variable in generic storey // change storey generic types to method generic types (VAR -> MVAR) // if (storey.Instance.Type.IsGenericOrParentIsGeneric) { var fs = MemberCache.GetMember (storey.Instance.Type, field.Spec); cached_outer_access = new FieldExpr (fs, field.Location); } else { cached_outer_access = new FieldExpr (field, field.Location); } cached_outer_access.InstanceExpression = storey.GetStoreyInstanceExpression (ec); return cached_outer_access; } FieldExpr inner_access; if (cached_inner_access != null) { if (!cached_inner_access.TryGetValue (ec.CurrentAnonymousMethod, out inner_access)) inner_access = null; } else { inner_access = null; cached_inner_access = new Dictionary<AnonymousExpression, FieldExpr> (4); } if (inner_access == null) { if (field.Parent.IsGenericOrParentIsGeneric) { var fs = MemberCache.GetMember (field.Parent.CurrentType, field.Spec); inner_access = new FieldExpr (fs, field.Location); } else { inner_access = new FieldExpr (field, field.Location); } inner_access.InstanceExpression = storey.GetStoreyInstanceExpression (ec); cached_inner_access.Add (ec.CurrentAnonymousMethod, inner_access); } return inner_access; }
public override void EmitStatement(EmitContext ec) { flags |= CSharpBinderFlags.ResultDiscarded; base.EmitStatement(ec); }
public override void Emit(EmitContext ec) { Emit(ec, false); }
void EmitHoistedFieldsInitialization (ResolveContext rc, EmitContext ec) { // // Initialize all storey reference fields by using local or hoisted variables // if (used_parent_storeys != null) { foreach (StoreyFieldPair sf in used_parent_storeys) { // // Get instance expression of storey field // Expression instace_expr = GetStoreyInstanceExpression (ec); var fs = sf.Field.Spec; if (TypeManager.IsGenericType (instace_expr.Type)) fs = MemberCache.GetMember (instace_expr.Type, fs); FieldExpr f_set_expr = new FieldExpr (fs, Location); f_set_expr.InstanceExpression = instace_expr; // TODO: CompilerAssign expression SimpleAssign a = new SimpleAssign (f_set_expr, sf.Storey.GetStoreyInstanceExpression (ec)); if (a.Resolve (rc) != null) a.EmitStatement (ec); } } // // Initialize hoisted `this' only once, everywhere else will be // referenced indirectly // if (initialize_hoisted_this) { rc.CurrentBlock.AddScopeStatement (new ThisInitializer (hoisted_this)); } // // Setting currect anonymous method to null blocks any further variable hoisting // AnonymousExpression ae = ec.CurrentAnonymousMethod; ec.CurrentAnonymousMethod = null; if (hoisted_params != null) { EmitHoistedParameters (ec, hoisted_params); } ec.CurrentAnonymousMethod = ae; }
protected override FieldExpr GetFieldExpression(EmitContext ec) { return(new FieldExpr(field, field.Location)); }
// // Creates storey instance expression regardless of currect IP // public Expression GetStoreyInstanceExpression (EmitContext ec) { AnonymousExpression am = ec.CurrentAnonymousMethod; // // Access from original block -> storey // if (am == null) return Instance; // // Access from anonymous method implemented as a static -> storey // if (am.Storey == null) return Instance; Field f = am.Storey.GetReferencedStoreyField (this); if (f == null) { if (am.Storey == this) { // // Access from inside of same storey (S -> S) // return new CompilerGeneratedThis (CurrentType, Location); } // // External field access // return Instance; } // // Storey was cached to local field // FieldExpr f_ind = new FieldExpr (f, Location); f_ind.InstanceExpression = new CompilerGeneratedThis (CurrentType, Location); return f_ind; }
public override void Emit(EmitContext ec) { throw new NotSupportedException("Missing Resolve call"); }
public void AddressOf (EmitContext ec, AddressOp mode) { GetFieldExpression (ec).AddressOf (ec, mode); }
public override Expression EmitToField(EmitContext ec) { stmt.EmitPrologue(ec); return(stmt.GetResultExpression(ec)); }
public Expression EmitToField (EmitContext ec) { return GetFieldExpression (ec); }
void IExpressionCleanup.EmitCleanup(EmitContext ec) { EmitAssign(ec, new NullConstant(type, loc), false, false); }
public void Emit (EmitContext ec, bool leave_copy) { GetFieldExpression (ec).Emit (ec, leave_copy); }
public void EmitAssign(EmitContext ec, FieldExpr field) { stmt.EmitPrologue(ec); field.InstanceExpression.Emit(ec); stmt.Emit(ec); }
public void EmitHoistingAssignment (EmitContext ec) { // // Remove hoisted redirection to emit assignment from original parameter // var temp = parameter.Parameter.HoistedVariant; parameter.Parameter.HoistedVariant = null; var a = new HoistedFieldAssign (GetFieldExpression (ec), parameter); a.EmitStatement (ec); parameter.Parameter.HoistedVariant = temp; }
protected override void DoEmit(EmitContext ec) { ec.CurrentAnonymousMethod = iterator; iterator.EmitDispose(ec); }