static private EmitLdloca ( ILGenerator il, |
||
il | ILGenerator | |
source_type | ||
return | void |
internal override void TranslateToIL(ILGenerator il, Type rtype) { Type t1 = Convert.ToType(this.operand1.InferType(null)); Type t2 = Convert.ToType(this.operand2.InferType(null)); if (t1 != t2) { t1 = Typeob.Object; } MethodInfo opTrue = t1.GetMethod("op_True", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] { t1 }, null); if (opTrue == null || (opTrue.Attributes & MethodAttributes.SpecialName) == 0 || opTrue.ReturnType != Typeob.Boolean) { opTrue = null; } MethodInfo bitwiseOr = null; if (opTrue != null) { bitwiseOr = t1.GetMethod("op_BitwiseOr", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] { t1, t1 }, null); } if (bitwiseOr == null || (bitwiseOr.Attributes & MethodAttributes.SpecialName) == 0) { opTrue = null; } Label exit = il.DefineLabel(); this.operand1.TranslateToIL(il, t1); il.Emit(OpCodes.Dup); if (opTrue != null) { if (t1.IsValueType) { Convert.EmitLdloca(il, t1); } il.Emit(OpCodes.Call, opTrue); il.Emit(OpCodes.Brtrue, exit); this.operand2.TranslateToIL(il, t1); il.Emit(OpCodes.Call, bitwiseOr); il.MarkLabel(exit); Convert.Emit(this, il, bitwiseOr.ReturnType, rtype); } else { Convert.Emit(this, il, t1, Typeob.Boolean, true); il.Emit(OpCodes.Brtrue, exit); il.Emit(OpCodes.Pop); this.operand2.TranslateToIL(il, t1); il.MarkLabel(exit); Convert.Emit(this, il, t1, rtype); } }
protected override void TranslateToILObject(ILGenerator il, Type obType, bool noValue) { if (noValue && obType.IsValueType && obType != Typeob.Enum) { if (this.temp == null) { this.rootObject.TranslateToILReference(il, obType); } else { Type tempType = Convert.ToType(this.rootObject.InferType(null)); if (tempType == obType) { il.Emit(OpCodes.Ldloca, this.temp); } else { il.Emit(OpCodes.Ldloc, this.temp); Convert.Emit(this, il, tempType, obType); Convert.EmitLdloca(il, obType); } } } else { if (this.temp == null || this.rootObject is ThisLiteral) { this.rootObject.TranslateToIL(il, obType); } else { il.Emit(OpCodes.Ldloc, this.temp); Type tempType = Convert.ToType(this.rootObject.InferType(null)); Convert.Emit(this, il, tempType, obType); } } }
private static MethodInvoker SpitAndInstantiateClassFor(MethodInfo method) { TypeBuilder tb = MethodInvoker.module.DefineType("invoker" + MethodInvoker.count++, TypeAttributes.Public, typeof(MethodInvoker)); MethodBuilder mb = tb.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(Object), new Type[] { typeof(Object), typeof(Object[]) }); #if !DEBUG mb.SetCustomAttribute(new CustomAttributeBuilder(CompilerGlobals.debuggerStepThroughAttributeCtor, new Object[] {})); mb.SetCustomAttribute(new CustomAttributeBuilder(CompilerGlobals.debuggerHiddenAttributeCtor, new Object[] {})); #endif ILGenerator il = mb.GetILGenerator(); if (!method.DeclaringType.IsPublic) { method = method.GetBaseDefinition(); } Type obT = method.DeclaringType; if (!method.IsStatic) { il.Emit(OpCodes.Ldarg_1); if (obT.IsValueType) { Convert.EmitUnbox(il, obT, Type.GetTypeCode(obT)); Convert.EmitLdloca(il, obT); } else { il.Emit(OpCodes.Castclass, obT); } } ParameterInfo[] parameters = method.GetParameters(); LocalBuilder[] outTemps = null; for (int i = 0, n = parameters.Length; i < n; i++) { il.Emit(OpCodes.Ldarg_2); ConstantWrapper.TranslateToILInt(il, i); Type pt = parameters[i].ParameterType; if (pt.IsByRef) { pt = pt.GetElementType(); if (outTemps == null) { outTemps = new LocalBuilder[n]; } outTemps[i] = il.DeclareLocal(pt); il.Emit(OpCodes.Ldelem_Ref); if (pt.IsValueType) { Convert.EmitUnbox(il, pt, Type.GetTypeCode(pt)); } il.Emit(OpCodes.Stloc, outTemps[i]); il.Emit(OpCodes.Ldloca, outTemps[i]); } else { il.Emit(OpCodes.Ldelem_Ref); if (pt.IsValueType) { Convert.EmitUnbox(il, pt, Type.GetTypeCode(pt)); } } } if (!method.IsStatic && method.IsVirtual && !method.IsFinal && !obT.IsSealed) { il.Emit(OpCodes.Callvirt, method); } else { il.Emit(OpCodes.Call, method); } Type rt = method.ReturnType; if (rt == Typeob.Void) { il.Emit(OpCodes.Ldnull); } else if (rt.IsValueType) { il.Emit(OpCodes.Box, rt); } if (outTemps != null) { for (int i = 0, n = parameters.Length; i < n; i++) { LocalBuilder loc = outTemps[i]; if (loc != null) { il.Emit(OpCodes.Ldarg_2); ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Ldloc, loc); Type pt = parameters[i].ParameterType.GetElementType(); if (pt.IsValueType) { il.Emit(OpCodes.Box, pt); } il.Emit(OpCodes.Stelem_Ref); } } } il.Emit(OpCodes.Ret); Type t = tb.CreateType(); return((MethodInvoker)Activator.CreateInstance(t)); }
internal override void TranslateToConditionalBranch(ILGenerator il, bool branchIfTrue, Label label, bool shortForm) { Type t1 = Convert.ToType(this.operand1.InferType(null)); Type t2 = Convert.ToType(this.operand2.InferType(null)); if (this.operand1 is ConstantWrapper) { if (this.operand1.Evaluate() == null) { t1 = Typeob.Empty; } } if (this.operand2 is ConstantWrapper) { if (this.operand2.Evaluate() == null) { t2 = Typeob.Empty; } } if (t1 != t2 && t1.IsPrimitive && t2.IsPrimitive) { if (t1 == Typeob.Single) { t2 = t1; } else if (t2 == Typeob.Single) { t1 = t2; } else if (Convert.IsPromotableTo(t2, t1)) { t2 = t1; } else if (Convert.IsPromotableTo(t1, t2)) { t1 = t2; } } bool nonPrimitive = true; if (t1 == t2 && t1 != Typeob.Object) { this.operand1.TranslateToIL(il, t1); if (!t1.IsPrimitive && t1.IsValueType) { Convert.EmitLdloca(il, t1); } this.operand2.TranslateToIL(il, t1); if (t1 == Typeob.String) { il.Emit(OpCodes.Call, CompilerGlobals.stringEqualsMethod); } else if (!t1.IsPrimitive) { il.Emit(OpCodes.Callvirt, CompilerGlobals.equalsMethod); } else { nonPrimitive = false; } } else if (t1 == Typeob.Empty) { this.operand2.TranslateToIL(il, Typeob.Object); branchIfTrue = !branchIfTrue; } else if (t2 == Typeob.Empty) { this.operand1.TranslateToIL(il, Typeob.Object); branchIfTrue = !branchIfTrue; } else { this.operand1.TranslateToIL(il, Typeob.Object); this.operand2.TranslateToIL(il, Typeob.Object); il.Emit(OpCodes.Call, CompilerGlobals.jScriptStrictEqualsMethod); } if (branchIfTrue) { if (this.operatorTok == JSToken.StrictEqual) { if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brtrue_S : OpCodes.Brtrue, label); } else { il.Emit(shortForm ? OpCodes.Beq_S : OpCodes.Beq, label); } } else if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brfalse_S : OpCodes.Brfalse, label); } else { il.Emit(shortForm ? OpCodes.Bne_Un_S : OpCodes.Bne_Un, label); } } else { if (this.operatorTok == JSToken.StrictEqual) { if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brfalse_S : OpCodes.Brfalse, label); } else { il.Emit(shortForm ? OpCodes.Bne_Un_S : OpCodes.Bne_Un, label); } } else if (nonPrimitive) { il.Emit(shortForm ? OpCodes.Brtrue_S : OpCodes.Brtrue, label); } else { il.Emit(shortForm ? OpCodes.Beq_S : OpCodes.Beq, label); } } return; }