public void Serialize(BinaryWriter writer, CSWCSerizlizer serizlizer) { writer.Write(id); writer.Write(name); writer.Write(define_class_id); writer.Write(isoutclass); writer.Write(hasTryStmt); writer.Write((ushort)totalStackSlots); serizlizer.SerializeObject(writer, (scopes.ScopeBase)scope); //writer.Write(opSteps.Count); //for (int i = 0; i < opSteps.Count; i++) //{ // var step = opSteps[i]; // serizlizer.SerializeObject(writer, step); //} writer.Write((ushort)instructions.Length); for (int i = 0; i < instructions.Length; i++) { var step = instructions[i]; serizlizer.SerializeObject(writer, step); } writer.Write((ushort)regConvFromVar.Length); for (int i = 0; i < regConvFromVar.Length; i++) { StackSlotAccessor conv = regConvFromVar[i]; //conv.Serialize(writer, serizlizer); serizlizer.SerializeObject(writer, conv); } }
private static void build_dot(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, ASBinCode.rtti.ClassMember member) { ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax._regMember = member; eax._regMemberSrcObj = v1; eax.setEAXTypeWhenCompile(member.valueType); make_dotStep(env, member, step.token, eax, v1); //OpStep op = new OpStep( // member.bindField is ClassMethodGetter? // OpCode.access_method // : // OpCode.access_dot // , new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); //op.reg = eax; //op.regType = eax.valueType; //op.arg1 = v1; //op.arg1Type = v1.valueType; //op.arg2 = (IRightValue)member.bindField; //new ASBinCode.rtData.RightValue(new ASBinCode.rtData.rtInt(member.index)); //op.arg2Type = member.valueType; //RunTimeDataType.rt_int; //env.block.opSteps.Add(op); }
public static StackSlotAccessor LoadRegister(BinaryReader reader,CSWCSerizlizer serizlizer,IDictionary <int,object> serizlized,int key) { RunTimeDataType valuetype = reader.ReadInt32(); //public readonly int Id; int id = reader.ReadInt32(); //public int _index; int _index = reader.ReadInt32(); //public readonly int stmtid; int stmtid = reader.ReadInt32(); StackSlotAccessor register = new StackSlotAccessor(id,stmtid); serizlized.Add(key,register); register._index = _index; ///// <summary> ///// 指示是否delete目标 ///// </summary> //public bool _isdeletetarget; register._isdeletetarget = reader.ReadBoolean(); ///// <summary> ///// 指示是否对其有=赋值操作 ///// </summary> //public bool _isassigntarget; register._isassigntarget = reader.ReadBoolean(); ///// <summary> ///// 指示是否对其有++,--,delete操作 ///// </summary> //public bool _hasUnaryOrShuffixOrDelete; register._hasUnaryOrShuffixOrDelete = reader.ReadBoolean(); ///// <summary> ///// 指示是否对其有++,-- ///// </summary> //public bool _hasUnaryOrShuffix; register._hasUnaryOrShuffix = reader.ReadBoolean(); ///// <summary> ///// 只是是否. [] 操作的目标 ///// </summary> //public bool _isDotAccessTarget; register._isDotAccessTarget = reader.ReadBoolean(); //public bool isFindByPath; register.isFindByPath = reader.ReadBoolean(); //public bool isFuncResult; register.isFuncResult = reader.ReadBoolean(); //public bool isConvertFromVariable; register.isConvertFromVariable = reader.ReadBoolean(); return(register); }
private static void build_dot_name(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1) { ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void); OpStep op = new OpStep(OpCode.access_dot_byname, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = new ASBinCode.rtData.RightValue( new ASBinCode.rtData.rtString(step.Arg3.Data.Value.ToString())); op.arg2Type = RunTimeDataType.rt_string; env.block.opSteps.Add(op); }
public static CodeBlock Deserialize(BinaryReader reader, CSWCSerizlizer serizlizer, IDictionary <int, object> serizlized, int key) { var id = reader.ReadInt32(); var name = reader.ReadString(); //writer.Write(name); var define_class_id = reader.ReadInt32(); //writer.Write(define_class_id); var isoutclass = reader.ReadBoolean(); //writer.Write(isoutclass); var hasTryStmt = reader.ReadBoolean(); // writer.Write(hasTryStmt); CodeBlock block = new CodeBlock(id, name, define_class_id, isoutclass); block.hasTryStmt = hasTryStmt; serizlized.Add(key, block); block.totalStackSlots = reader.ReadUInt16(); block.scope = serizlizer.DeserializeObject <scopes.ScopeBase>(reader, scopes.ScopeBase.Deserialize); int stepscount = reader.ReadUInt16(); block.instructions = new OpStep[stepscount]; block.opSteps = null; for (int i = 0; i < stepscount; i++) { OpStep step = serizlizer.DeserializeObject <OpStep>(reader, OpStep.Deserialize); //block.opSteps.Add(step); block.instructions[i] = step; } int regconvcount = reader.ReadUInt16(); block.regConvFromVar = new StackSlotAccessor[regconvcount]; for (int i = 0; i < regconvcount; i++) { StackSlotAccessor register = (StackSlotAccessor)serizlizer.DeserializeObject <ISWCSerializable>(reader, ISWCSerializableLoader.LoadIMember); block.regConvFromVar[i] = register; } return(block); }
public static ISWCSerializable LoadIMember(BinaryReader reader, CSWCSerizlizer serizlizer, IDictionary <int, object> serizlized, int key) { int membertype = reader.ReadInt32(); if (membertype == 0) { return(ClassMethodGetter.LoadClassMethodGetter(reader, serizlizer, serizlized, key)); } else if (membertype == 1) { return(InterfaceMethodGetter.LoadInterfaceMethodGetter(reader, serizlizer, serizlized, key)); } else if (membertype == 2) { return(ClassPropertyGetter.LoadClassPropertyGetter(reader, serizlizer, serizlized, key)); } else if (membertype == 3) { return(Variable.LoadVariable(reader, serizlizer, serizlized, key)); } else if (membertype == 4) { return(Field.LoadField(reader, serizlizer, serizlized, key)); } else if (membertype == 5) { return(StackSlotAccessor.LoadRegister(reader, serizlizer, serizlized, key)); } else if (membertype == 6) { return(rtData.RightValue.LoadRightValue(reader, serizlizer, serizlized, key)); } else if (membertype == 7) { return(StaticClassDataGetter.LoadStaticClassDataGetter(reader, serizlizer, serizlized, key)); } else if (membertype == 8) { return(ThisPointer.LoadThisPointer(reader, serizlizer, serizlized, key)); } else if (membertype == 9) { return(SuperPointer.LoadSuperPointer(reader, serizlizer, serizlized, key)); } else if (membertype == 10) { return(MemRegister_Number.LoadRegister(reader, serizlizer, serizlized, key)); } else if (membertype == 11) { return(MemRegister_Boolean.LoadRegister(reader, serizlizer, serizlized, key)); } else if (membertype == 12) { return(MemRegister_Int.LoadRegister(reader, serizlizer, serizlized, key)); } else if (membertype == 13) { return(MemRegister_UInt.LoadRegister(reader, serizlizer, serizlized, key)); } //else if (membertype == 14) //{ // return MemRegister_Object.LoadRegister(reader, serizlizer, serizlized, key); //} else { throw new IOException("格式异常"); } }
public void buildAccess(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, Builder builder) { if (step.OpCode == ".") { if (step.Arg1.IsReg) { ASBinCode.RightValueBase v1 = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder); if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { if (step.Arg3.Data.Value.ToString() == "null") { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "Syntax error: 'null' is not allowed here")); } } //ASBinCode.IRightValue v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder); if (v1 is ASBinCode.StaticClassDataGetter) { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { ASBinCode.StaticClassDataGetter sd = (ASBinCode.StaticClassDataGetter)v1; var cls = sd._class; build_class(env, step, v1, cls, builder); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } else if (v1 is PackagePathGetter) { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { PackagePathGetter pd = (PackagePathGetter)v1; string path = pd.path + "." + step.Arg3.Data.Value.ToString(); //**尝试查找类*** var found = TypeReader.findClassFromProject(path, builder, step.token); if (found.Count == 1) { var item = found[0]; OpStep stepInitClass = new OpStep(OpCode.init_staticclass, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); stepInitClass.arg1 = new ASBinCode.rtData.RightValue( new ASBinCode.rtData.rtInt(item.classid)); stepInitClass.arg1Type = item.staticClass.getRtType(); env.block.opSteps.Add(stepInitClass); ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax.setEAXTypeWhenCompile(item.staticClass.getRtType()); eax.isFindByPath = true; //eax._pathGetter = new PackagePathGetter(path); OpStep op = new OpStep(OpCode.assigning, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; op.arg1 = new StaticClassDataGetter(item.staticClass); op.arg1Type = item.staticClass.getRtType(); env.block.opSteps.Add(op); } else if (found.Count > 1) { throw new BuildException(step.token.line, step.token.ptr, step.token.sourceFile, "类型" + path + "不明确." ); } else { //没找到 PackagePathGetter g = new PackagePathGetter(path); ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax.setEAXTypeWhenCompile(RunTimeDataType.unknown); eax._pathGetter = g; } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } else if (v1 is ThisPointer && v1.valueType == RunTimeDataType.rt_void) { //throw new BuildException( // new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, // "动态查找成员 还没弄")); if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { build_dot_name(env, step, v1); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } else if (v1.valueType == RunTimeDataType.unknown) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "遇到了unknown类型")); } else if (v1.valueType > RunTimeDataType.unknown) { ASBinCode.rtti.Class cls = builder.getClassByRunTimeDataType(v1.valueType); if (cls == null) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "编译异常 类型" + v1.valueType + "未找到")); } else { build_class(env, step, v1, cls, builder); } } else { if (v1.valueType != RunTimeDataType.rt_void && v1.valueType < RunTimeDataType.unknown) { if ( builder.bin != null && builder.bin.primitive_to_class_table[v1.valueType] != null) { var cls = builder.bin.primitive_to_class_table[v1.valueType]; v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(), new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder ); build_class(env, step, v1, cls, builder); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "基础类型" + v1.valueType + "无法转换为引用类型")); } } else { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { build_dot_name(env, step, v1); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "编译异常 此处应该是个寄存器")); } } else if (step.OpCode == "[") //和.作用相同 { if (step.Arg1.IsReg) { ASBinCode.RightValueBase v1 = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder); if (v1 is ASBinCode.StaticClassDataGetter) { build_bracket_access(env, step, v1, builder); } else if (v1 is PackagePathGetter) { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { PackagePathGetter pd = (PackagePathGetter)v1; string path = pd.path + "." + step.Arg3.Data.Value.ToString(); //**尝试查找类*** //查找导入的类 var found = TypeReader.findClassFromImports(path, builder, step.token); if (found.Count == 1) { var item = found[0]; OpStep stepInitClass = new OpStep(OpCode.init_staticclass, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); stepInitClass.arg1 = new ASBinCode.rtData.RightValue( new ASBinCode.rtData.rtInt(item.classid)); stepInitClass.arg1Type = item.staticClass.getRtType(); env.block.opSteps.Add(stepInitClass); ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax.setEAXTypeWhenCompile(item.getRtType()); OpStep op = new OpStep(OpCode.assigning, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; op.arg1 = new StaticClassDataGetter(item.staticClass); op.arg1Type = item.staticClass.getRtType(); env.block.opSteps.Add(op); build_bracket_access(env, step, v1, builder); } else { throw new BuildException(step.token.line, step.token.ptr, step.token.sourceFile, "类型" + path + "不明确." ); } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } else if (v1 is ThisPointer && v1.valueType == RunTimeDataType.rt_void) { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { build_bracket_access(env, step, v1, builder); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } } else if (v1.valueType == RunTimeDataType.unknown) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "遇到了unknown类型")); } else if (v1.valueType > RunTimeDataType.unknown) { ASBinCode.rtti.Class cls = builder.getClassByRunTimeDataType(v1.valueType); if (cls == null) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "编译异常 类型" + v1.valueType + "未找到")); } else { //**todo**检查如果是数组的情况**** build_bracket_access(env, step, v1, builder); } } else { if (v1.valueType == RunTimeDataType.rt_array) { var v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder); if (v2.valueType == RunTimeDataType.rt_int || v2.valueType == RunTimeDataType.rt_number || v2.valueType == RunTimeDataType.rt_uint) { build_bracket_access(env, step, v1, builder); } else { v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(), new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder ); build_bracket_access(env, step, v1, builder); } } else if (v1.valueType != RunTimeDataType.rt_void && v1.valueType < RunTimeDataType.unknown ) { if (builder.bin.primitive_to_class_table[v1.valueType] != null) { v1 = ExpressionBuilder.addCastOpStep(env, v1, builder.bin.primitive_to_class_table[v1.valueType].getRtType(), new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder ); build_bracket_access(env, step, v1, builder); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "基础类型" + v1.valueType + "无法转换为引用类型")); } } else { build_bracket_access(env, step, v1, builder); } } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "编译异常 此处应该是个寄存器")); } } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "不支持的操作类型 " + step.Type + " " + step.OpCode)); } }
private static void build_bracket_access(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, Builder builder) { ASBinCode.StackSlotAccessor eax = env.createASTRegister(step.Arg1.Reg); eax.setEAXTypeWhenCompile(RunTimeDataType.rt_void); var v2 = ExpressionBuilder.getRightValue(env, step.Arg3, step.token, builder); if (v1.valueType == RunTimeDataType.rt_void ) { OpStep op = new OpStep(OpCode.bracket_access, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } else if (v1.valueType > RunTimeDataType.unknown && builder.bin.dict_Vector_type.ContainsKey(builder.getClassByRunTimeDataType(v1.valueType)) ) { ASBinCode.rtti.Class vector = builder.getClassByRunTimeDataType(v1.valueType); RunTimeDataType vt = builder.bin.dict_Vector_type[vector]; if (v2.valueType > RunTimeDataType.unknown) { v2 = ExpressionBuilder.addCastToPrimitive(env, v2, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile), builder); } if (v2.valueType == RunTimeDataType.rt_int || v2.valueType == RunTimeDataType.rt_number || v2.valueType == RunTimeDataType.rt_uint ) { v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder); eax.setEAXTypeWhenCompile(vt); { OpStep op = new OpStep(OpCode.vectorAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } } else { OpStep op = new OpStep(OpCode.vectorAccessor_convertidx, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } //if (v2.valueType != RunTimeDataType.rt_int) //{ // v2=ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int, // new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) // , builder); //} //eax.setEAXTypeWhenCompile(vt); //eax._vector_Type = vt; //{ // OpStep op = new OpStep(OpCode.vectorAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); // op.reg = eax; // op.regType = eax.valueType; // op.arg1 = v1; // op.arg1Type = v1.valueType; // op.arg2 = v2; // op.arg2Type = v2.valueType; // env.block.opSteps.Add(op); //} } else if (builder.bin.ArrayClass != null && builder.bin.ArrayClass.getRtType() == v1.valueType && (v2.valueType == RunTimeDataType.rt_int || v2.valueType == RunTimeDataType.rt_number || v2.valueType == RunTimeDataType.rt_uint ) ) { v1 = builds.ExpressionBuilder.addCastToPrimitive(env, v1, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile), builder); v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder); OpStep op = new OpStep(OpCode.arrayAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } else if (v1.valueType == RunTimeDataType.rt_array && (v2.valueType == RunTimeDataType.rt_int || v2.valueType == RunTimeDataType.rt_number || v2.valueType == RunTimeDataType.rt_uint ) ) { v2 = ExpressionBuilder.addCastOpStep(env, v2, RunTimeDataType.rt_int, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile) , builder); OpStep op = new OpStep(OpCode.arrayAccessor_bind, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } else { OpStep op = new OpStep(OpCode.bracket_byname, new SourceToken(step.token.line, step.token.ptr, step.token.sourceFile)); op.reg = eax; eax._isDotAccessTarget = true; op.regType = eax.valueType; op.arg1 = v1; op.arg1Type = v1.valueType; op.arg2 = v2; op.arg2Type = v2.valueType; env.block.opSteps.Add(op); } }