예제 #1
0
 public ClassDecl(TypeRegister register, JSValue ctorVal, JSValue protoVal, Type type)
 {
     _type     = type;
     _register = register;
     _context  = _register.GetContext();
     _ctor     = JSApi.JS_DupValue(_context, ctorVal);
     _proto    = JSApi.JS_DupValue(_context, protoVal);
 }
예제 #2
0
        //NOTE: 代替 bind_native, 用于对 c# 对象产生 js 包装对象
        // 分两种情况, 这里是第2种, 用于一般情况
        public static JSValue NewBridgeClassObject(JSContext ctx, object o)
        {
            if (o == null)
            {
                return(JSApi.JS_UNDEFINED);
            }
            // int type_id;
            var type    = o.GetType();
            var runtime = ScriptEngine.GetRuntime(ctx);
            var db      = runtime.GetTypeDB();
            // var proto = db.FindPrototypeOf(type, out type_id);
            var proto = db.GetPropertyOf(type);

            if (proto.IsNullish())
            {
                var register    = new TypeRegister(runtime, runtime.GetContext(ctx));
                var dynamicType = new DynamicType(type, false);
                dynamicType.Bind(register);
                register.Finish();
                proto = db.GetPropertyOf(type);
                if (proto.IsNullish())
                {
                    return(JSApi.JS_ThrowInternalError(ctx, string.Format("no prototype found for {0}", type)));
                }
            }

            var cache     = runtime.GetObjectCache();
            var object_id = cache.AddObject(o);
            var val       = JSApi.jsb_new_bridge_object(ctx, proto, object_id);

            if (val.IsException())
            {
                cache.RemoveObject(object_id);
            }
            else
            {
                // JSApi.JSB_SetBridgeType(ctx, val, type_id);
            }
            return(val);
        }
예제 #3
0
        public ClassDecl Bind(TypeRegister register, bool crossbind = false)
        {
            ClassDecl cls;
            var       db    = register.GetTypeDB();
            var       ctx   = (JSContext)register.GetContext();
            var       flags = DefaultFlags;
            var       proto = db.FindPrototypeOf(_type, out _type_id);

            if (proto.IsNullish())
            {
                _type_id = db.AddType(_type, JSApi.JS_UNDEFINED);
                // UnityEngine.Debug.Log($"add dynamic type {_type}: {_type_id}");

                #region BindConstructors(register, flags, type_id);
                var constructors       = _type.GetConstructors(flags);
                var dynamicConstructor = default(IDynamicMethod);
                if (constructors.Length > 0)
                {
                    var count = constructors.Length;
                    if (count == 1)
                    {
                        dynamicConstructor = new DynamicConstructor(this, constructors[0], crossbind);
                    }
                    else
                    {
                        var overloads = new DynamicMethods("constructor", count);
                        for (var i = 0; i < count; i++)
                        {
                            var overload = new DynamicConstructor(this, constructors[i], crossbind);
                            overloads.Add(overload);
                        }
                        dynamicConstructor = overloads;
                    }
                }
                #endregion

                cls = register.CreateClass(_type.Name, _type, dynamicConstructor);
            }
            else
            {
                cls = register.CreateClass(_type, proto);
            }

            #region BindMethods(register, flags);
            var instMap   = new Dictionary <string, List <MethodInfo> >();
            var staticMap = new Dictionary <string, List <MethodInfo> >();
            CollectMethod(ref cls, _type.GetMethods(flags), instMap, staticMap);
            AddMethods(ref cls, true, staticMap);
            AddMethods(ref cls, false, instMap);
            #endregion

            #region BindFields(register, flags);
            var fieldInfos = _type.GetFields(flags);
            for (int i = 0, count = fieldInfos.Length; i < count; i++)
            {
                var fieldInfo = fieldInfos[i];
                if (!fieldInfo.Name.StartsWith("_JSFIX_")) // skip hotfix slots
                {
                    var dynamicField = new DynamicField(this, fieldInfo);
                    cls.AddField(fieldInfo.IsStatic, fieldInfo.Name, dynamicField);
                }
            }
            #endregion

            #region BindProperties(register, flags);
            var propertyInfos = _type.GetProperties(flags);
            for (int i = 0, count = propertyInfos.Length; i < count; i++)
            {
                var propertyInfo    = propertyInfos[i];
                var anyMethod       = propertyInfo.GetMethod ?? propertyInfo.SetMethod;
                var dynamicProperty = new DynamicProperty(this, propertyInfo);
                cls.AddField(anyMethod.IsStatic, propertyInfo.Name, dynamicProperty);
            }
            #endregion

            // var ns = new NamespaceDecl();
            // typeDB.AddType()
            return(cls);
        }
예제 #4
0
 public NamespaceDecl(TypeRegister register, JSValue jsNsValue)
 {
     _register = register;
     _nsValue  = jsNsValue;
 }
