private object IsDefined(IMethod method) { if (method.Data is InlineCall || Abc.IsDefined(method)) { return(method.Data); } var m = method.AbcMethod(); if (m != null) { if (m.ImportedMethod != null) { return(m.ImportedMethod); } //external linking if (m.IsImported) { return(m); } } return(null); }
private void NewObject(AbcCode code, IMethod method) { var type = method.DeclaringType; var abcMethod = method.AbcMethod(); if (abcMethod != null) { if (abcMethod.IsInitializer) //default ctor! { if (type.Is(AvmTypeCode.Object)) { code.NewObject(0); } else { code.Construct(method.Parameters.Count); } return; } if (type.Is(SystemTypeCode.String)) { code.Call(abcMethod); return; } var ctor = _generator.TypeBuilder.DefineCtorStaticCall(method); code.Call(ctor); } else { throw new NotImplementedException(); } }
private static void Build(AbcInstance instance, IMethod method) { instance.DefineMethod( Sig.@from(method.AbcMethod()), code => { var impl = Impls[method.Name]; impl(method, code); }); }
private void Impl(IMethod method, AbcCoder coder) { var abcMethod = method.AbcMethod(); if (abcMethod == null) { return; } _generator.NewApi.SetProtoFunction(AvmTypeCode.String, abcMethod, coder); }
private void NewMethodInfo(AbcCode code, AbcInstance instance, IMethod method, int varMethod, int varParams, int varParam, IType mtype, int index) { var ctor = mtype.FindConstructor(0); if (ctor == null) { throw new InvalidOperationException(".ctor not found"); } var abcMethod = method.AbcMethod(); if (abcMethod == null) { throw new InvalidOperationException(); } abcMethod.MethodInfoIndex = index; code.NewObject(ctor, () => { }); code.SetLocal(varMethod); code.GetLocal(varMethod); code.PushString(method.Name); code.SetField(FieldId.MethodBase_Name); code.GetLocal(varMethod); var wrapper = DefineMetodWrapper(method, true); code.GetStaticFunction(wrapper); code.SetField(FieldId.MethodBase_Function); if (method.IsConstructor) { code.GetLocal(varMethod); wrapper = DefineMetodWrapper(method, false); code.GetStaticFunction(wrapper); code.SetField(FieldId.ConstructorInfo_CreateFunction); } var mattrs = (int)GetMethodAttributes(method); code.GetLocal(varMethod); code.PushInt(mattrs); code.SetField(FieldId.MethodBase_Attributes); code.GetLocal(varMethod); code.NewArray(varParams, mtype, method.Parameters, param => NewParameterInfo(code, instance, param, varMethod, varParam)); code.SetField(FieldId.MethodBase_Parameters); InitCustomAttributes(code, instance, method, varMethod); code.GetLocal(varMethod); }
private void LoadCtorReceiver(AbcCode code, IMethod method) { if (!method.IsConstructor) { throw new ArgumentException("method is not ctor", "method"); } var declType = method.DeclaringType; var vec = declType.Data as IVectorType; if (vec != null) { code.LoadGenericClass(vec.Name); return; } var nativeType = declType.Data as NativeType; if (nativeType != null) { code.Getlex(nativeType.Name); return; } var abcMethod = method.AbcMethod(); if (abcMethod == null) { throw new ArgumentException("Invalid method tag"); } var instance = DefineAbcInstance(declType); if (instance == null) { throw new InvalidOperationException(); } if (UseThisForStaticReceiver(declType)) { code.LoadThis(); return; } code.Getlex(instance); }
private static string GetBaseCallPrefix(IMethod method) { var abcMethod = method.AbcMethod(); if (abcMethod != null) { if (abcMethod.IsGetter) { return("$get_super$"); } if (abcMethod.IsSetter) { return("$set_super$"); } } return("$super$"); }
private void ConvertImpl(IMethod method) { var m = method.AbcMethod(); if (m == null) { return; } string name = method.Name; if (name == "ToString") { var impl = Abc.DefineMethod( Sig.@global(AvmTypeCode.String), code => code.ReturnThis()); _generator.NewApi.SetProtoFunction(AvmTypeCode.String, m.TraitName, impl); return; } if (name == "GetTypeCode") { Impl(method, code => { code.PushInt(18); code.ReturnValue(); }); return; } Impl(method, code => { var convertInstance = _generator.Corlib.Convert.Instance; var convertMethod = FindConvertImpl(method); var impl = _generator.MethodBuilder.BuildAbcMethod(convertMethod); code.Getlex(convertInstance); code.GetLocals(0, method.Parameters.Count); code.Call(impl); code.ReturnValue(); }); }
public static bool IsInitializer(this IMethod method) { if (method == null) { return(false); } if (!method.IsConstructor) { return(false); } var abcMethod = method.AbcMethod(); if (abcMethod == null) { return(false); } return(abcMethod.IsInitializer); }
private static void SetAccessor(AbcCode code, IMethod accessor, FieldId fieldId, int varProp) { if (accessor == null) { return; } var abcMethod = accessor.AbcMethod(); if (abcMethod == null) { return; } int index = abcMethod.MethodInfoIndex; code.GetLocal(varProp); code.PushInt(index); code.SetField(fieldId); }
private static bool ShouldWrap(IMethod m) { var abcMethod = m.AbcMethod(); if (abcMethod == null) { return(false); } if (abcMethod.IsAccessor) { return(true); } if (!m.IsStatic) { return(true); } return(false); }
private static bool MustCoerceReturnType(IMethod method) { if (method.IsVoid()) { return(false); } //NOTE: AVM Verifier uses type info (ABC traits) to determine return type //If verifier can not find given method then the method is treated as dynamic and return type is always * (any). //In this cases we should add coerce instruction var declType = method.DeclaringType; if (declType.UseNativeObject()) { return(true); } if (MustCoerceReturnType(declType)) { return(true); } var abcMethod = method.AbcMethod(); if (abcMethod != null) { if (abcMethod.IsNative) { return(true); } if (abcMethod.IsImported) { return(true); } if (abcMethod.OriginalMethod != null) { return(true); } } return(false); }
// Pointer and Reference type parameters currently not supported private static bool IsUnsupportedMethod(IMethod method) { var abcMethod = method.AbcMethod(); if (abcMethod == null) { return(true); } if (abcMethod.IsInitializer) { return(true); } if (method.IsGeneric) { return(true); } return (method.Parameters.Any( p => p.IsByRef() || p.Type.TypeKind == TypeKind.Pointer || p.Type.HasGenericParams())); }
private void CallCore(AbcCode code, IMethod method, AbcMultiname prop, bool super) { var abcMethod = method.AbcMethod(); if (abcMethod != null) { if (abcMethod.IsGetter) { code.Add(super ? InstructionCode.Getsuper : InstructionCode.Getproperty, prop); return; } if (abcMethod.IsSetter) { code.Add(super ? InstructionCode.Setsuper : InstructionCode.Setproperty, prop); return; } } int n = method.Parameters.Count; if (method.AsStaticCall()) { ++n; } bool isVoid = method.IsVoid(); if (CanUseCallStatic) { if (method.IsStaticCall() && method.IsManaged() && abcMethod != null && _abc.IsDefined(abcMethod)) { code.Add(InstructionCode.Callstatic, abcMethod, n); if (isVoid) { code.Pop(); } return; } } if (super) { if (isVoid) { code.Add(InstructionCode.Callsupervoid, prop, n); return; } code.Add(InstructionCode.Callsuper, prop, n); return; } if (isVoid) { code.Add(InstructionCode.Callpropvoid, prop, n); return; } code.Add(InstructionCode.Callproperty, prop, n); }
private AbcMethod DefineMetodWrapper(IMethod method, bool init) { var abcMethod = method.AbcMethod(); if (abcMethod == null) { return(null); } if (!ShouldWrap(method)) { return(abcMethod); } var provname = ++MethodWrappperCounter; const string prefix = "wrap_"; var name = _generator.Abc.DefineName(QName.PfxPublic(prefix + provname)); var instance = abcMethod.Instance; bool addParam = false; instance = FixInstance(instance); var wrapper = instance.DefineMethod( Sig.@static(name, AvmTypeCode.Object), code => { int n = abcMethod.Parameters.Count; bool hasReturn = false; if (method.IsConstructor) { if (init) { //addParam = true; if (abcMethod.IsInitializer) { //code.ThrowNotSupportedException(); //return; //addParam = true; //code.LoadArguments(n + 1); //code.Add(InstructionCode.Callstatic, am, n); } else { addParam = true; code.LoadArguments(n + 1); code.Call(abcMethod); } } else { hasReturn = true; code.Getlex(abcMethod); if (abcMethod.IsInitializer) { code.LoadArguments(n); code.Construct(n); } else { code.Construct(0); code.Dup(); code.LoadArguments(n); code.Call(abcMethod); } } } else { hasReturn = !abcMethod.IsVoid; if (method.IsStatic) { code.Getlex(abcMethod); } else { addParam = true; ++n; } code.LoadArguments(n); code.Call(abcMethod); } if (!hasReturn) { code.PushNull(); } code.ReturnValue(); }); if (addParam) { wrapper.Parameters.Add(Abc.CreateParameter(AvmTypeCode.Object, "obj")); } _generator.MethodBuilder.CopyParameters(wrapper, abcMethod); return(wrapper); }