//仅用于链接对象的new时,直接new到栈中,此时返回缓存对象再执行后续的构造函数操作 internal StackLinkObjectCache.StackCacheObject getStackCacheObject(ASBinCode.rtti.Class clsType) { needclear = true; refPropChanged = true; index = RunTimeDataType._OBJECT; var cacheobj = _linkObjCache.getCacheObj(clsType); if (clsType.isStruct) { } else { var link = (ASBinCode.rtti.LinkSystemObject)cacheobj.value; link._class = clsType; link.SetLinkData(null); cacheobj.rtType = clsType.getRtType(); cacheobj.objScope.blockId = clsType.blockid; } //store[RunTimeDataType._OBJECT] = cacheobj; store[COMMREFTYPEOBJ] = cacheobj; return(cacheobj); }
//仅用于链接对象的赋值更新 public void setLinkObjectValue <T>(ASBinCode.rtti.Class clsType,Player player,T value) { needclear = true; refPropChanged = true; index = RunTimeDataType._OBJECT; var cacheobj = _linkObjCache.getCacheObj(clsType); if (clsType.isStruct) { var link = (ASBinCode.rtti.LinkObj <T>)cacheobj.value; link.value = value; } else { var link = (ASBinCode.rtti.LinkSystemObject)cacheobj.value; link._class = clsType; link.SetLinkData(value); cacheobj.rtType = clsType.getRtType(); cacheobj.objScope.blockId = clsType.blockid; if (link.GetLinkData() == null) { index = RunTimeDataType.rt_null; } } //store[RunTimeDataType._OBJECT] = cacheobj; store[COMMREFTYPEOBJ] = cacheobj; }
public sealed override RunTimeValueBase getSuperMethod(RunTimeScope scope, ASBinCode.rtti.Class superClass) { while (scope.scopeType != RunTimeScopeType.objectinstance) { scope = scope.parent; } var m = ((rtObjectBase)scope.this_pointer).value._class.classMembers[indexofMember]; while (!ReferenceEquals(m.virtualLinkFromClass, superClass)) { m = m.virtualLink; } //rtData.rtFunction method = new rtData.rtFunction(((ClassMethodGetter)m.bindField).functionid, true); //method.bind(scope); //method.setThis(scope.this_pointer); //return method; _cachemethod.SetValue(((ClassMethodGetter)m.bindField).functionid, true); _cachemethod.bind(scope); _cachemethod.setThis(scope.this_pointer); return(_cachemethod); }
public static ClassMethodGetter LoadClassMethodGetter(BinaryReader reader, CSWCSerizlizer serizlizer, IDictionary <int, object> serizlized, int key) { //protected int indexofMember; int indexofMember = reader.ReadInt32(); //private readonly string _name; string _name = reader.ReadString(); //public readonly int refdefinedinblockid; int refdefinedinblockid = reader.ReadInt32(); //protected int functionid; int functionid = reader.ReadInt32(); ///// <summary> ///// 比如说,私有方法就肯定不是虚方法 ///// </summary> //protected bool isNotReadVirtual = false; bool isNotReadVirtual = reader.ReadBoolean(); RunTimeDataType datetype = reader.ReadInt32(); ClassMethodGetter cg = new ClassMethodGetter(_name, null, indexofMember, refdefinedinblockid); serizlized.Add(key, cg); //protected readonly ASBinCode.rtti.Class _class; ASBinCode.rtti.Class _class = serizlizer.DeserializeObject <rtti.Class>(reader, rtti.Class.LoadClass); cg._class = _class; cg.functionid = functionid; cg.isNotReadVirtual = isNotReadVirtual; cg.valueType = datetype; return(cg); }
public ClassPropertyGetter(string name, rtti.Class _class, int indexofMember ) { this._class = _class; this.indexofMember = indexofMember; this._name = name; this._tempSlot = new PropertySlot(); this.valueType = RunTimeDataType.unknown; }
public static List <ASBinCode.rtti.Class> findClassFromProject(string t, Builder builder, ASTool.Token token) { List <ASBinCode.rtti.Class> result = new List <ASBinCode.rtti.Class>(); if (!builder.isEval) { if (t.StartsWith("Vector.<")) { ASBinCode.rtti.Class outvectortype = null; t = builder.build_vector(t, token, out outvectortype); //如果是Vector,则先编译Vector类 result.Add(outvectortype); return(result); } } if (builder.buildingclasses.Count > 0) { //在所有类中查找 List <ASBinCode.rtti.Class> imports = new List <ASBinCode.rtti.Class>(); foreach (var item in builder.buildingclasses) { imports.Add(item.Value); } for (int i = 0; i < imports.Count; i++) { if (imports[i].isPackageFunction) { continue; } if (t.IndexOf(".") > -1 && !t.StartsWith("Vector.<")) //完全限定名 { if ((imports[i].package + "." + imports[i].name).Equals(t, StringComparison.Ordinal)) { result.Add(imports[i]); } } else { string name = imports[i].name; if (name.Equals(t, StringComparison.Ordinal)) { result.Add(imports[i]); } } } } return(result); }
public MethodGetterBase(string name, rtti.Class _class, int indexofMember , int refdefinedinblockid ) { this._class = _class; this.indexofMember = indexofMember; this._name = name; this.refdefinedinblockid = refdefinedinblockid; this.valueType = RunTimeDataType.rt_function; }
private bool Circularfind(ASBinCode.rtti.Class c1, Dictionary <ASBinCode.rtti.Class, int[]> imps) { foreach (var item in imps) { if (ReferenceEquals(c1, item.Key)) { return(true); } else { return(Circularfind(c1, item.Key.implements)); } } return(false); }
private void copyextendImplements(ASBinCode.rtti.Class cls, ASBinCode.rtti.Class impl) { List <ASBinCode.rtti.Class> implist = new List <ASBinCode.rtti.Class>(); foreach (var impls in impl.implements) { if (!cls.implements.ContainsKey(impls.Key)) { cls.implements.Add(impls.Key, null); implist.Add(impls.Key); } } for (int i = 0; i < implist.Count; i++) { copyextendImplements(cls, implist[i]); } }
public static bool Object_CanImplicit_ToPrimitive(ASBinCode.rtti.Class _class, out rt primitiveType) { if (_class.staticClass == null) { primitiveType = rt.unknown; return(false); } if (_class.staticClass.implicit_to != null) { primitiveType = _class.staticClass.implicit_to_type; return(true); } primitiveType = rt.unknown; return(false); }
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 ASBinCode.rtti.ClassMember findClassMember(ASBinCode.rtti.Class cls, string name, CompileEnv env, Builder builder ) { if (env.block.scope is ASBinCode.scopes.FunctionScope) { ASBinCode.scopes.FunctionScope funcscope = env.block.scope as ASBinCode.scopes.FunctionScope; if (!funcscope.function.IsAnonymous && funcscope.parentScope is ASBinCode.scopes.ObjectInstanceScope) { return(ASBinCode.ClassMemberFinder.find( cls, name, ((ASBinCode.scopes.ObjectInstanceScope)funcscope.parentScope)._class)); } } return(ASBinCode.ClassMemberFinder.find(cls, name, builder.getClassByRunTimeDataType(ASBinCode.RunTimeDataType._OBJECT) )); }
public void buildInterfaceMemberType(ASBinCode.rtti.Class cls, Builder builder, ASTool.AS3.AS3SrcFile as3srcfile) { builder._buildingClass.Push(cls); for (int i = 0; i < cls.classMembers.Count; i++) { ASBinCode.rtti.ClassMember member = cls.classMembers[i]; if (member.bindField is ClassPropertyGetter) { ClassPropertyGetter pg = (ClassPropertyGetter)member.bindField; continue; } _doBuildMemberType(member, builder, cls); } if (builder.buildErrors.Count == 0) { copyInheritsFromImplements(cls, builder); for (int i = 0; i < cls.classMembers.Count; i++) //检查访问器类型 { //if (cls.classMembers[i].inheritFrom != null) //{ // cls.classMembers[i].setTypeWhenCompile(cls.super.classMembers[i].valueType); // continue; //} //CheckProp(cls.classMembers[i], builder); } } builder._buildingClass.Pop(); }
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); } }
private static void build_class(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, RightValueBase v1, ASBinCode.rtti.Class cls, Builder builder) { if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { ASBinCode.rtti.ClassMember member = null; //***查找对象成员*** member = MemberFinder.findClassMember(cls, step.Arg3.Data.Value.ToString(), env, builder); if (member == null) { if (cls.dynamic && cls.staticClass != null //***编译时检查不能向Class动态加属性。 ) { //***此处编译为动态属性*** build_dot_name(env, step, v1); return; } } if (member == null) { if (step.Arg3.Data.Value.ToString() == "hasOwnProperty" ) //***这是Object原型链对象,特殊处理 { //***此处编译为动态属性*** build_dot_name(env, step, v1); return; } if (v1 is SuperPointer) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "Attempted access of inaccessible property " + step.Arg3.Data.Value + " through a reference with static type " + ((SuperPointer)v1).thisClass.name + ".")); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, cls.name + "对象成员" + step.Arg3.Data.Value + "未找到")); } } if (!member.isConst && env.isEval) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "Eval时忽略非Const成员")); } build_dot(env, step, v1, member); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "静态成员名期待一个identifier")); } }
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 StaticClassDataGetter(ASBinCode.rtti.Class _class) { this._class = _class; valueType = _class.getRtType(); }
public void buildConstructor(CompileEnv env, ASTool.AS3.Expr.AS3ExprStep step, Builder builder) { if (step.OpCode == "new") { if (step.Arg1.IsReg) { ASBinCode.rtti.Class _class = null; if (step.Arg2.IsReg) { var cls = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder); if (cls is ASBinCode.StaticClassDataGetter) { _class = builder.getClassByRunTimeDataType(cls.valueType).instanceClass; build_class(env, _class, step, builder); return; } else if (cls is MethodGetterBase) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "Method cannot be used as a constructor.")); } else if (cls.valueType == ASBinCode.RunTimeDataType.rt_void || cls.valueType == ASBinCode.RunTimeDataType.rt_function) { //从Class对象中new build_void(env, cls, step, builder); return; } else if (cls.valueType > ASBinCode.RunTimeDataType.unknown) { _class = builder.getClassByRunTimeDataType(cls.valueType); if (_class.isInterface) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, _class.name + " Interfaces cannot be instantiated with the new operator.")); } else if (_class.staticClass != null) { build_class(env, _class, step, builder); } else if (cls is StackSlotAccessor && ((StackSlotAccessor)cls).isFindByPath && _class.staticClass == null) { build_class(env, _class.instanceClass, step, builder); } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "类型" + cls.valueType + "不能new")); } return; } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "类型" + cls.valueType + "不能new")); } } else { //***查找对象类型 var find = TypeReader.findClassFromImports(step.Arg2.Data.Value.ToString(), builder, step.token); if (find.Count == 1) { _class = find[0]; if (_class.isInterface) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, _class.name + " Interfaces cannot be instantiated with the new operator.")); } else if (_class.no_constructor) { } build_class(env, _class, step, builder); return; } else { var cls = ExpressionBuilder.getRightValue(env, step.Arg2, step.token, builder); if (cls is ASBinCode.StaticClassDataGetter) { _class = builder.getClassByRunTimeDataType(cls.valueType).instanceClass; build_class(env, _class, step, builder); return; } else if (cls is MethodGetterBase) { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "Method cannot be used as a constructor.")); } else if (cls.valueType == ASBinCode.RunTimeDataType.rt_void || cls.valueType == ASBinCode.RunTimeDataType.rt_function) { //从Class对象中new build_void(env, cls, step, builder); return; } else if (cls.valueType > RunTimeDataType.unknown && (builder.getClassByRunTimeDataType(cls.valueType).classid == 2 || builder.getClassByRunTimeDataType(cls.valueType).classid == 0 )) { build_void(env, cls, step, builder); return; } else { throw new BuildException( new BuildError(step.token.line, step.token.ptr, step.token.sourceFile, "类型" + cls.valueType + "不能new")); } } } } 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)); } }
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 abstract RunTimeValueBase getSuperMethod(RunTimeScope scope,ASBinCode.rtti.Class superClass);
private void copyInheritsFromImplements(ASBinCode.rtti.Class cls, Builder builder) { foreach (var supercls in cls.implements.Keys) { for (int i = 0; i < supercls.classMembers.Count; i++) { var sm = supercls.classMembers[i]; var bf = sm.bindField; if (bf is InterfaceMethodGetter) { var sig = builder.dictSignatures[((InterfaceMethodGetter)bf).refdefinedinblockid][bf]; InterfaceMethodGetter ifm = new InterfaceMethodGetter(bf.name, cls, ((InterfaceMethodGetter)bf).refdefinedinblockid); ifm.setLinkMethod((InterfaceMethodGetter)bf); bf = ifm; if (!builder.dictSignatures.ContainsKey(ifm.refdefinedinblockid)) { builder.dictSignatures.Add(ifm.refdefinedinblockid, new Dictionary <IMember, ASBinCode.rtti.FunctionSignature>()); } builder.dictSignatures[ifm.refdefinedinblockid].Add(ifm, sig); } else if (bf is ClassPropertyGetter) { ClassPropertyGetter cg = new ClassPropertyGetter(bf.name, cls, cls.classMembers.Count); cg.valueType = ((ClassPropertyGetter)bf).valueType; cg.getter = ((ClassPropertyGetter)bf).getter; cg.setter = ((ClassPropertyGetter)bf).setter; bf = cg; } ASBinCode.rtti.ClassMember member = new ASBinCode.rtti.ClassMember(sm.name, cls, bf); member.defaultValue = sm.defaultValue; member.isConst = false; member.isConstructor = false; member.isGetter = sm.isGetter; member.isInternal = false; member.isOverride = false; member.isFinal = false; member.isPrivate = false; member.isProtectd = false; member.isPublic = true; member.isSetter = sm.isSetter; member.isStatic = false; member.setTypeWhenCompile(sm.valueType); member.virtualLink = sm; //member.virtualLinkFromClass = supercls; if (sm.inheritFrom == null) { member.inheritFrom = supercls; } else { member.inheritFrom = sm.inheritFrom; } if (sm.inheritSrcMember == null) { member.inheritSrcMember = sm; } else { member.inheritSrcMember = sm.inheritSrcMember; } bool iskip = false; for (int m = 0; m < cls.classMembers.Count; m++) { var om = cls.classMembers[m]; ASTool.AS3.IAS3Stmt stmt = null; if (om.name == member.name) { if (om.bindField is ClassPropertyGetter || member.bindField is ClassPropertyGetter) { if (om.bindField is ClassPropertyGetter && member.bindField is ClassPropertyGetter) { iskip = true; break; } else { foreach (var item in builder.buildingclasses) { if (item.Value == cls) { stmt = item.Key; } } throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,一个是访问器一个不是 " + cls.name + ":" + member.name) ); } } ASBinCode.rtti.FunctionSignature sig = null; //**检查签名*** if (om.inheritFrom == null) { sig = builder.dictSignatures[cls.blockid][om.bindField]; stmt = builder._buildingmembers[om]; } else { sig = builder.dictSignatures[om.inheritFrom.blockid][om.inheritSrcMember.bindField]; stmt = builder._buildingmembers[om.inheritSrcMember]; } ASBinCode.rtti.FunctionSignature sig2 = null; if (member.inheritFrom == null) { sig2 = builder.dictSignatures[cls.blockid][member.bindField]; } else { sig2 = builder.dictSignatures[member.inheritFrom.blockid][member.inheritSrcMember.bindField]; } //***检查2个接口签名完全匹配*** if (om.isGetter != member.isGetter || om.isSetter != member.isSetter) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,访问器类型不匹配" + member.refClass.name + "::" + member.name) ); } else if (sig.returnType != sig2.returnType) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,签名不匹配" + member.refClass.name + "::" + member.name) ); } else if (sig.parameters.Count != sig2.parameters.Count) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,签名不匹配" + member.refClass.name + "::" + member.name) ); } else { //***比较所有参数*** for (int j = 0; j < sig.parameters.Count; j++) { if (sig.parameters[j].type != sig2.parameters[j].type || sig.parameters[j].isPara != sig2.parameters[j].isPara ) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "重复的接口成员,签名不匹配" + member.refClass.name + "::" + member.name) ); } } } //***检查通过,跳过这次添加*** iskip = true; } } if (!iskip) { cls.classMembers.Add(member); } } } //***拷贝完成,重新确认propertygetersetter,并设定索引*** for (int i = 0; i < cls.classMembers.Count; i++) { var m = cls.classMembers[i]; if (m.bindField is ClassPropertyGetter) { ClassPropertyGetter pg = (ClassPropertyGetter)m.bindField; //if (pg._class == cls) { pg.getter = null; pg.setter = null; for (int j = 0; j < cls.classMembers.Count; j++) { if (cls.classMembers[j].name == "@" + pg.name + "_get") { pg.getter = (InterfaceMethodGetter)cls.classMembers[j].bindField; } else if (cls.classMembers[j].name == "@" + pg.name + "_set") { pg.setter = (InterfaceMethodGetter)cls.classMembers[j].bindField; } } } } else { InterfaceMethodGetter ig = (InterfaceMethodGetter)m.bindField; ig.setIndexMember(i, cls); } } }
public SuperPointer(ASBinCode.rtti.Class superClass, rtti.Class thisClass) { this.superClass = superClass; this.thisClass = thisClass; valueType = superClass.getRtType(); }
public static List <ASBinCode.rtti.Class> findClassFromImports(string t, Builder builder, ASTool.Token token) { List <ASBinCode.rtti.Class> result = new List <ASBinCode.rtti.Class>(); if (!builder.isEval) { if (t.StartsWith("Vector.<")) { ASBinCode.rtti.Class outvectortype = null; t = builder.build_vector(t, token, out outvectortype); //如果是Vector,则先编译Vector类 result.Add(outvectortype); return(result); } } //***查找类定义*** //if (builder._buildingClass.Count > 0) //{ // //***查找是否是当前类的包外类 // var cls = builder._buildingClass.Peek(); // if (cls.mainClass == null) // { // //***查找当前类的包外类*** // foreach (var item in builder.buildingclasses) // { // if (item.Value.mainClass == cls) // { // if (item.Value.name.Equals(cls.name + "$" + t, StringComparison.Ordinal)) // { // result.Add(item.Value); // //return ASBinCode.RunTimeDataType.unknown; // } // } // } // } //} if (builder._currentImports.Count > 0) { //**查找当前导入的类 var imports = builder._currentImports.Peek(); for (int i = 0; i < imports.Count; i++) { if (imports[i].isPackageFunction) { continue; } if (t.IndexOf(".") > -1 && !t.StartsWith("Vector.<")) //完全限定名 { if ((imports[i].package + "." + imports[i].name).Equals(t, StringComparison.Ordinal)) { result.Add(imports[i]); } } else { string name = imports[i].name; if (name.Equals(t, StringComparison.Ordinal)) { result.Add(imports[i]); } } } } return(result); }
private void _doBuildMemberType(ASBinCode.rtti.ClassMember member, Builder builder, ASBinCode.rtti.Class cls) { ASTool.AS3.IAS3Stmt stmt = builder._buildingmembers[member]; CompileEnv env;// = builder._classbuildingEnv[cls]; if (member.isStatic) { env = builder._classbuildingEnv[cls.staticClass]; } else { env = builder._classbuildingEnv[cls]; } { if (stmt is ASTool.AS3.AS3Function) { member.setTypeWhenCompile(RunTimeDataType.rt_function); //**编译函数签名 builder.buildNamedFunctionSignature(env, (ASTool.AS3.AS3Function)stmt); } else { throw new Exception("异常的成员类型"); } //((Variable)env.block.scope.members[member.index]).valueType = member.valueType; if (member.bindField is Field) { throw new Exception("在接口中异常出现Field"); } } }
public ASBinCode.rtti.Class buildInterfaceDefine(ASTool.AS3.AS3Interface as3interface, Builder builder, ASBinCode.rtti.Class mainClass, ASTool.AS3.AS3SrcFile as3srcfile, bool isbuildvector, RunTimeDataType vectortype) { if (builder.buildingclasses.isExistsBuildSuccess(new ASBinCode.rtti.Class(-1, -1, builder.bin, as3srcfile.md5Key + "_" + as3interface.Name) { name = as3interface.Name, package = as3interface.Package.Name })) { //重复编译,跳过 return(null); } int classid = builder.getClassId(); int blockid = builder.getBlockId(); ASBinCode.rtti.Class cls = new ASBinCode.rtti.Class(classid, blockid, builder.bin, as3srcfile.md5Key + "_" + as3interface.Name); cls.package = as3interface.Package.Name; cls.name = as3interface.Name; builder.buildingclasses.Add(as3interface, cls); if (isbuildvector) { builder.bin.dict_Vector_type.Add(cls, vectortype); } cls.ispackageout = false; cls.isPublic = as3interface.Access.IsPublic; cls.package = as3interface.Package.Name; cls.name = as3interface.Name; cls.no_constructor = true; cls.isInterface = true; if (as3interface.Access.IsDynamic) { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "Interface attribute dynamic is invalid."); } if (as3interface.Access.IsFinal) { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "Interface attribute final is invalid."); } //cls.dynamic = as3class.Access.IsDynamic; //cls.final = as3class.Access.IsFinal; if (mainClass != null) { cls.mainClass = mainClass; cls.ispackageout = true; } NativeFunctionBase creatorfunction = null; if (as3interface.Meta != null) { foreach (var m in as3interface.Meta) { if (!m.Value.IsReg) { if (m.Value.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { if (m.Value.Data.Value.ToString() == "_IEnumerator_") { if (builder.bin.IEnumeratorInterface == null) { builder.bin.IEnumeratorInterface = cls; } else { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "[_IEnumerator_]只能指定一次"); } } else if (m.Value.Data.Value.ToString() == "_IEnumerable_") { if (builder.bin.IEnumerableInterface == null) { builder.bin.IEnumerableInterface = cls; } else { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "[_IEnumerable_]只能指定一次"); } } } } else { if (m.exprStepList != null && m.exprStepList.Count == 1) { var step = m.exprStepList[0]; if (step.Type == ASTool.AS3.Expr.OpType.CallFunc) { if (!step.Arg2.IsReg) { if (step.Arg2.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { if (step.Arg2.Data.Value.ToString() == "link_system_interface") { cls.isLink_System = true; if (step.Arg3.Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.as3_callargements) { List <ASTool.AS3.Expr.AS3DataStackElement> cargs = (List <ASTool.AS3.Expr.AS3DataStackElement>)step.Arg3.Data.Value; if (cargs.Count == 1) { if (cargs[0].Data.FF1Type == ASTool.AS3.Expr.FF1DataValueType.identifier) { string creator = cargs[0].Data.Value.ToString(); if (builder.bin.ContainsNativeFunction(creator)) { var nf = builder.bin.getNativeFunction(creator); //nativefunctions[builder.bin.nativefunctionNameIndex[creator]]; if (!(nf is ASBinCode.rtti.ILinkSystemObjCreator)) { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "链接接口必须有一个INativeFunctionRegister类型的创建器"); } creatorfunction = nf; } else if (!builder.options.CheckNativeFunctionSignature) { creatorfunction = new mocks.MockNativeFunction(creator); } else { throw new BuildException(as3interface.token.line, as3interface.token.ptr, as3interface.token.sourceFile, "本地函数 " + creator + " 未注册"); } } } } } } } } } } } } //****编译metaclass*** int metaclassid = builder.getClassId(); int metablockid = builder.getBlockId(); ASBinCode.rtti.Class metaclass = new ASBinCode.rtti.Class(metaclassid, metablockid, builder.bin, as3srcfile.md5Key + "_metaclass_" + "$" + as3interface.Name); metaclass.package = as3interface.Package.Name; metaclass.ispackageout = false; metaclass.isPublic = as3interface.Access.IsPublic; metaclass.name = "$" + as3interface.Name; metaclass.dynamic = true; metaclass.final = true; cls.staticClass = metaclass; metaclass.instanceClass = cls; if (cls.isLink_System) { builder.linkinterfaceCreators.Add(cls, creatorfunction); } return(cls); }
public ObjectInstanceScope(rtti.Class _class) { this._class = _class; }
public CodeGen(ASBinCode.rtti.Class as3class, CSWC swc, ASRuntime.Player player) { this.swc = swc; this.as3class = as3class; this.player = player; }
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)); } }
public static ASBinCode.IMember find(string name, CompileEnv env, bool isStaticMember, Builder builder, ASTool.Token token) { //List<IScope> findpath = new List<IScope>(); //List<IScope> outscopes = new List<IScope>();//查找顺序,最后查找包外代码 //Dictionary<IScope, ASBinCode.rtti.Class> finderclass = new Dictionary<IScope, ASBinCode.rtti.Class>(); //{ // ASBinCode.rtti.Class defineClass = null; // IScope s = env.block.scope; // while (s !=null) // { // if (s is ASBinCode.scopes.ObjectInstanceScope) // { // ASBinCode.rtti.Class cls = ((ASBinCode.scopes.ObjectInstanceScope)s)._class; // if (isStaticMember && cls.staticClass != null) // { // cls = cls.staticClass; // } // if (defineClass == null) // { // defineClass = cls; // if (cls.mainClass != null) // { // defineClass = cls.mainClass; // } // } // } // finderclass.Add(s,defineClass); // if (s is ASBinCode.scopes.OutPackageMemberScope && !(ReferenceEquals(s,env.block.scope))) // { // outscopes.Add(s); // } // else // { // findpath.Add(s); // } // s = s.parentScope; // } // findpath.AddRange(outscopes); //} //ASBinCode.IScope scope = null; //for (int j = 0; j < findpath.Count; j++) //{ // scope = findpath[j]; // if (scope is ASBinCode.scopes.ObjectInstanceScope) // { // //查找类方法 // ASBinCode.rtti.Class cls = ((ASBinCode.scopes.ObjectInstanceScope)scope)._class; // var fm = ASBinCode.ClassMemberFinder.find(cls, name, finderclass[scope]); // if (fm != null) // { // return fm.bindField; // } // } // if (!(scope is ASBinCode.scopes.OutPackageMemberScope) // || // ( // finderclass[scope] == null // || // ((ASBinCode.scopes.OutPackageMemberScope)scope).mainclass == finderclass[scope] // ) // ) // { // //从后往前找。可解决catch块同名变量e问题 // for (int i = scope.members.Count - 1; i >= 0; i--) // { // if (scope.members[i].name == name // ) // { // return scope.members[i].clone(); // } // } // } //} bool skipoutpackagescope = false; ASBinCode.rtti.Class defineClass = null; ASBinCode.IScope scope = env.block.scope; while (scope != null) { if (scope is ASBinCode.scopes.ObjectInstanceScope) { //查找类方法 ASBinCode.rtti.Class cls = ((ASBinCode.scopes.ObjectInstanceScope)scope)._class; if (defineClass == null) { defineClass = cls; } if (!isStaticMember && cls.staticClass == null) { defineClass = defineClass.instanceClass; skipoutpackagescope = true; break; } else { var fm = ASBinCode.ClassMemberFinder.find(cls, name, defineClass); if (fm != null) { return(fm.bindField); } else { break; } } } if (!(scope is ASBinCode.scopes.OutPackageMemberScope) || ( defineClass == null || ((ASBinCode.scopes.OutPackageMemberScope)scope).mainclass == defineClass ) ) { //从后往前找。可解决catch块同名变量e问题 for (int i = scope.members.Count - 1; i >= 0; i--) { if (scope.members[i].name == name ) { return(scope.members[i].clone()); } } } scope = scope.parentScope; } //***如果成员未找到,查找@__buildin__// if (!env.isEval) { var buildin = TypeReader.findClassFromImports("@__buildin__", builder, token); if (buildin.Count == 1) { var bi = buildin[0].staticClass; var member = ClassMemberFinder.find(bi, name, bi); if (member != null && !(member.bindField is ClassPropertyGetter) && member.inheritFrom == null && member.name != "Object" ) { FindStaticMember sm = new FindStaticMember(); sm.classMember = member; sm.static_class = new StaticClassDataGetter(bi); return(sm); //return member.bindField; } } } //***在静态成员中查找*** var findstaticclass = defineClass; while (findstaticclass != null && findstaticclass.staticClass != null) { var bi = findstaticclass.staticClass; var member = ClassMemberFinder.find(bi, name, defineClass.staticClass); if (member != null) { if (member != null && member.bindField is ClassPropertyGetter && name == "prototype") { throw new BuildException(token.line, token.ptr, token.sourceFile, "Access of possibly undefined property prototype."); } FindStaticMember sm = new FindStaticMember(); sm.classMember = member; sm.static_class = new StaticClassDataGetter(bi); return(sm); //return member.bindField; } findstaticclass = findstaticclass.super; } if (skipoutpackagescope) { return(null); } if (defineClass != null && defineClass.mainClass != null) { defineClass = defineClass.mainClass; } //***在包外代码中查找**** if (defineClass != null && defineClass.staticClass != null) { IScope outpackagescope = null; if (defineClass.mainClass == null) { outpackagescope = builder._class_outScopeBlock[defineClass].scope; } else { outpackagescope = builder._class_outScopeBlock[defineClass.mainClass].scope; } for (int i = outpackagescope.members.Count - 1; i >= 0; i--) { if (outpackagescope.members[i].name == name ) { //return outpackagescope.members[i].clone(); FindOutPackageScopeMember fo = new FindOutPackageScopeMember(); fo.member = outpackagescope.members[i].clone(); fo.outscopeclass = ((ASBinCode.scopes.OutPackageMemberScope)outpackagescope).mainclass; return(fo); //return fo; } } } return(null); }
private void buildInterfaceMember(CompileEnv env, ASTool.AS3.IAS3Stmt stmt, ASBinCode.rtti.Class cls, Builder builder ) { if (stmt is ASTool.AS3.AS3Block) { ASTool.AS3.AS3Block as3block = (ASTool.AS3.AS3Block)stmt; for (int i = 0; i < as3block.CodeList.Count; i++) { buildInterfaceMember(env, as3block.CodeList[i], cls, builder); } } else if (stmt is ASTool.AS3.AS3Function) { ASTool.AS3.AS3Function as3function = (ASTool.AS3.AS3Function)stmt; { if (!as3function.IsAnonymous) { //List<ASBinCode.rtti.ClassMember> tooverridefunctions = new List<ASBinCode.rtti.ClassMember>(); string funcname = as3function.Name; if (as3function.IsGet || as3function.IsSet) { funcname = "@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"); } //for (int j = 0; j < cls.classMembers.Count; j++) //{ // if (cls.classMembers[j].name == funcname //as3function.Name // && // ( // cls.classMembers[j].inheritFrom == null // || // (cls.classMembers[j].isPublic && as3function.Access.IsPublic // ) // ) // && // ( // cls.classMembers[j].inheritFrom != null // && // !cls.classMembers[j].inheritFrom.classMembers[j].isConstructor // ) // ) // { // if (as3function.Access.IsOverride // ) // { // if (!(cls.classMembers[j].bindField is ClassMethodGetter) // || // cls.classMembers[j].inheritFrom.classMembers[j].isConstructor // ) // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "Method marked override must override another method.") // ); // } // if (cls.classMembers[j].isFinal) // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "Cannot redefine a final method.") // ); // } // tooverridefunctions.Add(cls.classMembers[j]); // continue; // } // if (cls.classMembers[j].inheritFrom == null // ) // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "重复的类成员:" + as3function.Name) // ); // } // else // { // throw new BuildException( // new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, // "Overriding a function that is not marked for override") // ); // } // } //} if (as3function.Access.IsStatic) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "The static attribute may be used only on definitions inside a class.") ); } if (as3function.Access.IsOverride) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "The override attribute can only be used on a method defined in a class.") ); } //***非访问器*** if (!as3function.IsGet && !as3function.IsSet) { ASBinCode.rtti.ClassMember member = new ASBinCode.rtti.ClassMember(as3function.Name, cls, new InterfaceMethodGetter(as3function.Name, cls, env.block.id) ); member.setTypeWhenCompile(RunTimeDataType.rt_function); member.isInternal = as3function.Access.IsInternal; member.isPrivate = as3function.Access.IsPrivate; member.isProtectd = as3function.Access.IsProtected; member.isPublic = as3function.Access.IsPublic; member.isStatic = as3function.Access.IsStatic; member.isConst = true; member.isOverride = as3function.Access.IsOverride; member.isFinal = as3function.Access.IsFinal; member.isGetter = as3function.IsGet; member.isSetter = as3function.IsSet; member.isConstructor = as3function.IsConstructor; if (member.isPrivate) { ((MethodGetterBase)member.bindField).setNotReadVirtual(); } int s = 0; if (member.isPrivate) { s++; } if (member.isPublic) { s++; } if (member.isProtectd) { s++; } if (member.isInternal) { s++; } if (s != 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Members of an interface cannot be declared public, private, protected, or internal.") ); } member.isPublic = true; if (as3function.FunctionBody.Nodes.Count > 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Methods defined in an interface must not have a body.") ); } cls.classMembers.Add(member); builder._buildingmembers.Add(member, as3function); } else { ASBinCode.rtti.ClassMember member = new ASBinCode.rtti.ClassMember("@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"), cls, new InterfaceMethodGetter("@" + as3function.Name + (as3function.IsGet ? "_get" : "_set"), cls, env.block.id) ); member.setTypeWhenCompile(RunTimeDataType.rt_function); member.isInternal = as3function.Access.IsInternal; member.isPrivate = as3function.Access.IsPrivate; member.isProtectd = as3function.Access.IsProtected; member.isPublic = as3function.Access.IsPublic; member.isStatic = as3function.Access.IsStatic; member.isConst = true; member.isOverride = as3function.Access.IsOverride; member.isFinal = as3function.Access.IsFinal; member.isGetter = as3function.IsGet; member.isSetter = as3function.IsSet; member.isConstructor = as3function.IsConstructor; if (member.isGetter && member.isSetter) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "不能同时是getter和setter") ); } int s = 0; if (member.isPrivate) { s++; } if (member.isPublic) { s++; } if (member.isProtectd) { s++; } if (member.isInternal) { s++; } if (s != 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Members of an interface cannot be declared public, private, protected, or internal.") ); } member.isPublic = true; if (as3function.FunctionBody.Nodes.Count > 0) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "Methods defined in an interface must not have a body.") ); } cls.classMembers.Add(member); builder._buildingmembers.Add(member, as3function); //***查找ClassPropertyGetter**** ClassPropertyGetter pg = null; for (int i = 0; i < cls.classMembers.Count; i++) { if (cls.classMembers[i].name == as3function.Name && cls.classMembers[i].inheritFrom == null) { if (cls.classMembers[i].bindField is ClassPropertyGetter) { pg = (ClassPropertyGetter)cls.classMembers[i].bindField; if (member.isGetter && pg.getter != null && cls.classMembers[pg.getter.indexOfMembers].inheritFrom == null ) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "属性访问器重复") ); } else if (member.isSetter && pg.setter != null && cls.classMembers[pg.setter.indexOfMembers].inheritFrom == null ) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "属性设置器重复") ); } } else { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "期望一个属性") ); } } } if (pg == null) { pg = new ClassPropertyGetter(as3function.Name, cls, cls.classMembers.Count); ASBinCode.rtti.ClassMember m = new ASBinCode.rtti.ClassMember(as3function.Name, cls, pg); cls.classMembers.Add(m); m.isPublic = true; m.isStatic = member.isStatic; } if (member.isGetter) { pg.getter = (MethodGetterBase)member.bindField; } else { pg.setter = (MethodGetterBase)member.bindField; } } } else { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "'function' is not allowed here") ); } } } else if (stmt is ASTool.AS3.AS3Variable) { //字段 数据成员 throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "A 'var' declaration is not permitted in an interface.") ); // } else if (stmt is ASTool.AS3.AS3Const) { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "A 'const' declaration is not permitted in an interface.") ); } else { throw new BuildException( new BuildError(stmt.Token.line, stmt.Token.ptr, stmt.Token.sourceFile, "接口成员中不能出现" + stmt) ); } }