static private TranslateToILInt ( |
||
il | ||
i | int | |
Результат | void |
internal override void TranslateToILDelete(ILGenerator il, Type rtype) { IReflect ir = this.func.InferType(null); Type type = Microsoft.JScript.Convert.ToType(ir); this.func.TranslateToIL(il, type); this.args.TranslateToIL(il, Typeob.ArrayOfObject); if (this.func is Binding) { MethodInfo deleteOpMethod; if (ir is ClassScope) { deleteOpMethod = ((ClassScope)ir).owner.deleteOpMethod; } else { deleteOpMethod = ir.GetMethod("op_Delete", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] { type, Typeob.ArrayOfObject }, null); } if (((deleteOpMethod != null) && ((deleteOpMethod.Attributes & MethodAttributes.SpecialName) != MethodAttributes.PrivateScope)) && (deleteOpMethod.ReturnType == Typeob.Boolean)) { il.Emit(OpCodes.Call, deleteOpMethod); Microsoft.JScript.Convert.Emit(this, il, Typeob.Boolean, rtype); return; } } ConstantWrapper.TranslateToILInt(il, this.args.count - 1); il.Emit(OpCodes.Ldelem_Ref); Microsoft.JScript.Convert.Emit(this, il, Typeob.Object, Typeob.String); il.Emit(OpCodes.Call, CompilerGlobals.deleteMemberMethod); Microsoft.JScript.Convert.Emit(this, il, Typeob.Boolean, rtype); }
internal override void TranslateToILDelete(ILGenerator il, Type rtype) { IReflect ir = this.func.InferType(null); Type obType = Convert.ToType(ir); this.func.TranslateToIL(il, obType); this.args.TranslateToIL(il, typeof(Object[])); if (this.func is Binding) { MethodInfo deleteOp; if (ir is ClassScope) { deleteOp = ((ClassScope)ir).owner.deleteOpMethod; } else { deleteOp = ir.GetMethod("op_Delete", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] { obType, typeof(Object[]) }, null); } if (deleteOp != null && (deleteOp.Attributes & MethodAttributes.SpecialName) != 0 && deleteOp.ReturnType == Typeob.Boolean) { il.Emit(OpCodes.Call, deleteOp); Convert.Emit(this, il, Typeob.Boolean, rtype); return; } } ConstantWrapper.TranslateToILInt(il, this.args.count - 1); il.Emit(OpCodes.Ldelem_Ref); Convert.Emit(this, il, Typeob.Object, Typeob.String); il.Emit(OpCodes.Call, CompilerGlobals.deleteMemberMethod); Convert.Emit(this, il, Typeob.Boolean, rtype); }
internal override void TranslateToILPreSetPlusGet(ILGenerator il) { if (this.isFullyResolved) { base.TranslateToILPreSetPlusGet(il); return; } //Need to do a dynamic lookup to see if there is a dynamically introduced (by eval or with) hiding definition. //Leave a FieldInfo on the stack if there is such a member, otherwise leave null on the stack Label done = il.DefineLabel(); Label latebound = il.DefineLabel(); LocalBuilder fieldTok = this.fieldLoc = il.DeclareLocal(Typeob.FieldInfo); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod); il.Emit(OpCodes.Castclass, Typeob.IActivationObject); il.Emit(OpCodes.Ldstr, this.name); ConstantWrapper.TranslateToILInt(il, this.lexLevel); il.Emit(OpCodes.Callvirt, CompilerGlobals.getFieldMethod); il.Emit(OpCodes.Stloc, fieldTok); il.Emit(OpCodes.Ldloc, fieldTok); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Bne_Un_S, latebound); base.TranslateToILPreSetPlusGet(il); il.Emit(OpCodes.Br_S, done); il.MarkLabel(latebound); if (this.thereIsAnObjectOnTheStack) { il.Emit(OpCodes.Ldnull); //Push a dummy object so that both latebound and early bound code paths leave an object on the stack } il.Emit(OpCodes.Ldloc, this.fieldLoc); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Callvirt, CompilerGlobals.getFieldValueMethod); il.MarkLabel(done); }
internal override void TranslateToILPreSetPlusGet(ILGenerator il) { if (base.isFullyResolved) { base.TranslateToILPreSetPlusGet(il); } else { Label label = il.DefineLabel(); Label label2 = il.DefineLabel(); LocalBuilder local = this.fieldLoc = il.DeclareLocal(Typeob.FieldInfo); base.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod); il.Emit(OpCodes.Castclass, Typeob.IActivationObject); il.Emit(OpCodes.Ldstr, base.name); ConstantWrapper.TranslateToILInt(il, this.lexLevel); il.Emit(OpCodes.Callvirt, CompilerGlobals.getFieldMethod); il.Emit(OpCodes.Stloc, local); il.Emit(OpCodes.Ldloc, local); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Bne_Un_S, label2); base.TranslateToILPreSetPlusGet(il); il.Emit(OpCodes.Br_S, label); il.MarkLabel(label2); if (this.thereIsAnObjectOnTheStack) { il.Emit(OpCodes.Ldnull); } il.Emit(OpCodes.Ldloc, this.fieldLoc); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Callvirt, CompilerGlobals.getFieldValueMethod); il.MarkLabel(label); } }
internal override void TranslateToILInitializer(ILGenerator il) { //This is executed only once for a given scope. It creates a FunctionObject and stores it in a private local. //The FunctionObject is then used to construct a new closure every time the function expression is evaluated. //This way, what is a method to IL, ends up as a ScriptFunction object that behaves just like an ECMAScript function. this.func.TranslateToIL(compilerGlobals); this.func_local = il.DeclareLocal(Typeob.FunctionObject); il.Emit(OpCodes.Ldtoken, this.func.classwriter); il.Emit(OpCodes.Ldstr, this.name); il.Emit(OpCodes.Ldstr, this.func.GetName()); int n = this.func.formal_parameters.Length; ConstantWrapper.TranslateToILInt(il, n); il.Emit(OpCodes.Newarr, Typeob.String); for (int i = 0; i < n; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Ldstr, this.func.formal_parameters[i]); il.Emit(OpCodes.Stelem_Ref); } n = this.func.fields.Length; ConstantWrapper.TranslateToILInt(il, n); il.Emit(OpCodes.Newarr, Typeob.JSLocalField); for (int i = 0; i < n; i++) { JSLocalField field = this.func.fields[i]; il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Ldstr, field.Name); il.Emit(OpCodes.Ldtoken, field.FieldType); ConstantWrapper.TranslateToILInt(il, field.slotNumber); il.Emit(OpCodes.Newobj, CompilerGlobals.jsLocalFieldConstructor); il.Emit(OpCodes.Stelem_Ref); } if (this.func.must_save_stack_locals) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } if (this.func.hasArgumentsObject) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } il.Emit(OpCodes.Ldstr, this.func.ToString()); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.jScriptFunctionExpressionMethod); il.Emit(OpCodes.Stloc, this.func_local); }
internal override void TranslateToILInitializer(ILGenerator il) { this.func.TranslateToIL(base.compilerGlobals); this.func_local = il.DeclareLocal(Typeob.FunctionObject); il.Emit(OpCodes.Ldtoken, this.func.classwriter); il.Emit(OpCodes.Ldstr, this.name); il.Emit(OpCodes.Ldstr, this.func.GetName()); int length = this.func.formal_parameters.Length; ConstantWrapper.TranslateToILInt(il, length); il.Emit(OpCodes.Newarr, Typeob.String); for (int i = 0; i < length; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Ldstr, this.func.formal_parameters[i]); il.Emit(OpCodes.Stelem_Ref); } length = this.func.fields.Length; ConstantWrapper.TranslateToILInt(il, length); il.Emit(OpCodes.Newarr, Typeob.JSLocalField); for (int j = 0; j < length; j++) { JSLocalField field = this.func.fields[j]; il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, j); il.Emit(OpCodes.Ldstr, field.Name); il.Emit(OpCodes.Ldtoken, field.FieldType); ConstantWrapper.TranslateToILInt(il, field.slotNumber); il.Emit(OpCodes.Newobj, CompilerGlobals.jsLocalFieldConstructor); il.Emit(OpCodes.Stelem_Ref); } if (this.func.must_save_stack_locals) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } if (this.func.hasArgumentsObject) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } il.Emit(OpCodes.Ldstr, this.func.ToString()); base.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.jScriptFunctionExpressionMethod); il.Emit(OpCodes.Stloc, this.func_local); }
internal override void TranslateToILInitializer(ILGenerator il) { IReflect reflect = this.InferType(null); base.operand.TranslateToILInitializer(il); if (reflect == Typeob.Object) { this.metaData = il.DeclareLocal(Typeob.NumericUnary); ConstantWrapper.TranslateToILInt(il, (int)this.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.numericUnaryConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); } }
internal void EmitLocalInfoForFields(ILGenerator il) { foreach (JSLocalField field in this.localFieldsForDebugInfo) { ((LocalBuilder)field.metaData).SetLocalSymInfo(field.debuggerName); } if (this.parent is GlobalScope) { LocalBuilder loc = il.DeclareLocal(Typeob.Int32); loc.SetLocalSymInfo("scopeId for catch block"); ConstantWrapper.TranslateToILInt(il, this.scopeId); il.Emit(OpCodes.Stloc, loc); } }
internal override void TranslateToILInitializer(ILGenerator il) { IReflect rtype = this.InferType(null); this.operand.TranslateToILInitializer(il); if (rtype != Typeob.Object) { return; } this.metaData = il.DeclareLocal(typeof(PostOrPrefixOperator)); ConstantWrapper.TranslateToILInt(il, (int)this.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.postOrPrefixConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); }
internal override void TranslateToILInitializer(ILGenerator il) { this.operand1.TranslateToILInitializer(il); this.operand2.TranslateToILInitializer(il); MethodInfo oper = this.GetOperator(this.operand1.InferType(null), this.operand2.InferType(null)); if (oper != null) { this.metaData = oper; return; } if (this.operand1 is ConstantWrapper) { Object val = this.operand1.Evaluate(); if (val == null) { this.type1 = Typeob.Empty; } else if (val is DBNull) { this.type1 = Typeob.Null; } } if (this.operand2 is ConstantWrapper) { Object val = this.operand2.Evaluate(); if (val == null) { this.type2 = Typeob.Empty; } else if (val is DBNull) { this.type2 = Typeob.Null; } } if (this.type1 == Typeob.Empty || this.type1 == Typeob.Null || this.type2 == Typeob.Empty || this.type2 == Typeob.Null) { return; } if ((this.type1.IsPrimitive || this.type1 == Typeob.String || Typeob.JSObject.IsAssignableFrom(this.type1)) && (this.type2.IsPrimitive || this.type2 == Typeob.String || Typeob.JSObject.IsAssignableFrom(this.type2))) { return; } this.metaData = il.DeclareLocal(Typeob.Equality); ConstantWrapper.TranslateToILInt(il, (int)this.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.equalityConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); }
internal override void TranslateToILCall(ILGenerator il, Type rtype, ASTList argList, bool construct, bool brackets) { if (base.isFullyResolved) { base.TranslateToILCall(il, rtype, argList, construct, brackets); } else { Label label = il.DefineLabel(); Label label2 = il.DefineLabel(); base.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod); il.Emit(OpCodes.Castclass, Typeob.IActivationObject); il.Emit(OpCodes.Ldstr, base.name); ConstantWrapper.TranslateToILInt(il, this.lexLevel); il.Emit(OpCodes.Callvirt, CompilerGlobals.getMemberValueMethod); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Call, CompilerGlobals.isMissingMethod); il.Emit(OpCodes.Brfalse, label); il.Emit(OpCodes.Pop); base.TranslateToILCall(il, Typeob.Object, argList, construct, brackets); il.Emit(OpCodes.Br, label2); il.MarkLabel(label); this.TranslateToILDefaultThisObject(il); argList.TranslateToIL(il, Typeob.ArrayOfObject); if (construct) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } if (brackets) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } base.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.callValue2Method); il.MarkLabel(label2); Microsoft.JScript.Convert.Emit(this, il, Typeob.Object, rtype); } }
internal override void TranslateToILCall(ILGenerator il, Type rtype, ASTList argList, bool construct, bool brackets) { if (this.isFullyResolved) { base.TranslateToILCall(il, rtype, argList, construct, brackets); return; } //Need to do a dynamic lookup to see if there is a dynamically introduced (by eval or with) hiding definition. Label lateBoundCall = il.DefineLabel(); Label done = il.DefineLabel(); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod); il.Emit(OpCodes.Castclass, Typeob.IActivationObject); il.Emit(OpCodes.Ldstr, this.name); ConstantWrapper.TranslateToILInt(il, this.lexLevel); il.Emit(OpCodes.Callvirt, CompilerGlobals.getMemberValueMethod); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Call, CompilerGlobals.isMissingMethod); il.Emit(OpCodes.Brfalse, lateBoundCall); //dynamic lookup succeeded, do not call early bound method il.Emit(OpCodes.Pop); //The dynamic lookup returned Missing.Value, discard it and go on to use the value from the early bound location. base.TranslateToILCall(il, Typeob.Object, argList, construct, brackets); il.Emit(OpCodes.Br, done); //Skip over the latebound call sequence il.MarkLabel(lateBoundCall); this.TranslateToILDefaultThisObject(il); argList.TranslateToIL(il, Typeob.ArrayOfObject); if (construct) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } if (brackets) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.callValue2Method); il.MarkLabel(done); Convert.Emit(this, il, Typeob.Object, rtype); }
internal override void TranslateToILInitializer(ILGenerator il) { base.operand1.TranslateToILInitializer(il); base.operand2.TranslateToILInitializer(il); MethodInfo @operator = base.GetOperator(base.operand1.InferType(null), base.operand2.InferType(null)); if (@operator != null) { this.metaData = @operator; } else { if (base.operand1 is ConstantWrapper) { object obj2 = base.operand1.Evaluate(); if (obj2 == null) { base.type1 = Typeob.Empty; } else if (obj2 is DBNull) { base.type1 = Typeob.Null; } } if (base.operand2 is ConstantWrapper) { object obj3 = base.operand2.Evaluate(); if (obj3 == null) { base.type2 = Typeob.Empty; } else if (obj3 is DBNull) { base.type2 = Typeob.Null; } } if ((((base.type1 != Typeob.Empty) && (base.type1 != Typeob.Null)) && ((base.type2 != Typeob.Empty) && (base.type2 != Typeob.Null))) && (((!base.type1.IsPrimitive && (base.type1 != Typeob.String)) && !Typeob.JSObject.IsAssignableFrom(base.type1)) || ((!base.type2.IsPrimitive && (base.type2 != Typeob.String)) && !Typeob.JSObject.IsAssignableFrom(base.type2)))) { this.metaData = il.DeclareLocal(Typeob.Equality); ConstantWrapper.TranslateToILInt(il, (int)base.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.equalityConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); } } }
internal override void TranslateToILInitializer(ILGenerator il) { base.operand1.TranslateToILInitializer(il); base.operand2.TranslateToILInitializer(il); MethodInfo @operator = base.GetOperator(base.operand1.InferType(null), base.operand2.InferType(null)); if (@operator != null) { this.metaData = @operator; } else if ((!base.type1.IsPrimitive && !Typeob.JSObject.IsAssignableFrom(base.type1)) || (!base.type2.IsPrimitive && !Typeob.JSObject.IsAssignableFrom(base.type2))) { this.metaData = il.DeclareLocal(Typeob.Relational); ConstantWrapper.TranslateToILInt(il, (int)base.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.relationalConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); } }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (this.context.document.debugOn) { il.Emit(OpCodes.Nop); } ASTList astList = this.operand; int n = astList.count; for (int i = 0; i < n; i++) { AST ast = astList[i]; IReflect ir = ast.InferType(null); if (ir == Typeob.String) { ast.TranslateToIL(il, Typeob.String); } else { ast.TranslateToIL(il, Typeob.Object); ConstantWrapper.TranslateToILInt(il, 1); il.Emit(OpCodes.Call, CompilerGlobals.toStringMethod); } if (i == n - 1) { il.Emit(OpCodes.Call, CompilerGlobals.writeLineMethod); } else { il.Emit(OpCodes.Call, CompilerGlobals.writeMethod); } } if (n == 0) { il.Emit(OpCodes.Ldstr, ""); il.Emit(OpCodes.Call, CompilerGlobals.writeLineMethod); } if (rtype != Typeob.Void) { il.Emit(OpCodes.Ldsfld, CompilerGlobals.undefinedField); Convert.Emit(this, il, Typeob.Object, rtype); } }
private void TranslateToILArray(ILGenerator il, Type etype) { int count = this.elements.count; ConstantWrapper.TranslateToILInt(il, count); Type.GetTypeCode(etype); il.Emit(OpCodes.Newarr, etype); for (int i = 0; i < count; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); if (etype.IsValueType && !etype.IsPrimitive) { il.Emit(OpCodes.Ldelema, etype); } this.elements[i].TranslateToIL(il, etype); Binding.TranslateToStelem(il, etype); } }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (base.context.document.debugOn) { il.Emit(OpCodes.Nop); } ASTList operand = this.operand; int count = operand.count; for (int i = 0; i < count; i++) { AST ast = operand[i]; if (ast.InferType(null) == Typeob.String) { ast.TranslateToIL(il, Typeob.String); } else { ast.TranslateToIL(il, Typeob.Object); ConstantWrapper.TranslateToILInt(il, 1); il.Emit(OpCodes.Call, CompilerGlobals.toStringMethod); } if (i == (count - 1)) { il.Emit(OpCodes.Call, CompilerGlobals.writeLineMethod); } else { il.Emit(OpCodes.Call, CompilerGlobals.writeMethod); } } if (count == 0) { il.Emit(OpCodes.Ldstr, ""); il.Emit(OpCodes.Call, CompilerGlobals.writeLineMethod); } if (rtype != Typeob.Void) { il.Emit(OpCodes.Ldsfld, CompilerGlobals.undefinedField); Microsoft.JScript.Convert.Emit(this, il, Typeob.Object, rtype); } }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Label label = (Label)base.compilerGlobals.BreakLabelStack.Peek(this.completion.Exit - 1); base.context.EmitLineInfo(il); if (this.leavesFinally) { ConstantWrapper.TranslateToILInt(il, base.compilerGlobals.BreakLabelStack.Size() - this.completion.Exit); il.Emit(OpCodes.Newobj, CompilerGlobals.breakOutOfFinallyConstructor); il.Emit(OpCodes.Throw); } else if (base.compilerGlobals.InsideProtectedRegion) { il.Emit(OpCodes.Leave, label); } else { il.Emit(OpCodes.Br, label); } }
internal override void TranslateToILInitializer(ILGenerator il) { this.operand1.TranslateToILInitializer(il); this.operand2.TranslateToILInitializer(il); MethodInfo oper = this.GetOperator(this.operand1.InferType(null), this.operand2.InferType(null)); if (oper != null) { this.metaData = oper; return; } if ((this.type1.IsPrimitive || Typeob.JSObject.IsAssignableFrom(this.type1)) && (this.type2.IsPrimitive || Typeob.JSObject.IsAssignableFrom(this.type2))) { return; } this.metaData = il.DeclareLocal(Typeob.Relational); ConstantWrapper.TranslateToILInt(il, (int)this.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.relationalConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Label break_label = (Label)compilerGlobals.BreakLabelStack.Peek(this.completion.Exit - 1); this.context.EmitLineInfo(il); if (this.leavesFinally) { ConstantWrapper.TranslateToILInt(il, compilerGlobals.BreakLabelStack.Size() - this.completion.Exit); il.Emit(OpCodes.Newobj, CompilerGlobals.breakOutOfFinallyConstructor); il.Emit(OpCodes.Throw); } else if (compilerGlobals.InsideProtectedRegion) { il.Emit(OpCodes.Leave, break_label); } else { il.Emit(OpCodes.Br, break_label); } //Do not leave anything on the stack, even if rtype != Void.class }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Type elementType = rtype.GetElementType(); int count = this.count; ConstantWrapper.TranslateToILInt(il, count); il.Emit(OpCodes.Newarr, elementType); bool flag = elementType.IsValueType && !elementType.IsPrimitive; AST[] list = this.list; for (int i = 0; i < count; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); list[i].TranslateToIL(il, elementType); if (flag) { il.Emit(OpCodes.Ldelema, elementType); } Binding.TranslateToStelem(il, elementType); } }
private int TranslateToILArrayOfStrings(ILGenerator il, int n) { int len = n + 2; if (this.operand1 is Plus && this.type1 == Typeob.String) { len = ((Plus)this.operand1).TranslateToILArrayOfStrings(il, n + 1); } else { ConstantWrapper.TranslateToILInt(il, len); il.Emit(OpCodes.Newarr, Typeob.String); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldc_I4_0); Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand1); il.Emit(OpCodes.Stelem_Ref); } il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, len - 1 - n); Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand2); il.Emit(OpCodes.Stelem_Ref); return(len); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Debug.Assert(rtype.IsArray); Type etype = rtype.GetElementType(); int n = this.count; ConstantWrapper.TranslateToILInt(il, n); il.Emit(OpCodes.Newarr, etype); bool doLdelema = etype.IsValueType && !etype.IsPrimitive; AST[] list = this.list; for (int i = 0; i < n; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); list[i].TranslateToIL(il, etype); if (doLdelema) { il.Emit(OpCodes.Ldelema, etype); } Binding.TranslateToStelem(il, etype); } }
private int TranslateToILArrayOfStrings(ILGenerator il, int n) { int i = n + 2; if ((base.operand1 is Plus) && (base.type1 == Typeob.String)) { i = ((Plus)base.operand1).TranslateToILArrayOfStrings(il, n + 1); } else { ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Newarr, Typeob.String); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldc_I4_0); TranslateToStringWithSpecialCaseForNull(il, base.operand1); il.Emit(OpCodes.Stelem_Ref); } il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, (i - 1) - n); TranslateToStringWithSpecialCaseForNull(il, base.operand2); il.Emit(OpCodes.Stelem_Ref); return(i); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (rtype == Typeob.Array) { this.TranslateToILArray(il, Typeob.Object); return; } if (rtype.IsArray && rtype.GetArrayRank() == 1) { this.TranslateToILArray(il, rtype.GetElementType()); return; } int n = this.elements.count; MethodInfo constructorMethod = null; if (this.Engine.Globals.globalObject is LenientGlobalObject) { this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.getOriginalArrayConstructorMethod); constructorMethod = CompilerGlobals.constructArrayMethod; } else { constructorMethod = CompilerGlobals.fastConstructArrayLiteralMethod; } ConstantWrapper.TranslateToILInt(il, n); il.Emit(OpCodes.Newarr, Typeob.Object); for (int i = 0; i < n; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); this.elements[i].TranslateToIL(il, Typeob.Object); il.Emit(OpCodes.Stelem_Ref); } il.Emit(OpCodes.Call, constructorMethod); Convert.Emit(this, il, Typeob.ArrayObject, rtype); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (this.isFullyResolved) { base.TranslateToIL(il, rtype); return; } //Need to do a dynamic lookup to see if there is a dynamically introduced (by eval or with) hiding definition. Label done = il.DefineLabel(); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod); il.Emit(OpCodes.Castclass, Typeob.IActivationObject); il.Emit(OpCodes.Ldstr, this.name); ConstantWrapper.TranslateToILInt(il, this.lexLevel); il.Emit(OpCodes.Callvirt, CompilerGlobals.getMemberValueMethod); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Call, CompilerGlobals.isMissingMethod); il.Emit(OpCodes.Brfalse, done); //dynamic lookup succeeded, do not use the value from the early bound location. il.Emit(OpCodes.Pop); //The dynamic lookup returned Missing.Value, discard it and go on to use the value from the early bound location. base.TranslateToIL(il, Typeob.Object); il.MarkLabel(done); Convert.Emit(this, il, Typeob.Object, rtype); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (base.isFullyResolved) { base.TranslateToIL(il, rtype); } else { Label label = il.DefineLabel(); base.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod); il.Emit(OpCodes.Castclass, Typeob.IActivationObject); il.Emit(OpCodes.Ldstr, base.name); ConstantWrapper.TranslateToILInt(il, this.lexLevel); il.Emit(OpCodes.Callvirt, CompilerGlobals.getMemberValueMethod); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Call, CompilerGlobals.isMissingMethod); il.Emit(OpCodes.Brfalse, label); il.Emit(OpCodes.Pop); base.TranslateToIL(il, Typeob.Object); il.MarkLabel(label); Microsoft.JScript.Convert.Emit(this, il, Typeob.Object, rtype); } }
private void TranslateToIL(ILGenerator il, Object val, Type rtype) { IConvertible ic = Convert.GetIConvertible(val); switch (Convert.GetTypeCode(val, ic)) { case TypeCode.Empty: il.Emit(OpCodes.Ldnull); if (rtype.IsValueType) { Convert.Emit(this, il, Typeob.Object, rtype); } return; case TypeCode.Object: break; case TypeCode.DBNull: il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField("Value")); Convert.Emit(this, il, Typeob.Null, rtype); return; case TypeCode.Boolean: ConstantWrapper.TranslateToILInt(il, ic.ToInt32(null)); Convert.Emit(this, il, Typeob.Boolean, rtype); return; case TypeCode.Char: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: ConstantWrapper.TranslateToILInt(il, ic.ToInt32(null)); if (rtype.IsEnum) { return; } if (val is EnumWrapper) { Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype); } else { Convert.Emit(this, il, val.GetType(), rtype); } return; case TypeCode.UInt32: ConstantWrapper.TranslateToILInt(il, (int)ic.ToUInt32(null)); if (rtype.IsEnum) { return; } if (val is EnumWrapper) { Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype); } else { Convert.Emit(this, il, Typeob.UInt32, rtype); } return; case TypeCode.Int64: long l = ic.ToInt64(null); if (Int32.MinValue <= l && l <= Int32.MaxValue) { ConstantWrapper.TranslateToILInt(il, (int)l); il.Emit(OpCodes.Conv_I8); } else { il.Emit(OpCodes.Ldc_I8, l); } if (rtype.IsEnum) { return; } if (val is EnumWrapper) { Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype); } else { Convert.Emit(this, il, Typeob.Int64, rtype); } return; case TypeCode.UInt64: ulong ul = ic.ToUInt64(null); if (ul <= Int32.MaxValue) { ConstantWrapper.TranslateToILInt(il, (int)ul); il.Emit(OpCodes.Conv_I8); } else { il.Emit(OpCodes.Ldc_I8, (long)ul); } if (rtype.IsEnum) { return; } if (val is EnumWrapper) { Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype); } else { Convert.Emit(this, il, Typeob.UInt64, rtype); } return; case TypeCode.Single: float f = ic.ToSingle(null); if (f == f && (f != 0 || !Single.IsNegativeInfinity(1 / f))) { int i = (int)f; if (-128 <= i && i <= 127 && f == (float)i) { ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Conv_R4); } else { il.Emit(OpCodes.Ldc_R4, f); } } else { il.Emit(OpCodes.Ldc_R4, f); } Convert.Emit(this, il, Typeob.Single, rtype); return; case TypeCode.Double: double d = ic.ToDouble(null); if (d == d && (d != 0 || !Double.IsNegativeInfinity(1 / d))) { int i = (int)d; if (-128 <= i && i <= 127 && d == (double)i) { ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Conv_R8); } else { il.Emit(OpCodes.Ldc_R8, d); } } else { il.Emit(OpCodes.Ldc_R8, d); } Convert.Emit(this, il, Typeob.Double, rtype); return; case TypeCode.Decimal: int[] bits = Decimal.GetBits(ic.ToDecimal(null)); ConstantWrapper.TranslateToILInt(il, bits[0]); ConstantWrapper.TranslateToILInt(il, bits[1]); ConstantWrapper.TranslateToILInt(il, bits[2]); il.Emit(bits[3] < 0 ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); //bool isNegative ConstantWrapper.TranslateToILInt(il, (bits[3] & 0x7FFFFFFF) >> 16); il.Emit(OpCodes.Newobj, CompilerGlobals.decimalConstructor); Convert.Emit(this, il, Typeob.Decimal, rtype); return; case TypeCode.DateTime: l = ic.ToDateTime(null).Ticks; il.Emit(OpCodes.Ldc_I8, l); Convert.Emit(this, il, Typeob.Int64, rtype); return; case TypeCode.String: String str = ic.ToString(null); if (rtype == Typeob.Char && str.Length == 1) { ConstantWrapper.TranslateToILInt(il, (int)str[0]); return; } il.Emit(OpCodes.Ldstr, str); Convert.Emit(this, il, Typeob.String, rtype); return; } if (val is Enum) { if (rtype == Typeob.String) { this.TranslateToIL(il, val.ToString(), rtype); } else if (rtype.IsPrimitive) { this.TranslateToIL(il, System.Convert.ChangeType(val, Enum.GetUnderlyingType(val.GetType())), rtype); } else { Type et = val.GetType(); Type ut = Enum.GetUnderlyingType(et); this.TranslateToIL(il, System.Convert.ChangeType(val, ut), ut); il.Emit(OpCodes.Box, et); Convert.Emit(this, il, Typeob.Object, rtype); } return; } if (val is EnumWrapper) { if (rtype == Typeob.String) { this.TranslateToIL(il, val.ToString(), rtype); } else if (rtype.IsPrimitive) { this.TranslateToIL(il, ((EnumWrapper)val).ToNumericValue(), rtype); } else { Type et = ((EnumWrapper)val).type.owner.GetTypeBuilderOrEnumBuilder(); Type ut = ((EnumWrapper)val).value.GetType(); this.TranslateToIL(il, ((EnumWrapper)val).value, ut); il.Emit(OpCodes.Box, et); Convert.Emit(this, il, Typeob.Object, rtype); } return; } if (val is Type) { il.Emit(OpCodes.Ldtoken, (Type)val); il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod); Convert.Emit(this, il, Typeob.Type, rtype); } else if (val is Namespace) { il.Emit(OpCodes.Ldstr, ((Namespace)val).Name); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.getNamespaceMethod); Convert.Emit(this, il, typeof(Namespace), rtype); } else if (val is ClassScope) { il.Emit(OpCodes.Ldtoken, ((ClassScope)val).GetTypeBuilderOrEnumBuilder()); il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod); Convert.Emit(this, il, Typeob.Type, rtype); } else if (val is TypedArray) { il.Emit(OpCodes.Ldtoken, Convert.ToType((TypedArray)val)); il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod); Convert.Emit(this, il, Typeob.Type, rtype); } else if (val is NumberObject) { this.TranslateToIL(il, ((NumberObject)val).value, Typeob.Object); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.toObjectMethod); Convert.Emit(this, il, Typeob.NumberObject, rtype); } else if (val is StringObject) { il.Emit(OpCodes.Ldstr, ((StringObject)val).value); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.toObjectMethod); Convert.Emit(this, il, Typeob.StringObject, rtype); } else if (val is BooleanObject) { il.Emit(((BooleanObject)val).value ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); il.Emit(OpCodes.Box, Typeob.Boolean); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.toObjectMethod); Convert.Emit(this, il, Typeob.BooleanObject, rtype); } else if (val is ActiveXObjectConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("ActiveXObject").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is ArrayConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Array").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is BooleanConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Boolean").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is DateConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Date").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is EnumeratorConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Enumerator").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is ErrorConstructor) { ErrorConstructor error = (ErrorConstructor)val; if (error == ErrorConstructor.evalOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("EvalError").GetGetMethod()); } else if (error == ErrorConstructor.rangeOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("RangeError").GetGetMethod()); } else if (error == ErrorConstructor.referenceOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("ReferenceError").GetGetMethod()); } else if (error == ErrorConstructor.syntaxOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("SyntaxError").GetGetMethod()); } else if (error == ErrorConstructor.typeOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("TypeError").GetGetMethod()); } else if (error == ErrorConstructor.uriOb) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("URIError").GetGetMethod()); } else { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Error").GetGetMethod()); } Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is FunctionConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Function").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is MathObject) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Math").GetGetMethod()); Convert.Emit(this, il, Typeob.JSObject, rtype); } else if (val is NumberConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Number").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is ObjectConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Object").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is RegExpConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("RegExp").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is StringConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("String").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is VBArrayConstructor) { il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("VBArray").GetGetMethod()); Convert.Emit(this, il, Typeob.ScriptFunction, rtype); } else if (val is IntPtr) { il.Emit(OpCodes.Ldc_I8, (long)(IntPtr)val); il.Emit(OpCodes.Conv_I); Convert.Emit(this, il, typeof(IntPtr), rtype); } else if (val is UIntPtr) { il.Emit(OpCodes.Ldc_I8, (long)(UIntPtr)val); il.Emit(OpCodes.Conv_U); Convert.Emit(this, il, typeof(UIntPtr), rtype); } else if (val is Missing) { il.Emit(OpCodes.Ldsfld, CompilerGlobals.missingField); Convert.Emit(this, il, Typeob.Object, rtype); } else if (val is System.Reflection.Missing) { if (rtype.IsPrimitive) { this.TranslateToIL(il, Double.NaN, rtype); } else if (rtype != Typeob.Object && !rtype.IsValueType) { il.Emit(OpCodes.Ldnull); } else { il.Emit(OpCodes.Ldsfld, CompilerGlobals.systemReflectionMissingField); Convert.Emit(this, il, Typeob.Object, rtype); } } else if (val != this.value) //Value was coerced to some type we have no compile time knowlegde of { this.TranslateToIL(il, this.value, rtype); } else { throw new JScriptException(JSError.InternalError, this.context); //It should not be possible to wrap any other kind of object } }
private static MethodInvoker SpitAndInstantiateClassFor(MethodInfo method, bool requiresDemand) { TypeBuilder builder = Runtime.ThunkModuleBuilder.DefineType("invoker" + count++, TypeAttributes.Public, typeof(MethodInvoker)); MethodBuilder builder2 = builder.DefineMethod("Invoke", MethodAttributes.Virtual | MethodAttributes.Public, typeof(object), new Type[] { typeof(object), typeof(object[]) }); if (requiresDemand) { builder2.AddDeclarativeSecurity(SecurityAction.Demand, new NamedPermissionSet("FullTrust")); } builder2.SetCustomAttribute(new CustomAttributeBuilder(Runtime.TypeRefs.debuggerStepThroughAttributeCtor, new object[0])); builder2.SetCustomAttribute(new CustomAttributeBuilder(Runtime.TypeRefs.debuggerHiddenAttributeCtor, new object[0])); ILGenerator iLGenerator = builder2.GetILGenerator(); if (!method.DeclaringType.IsPublic) { method = method.GetBaseDefinition(); } Type declaringType = method.DeclaringType; if (!method.IsStatic) { iLGenerator.Emit(OpCodes.Ldarg_1); if (declaringType.IsValueType) { Microsoft.JScript.Convert.EmitUnbox(iLGenerator, declaringType, Type.GetTypeCode(declaringType)); Microsoft.JScript.Convert.EmitLdloca(iLGenerator, declaringType); } else { iLGenerator.Emit(OpCodes.Castclass, declaringType); } } ParameterInfo[] parameters = method.GetParameters(); LocalBuilder[] builderArray = null; int i = 0; int length = parameters.Length; while (i < length) { iLGenerator.Emit(OpCodes.Ldarg_2); ConstantWrapper.TranslateToILInt(iLGenerator, i); Type parameterType = parameters[i].ParameterType; if (parameterType.IsByRef) { parameterType = parameterType.GetElementType(); if (builderArray == null) { builderArray = new LocalBuilder[length]; } builderArray[i] = iLGenerator.DeclareLocal(parameterType); iLGenerator.Emit(OpCodes.Ldelem_Ref); if (parameterType.IsValueType) { Microsoft.JScript.Convert.EmitUnbox(iLGenerator, parameterType, Type.GetTypeCode(parameterType)); } iLGenerator.Emit(OpCodes.Stloc, builderArray[i]); iLGenerator.Emit(OpCodes.Ldloca, builderArray[i]); } else { iLGenerator.Emit(OpCodes.Ldelem_Ref); if (parameterType.IsValueType) { Microsoft.JScript.Convert.EmitUnbox(iLGenerator, parameterType, Type.GetTypeCode(parameterType)); } } i++; } if (((!method.IsStatic && method.IsVirtual) && !method.IsFinal) && (!declaringType.IsSealed || !declaringType.IsValueType)) { iLGenerator.Emit(OpCodes.Callvirt, method); } else { iLGenerator.Emit(OpCodes.Call, method); } Type returnType = method.ReturnType; if (returnType == typeof(void)) { iLGenerator.Emit(OpCodes.Ldnull); } else if (returnType.IsValueType) { iLGenerator.Emit(OpCodes.Box, returnType); } if (builderArray != null) { int index = 0; int num4 = parameters.Length; while (index < num4) { LocalBuilder local = builderArray[index]; if (local != null) { iLGenerator.Emit(OpCodes.Ldarg_2); ConstantWrapper.TranslateToILInt(iLGenerator, index); iLGenerator.Emit(OpCodes.Ldloc, local); Type elementType = parameters[index].ParameterType.GetElementType(); if (elementType.IsValueType) { iLGenerator.Emit(OpCodes.Box, elementType); } iLGenerator.Emit(OpCodes.Stelem_Ref); } index++; } } iLGenerator.Emit(OpCodes.Ret); return((MethodInvoker)Activator.CreateInstance(builder.CreateType())); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Type type = Convert.ToType(this.InferType(null)); if (this.metaData == null) { Type rt = Typeob.Object; if (rtype == Typeob.Double) { rt = rtype; } else if (this.type1 == Typeob.Char && this.type2 == Typeob.Char) { rt = Typeob.String; } else if (Convert.IsPrimitiveNumericType(rtype) && Convert.IsPromotableTo(this.type1, rtype) && Convert.IsPromotableTo(this.type2, rtype)) { rt = rtype; } else if (this.type1 != Typeob.String && this.type2 != Typeob.String) //Both will be converted to numbers { rt = Typeob.Double; //Won't get here unless InferType returned Typeob.Double. } else { rt = Typeob.String; } if (rt == Typeob.SByte || rt == Typeob.Int16) { rt = Typeob.Int32; } else if (rt == Typeob.Byte || rt == Typeob.UInt16 || rt == Typeob.Char) { rt = Typeob.UInt32; } if (rt == Typeob.String) { if (this.operand1 is Plus && this.type1 == rt) { Plus op1 = (Plus)this.operand1; if (op1.operand1 is Plus && op1.type1 == rt) { Plus op11 = (Plus)op1.operand1; if (op11.operand1 is Plus && op11.type1 == rt) { int len = op1.TranslateToILArrayOfStrings(il, 1); il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, len - 1); this.operand2.TranslateToIL(il, rt); il.Emit(OpCodes.Stelem_Ref); il.Emit(OpCodes.Call, CompilerGlobals.stringConcatArrMethod); Convert.Emit(this, il, rt, rtype); return; } Plus.TranslateToStringWithSpecialCaseForNull(il, op11.operand1); Plus.TranslateToStringWithSpecialCaseForNull(il, op11.operand2); Plus.TranslateToStringWithSpecialCaseForNull(il, op1.operand2); Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand2); il.Emit(OpCodes.Call, CompilerGlobals.stringConcat4Method); Convert.Emit(this, il, rt, rtype); return; } Plus.TranslateToStringWithSpecialCaseForNull(il, op1.operand1); Plus.TranslateToStringWithSpecialCaseForNull(il, op1.operand2); Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand2); il.Emit(OpCodes.Call, CompilerGlobals.stringConcat3Method); Convert.Emit(this, il, rt, rtype); return; } Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand1); Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand2); il.Emit(OpCodes.Call, CompilerGlobals.stringConcat2Method); Convert.Emit(this, il, rt, rtype); return; } this.operand1.TranslateToIL(il, rt); this.operand2.TranslateToIL(il, rt); if (rt == Typeob.Object) { il.Emit(OpCodes.Call, CompilerGlobals.plusDoOpMethod); } else if (rt == Typeob.Double || rt == Typeob.Single) { il.Emit(OpCodes.Add); } else if (rt == Typeob.Int32 || rt == Typeob.Int64) { il.Emit(OpCodes.Add_Ovf); } else { il.Emit(OpCodes.Add_Ovf_Un); } if (type == Typeob.Char) { Convert.Emit(this, il, rt, Typeob.Char); Convert.Emit(this, il, Typeob.Char, rtype); } else { Convert.Emit(this, il, rt, rtype); } return; } if (this.metaData is MethodInfo) { MethodInfo oper = (MethodInfo)this.metaData; ParameterInfo[] pars = oper.GetParameters(); this.operand1.TranslateToIL(il, pars[0].ParameterType); this.operand2.TranslateToIL(il, pars[1].ParameterType); il.Emit(OpCodes.Call, oper); Convert.Emit(this, il, oper.ReturnType, rtype); return; } //Getting here is just too bad. We do not know until the code runs whether or not to call an overloaded operator method. //Compile operands to objects and devolve the decision making to run time thunks //Also get here when dealing with Int64 and UInt64. These cannot always be converted to doubles. The late-bound code checks for this. il.Emit(OpCodes.Ldloc, (LocalBuilder)this.metaData); this.operand1.TranslateToIL(il, Typeob.Object); this.operand2.TranslateToIL(il, Typeob.Object); il.Emit(OpCodes.Callvirt, CompilerGlobals.evaluatePlusMethod); Convert.Emit(this, il, Typeob.Object, rtype); }