public override void EmitGet(CodeGen cg) { Contract.RequiresNotNull(cg, "cg"); _instance.EmitGet(cg); cg.Emit(OpCodes.Ldfld, _field); }
public override void EmitGet(CodeGen cg) { // RuntimeHelpers.LookupName(context, name) _frame.EmitGet(cg); cg.EmitSymbolId(_name); cg.EmitCall(typeof(RuntimeHelpers), "LookupName"); }
public override void EmitGet(CodeGen cg) { Contract.RequiresNotNull(cg, "cg"); _instance.EmitGet(cg); cg.EmitInt(_index); if (Type == typeof(object)) { cg.Emit(OpCodes.Ldelem_Ref); } else { cg.Emit(OpCodes.Ldelem, Type); } }
/// <summary> /// Generates stub to receive the CLR call and then call the dynamic language code. /// </summary> public static void EmitClrCallStub(CodeGen cg, Slot callTarget, int firstArg, CallType functionAttributes) { List<ReturnFixer> fixers = new List<ReturnFixer>(0); IList<Slot> args = cg.ArgumentSlots; int nargs = args.Count - firstArg; CallAction action; if ((functionAttributes & CallType.ArgumentList) != 0) { ArgumentInfo[] infos = CompilerHelpers.MakeRepeatedArray(ArgumentInfo.Simple, nargs); infos[nargs - 1] = new ArgumentInfo(ArgumentKind.List); action = CallAction.Make(new CallSignature(infos)); } else { action = CallAction.Make(nargs); } bool fast; Slot site = cg.CreateDynamicSite(action, CompilerHelpers.MakeRepeatedArray(typeof(object), nargs + 2), out fast); site.EmitGet(cg); if (!fast) cg.EmitCodeContext(); if (DynamicSiteHelpers.IsBigTarget(site.Type)) { cg.EmitTuple(site.Type.GetGenericArguments()[0], args.Count + 1, delegate(int index) { if (index == 0) { callTarget.EmitGet(cg); } else { ReturnFixer rf = ReturnFixer.EmitArgument(cg, args[index - 1]); if (rf != null) fixers.Add(rf); } }); } else { callTarget.EmitGet(cg); for (int i = firstArg; i < args.Count; i++) { ReturnFixer rf = ReturnFixer.EmitArgument(cg, args[i]); if (rf != null) fixers.Add(rf); } } cg.EmitCall(site.Type, "Invoke"); foreach (ReturnFixer rf in fixers) { rf.FixReturn(cg); } cg.EmitReturnFromObject(); }
public void FixReturn(CodeGen cg) { _argSlot.EmitGet(cg); _refSlot.EmitGet(cg); cg.EmitCall(typeof(BinderOps).GetMethod("GetBox").MakeGenericMethod(_argSlot.Type.GetElementType())); cg.EmitStoreValueIndirect(_argSlot.Type.GetElementType()); }
// Must override at least one of these two methods or get infinite loop public virtual void EmitSet(CodeGen cg, Slot val) { Contract.RequiresNotNull(val, "val"); Contract.RequiresNotNull(cg, "cg"); val.EmitGet(cg); EmitSet(cg); }
public override void EmitGet(CodeGen cg) { Contract.RequiresNotNull(cg, "cg"); _param.EmitGet(cg); cg.EmitInt(_index); cg.Emit(OpCodes.Ldelem_Ref); }
public override void EmitSet(CodeGen cg, Slot val) { Contract.RequiresNotNull(cg, "cg"); Contract.RequiresNotNull(val, "val"); _instance.EmitGet(cg); val.EmitGet(cg); cg.Emit(OpCodes.Stfld, _field); }
public override void EmitSet(CodeGen cg, Slot val) { Contract.RequiresNotNull(cg, "cg"); Contract.RequiresNotNull(val, "val"); _instance.EmitGet(cg); cg.EmitInt(_index); val.EmitGet(cg); cg.EmitStoreElement(Type); }
private static void EmitNestedTupleInit(CodeGen cg, Type storageType) { if (Tuple.GetSize(storageType) > Tuple.MaxSize) { Slot tmp = cg.GetLocalTmp(storageType); tmp.EmitSet(cg); Type[] nestedTuples = storageType.GetGenericArguments(); for (int i = 0; i < nestedTuples.Length; i++) { Type t = nestedTuples[i]; if (t.IsSubclassOf(typeof(Tuple))) { tmp.EmitGet(cg); cg.EmitNew(t.GetConstructor(ArrayUtils.EmptyTypes)); cg.EmitPropertySet(storageType, String.Format("Item{0:D3}", i)); tmp.EmitGet(cg); cg.EmitPropertyGet(storageType, String.Format("Item{0:D3}", i)); EmitNestedTupleInit(cg, t); } } cg.FreeLocalTmp(tmp); } else { int capacity = 0; foreach (Type t in storageType.GetGenericArguments()) { if (t == typeof(None)) { break; } capacity++; } cg.EmitInt(capacity); cg.EmitCall(typeof(RuntimeHelpers), "UninitializeEnvironmentTuple"); } }
public override void EmitSet(CodeGen cg, Slot val) { Contract.RequiresNotNull(cg, "cg"); Contract.RequiresNotNull(val, "val"); MethodInfo method = _property.GetSetMethod(); Debug.Assert(method != null, "Cannot set property"); Debug.Assert(method.GetParameters().Length == 1, "Wrong number of parameters on the property setter"); // Emit instance if (!method.IsStatic) { Debug.Assert(_instance != null, "need instance slot for instance property"); _instance.EmitGet(cg); } // Emit value val.EmitGet(cg); // Emit call cg.EmitCall(method); }
public static ReturnFixer EmitArgument(CodeGen cg, Slot argSlot) { argSlot.EmitGet(cg); if (argSlot.Type.IsByRef) { Type elementType = argSlot.Type.GetElementType(); Type concreteType = typeof(StrongBox<>).MakeGenericType(elementType); Slot refSlot = cg.GetLocalTmp(concreteType); cg.EmitLoadValueIndirect(elementType); cg.EmitNew(concreteType, new Type[] { elementType }); refSlot.EmitSet(cg); refSlot.EmitGet(cg); return new ReturnFixer(refSlot, argSlot); } else { cg.EmitBoxing(argSlot.Type); return null; } }
public override void EmitGet(CodeGen cg) { Contract.RequiresNotNull(cg, "cg"); _instance.EmitGet(cg); if (!_type.IsAssignableFrom(_instance.Type)) { if (_type.IsValueType) { Debug.Assert(_instance.Type == typeof(object)); cg.Emit(OpCodes.Unbox_Any, _type); } else { cg.Emit(OpCodes.Castclass, _type); } } }
private CodeGen MakeRawKeysMethod(LanguageInfo li, Dictionary <SymbolId, Slot> fields) { Slot rawKeysCache = li.TypeGen.AddStaticField(typeof(SymbolId[]), "ExtraKeysCache"); CodeGen init = li.TypeGen.TypeInitializer; init.EmitInt(0); init.Emit(OpCodes.Newarr, typeof(SymbolId)); rawKeysCache.EmitSet(init); CodeGen cg = li.TypeGen.DefineMethodOverride(typeof(CustomSymbolDictionary).GetMethod("GetExtraKeys", BindingFlags.Public | BindingFlags.Instance)); rawKeysCache.EmitGet(cg); cg.EmitReturn(); cg.Finish(); return(cg); }
public static ReturnFixer EmitArgument(CodeGen cg, Slot argSlot) { argSlot.EmitGet(cg); if (argSlot.Type.IsByRef) { Type elementType = argSlot.Type.GetElementType(); Type concreteType = typeof(StrongBox <>).MakeGenericType(elementType); Slot refSlot = cg.GetLocalTmp(concreteType); cg.EmitLoadValueIndirect(elementType); cg.EmitNew(concreteType, new Type[] { elementType }); refSlot.EmitSet(cg); refSlot.EmitGet(cg); return(new ReturnFixer(refSlot, argSlot)); } else { cg.EmitBoxing(argSlot.Type); return(null); } }
public override void EmitNewEnvironment(CodeGen cg) { ConstructorInfo ctor = EnvironmentType.GetConstructor( ScriptDomainManager.Options.DebugMode ? new Type[] { StorageType, typeof(SymbolId[]), } : new Type[] { StorageType, }); // emit: dict.Tuple[.Item000...].Item000 = dict, and then leave dict on the stack cg.EmitNew(ctor); cg.Emit(OpCodes.Dup); Slot tmp = cg.GetLocalTmp(EnvironmentType); tmp.EmitSet(cg); cg.EmitPropertyGet(EnvironmentType, "TupleData"); PropertyInfo last = null; foreach (PropertyInfo pi in Tuple.GetAccessPath(StorageType, 0)) { if (last != null) { cg.EmitPropertyGet(last); } last = pi; } tmp.EmitGet(cg); cg.EmitPropertySet(last); cg.FreeLocalTmp(tmp); }
public override void EmitNewEnvironment(CodeGen cg) { ConstructorInfo ctor = EnvironmentType.GetConstructor(new Type[] { StorageType }); // emit: dict.Tuple[.Item000...].Item000 = dict, and then leave dict on the stack cg.EmitNew(ctor); cg.Emit(OpCodes.Dup); Slot tmp = cg.GetLocalTmp(EnvironmentType); tmp.EmitSet(cg); cg.EmitPropertyGet(EnvironmentType, "Data"); var fld = StorageType.GetField("$parent$"); //cg.EmitFieldGet(fld); tmp.EmitGet(cg); cg.EmitFieldSet(fld); cg.FreeLocalTmp(tmp); }
public override void EmitGet(CodeGen cg) { _storage.EmitGet(cg); }
/// <summary> /// Generates stub to receive the CLR call and then call the dynamic language code. /// </summary> public static void EmitClrCallStub(CodeGen cg, Slot callTarget, int firstArg, CallType functionAttributes) { List <ReturnFixer> fixers = new List <ReturnFixer>(0); IList <Slot> args = cg.ArgumentSlots; int nargs = args.Count - firstArg; CallAction action; if ((functionAttributes & CallType.ArgumentList) != 0) { ArgumentInfo[] infos = CompilerHelpers.MakeRepeatedArray(ArgumentInfo.Simple, nargs); infos[nargs - 1] = new ArgumentInfo(ArgumentKind.List); action = CallAction.Make(new CallSignature(infos)); } else { action = CallAction.Make(nargs); } bool fast; Slot site = cg.CreateDynamicSite(action, CompilerHelpers.MakeRepeatedArray(typeof(object), nargs + 2), out fast); site.EmitGet(cg); if (!fast) { cg.EmitCodeContext(); } if (DynamicSiteHelpers.IsBigTarget(site.Type)) { cg.EmitTuple(site.Type.GetGenericArguments()[0], args.Count + 1, delegate(int index) { if (index == 0) { callTarget.EmitGet(cg); } else { ReturnFixer rf = ReturnFixer.EmitArgument(cg, args[index - 1]); if (rf != null) { fixers.Add(rf); } } }); } else { callTarget.EmitGet(cg); for (int i = firstArg; i < args.Count; i++) { ReturnFixer rf = ReturnFixer.EmitArgument(cg, args[i]); if (rf != null) { fixers.Add(rf); } } } cg.EmitCall(site.Type, "Invoke"); foreach (ReturnFixer rf in fixers) { rf.FixReturn(cg); } cg.EmitReturnFromObject(); }
public override void EmitSet(CodeGen cg, Slot val) { _wrapper.EmitGet(cg); val.EmitGet(cg); cg.EmitPropertySet(typeof(ModuleGlobalWrapper), "CurrentValue"); }
/// <summary> /// If the finally statement contains break, continue, return or yield, we need to /// handle the control flow statement after we exit out of finally via OpCodes.Endfinally. /// </summary> private static void EmitFinallyFlowControl(CodeGen cg, TryFlowResult flow, Slot flag) { if (flow.Return || flow.Yield) { Debug.Assert(flag != null); Label noReturn = cg.DefineLabel(); flag.EmitGet(cg); cg.EmitInt(CodeGen.BranchForReturn); cg.Emit(OpCodes.Bne_Un, noReturn); if (cg.IsGenerator) { // return true from the generator method cg.Emit(OpCodes.Ldc_I4_1); cg.EmitReturn(); } else if (flow.Any) { // return the actual value cg.EmitReturnValue(); cg.EmitReturn(); } cg.MarkLabel(noReturn); } // Only emit break handling if it is actually needed if (flow.Break) { Debug.Assert(flag != null); Label noReturn = cg.DefineLabel(); flag.EmitGet(cg); cg.EmitInt(CodeGen.BranchForBreak); cg.Emit(OpCodes.Bne_Un, noReturn); cg.EmitBreak(); cg.MarkLabel(noReturn); } // Only emit continue handling if it if actually needed if (flow.Continue) { Debug.Assert(flag != null); Label noReturn = cg.DefineLabel(); flag.EmitGet(cg); cg.EmitInt(CodeGen.BranchForContinue); cg.Emit(OpCodes.Bne_Un, noReturn); cg.EmitContinue(); cg.MarkLabel(noReturn); } }