internal void create_closure(EmitContext ec) { string name = func_obj.name; string full_name; TypeBuilder type = ec.type_builder; ILGenerator ig = ec.ig; if (prefix == String.Empty) { full_name = name; } else { full_name = prefix + "." + name; } MethodBuilder method_builder = type.DefineMethod(full_name, func_obj.attr, HandleReturnType, func_obj.params_types()); MethodBuilder tmp = (MethodBuilder)TypeManager.Get(name); if (tmp == null) { TypeManager.Add(name, method_builder); } else { TypeManager.Set(name, method_builder); } set_custom_attr(method_builder); this.ig = method_builder.GetILGenerator(); if (parent == null || parent.GetType() == typeof(ScriptBlock)) { type.DefineField(name, typeof(Microsoft.JScript.ScriptFunction), FieldAttributes.Public | FieldAttributes.Static); } else { local_func = ig.DeclareLocal(typeof(Microsoft.JScript.ScriptFunction)); TypeManager.AddLocalScriptFunction(name, local_func); } build_closure(ec, full_name, func_obj.source); }
internal override void Emit(EmitContext ec) { TypeManager.BeginScope(); string name = func_obj.name; string full_name; TypeBuilder type = ec.type_builder; ILGenerator ig = ec.ig; if (prefix == null || prefix == String.Empty) { if (name == String.Empty) { full_name = SemanticAnalyser.NextAnonymousMethod; } else { full_name = name; } } else { if (name == String.Empty) { full_name = prefix + "." + SemanticAnalyser.NextAnonymousMethod; } else { full_name = prefix + "." + name; } } MethodBuilder method_builder = type.DefineMethod(full_name, func_obj.attr, HandleReturnType, func_obj.params_types()); MethodBuilder tmp = (MethodBuilder)TypeManager.Get(name); if (tmp == null) { TypeManager.Add(name, method_builder); } else { TypeManager.Set(name, method_builder); } set_custom_attr(method_builder); EmitContext new_ec = new EmitContext(ec.type_builder, ec.mod_builder, method_builder.GetILGenerator()); if (InFunction) { local_script_func = ig.DeclareLocal(typeof(ScriptFunction)); local_func = ig.DeclareLocal(typeof(FunctionObject)); } else { if (name != String.Empty) { field = type.DefineField(name, typeof(object), FieldAttributes.Public | FieldAttributes.Static); local_func = ig.DeclareLocal(typeof(FunctionObject)); } else { local_func = ig.DeclareLocal(typeof(FunctionObject)); } } build_closure(ec, full_name, func_obj.source); func_obj.body.Emit(new_ec); new_ec.ig.Emit(OpCodes.Ret); TypeManager.EndScope(); }
internal override void Emit(EmitContext ec) { ILGenerator ig = ec.ig; bool varStm = lhs is VariableStatement; object var = null; if (varStm) { VariableStatement stm = (VariableStatement)lhs; ig.Emit(OpCodes.Ldnull); var = TypeManager.Get(((VariableDeclaration)stm.var_decls [0]).id); set_builder(ig, var); } if (obj != null) { obj.Emit(ec); } CodeGenerator.load_engine(InFunction, ig); Type convert = typeof(Convert); ig.Emit(OpCodes.Call, convert.GetMethod("ToForInObject")); ig.Emit(OpCodes.Call, typeof(ForIn).GetMethod("JScriptGetEnumerator")); Type ienumerator = typeof(IEnumerator); LocalBuilder iter = ig.DeclareLocal(ienumerator); LocalBuilder current = ig.DeclareLocal(typeof(object)); ig.Emit(OpCodes.Stloc, iter); Label init_loop = ig.DefineLabel(); Label move_next = ig.DefineLabel(); Label exit = ig.DefineLabel(); ig.Emit(OpCodes.Br, move_next); ig.MarkLabel(init_loop); if (body != null) { body.Emit(ec); } ig.MarkLabel(move_next); ig.Emit(OpCodes.Ldloc, iter); ig.Emit(OpCodes.Callvirt, ienumerator.GetMethod("MoveNext")); ig.Emit(OpCodes.Brfalse, exit); ig.Emit(OpCodes.Ldloc, iter); ig.Emit(OpCodes.Callvirt, ienumerator.GetProperty("Current").GetGetMethod()); ig.Emit(OpCodes.Stloc, current); ig.Emit(OpCodes.Ldloc, current); if (varStm) { set_builder(ig, var); } else { if (lhs is Expression) { AST ast = ((Expression)lhs).Last; if (ast is Identifier) { ((Identifier)ast).EmitStore(ec); } else { throw new NotImplementedException(); } } else { throw new NotImplementedException(); } } ig.Emit(OpCodes.Br, init_loop); ig.MarkLabel(exit); }