private AbcMethod BuildUnary(IMethod op) { if (op == null) { throw new ArgumentNullException("op"); } var abcOp = _generator.MethodBuilder.BuildAbcMethod(op); var instance = _generator.TypeBuilder.BuildInstance(op.DeclaringType); string name = "this_" + abcOp.TraitName.NameString; var thisName = Abc.DefineName(QName.Global(name)); var retType = _generator.TypeBuilder.BuildReturnType(op.Type); return(instance.DefineMethod( Sig.@this(thisName, retType), code => { code.Getlex(instance); code.GetLocal(0); code.Call(abcOp); code.Coerce(op.Type, true); code.ReturnValue(); })); }
private AbcMethod BuildAddressImpl(IMethod method, AbcInstance instance) { if (method.IsStatic) { return(null); } var type = method.DeclaringType; if (!type.IsArray) { return(null); } if (method.Name != CLRNames.Array.Address) { return(null); } var elemPtr = _generator.Pointers.ElemPtr.Instance; string name = "GetAddr_" + method.GetParametersSignature(Runtime.Avm); return(instance.DefineMethod( Sig.@this(name, elemPtr.Name, method), code => { code.Getlex(elemPtr); code.LoadThis(); //arr ToFlatIndex(code, method.Parameters.Count, true); code.Construct(2); code.ReturnValue(); })); }
public AbcMethod Build(BinaryOperator op, IType left, IType right) { var method = Find(op, left, right); if (method == null) { throw new InvalidOperationException(); } var abcOp = _generator.MethodBuilder.BuildAbcMethod(method); var instance = _generator.TypeBuilder.BuildInstance(method.DeclaringType); Debug.Assert(instance.Abc == Abc); string name = "this_" + abcOp.TraitName.NameString; var thisName = Abc.DefineName(QName.Global(name)); var retType = _generator.TypeBuilder.BuildReturnType(method.Type); return(instance.DefineMethod( Sig.@this(thisName, retType, right, "right"), code => { code.Getlex(instance); code.GetLocal(0); //left code.GetLocal(1); //right code.Call(abcOp); code.Coerce(retType); code.ReturnValue(); })); }
private AbcMethod BuildSetterImpl(IMethod method, AbcInstance instance) { if (method.IsStatic) { return(null); } var type = method.DeclaringType; if (!type.IsArray) { return(null); } if (method.Name != CLRNames.Array.Setter) { return(null); } var name = _generator.MethodBuilder.DefineQName(method); return(instance.DefineMethod( Sig.@this(name, method.Type, method), code => { int n = method.Parameters.Count; code.LoadThis(); ToFlatIndex(code, n, false); code.GetLocal(n); //value code.SetArrayElem(false); code.ReturnVoid(); })); }
private AbcMethod BuildGetterImpl(IMethod method, AbcInstance instance) { if (method.IsStatic) { return(null); } var type = method.DeclaringType; if (!type.IsArray) { return(null); } if (method.Name != CLRNames.Array.Getter) { return(null); } //string name = "Get" + NameUtil.GetParamsString(method); var name = _generator.MethodBuilder.DefineQName(method); return(instance.DefineMethod( Sig.@this(name, method.Type, method), code => { code.LoadThis(); ToFlatIndex(code, method.Parameters.Count, true); code.GetArrayElem(method.Type, false); code.ReturnValue(); })); }
void DefineInitTypeMethod(IType type, int typeId) { Debug.Assert(typeId >= 0); var instance = _generator.Corlib.Assembly.Instance; instance.DefineMethod( Sig.@this(QName.Global(Const.InitTypePrefix + typeId), AvmTypeCode.Void, SystemTypes.Type, "type"), code => { InitTypeInfo(code, type, typeId); code.ReturnVoid(); }); }
public AbcMethod GetElemPtr() { var instance = _generator.Corlib.Array.Instance; var name = _generator.Abc.DefineName(QName.PfxPublic("GetElemPtr")); return(instance.DefineMethod( Sig.@this(name, AvmTypeCode.Object, AvmTypeCode.Int32, "index"), code => { var ptr = ElemPtr.Instance; code.Getlex(ptr); code.LoadThis(); code.GetLocal(1); //index code.Construct(2); code.ReturnValue(); })); }
/// <summary> /// Signature: void Instance.__copy_from__(Instance value) /// </summary> /// <param name="instance"></param> /// <returns></returns> public static AbcMethod CopyFrom(AbcInstance instance) { var type = instance.Type; if (!type.SupportsCopyMethods()) { return(null); } var generator = instance.Generator; var name = generator.Abc.DefineName(QName.PfxPublic("__copy_from__")); return(instance.DefineMethod( Sig.@this(name, AvmTypeCode.Void, instance.Name, "value"), code => { code.CopySlots(instance, 1, 0); code.ReturnVoid(); })); }
private AbcMethod DefineInitFlexAppStyles(AbcInstance instance) { var done = instance.DefineSlot("_init_styles_done", AvmTypeCode.Boolean); return(instance.DefineMethod( Sig.@this("$init_flex_styles$", AvmTypeCode.Void), code => { code.LoadThis(); code.GetProperty(done); var br = code.IfFalse(); code.ReturnVoid(); br.BranchTarget = code.Label(); code.LoadThis(); code.Add(InstructionCode.Pushtrue); code.SetProperty(done); //TODO: init app CSSStyleDeclaration //TODO: init app effects if (IsFlex4) { code.LoadThis(); code.GetProperty("styleManager"); code.CallVoid("initProtoChainRoots", 0); } else { var styleMgr = _generator.ImportType("mx.styles.StyleManager"); code.Getlex(styleMgr); code.CallVoid(Abc.DefineName(QName.MxInternal("initProtoChainRoots")), 0); } code.ReturnVoid(); })); }
private AbcMethod DefineBaseCall(IType receiverType, IMethod method) { var instance = DefineAbcInstance(receiverType); var mname = GetMethodName(method); string prefix = "$C" + instance.Index; prefix += GetBaseCallPrefix(method); var rname = _abc.DefineQName(mname.Namespace, prefix + mname.NameString); var retType = DefineMemberType(method.Type); return(instance.DefineMethod( Sig.@this(rname, retType, method), code => { code.LoadThis(); code.LoadArguments(method); CallCore(code, method, mname, true); code.Return(method); })); }
/// <summary> /// Signature: Instance Instance.__copy__() /// </summary> /// <param name="instance"></param> /// <returns></returns> public static AbcMethod Copy(AbcInstance instance) { var type = instance.Type; if (type == null) { return(null); } if (!type.SupportsCopyMethods()) { return(null); } var generator = instance.Generator; var name = generator.Abc.DefineName(QName.PfxPublic("__copy__")); return(instance.DefineMethod( Sig.@this(name, instance.Name), code => { //SUPER BUG: //For some times like System.Int64 DefineCopyMethod method can be called before DefineFields //so we should define type fields generator.TypeBuilder.DefineFields(type); const int obj = 1; code.CreateInstance(instance); code.SetLocal(obj); code.CopySlots(instance, 0, obj); code.GetLocal(obj); code.ReturnValue(); })); }
void BuildSystemManagerInfo(AbcFile abc, AbcInstance instance) { var objType = abc.BuiltinTypes.Object; if (_cacheInfoObject) { var method = instance.DefineMethod(Sig.@this("$info$", objType), null); _compiler.AddLateMethod(method, BuildSystemManagerInfo); var infoField = instance.DefineSlot("__info", AvmTypeCode.Object); instance.DefineMethod( Sig.@virtual("info", objType).@override(), code => { code.LoadThis(); code.GetProperty(infoField); var br = code.IfNotNull(); code.LoadThis(); code.LoadThis(); code.Call(method); code.SetProperty(infoField); br.BranchTarget = code.Label(); code.LoadThis(); code.GetProperty(infoField); code.ReturnValue(); }); } else { var method = instance.DefineMethod(Sig.@virtual("info", objType).@override(), null); _compiler.AddLateMethod(method, BuildSystemManagerInfo); } }
internal AbcInstance DefineFlexInitMixin(AbcFile app) { var flexModuleFactoryInterface = FlexTypes.GetFlexModuleFactoryInterface(app); var childManagerInstance = FlexTypes.GetChildManagerInstance(app); var flex4 = childManagerInstance != null; string name = "_FlexInit_" + _compiler.FlexAppPrefix; string ns = _compiler.RootNamespace; var instance = new AbcInstance(true) { Name = app.DefineName(QName.Package(ns, name)), BaseTypeName = app.BuiltinTypes.Object, IsMixin = true, IsFlexInitMixin = true, Initializer = app.DefineMethod( Sig.@this(null, AvmTypeCode.Void), code => { code.ConstructSuper(); code.ReturnVoid(); }), Class = { Initializer = app.DefineEmptyMethod() } }; app.AddInstance(instance); instance.DefineMethod( Sig.@static("init", AvmTypeCode.Void, flexModuleFactoryInterface, "f"), code => { code.PushThisScope(); const int moduleFactoryArg = 1; const int styleManagerVar = 2; if (flex4) { CreateInstance(code, childManagerInstance, moduleFactoryArg); code.Pop(); var styleManager2 = FlexTypes.GetStyleManager2Interface(app); var styleManagerImpl = FlexTypes.GetStyleManagerImpl(app); CreateInstance(code, styleManagerImpl, moduleFactoryArg); code.Coerce(styleManager2); code.SetLocal(styleManagerVar); } RegisterEffectTriggers(app, code); RegisterRemoteClasses(app, code); Action pushStyleManager; if (flex4) { pushStyleManager = () => code.GetLocal(styleManagerVar); } else { pushStyleManager = () => code.Getlex(FlexTypes.GetStyleManagerInstance(app)); } RegisterInheritStyles(app, code, pushStyleManager, flex4); //NOTE: Uncomment to add forward refernce to Flex Application //var appInstance = app.generator.MainInstance; //code.Trace(string.Format("PFC: forward reference to FlexApp class {0}", appInstance.FullName)); //code.Getlex(appInstance); //code.Pop(); code.ReturnVoid(); }); return(instance); }
public AbcMethod GetElemInt64(IType elemType, bool item) { if (elemType == null) { throw new ArgumentNullException("elemType"); } if (!elemType.IsInt64Based()) { throw new ArgumentException("Invalid elem type"); } if (elemType.IsEnum) { elemType = elemType.ValueType; } string name = (item ? "get_item_" : "get_elem_") + elemType.GetSigName(); var elemTypeName = BuildReturnType(elemType); var oppositeType = elemType.Is(SystemTypeCode.Int64) ? SystemTypes.UInt64 : SystemTypes.Int64; var oppositeTypeName = BuildReturnType(oppositeType); return(Instance.DefineMethod( Sig.@this(name, elemTypeName, AvmTypeCode.Int32, "index"), code => { const int index = 1; const int value = 2; code.LoadThis(); code.GetLocal(index); code.Call(item ? ArrayMethodId.GetItem : ArrayMethodId.GetElem); code.CoerceObject(); code.SetLocal(value); //check elemType code.GetLocal(value); code.As(elemTypeName); code.PushNull(); var ifElemType = code.IfNotEquals(); //check opposite type code.GetLocal(value); code.As(oppositeTypeName); code.PushNull(); var ifOppositeType = code.IfNotEquals(); code.ThrowInvalidCastException("not int64"); //casting var labelCast = code.Label(); ifOppositeType.BranchTarget = labelCast; //gotoCast.BranchTarget = labelCast; code.GetLocal(value); code.Cast(oppositeType, elemType); code.ReturnValue(); var normalExit = code.Label(); ifElemType.BranchTarget = normalExit; code.GetLocal(value); code.Coerce(elemTypeName); code.ReturnValue(); })); }