コード例 #1
0
        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);
        }
コード例 #2
0
        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();
            }
        }
コード例 #3
0
 private static void Build(AbcInstance instance, IMethod method)
 {
     instance.DefineMethod(
         Sig.@from(method.AbcMethod()),
         code =>
     {
         var impl = Impls[method.Name];
         impl(method, code);
     });
 }
コード例 #4
0
        private void Impl(IMethod method, AbcCoder coder)
        {
            var abcMethod = method.AbcMethod();

            if (abcMethod == null)
            {
                return;
            }
            _generator.NewApi.SetProtoFunction(AvmTypeCode.String, abcMethod, coder);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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$");
        }
コード例 #8
0
        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();
            });
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        // 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()));
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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);
        }