예제 #5
0
        ///<summary>
        /// 实际定义运算符重载 (请保证 create 本身有效)
        ///</summary>
        public unsafe void Register(TypeRegister register, JSContext ctx, JSValue create)
        {
            var proto = register.FindChainedPrototypeOf(type);
            var argv  = new JSValue[_count];

            argv[0] = JSApi.JS_NewObject(ctx);
            for (int i = 0, len = self.Count; i < len; i++)
            {
                var def = self[i];
                // var funcVal = JSApi.JS_NewCFunction(ctx, def.func, def.op, def.length);
                JSApi.JS_DefinePropertyValue(ctx, argv[0], register.GetAtom(def.op), def.value, JSPropFlags.DEFAULT);
                // Debug.LogFormat("{0} operator {1}", type, def.op);
            }

            for (int i = 0, len = left.Count; i < len; i++)
            {
                var cross     = left[i];
                var sideCtor  = register.GetConstructor(cross.type);
                var operator_ = JSApi.JS_NewObject(ctx);
                var side      = "left";
                JSApi.JS_SetProperty(ctx, operator_, register.GetAtom(side), sideCtor);
                for (int opIndex = 0, opCount = cross.operators.Count; opIndex < opCount; opIndex++)
                {
                    var def = cross.operators[opIndex];
                    // var funcVal = JSApi.JS_NewCFunction(ctx, def.func, def.op, def.length);
                    JSApi.JS_DefinePropertyValue(ctx, operator_, register.GetAtom(def.op), def.value, JSPropFlags.DEFAULT);
                    argv[i + 1] = operator_;
                    // Debug.LogFormat("{0} {1} operator {2} {3} ({4})", type, side, def.op, cross.type, sideCtor);
                }
            }

            for (int i = 0, len = right.Count; i < len; i++)
            {
                var cross     = right[i];
                var sideCtor  = register.GetConstructor(cross.type);
                var operator_ = JSApi.JS_NewObject(ctx);
                var side      = "right";
                JSApi.JS_SetProperty(ctx, operator_, register.GetAtom(side), sideCtor);
                for (int opIndex = 0, opCount = cross.operators.Count; opIndex < opCount; opIndex++)
                {
                    var def = cross.operators[opIndex];
                    // var funcVal = JSApi.JS_NewCFunction(ctx, def.func, def.op, def.length);
                    JSApi.JS_DefinePropertyValue(ctx, operator_, register.GetAtom(def.op), def.value, JSPropFlags.DEFAULT);
                    argv[i + 1 + left.Count] = operator_;
                    // Debug.LogFormat("{0} {1} operator {2} {3} ({4})", type, side, def.op, cross.type, sideCtor);
                }
            }

            fixed(JSValue *ptr = argv)
            {
                var rval = JSApi.JS_Call(ctx, create, JSApi.JS_UNDEFINED, argv.Length, ptr);

                if (rval.IsException())
                {
                    ctx.print_exception(Utils.LogLevel.Warn, string.Format("[{0} operators failed]", type));
                }
                else
                {
                    JSApi.JS_DefinePropertyValue(ctx, proto, JSApi.JS_ATOM_Symbol_operatorSet, rval, JSPropFlags.DEFAULT);
                }
            }

            for (int i = 0, len = argv.Length; i < len; i++)
            {
                JSApi.JS_FreeValue(ctx, argv[i]);
            }
        }
예제 #6
0
        public void Bind(TypeRegister register)
        {
            // UnityEngine.Debug.LogErrorFormat("dynamic bind {0}", _type);
            var db     = register.GetTypeDB();
            var ctx    = (JSContext)register.GetContext();
            var flags  = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
            var pflags = flags | BindingFlags.NonPublic;

            _type_id = register.RegisterType(_type);

            #region BindConstructors(register, flags, type_id);
            var constructors       = _type.GetConstructors(flags);
            var dynamicConstructor = default(IDynamicMethod);
            if (constructors.Length > 0)
            {
                var count = constructors.Length;
                if (count == 1)
                {
                    dynamicConstructor = new DynamicConstructor(this, constructors[0]);
                }
                else
                {
                    var overloads = new DynamicMethods(count);
                    for (var i = 0; i < count; i++)
                    {
                        var overload = new DynamicConstructor(this, constructors[i]);
                        overloads.Add(overload);
                    }
                    dynamicConstructor = overloads;
                }
            }
            #endregion

            var cls = register.CreateClass(_type.Name, _type, dynamicConstructor);

            #region BindMethods(register, pflags);
            var instMap   = new Dictionary <string, List <MethodInfo> >();
            var staticMap = new Dictionary <string, List <MethodInfo> >();
            CollectMethod(_type.GetMethods(pflags), instMap, staticMap);
            AddMethods(cls, true, staticMap);
            AddMethods(cls, false, instMap);
            #endregion

            #region BindFields(register, pflags);
            var fieldInfos = _type.GetFields(pflags);
            for (int i = 0, count = fieldInfos.Length; i < count; i++)
            {
                var fieldInfo = fieldInfos[i];
                if (fieldInfo.Name.StartsWith("_JSFIX_"))
                {
                    //TODO: collect hotfix slots
                }
                else
                {
                    var dynamicField = new DynamicField(this, fieldInfo);
                    cls.AddField(fieldInfo.IsStatic, fieldInfo.Name, dynamicField);
                }
            }
            #endregion

            #region BindProperties(register, pflags);
            var propertyInfos = _type.GetProperties(pflags);
            for (int i = 0, count = propertyInfos.Length; i < count; i++)
            {
                var propertyInfo    = propertyInfos[i];
                var anyMethod       = propertyInfo.GetMethod ?? propertyInfo.SetMethod;
                var dynamicProperty = new DynamicProperty(this, propertyInfo);
                cls.AddField(anyMethod.IsStatic, propertyInfo.Name, dynamicProperty);
            }
            #endregion

            // var ns = new NamespaceDecl();
            // typeDB.AddType()
            cls.Close();
        }