private SLOT _getArgementSlot(int id) { var signature = toCallFunc.signature; if (signature.onStackParameters > 0) { ASBinCode.rtti.FunctionParameter fp = signature.parameters[id]; if (fp.isOnStack) { StackSlotAccessor r = (StackSlotAccessor)fp.varorreg; //int index = invokerFrame.offset + invokerFrame.block.totalRegisters + 1 + 1 + invokerFrame.call_parameter_slotCount + r._index; int index = invokerFrame.baseBottomSlotIndex + invokerFrame.call_parameter_slotCount + r._index; return(invokerFrame.stack[index]); } else { return(CallFuncHeap[((Variable)fp.varorreg).indexOfMembers]); } } else { return(CallFuncHeap[id]); } }
private void _storeArgementToSlot(int id,RunTimeValueBase v) { var signature = toCallFunc.signature; if (signature.onStackParameters > 0) { ASBinCode.rtti.FunctionParameter fp = signature.parameters[id]; if (fp.isOnStack) { StackSlotAccessor r = (StackSlotAccessor)fp.varorreg; //int index = invokerFrame.offset + invokerFrame.block.totalRegisters + 1 + 1+ invokerFrame.call_parameter_slotCount + r._index; int index = invokerFrame.baseBottomSlotIndex + invokerFrame.call_parameter_slotCount + r._index; invokerFrame.stack[index].directSet(v); } else { CallFuncHeap[((Variable)fp.varorreg).indexOfMembers].directSet( v ); } } else { CallFuncHeap[id].directSet(v); } }
private static void _execSuffixDec_toString_Callbacker(ASBinCode.RunTimeValueBase v1, ASBinCode.RunTimeValueBase v2, StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope) { double n = TypeConverter.ConvertToNumber(v1); step.reg.getSlot(scope, frame).setValue(n); ASBinCode.rtData.rtNumber num = new ASBinCode.rtData.rtNumber(--n); StackSlotAccessor register = step.arg1 as StackSlotAccessor; if (register != null) { bool issuccess; register.getSlotForAssign(scope, frame).assign(num, out issuccess); if (!issuccess) { frame.throwError(step.token, 0, "操作失败"); } } else { ((ASBinCode.LeftValueBase)step.arg1).getSlot(scope, frame).directSet(num); } frame.endStep(step); }
public static void make_dotStep(CompileEnv env, ASBinCode.rtti.ClassMember member, ASTool.Token token, StackSlotAccessor eax, RightValueBase rvObj ) { OpStep op = new OpStep( member.bindField is MethodGetterBase ? OpCode.access_method : OpCode.access_dot , new SourceToken(token.line, token.ptr, token.sourceFile)); RightValueBase field = (RightValueBase)member.bindField; op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = rvObj; op.arg1Type = rvObj.valueType; op.arg2 = field; op.arg2Type = member.valueType; env.block.opSteps.Add(op); }
private static void _execSuffixInc_ValueOf_Callbacker(ASBinCode.RunTimeValueBase v1, ASBinCode.RunTimeValueBase v2, StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope) { if (v1.rtType > ASBinCode.RunTimeDataType.unknown) { OpCast.InvokeTwoToString(v1, ASBinCode.rtData.rtNull.nullptr, frame, step.token, scope, frame._tempSlot1, frame._tempSlot2, step, _execSuffixInc_toString_Callbacker); } else { double n = TypeConverter.ConvertToNumber(v1); step.reg.getSlot(scope, frame).setValue(n); ASBinCode.rtData.rtNumber num = new ASBinCode.rtData.rtNumber(++n); StackSlotAccessor register = step.arg1 as StackSlotAccessor; if (register != null) { bool issuccess; ((StackSlot)register.getSlotForAssign(scope, frame)).assign(num, out issuccess); if (!issuccess) { frame.throwError(step.token, 0, "操作失败"); } } else { ((ASBinCode.LeftValueBase)step.arg1).getSlot(scope, frame).directSet(num); } frame.endStep(step); } }
public static void execDecInt(StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope) { var v = step.arg1.getValue(scope, frame); StackSlotAccessor register = step.arg1 as StackSlotAccessor; if (register != null) { ((StackSlot)register.getSlotForAssign(scope, frame)).linkTo(null); } { ASBinCode.rtData.rtInt iv = (ASBinCode.rtData.rtInt)v; iv.value--; ((LeftValueBase)step.arg1).getSlot(scope, frame).directSet(iv); ((ASBinCode.LeftValueBase)step.reg).getSlot(scope, frame).setValue(iv.value); } //frame.endStep(step); frame.endStepNoError(); }
private void build_void(CompileEnv env, RightValueBase cls, ASTool.AS3.Expr.AS3ExprStep step, Builder builder) { OpStep opnewclass = new OpStep(OpCode.new_instance_class, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); opnewclass.arg1 = cls; opnewclass.arg1Type = RunTimeDataType.rt_void; StackSlotAccessor _eax = env.createASTRegister(step.Arg1.Reg); _eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void); opnewclass.reg = _eax; opnewclass.regType = RunTimeDataType.rt_void; OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_class_argement, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); opMakeArgs.arg1 = cls; opMakeArgs.arg1Type = RunTimeDataType.rt_void; env.block.opSteps.Add(opMakeArgs); if (step.Arg3 != null) { List <ASTool.AS3.Expr.AS3DataStackElement> args = (List <ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value; for (int i = 0; i < args.Count; i++) { ASTool.AS3.Expr.AS3DataStackElement argData = args[i]; RightValueBase arg = builds.ExpressionBuilder.getRightValue(env, argData, step.token, builder); //***参数准备*** OpStep opPushArgs = new OpStep(OpCode.push_parameter_class, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); opPushArgs.arg1 = arg; opPushArgs.arg1Type = arg.valueType; opPushArgs.arg2 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(i)); opPushArgs.arg2Type = RunTimeDataType.rt_int; env.block.opSteps.Add(opPushArgs); } } env.block.opSteps.Add(opnewclass); }
public void build_class(CompileEnv env, ASBinCode.rtti.Class _class, ASTool.Token token, Builder builder, StackSlotAccessor outeax, List <ASTool.AS3.Expr.AS3DataStackElement> args ) { //***查找构造函数** if (_class.constructor != null) { MethodGetterBase field = (MethodGetterBase)_class.constructor.bindField; //(Field)builder._classbuildingEnv[_class].block.scope.members[_class.constructor.index]; int blockid = field.refdefinedinblockid; var signature = builder.dictSignatures[blockid][field]; FuncCallBuilder funcbuilder = new FuncCallBuilder(); funcbuilder.createParaOp(args, signature, token, env, field, builder, true, _class); } else { OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_argement, new SourceToken(token.line, token.ptr, token.sourceFile)); opMakeArgs.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(_class.classid)); opMakeArgs.arg1Type = RunTimeDataType.rt_int; env.block.opSteps.Add(opMakeArgs); } OpStep op = new OpStep(OpCode.new_instance, new SourceToken(token.line, token.ptr, token.sourceFile)); op.arg1 = new RightValue(new rtInt(_class.classid)); op.arg1Type = _class.getRtType(); outeax.setEAXTypeWhenCompile(_class.getRtType()); op.reg = outeax; op.regType = _class.getRtType(); env.block.opSteps.Add(op); }
public static void exec_link(StackFrame frame, OpStep step, RunTimeScope scope) { StackSlot l = (StackSlot)step.reg.getSlot(scope, frame); int classid = ((ASBinCode.rtData.rtInt)step.arg2.getValue(scope, frame)).value; var outscope = frame.player.outpackage_runtimescope[classid]; SLOT outpackagescopeslot = ((VariableBase)step.arg1).getSlot(outscope,null); StackSlotAccessor register = (StackSlotAccessor)step.reg; if (register._isassigntarget || register._hasUnaryOrShuffixOrDelete) { l.linkTo(outpackagescopeslot); } else { l.directSet(outpackagescopeslot.getValue()); } frame.endStep(step); }
public static void execIncrement(StackFrame frame, ASBinCode.OpStep step, ASBinCode.RunTimeScope scope) { var v = step.arg1.getValue(scope, frame); StackSlotAccessor register = step.arg1 as StackSlotAccessor; if (register != null) { ((StackSlot)register.getSlotForAssign(scope, frame)).linkTo(null); } switch (v.rtType) { case ASBinCode.RunTimeDataType.rt_int: { ASBinCode.rtData.rtInt iv = (ASBinCode.rtData.rtInt)v; iv.value++; ((LeftValueBase)step.arg1).getSlot(scope, frame).directSet(iv); step.reg.getSlot(scope, frame).setValue(iv.value); } break; case ASBinCode.RunTimeDataType.rt_uint: { ASBinCode.rtData.rtUInt iv = (ASBinCode.rtData.rtUInt)v; iv.value++; ((LeftValueBase)step.arg1).getSlot(scope, frame).directSet(iv); step.reg.getSlot(scope, frame).setValue(iv.value); } break; case ASBinCode.RunTimeDataType.rt_number: { ASBinCode.rtData.rtNumber iv = (ASBinCode.rtData.rtNumber)v; iv.value++; ((LeftValueBase)step.arg1).getSlot(scope, frame).directSet(iv); step.reg.getSlot(scope, frame).setValue(iv.value); } break; case ASBinCode.RunTimeDataType.rt_string: { double n = TypeConverter.ConvertToNumber(v); if (string.IsNullOrEmpty(((ASBinCode.rtData.rtString)v).value)) { n = 0; } ASBinCode.rtData.rtNumber num = new ASBinCode.rtData.rtNumber(++n); step.reg.getSlot(scope, frame).directSet(num); } break; case ASBinCode.RunTimeDataType.rt_boolean: case ASBinCode.RunTimeDataType.rt_void: case ASBinCode.RunTimeDataType.rt_null: { double n = TypeConverter.ConvertToNumber(v); ASBinCode.rtData.rtNumber num = new ASBinCode.rtData.rtNumber(++n); ((ASBinCode.LeftValueBase)step.reg).getSlot(scope, frame).directSet(num); } break; case ASBinCode.RunTimeDataType.unknown: default: { OpCast.InvokeTwoValueOf(v, ASBinCode.rtData.rtNull.nullptr, frame, step.token, scope, frame._tempSlot1, frame._tempSlot2, step, _execIncrement_ValueOf_Callbacker); return; } } //frame.endStep(step); frame.endStepNoError(); }
private void build_class(CompileEnv env, ASBinCode.rtti.Class _class, ASTool.AS3.Expr.AS3ExprStep step, Builder builder) { //***参数检查*** List <ASTool.AS3.Expr.AS3DataStackElement> args; if (!step.Arg2.IsReg && step.Arg2.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.as3_vector) { ASTool.AS3.AS3Vector vector = (ASTool.AS3.AS3Vector)step.Arg2.Data.Value; if (vector.Constructor == null) { args = new List <ASTool.AS3.Expr.AS3DataStackElement>(); } else { if (vector.isInitData) { args = new List <ASTool.AS3.Expr.AS3DataStackElement>(); } else { args = (List <ASTool.AS3.Expr.AS3DataStackElement>)vector.Constructor.Data.Value; } } } else { if (step.Arg3 != null) { args = (List <ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value; } else { args = new List <ASTool.AS3.Expr.AS3DataStackElement>(); } } StackSlotAccessor insEax = env.createASTRegister(step.Arg1.Reg); build_class(env, _class, step.token, builder, insEax, args ); if (!step.Arg2.IsReg && step.Arg2.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.as3_vector) { ASTool.AS3.AS3Vector vector = (ASTool.AS3.AS3Vector)step.Arg2.Data.Value; if (vector.Constructor != null && vector.isInitData) { //***追加初始化Vector*** var initdata = (List <ASTool.AS3.Expr.AS3DataStackElement>)vector.Constructor.Data.Value; var vt = builder.bin.dict_Vector_type[_class]; for (int i = 0; i < initdata.Count; i++) { var d = ExpressionBuilder.getRightValue(env, initdata[i], step.token, builder); if (!ASRuntime.TypeConverter.testImplicitConvert(d.valueType, vt, builder)) { throw(new BuildException(new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "不能将[" + d.valueType + "]类型存入Vector.<" + vt + ">"))); } if (d.valueType != vt) { d = ExpressionBuilder.addCastOpStep(env, d, vt, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder); } OpStep oppush = new OpStep(OpCode.vector_push, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); oppush.reg = null; oppush.regType = RunTimeDataType.unknown; oppush.arg1 = insEax; oppush.arg1Type = insEax.valueType; oppush.arg2 = d; oppush.arg2Type = d.valueType; env.block.opSteps.Add(oppush); } //throw new NotImplementedException(); } } ////***查找构造函数** //if (_class.constructor != null) //{ // ClassMethodGetter field = (ClassMethodGetter)_class.constructor.bindField; //(Field)builder._classbuildingEnv[_class].block.scope.members[_class.constructor.index]; // int blockid = field.refdefinedinblockid; // var signature = // builder.dictSignatures[blockid][field]; // //***参数检查*** // List<ASTool.AS3.Expr.AS3DataStackElement> args; // if (step.Arg3 != null) // { // args = (List<ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value; // } // else // { // args = new List<ASTool.AS3.Expr.AS3DataStackElement>(); // } // FuncCallBuilder funcbuilder = new FuncCallBuilder(); // funcbuilder.createParaOp(args, signature, step, env, field, builder, true, _class); //} //else //{ // OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_argement, // new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); // opMakeArgs.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(_class.classid)); // opMakeArgs.arg1Type = RunTimeDataType.rt_int; // env.block.opSteps.Add(opMakeArgs); //} //OpStep op = new OpStep(OpCode.new_instance, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); //op.arg1 = new RightValue(new rtInt(_class.classid)); //op.arg1Type = _class.getRtType(); //Register eax = env.createASTRegister(step.Arg1.Reg.ID); //eax.setEAXTypeWhenCompile(_class.getRtType()); //op.reg = eax; //op.regType = _class.getRtType(); //env.block.opSteps.Add(op); }
public void build_class(CompileEnv env, ASBinCode.rtti.Class _class, ASTool.Token token, Builder builder, StackSlotAccessor outeax, List <ASTool.AS3.Expr.AS3DataStackElement> args ) { var _cls = _class; if (_cls.staticClass == null) { _cls = _cls.instanceClass; } if (_cls.isLink_System) { OpStep stepInitClass = new OpStep(OpCode.init_staticclass, new SourceToken(token.line, token.ptr, token.sourceFile)); stepInitClass.arg1 = new ASBinCode.rtData.RightValue( new ASBinCode.rtData.rtInt(_cls.classid)); stepInitClass.arg1Type = _cls.staticClass.getRtType(); env.block.opSteps.Add(stepInitClass); } //***查找构造函数** if (_class.constructor != null) { MethodGetterBase field = (MethodGetterBase)_class.constructor.bindField; //(Field)builder._classbuildingEnv[_class].block.scope.members[_class.constructor.index]; int blockid = field.refdefinedinblockid; var signature = builder.dictSignatures[blockid][field]; FuncCallBuilder funcbuilder = new FuncCallBuilder(); OpStep opMakeArgs = null; funcbuilder.createParaOp(out opMakeArgs, args, signature, token, env, field, builder, true, _class); if (_cls.isLink_System) { if (signature.parameters.Count == 0) { opMakeArgs.opCode = OpCode.prepare_constructor_argement_linksystem; opMakeArgs.memregid1 = 0; } else { bool canconvert = true; for (int i = 0; i < signature.parameters.Count; i++) { if (signature.parameters[i].defaultValue != null || signature.parameters[i].isPara) { canconvert = false; } } if (canconvert) { opMakeArgs.opCode = OpCode.prepare_constructor_argement_linksystem; opMakeArgs.memregid1 = (short)signature.parameters.Count; } } } } else { OpStep opMakeArgs = new OpStep(OpCode.prepare_constructor_argement, new SourceToken(token.line, token.ptr, token.sourceFile)); opMakeArgs.arg1 = new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(_class.classid)); opMakeArgs.arg1Type = RunTimeDataType.rt_int; env.block.opSteps.Add(opMakeArgs); if (_cls.isLink_System) { opMakeArgs.opCode = OpCode.prepare_constructor_argement_linksystem; opMakeArgs.memregid1 = 0; } } OpStep op = new OpStep(OpCode.new_instance, new SourceToken(token.line, token.ptr, token.sourceFile)); op.arg1 = new RightValue(new rtInt(_class.classid)); op.arg1Type = _class.getRtType(); outeax.setEAXTypeWhenCompile(_class.getRtType()); op.reg = outeax; op.regType = _class.getRtType(); env.block.opSteps.Add(op); }
public static void exec_AccessorBind_ConvertIdx(StackFrame frame, OpStep step, RunTimeScope scope) { RunTimeValueBase obj = step.arg1.getValue(scope, frame); if (rtNull.nullptr.Equals(obj)) { frame.throwError( step.token, 1009, "Cannot access a property or method of a null object reference." ); frame.endStep(); return; } ASBinCode.rtti.Vector_Data vector = (ASBinCode.rtti.Vector_Data)((ASBinCode.rtti.HostedObject)((ASBinCode.rtData.rtObjectBase)obj).value).hosted_object; var idxvalue = step.arg2.getValue(scope, frame); double idx = double.NaN; if (idxvalue.rtType > RunTimeDataType.unknown) { RunTimeDataType ot; if (TypeConverter.Object_CanImplicit_ToPrimitive(idxvalue.rtType, frame.player.swc, out ot)) { var v = TypeConverter.ObjectImplicit_ToPrimitive((rtObjectBase)idxvalue); idx = TypeConverter.ConvertToNumber(v); } } else if (idxvalue.rtType == RunTimeDataType.rt_string || idxvalue.rtType == RunTimeDataType.rt_int || idxvalue.rtType == RunTimeDataType.rt_number || idxvalue.rtType == RunTimeDataType.rt_uint ) { idx = TypeConverter.ConvertToNumber(idxvalue); } if (double.IsNaN(idx)) { frame.throwError( step.token, 0, "索引" + idxvalue + "不能转为int" ); } else { int index = (int)idx; if (index < 0 || index > vector.innnerList.Count) { frame.throwError(step.token, 1125, "The index " + index + " is out of range " + vector.innnerList.Count + "."); } StackSlotAccessor reg = (StackSlotAccessor)step.reg; if (idx == vector.innnerList.Count) { if (vector.isFixed || !reg._isassigntarget) { frame.throwError(step.token, 1125, "The index " + idx + " is out of range " + vector.innnerList.Count + "."); frame.endStep(step); return; } else { vector.innnerList.Add(TypeConverter.getDefaultValue(vector.vector_type).getValue(null, null)); } } StackSlot slot = (StackSlot)step.reg.getSlot(scope, frame); if (reg._isassigntarget || reg._hasUnaryOrShuffixOrDelete) { slot._cache_vectorSlot.idx = index; slot._cache_vectorSlot.vector_data = vector; slot.linkTo(slot._cache_vectorSlot); } else { slot.directSet(vector.innnerList[index]); } } frame.endStep(step); }
public static void exec_AccessorBind(StackFrame frame, OpStep step, RunTimeScope scope) { RunTimeValueBase obj = step.arg1.getValue(scope, frame); if (rtNull.nullptr.Equals(obj)) { frame.throwError( step.token, 1009, "Cannot access a property or method of a null object reference." ); frame.endStep(); return; } ASBinCode.rtti.Vector_Data vector = (ASBinCode.rtti.Vector_Data)((ASBinCode.rtti.HostedObject)((rtObjectBase)obj).value).hosted_object; int idx = TypeConverter.ConvertToInt(step.arg2.getValue(scope, frame)); if (idx < 0 || idx > vector.innnerList.Count) { frame.throwError(step.token, 1125, "The index " + idx + " is out of range " + vector.innnerList.Count + "."); } StackSlotAccessor reg = (StackSlotAccessor)step.reg; if (idx == vector.innnerList.Count) { if (vector.isFixed || !reg._isassigntarget) { frame.throwError(step.token, 1125, "The index " + idx + " is out of range " + vector.innnerList.Count + "." ); frame.endStep(step); return; } else { vector.innnerList.Add(TypeConverter.getDefaultValue(vector.vector_type).getValue(null, null)); } } StackSlot slot = (StackSlot)step.reg.getSlot(scope, frame); if (reg._isassigntarget || reg._hasUnaryOrShuffixOrDelete) { slot._cache_vectorSlot.idx = idx; slot._cache_vectorSlot.vector_data = vector; slot.linkTo(slot._cache_vectorSlot); } else { slot.directSet(vector.innnerList[idx]); } frame.endStep(step); }
public void buildAS3ForEach(CompileEnv env, ASTool.AS3.AS3ForEach as3foreach, Builder builder) { if (!string.IsNullOrEmpty(as3foreach.label)) { //**包装一个block** ASTool.AS3.AS3Block tempblock = new ASTool.AS3.AS3Block(as3foreach.Token); tempblock.CodeList = new List <ASTool.AS3.IAS3Stmt>(); tempblock.CodeList.Add(as3foreach); tempblock.label = as3foreach.label; as3foreach.label = null; OpStep lbl_forlabel = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_forlabel.flag = "LOOP_LABEL_START_" + tempblock.label; env.block.opSteps.Add(lbl_forlabel); builder.buildStmt(env, tempblock); OpStep lbl_forlabel_end = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_forlabel_end.flag = "LOOP_LABEL_END_" + tempblock.label; env.block.opSteps.Add(lbl_forlabel_end); } else { int lblid = env.getLabelId(); builder.buildStmt(env, as3foreach.ForArg); LeftValueBase varvalue = null; if (as3foreach.ForArg is ASTool.AS3.AS3StmtExpressions) { ASTool.AS3.AS3StmtExpressions exprs = (ASTool.AS3.AS3StmtExpressions)as3foreach.ForArg; if (exprs.as3exprlist.Count != 1) { throw new BuildException( as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile, "Syntax error: invalid for-in initializer, only 1 expression expected."); } ASTool.AS3.AS3Expression expr = exprs.as3exprlist[0]; varvalue = (LeftValueBase)ExpressionBuilder.getRightValue(env, expr.Value, expr.token, builder); } else if (as3foreach.ForArg is ASTool.AS3.AS3Variable) { ASTool.AS3.AS3Variable v = (ASTool.AS3.AS3Variable)as3foreach.ForArg; varvalue = (VariableBase)MemberFinder.find(v.Name, env, false, builder, v.token); } else { throw new BuildException( as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile, "异常错误,获得的变量类型不正确"); } builder.buildExpression(env, as3foreach.ForExpr); RightValueBase enumerator = ExpressionBuilder.getRightValue(env, as3foreach.ForExpr.Value, as3foreach.ForExpr.token, builder); if (enumerator.valueType == RunTimeDataType.rt_void || enumerator.valueType < RunTimeDataType.unknown ) { enumerator = ExpressionBuilder.addCastOpStep(env, enumerator, RunTimeDataType._OBJECT, new SourceToken(as3foreach.ForExpr.token.line, as3foreach.ForExpr.token.ptr, as3foreach.ForExpr.token.sourceFile) , builder); } //Register regSaveEnumerator = env.getAdditionalRegister(); Variable varSaveEnumerator = new Variable("@saveEnumeraor_" + env.block.scope.members.Count, env.block.scope.members.Count, env.block.id); env.block.scope.members.Add(varSaveEnumerator); varSaveEnumerator.valueType = (RunTimeDataType.rt_void); { //**IEnumerator Get And Reset(); OpStep opGetEnumerator = new OpStep(OpCode.foreach_get_enumerator, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) ); opGetEnumerator.reg = varSaveEnumerator; opGetEnumerator.regType = RunTimeDataType.rt_void; opGetEnumerator.arg1 = enumerator; opGetEnumerator.arg1Type = enumerator.valueType; env.block.opSteps.Add(opGetEnumerator); } string loopstart = "LOOP_START_" + lblid; string loopbody = "LOOP_BODY_" + lblid; string loopcontinue = "LOOP_CONTINUE_" + lblid; string loopend = "LOOP_END_" + lblid; { OpStep lbl_loopstart = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopstart.flag = loopstart; env.block.opSteps.Add(lbl_loopstart); } StackSlotAccessor eaxismovenext = env.getAdditionalRegister(); eaxismovenext.setEAXTypeWhenCompile(RunTimeDataType.rt_boolean); { //**IEnumerator MoveNext() OpStep opMoveNext = new OpStep(OpCode.enumerator_movenext, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) ); opMoveNext.reg = eaxismovenext; opMoveNext.regType = RunTimeDataType.rt_boolean; opMoveNext.arg1 = varSaveEnumerator; opMoveNext.arg1Type = varSaveEnumerator.valueType; env.block.opSteps.Add(opMoveNext); } { OpStep op = new OpStep(OpCode.if_jmp, new SourceToken(as3foreach.ForExpr.token.line, as3foreach.ForExpr.token.ptr, as3foreach.ForExpr.token.sourceFile)); op.reg = null; op.regType = RunTimeDataType.unknown; op.arg1 = eaxismovenext; op.arg1Type = eaxismovenext.valueType; op.arg2 = new ASBinCode.rtData.RightValue( new ASBinCode.rtData.rtString(loopbody)); op.arg2Type = RunTimeDataType.rt_string; env.block.opSteps.Add(op); } { ASTool.AS3.AS3StmtExpressions jumptoend = new ASTool.AS3.AS3StmtExpressions(as3foreach.Token); jumptoend.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3foreach.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3foreach.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = loopend; expression.exprStepList.Add(step); jumptoend.as3exprlist.Add(expression); builder.buildStmt(env, jumptoend); } { OpStep lbl_loopbody = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopbody.flag = loopbody; env.block.opSteps.Add(lbl_loopbody); } { RightValueBase loadValue = env.getAdditionalRegister(); ((StackSlotAccessor)loadValue).setEAXTypeWhenCompile(RunTimeDataType.rt_void); //**IEnumerator Current() OpStep opCurrent = new OpStep(OpCode.enumerator_current, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) ); opCurrent.reg = (StackSlotAccessor)loadValue; opCurrent.regType = RunTimeDataType.rt_void; opCurrent.arg1 = varSaveEnumerator; opCurrent.arg1Type = varSaveEnumerator.valueType; env.block.opSteps.Add(opCurrent); if (varvalue.valueType != RunTimeDataType.rt_void) { loadValue = ExpressionBuilder.addCastOpStep(env, loadValue, varvalue.valueType, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile) , builder ); } var op = new OpStep(OpCode.assigning, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); op.reg = varvalue; op.regType = varvalue.valueType; op.arg1 = loadValue; op.arg1Type = loadValue.valueType; op.arg2 = null; op.arg2Type = RunTimeDataType.unknown; env.block.opSteps.Add(op); } if (as3foreach.Body != null) { for (int i = 0; i < as3foreach.Body.Count; i++) { builder.buildStmt(env, as3foreach.Body[i]); } } { OpStep lbl_loopcontinue = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopcontinue.flag = loopcontinue; env.block.opSteps.Add(lbl_loopcontinue); } { //强行跳回开始 ASTool.AS3.AS3StmtExpressions jumptostart = new ASTool.AS3.AS3StmtExpressions(as3foreach.Token); jumptostart.as3exprlist = new List <ASTool.AS3.AS3Expression>(); ASTool.AS3.AS3Expression expression = new ASTool.AS3.AS3Expression(as3foreach.Token); expression.exprStepList = new ASTool.AS3.Expr.AS3ExprStepList(); ASTool.AS3.Expr.AS3ExprStep step = new ASTool.AS3.Expr.AS3ExprStep(as3foreach.Token); step.Type = ASTool.AS3.Expr.OpType.GotoFlag; step.OpCode = loopstart; expression.exprStepList.Add(step); jumptostart.as3exprlist.Add(expression); builder.buildStmt(env, jumptostart); } { //结束标记 OpStep lbl_loopend = new OpStep(OpCode.flag, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); lbl_loopend.flag = loopend; env.block.opSteps.Add(lbl_loopend); } { OpStep opClose = new OpStep(OpCode.enumerator_close, new SourceToken(as3foreach.Token.line, as3foreach.Token.ptr, as3foreach.Token.sourceFile)); opClose.reg = null; opClose.regType = RunTimeDataType.unknown; opClose.arg1 = varSaveEnumerator; opClose.arg1Type = RunTimeDataType.rt_void; opClose.arg2 = null; opClose.arg2Type = RunTimeDataType.rt_void; env.block.opSteps.Add(opClose); } } }