void CJSRuntime::InitializePrototypes(void) { protoList.resize(JSP_COUNT); JSContext *cx = jsContext; JSObject *obj = jsGlobal; protoList[JSP_CHAR] = JS_InitClass(cx, obj, NULL, &UOXChar_class.base, NULL, 0, CCharacterProps, CChar_Methods, NULL, NULL); protoList[JSP_ITEM] = JS_InitClass(cx, obj, NULL, &UOXItem_class.base, NULL, 0, CItemProps, CItem_Methods, NULL, NULL); protoList[JSP_SPELL] = JS_InitClass(cx, obj, NULL, &UOXSpell_class, NULL, 0, CSpellProperties, NULL, NULL, NULL); protoList[JSP_SPELLS] = JS_InitClass(cx, obj, NULL, &UOXSpells_class, NULL, 0, NULL, NULL, NULL, NULL); protoList[JSP_SOCK] = JS_InitClass(cx, obj, NULL, &UOXSocket_class.base, NULL, 0, CSocketProps, CSocket_Methods, NULL, NULL); protoList[JSP_ACCOUNTS] = JS_InitClass(cx, obj, NULL, &UOXAccount_class, NULL, 0, CAccountProperties, CAccount_Methods, NULL, NULL); protoList[JSP_CONSOLE] = JS_InitClass(cx, obj, NULL, &UOXConsole_class, NULL, 0, CConsoleProperties, CConsole_Methods, NULL, NULL); protoList[JSP_REGION] = JS_InitClass(cx, obj, NULL, &UOXRegion_class, NULL, 0, CRegionProperties, NULL, NULL, NULL); protoList[JSP_RESOURCE] = JS_InitClass(cx, obj, NULL, &UOXResource_class, NULL, 0, CResourceProperties, NULL, NULL, NULL); protoList[JSP_RACE] = JS_InitClass(cx, obj, NULL, &UOXRace_class, NULL, 0, CRaceProperties, CRace_Methods, NULL, NULL); protoList[JSP_GUILD] = JS_InitClass(cx, obj, NULL, &UOXGuild_class, NULL, 0, CGuildProperties, CGuild_Methods, NULL, NULL); protoList[JSP_PARTY] = JS_InitClass(cx, obj, NULL, &UOXParty_class.base, NULL, 0, CPartyProperties, CParty_Methods, NULL, NULL); protoList[JSP_PACKET] = JS_InitClass(cx, obj, NULL, &UOXPacket_class, Packet, 0, NULL, NULL, NULL, NULL); protoList[JSP_GUMP] = JS_InitClass(cx, obj, NULL, &UOXGump_class, Gump, 0, NULL, NULL, NULL, NULL); protoList[JSP_FILE] = JS_InitClass(cx, obj, NULL, &UOXFile_class, UOXCFile, 0, NULL, NULL, NULL, NULL); spellsObj = JS_DefineObject(cx, obj, "Spells", &UOXSpells_class, protoList[JSP_SPELLS], 0); accountsObj = JS_DefineObject(cx, obj, "Accounts", &UOXAccount_class, protoList[JSP_ACCOUNTS], 0); consoleObj = JS_DefineObject(cx, obj, "Console", &UOXConsole_class, protoList[JSP_CONSOLE], 0); protoList[JSACT_SQL] = JS_InitClass(cx, obj, NULL, &UOXSQLM_class, NULL, 0, CSQLMProperties, CSQLM_Methods, NULL, NULL); sqlmObj = JS_DefineObject(cx, obj, "SQLM", &UOXSQLM_class, protoList[JSACT_SQL], 0); JS_LockGCThing(cx, sqlmObj); JS_LockGCThing(cx, spellsObj); //JS_AddRoot(cx, &spellsObj); JS_LockGCThing(cx, accountsObj); //JS_AddRoot(cx, &accountsObj); JS_LockGCThing(cx, consoleObj); //JS_AddRoot(cx, &consoleObj); for (size_t i = JSP_ITEM; i < JSP_COUNT; ++i) { JS_LockGCThing(cx, protoList[i]); //JS_AddRoot(cx, &protoList[i]); } }
CJSRuntime::CJSRuntime(UI32 engineSize) { jsRuntime = JS_NewRuntime(engineSize); if (jsRuntime == NULL) Shutdown(FATAL_UOX3_JAVASCRIPT); jsContext = JS_NewContext(jsRuntime, 0x500000); if (jsContext == NULL) Shutdown(FATAL_UOX3_JAVASCRIPT); jsGlobal = JS_NewObject(jsContext, &global_class, NULL, NULL); if (jsGlobal == NULL) Shutdown(FATAL_UOX3_JAVASCRIPT); JS_LockGCThing(jsContext, jsGlobal); //JS_AddRoot(jsContext, &jsGlobal); JS_InitStandardClasses(jsContext, jsGlobal); objectList.resize(IUE_COUNT); InitializePrototypes(); }
/* Constructor method for a JSComponent object */ static JSComponent* component_create_self(JSContext *cx, MochaDecoder* decoder, JSComponent *component, const char *name) { JSObject *obj; /* JSComponent may be malloc'd previous to this to make it easier * to fill in the struct with data from the Mozilla thread */ if (!component) { component = JS_malloc(cx, sizeof(JSComponent)); if (!component) return NULL; } obj = JS_NewObject(cx, &lm_component_class, NULL, NULL); if (!obj || !JS_SetPrivate(cx, obj, component)) { JS_free(cx, component); return NULL; } if (!JS_DefineProperties(cx, obj, component_props)) return NULL; if (!JS_DefineFunctions(cx, obj, component_methods)) return NULL; /* Fill out static property fields */ component->decoder = HOLD_BACK_COUNT(decoder); component->obj = obj; component->name = JS_NewStringCopyZ(cx, name); if (!component->name || !JS_LockGCThing(cx, component->name)) return NULL; return component; }
JSObject *CJSRuntime::MakeNewObject(IUEEntries iType) { JSObject *toMake = NULL; switch(iType) { case IUE_RACE: toMake = JS_NewObject(jsContext, &UOXRace_class, protoList[JSP_RACE], jsGlobal); if (toMake == NULL) return NULL; //JS_DefineFunctions(jsContext, toMake, CRace_Methods); //JS_DefineProperties(jsContext, toMake, CRaceProperties); break; case IUE_CHAR: toMake = JS_NewObject(jsContext, &UOXChar_class.base, protoList[JSP_CHAR], jsGlobal); if (toMake == NULL) return NULL; //JS_DefineProperties(jsContext, toMake, CCharacterProps); //JS_DefineFunctions(jsContext, toMake, CChar_Methods); break; case IUE_ITEM: toMake = JS_NewObject(jsContext, &UOXItem_class.base, protoList[JSP_ITEM], jsGlobal); if (toMake == NULL) return NULL; //JS_DefineFunctions(jsContext, toMake, CItem_Methods); //JS_DefineProperties(jsContext, toMake, CItemProps); break; case IUE_SOCK: toMake = JS_NewObject(jsContext, &UOXSocket_class.base, protoList[JSP_SOCK], jsGlobal); if (toMake == NULL) return NULL; //JS_DefineFunctions(jsContext, toMake, CSocket_Methods); //JS_DefineProperties(jsContext, toMake, CSocketProps); break; case IUE_GUILD: toMake = JS_NewObject(jsContext, &UOXGuild_class, protoList[JSP_GUILD], jsGlobal); if (toMake == NULL) return NULL; //JS_DefineFunctions(jsContext, toMake, CGuild_Methods); //JS_DefineProperties(jsContext, toMake, CGuildProperties); break; case IUE_REGION: toMake = JS_NewObject(jsContext, &UOXRegion_class, protoList[JSP_REGION], jsGlobal); if (toMake == NULL) return NULL; //JS_DefineFunctions(jsContext, toMake, CRegion_Methods); //JS_DefineProperties(jsContext, toMake, CRegionProperties); break; case IUE_PARTY: toMake = JS_NewObject(jsContext, &UOXParty_class.base, protoList[JSP_PARTY], jsGlobal); if (toMake == NULL) return NULL; //JS_DefineFunctions(jsContext, toMake, CRegion_Methods); //JS_DefineProperties(jsContext, toMake, CRegionProperties); break; default: case IUE_COUNT: return NULL; } // DAMN! Using the deprecated function it works! JS_LockGCThing(jsContext, toMake); //JS_AddRoot(jsContext, &toMake); return toMake; }
JSObject * LM_ReflectNamedAnchor(MWContext *context, lo_NameList *name_rec, PA_Tag * tag, int32 layer_id, uint index) { JSObject *obj, *array_obj, *document; MochaDecoder *decoder; JSContext *cx; JSObjectArray *array; JSAnchor *named_anchor; lo_TopState *top_state; PRHashTable *map; JSString *str; obj = name_rec->mocha_object; if (obj) return obj; decoder = LM_GetMochaDecoder(context); if (!decoder) return NULL; cx = decoder->js_context; top_state = lo_GetMochaTopState(context); if (top_state->resize_reload) { map = lm_GetIdToObjectMap(decoder); if (map) obj = (JSObject *)PR_HashTableLookup(map, LM_GET_MAPPING_KEY(LM_NAMEDANCHORS, layer_id, index)); if (obj) { name_rec->mocha_object = obj; LM_PutMochaDecoder(decoder); return obj; } } /* Get the document object that will hold this anchor */ document = lm_GetDocumentFromLayerId(decoder, layer_id); if (!document) { LM_PutMochaDecoder(decoder); return NULL; } array_obj = lm_GetNameArray(decoder, document); if (!array_obj) { LM_PutMochaDecoder(decoder); return NULL; } array = JS_GetPrivate(cx, array_obj); if (!array) { LM_PutMochaDecoder(decoder); return NULL; } named_anchor = JS_malloc(cx, sizeof *named_anchor); if (!named_anchor) { LM_PutMochaDecoder(decoder); return NULL; } XP_BZERO(named_anchor, sizeof *named_anchor); obj = JS_NewObject(cx, &lm_anchor_class, decoder->anchor_prototype, document); if (!obj || !JS_SetPrivate(cx, obj, named_anchor)) { JS_free(cx, named_anchor); LM_PutMochaDecoder(decoder); return NULL; } /* Put obj into the document.anchors array. */ JS_DefineProperty(cx, array_obj, (char *) name_rec->name, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE|JSPROP_READONLY); JS_AliasElement(cx, array_obj, (char *) name_rec->name, index); /* Put it in the index to object hash table */ map = lm_GetIdToObjectMap(decoder); if (map) { PR_HashTableAdd(map, LM_GET_MAPPING_KEY(LM_NAMEDANCHORS, layer_id, index), obj); } if ((jsint) index >= array->length) array->length = index + 1; named_anchor->decoder = HOLD_BACK_COUNT(decoder); named_anchor->layer_id = layer_id; named_anchor->index = index; if (name_rec->element && name_rec->element->type == LO_TEXT) { str = lm_LocalEncodingToStr(context, (char *) name_rec->element->lo_text.text); if (!str || !JS_LockGCThing(cx, str)) { LM_PutMochaDecoder(decoder); return NULL; } named_anchor->text = str; } str = JS_NewStringCopyZ(cx, (char *) name_rec->name); if (!str || !JS_LockGCThing(cx, str)) { LM_PutMochaDecoder(decoder); return NULL; } named_anchor->name = str; name_rec->mocha_object = obj; /* see if there are any attributes for event handlers */ if(tag) { PA_Block onlocate, id; /* don't hold the layout lock across compiles */ LO_UnlockLayout(); onlocate = lo_FetchParamValue(context, tag, PARAM_ONLOCATE); id = lo_FetchParamValue(context, tag, PARAM_ID); if (onlocate) { (void) lm_CompileEventHandler(decoder, id, tag->data, tag->newline_count, obj, PARAM_ONLOCATE, onlocate); PA_FREE(onlocate); } if (id) PA_FREE(id); LO_LockLayout(); } LM_PutMochaDecoder(decoder); return obj; }