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 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 override void clear() { setindex = null; bindObj = null; set_this_item = null; get_this_item = null; }
private string GetLoadFieldValueStmt(string fieldname, string fieldtype, ASBinCode.rtti.ClassMember member, bool isclass, string indexArg, string addtab = "") { string result = string.Empty; if ((fieldtype == "byte[]") || (fieldtype == "System.UInt64") || (fieldtype == "System.Int64") || !isclass) { //if (prop.setter != null && prop.setter.classmember.isPublic) //{ // filed += "set { player.setMemberValue(as3Object, \"" + member.name + "\", " + GetConvertToAS3ParameterFunctionName(member.valueType) + "(value)); }"; //} if (enumMembers.ContainsKey(member.name)) { fieldtype = enumMembers[member.name]; } if (!string.IsNullOrEmpty(indexArg) && repeatEnumMembers.ContainsKey(member.name) ) { fieldtype = repeatEnumMembers[member.name]; } result += addtab + "\t\t\t" + fieldname + " = (" + fieldtype + ")(" + GetConvertFromAS3ParameterFunctionName(member.valueType) + "(player.getMemberValue(as3Object, \"" + member.name + "\" " + (string.IsNullOrEmpty(indexArg)?"":"," + indexArg) + " )));\n"; } else { //var obj = player.getMemberValue(as3Object, "[NAME]"); //if (obj != null) // ___[CNAME] = [PROPERTYTYPE].Create(obj); result += addtab + "\t\t\t{\n"; result += addtab + "\t\t\t\tvar obj = player.getMemberValue(as3Object, \"" + member.name + "\"" + (string.IsNullOrEmpty(indexArg) ? "" : "," + indexArg) + ");\n"; result += addtab + "\t\t\t\tif (obj !=null)\n"; result += addtab + "\t\t\t\t\t" + fieldname + " = " + fieldtype + ".Create(obj);\n"; result += addtab + "\t\t\t\telse\n"; result += addtab + "\t\t\t\t\t" + fieldname + " = null;\n"; result += addtab + "\t\t\t}\n"; } return(result); }
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 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); } } }
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) ); } }
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); }
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")); } }