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); }
//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); }
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); }
public NamespaceDecl(TypeRegister register, JSValue jsNsValue) { _register = register; _nsValue = jsNsValue; }
///<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]); } }
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(); }