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); }