JSObject * js_InitExceptionClasses(JSContext *cx, JSObject *obj) { jsval roots[3]; JSObject *obj_proto, *error_proto; jsval empty; /* * If lazy class initialization occurs for any Error subclass, then all * classes are initialized, starting with Error. To avoid reentry and * redundant initialization, we must not pass a null proto parameter to * js_NewObject below, when called for the Error superclass. We need to * ensure that Object.prototype is the proto of Error.prototype. * * See the equivalent code to ensure that parent_proto is non-null when * JS_InitClass calls js_NewObject, in jsapi.c. */ if (!js_GetClassPrototype(cx, obj, INT_TO_JSID(JSProto_Object), &obj_proto)) { return NULL; } memset(roots, 0, sizeof(roots)); JSAutoTempValueRooter tvr(cx, JS_ARRAY_LENGTH(roots), roots); #ifdef __GNUC__ error_proto = NULL; /* quell GCC overwarning */ #endif /* Initialize the prototypes first. */ for (intN i = JSEXN_ERR; i != JSEXN_LIMIT; i++) { JSObject *proto; JSProtoKey protoKey; JSAtom *atom; JSFunction *fun; /* Make the prototype for the current constructor name. */ proto = js_NewObject(cx, &js_ErrorClass, (i != JSEXN_ERR) ? error_proto : obj_proto, obj); if (!proto) return NULL; if (i == JSEXN_ERR) { error_proto = proto; roots[0] = OBJECT_TO_JSVAL(proto); } else { // We cannot share the root for error_proto and other prototypes // as error_proto must be rooted until the function returns. roots[1] = OBJECT_TO_JSVAL(proto); } /* So exn_finalize knows whether to destroy private data. */ proto->setPrivate(NULL); /* Make a constructor function for the current name. */ protoKey = GetExceptionProtoKey(i); atom = cx->runtime->atomState.classAtoms[protoKey]; fun = js_DefineFunction(cx, obj, atom, Exception, 3, 0); if (!fun) return NULL; roots[2] = OBJECT_TO_JSVAL(FUN_OBJECT(fun)); /* Make this constructor make objects of class Exception. */ FUN_CLASP(fun) = &js_ErrorClass; /* Make the prototype and constructor links. */ if (!js_SetClassPrototype(cx, FUN_OBJECT(fun), proto, JSPROP_READONLY | JSPROP_PERMANENT)) { return NULL; } /* Add the name property to the prototype. */ if (!JS_DefineProperty(cx, proto, js_name_str, ATOM_KEY(atom), NULL, NULL, JSPROP_ENUMERATE)) { return NULL; } /* Finally, stash the constructor for later uses. */ if (!js_SetClassObject(cx, obj, protoKey, FUN_OBJECT(fun))) return NULL; } /* * Set default values and add methods. We do it only for Error.prototype * as the rest of exceptions delegate to it. */ empty = STRING_TO_JSVAL(cx->runtime->emptyString); if (!JS_DefineProperty(cx, error_proto, js_message_str, empty, NULL, NULL, JSPROP_ENUMERATE) || !JS_DefineProperty(cx, error_proto, js_fileName_str, empty, NULL, NULL, JSPROP_ENUMERATE) || !JS_DefineProperty(cx, error_proto, js_lineNumber_str, JSVAL_ZERO, NULL, NULL, JSPROP_ENUMERATE) || !JS_DefineFunctions(cx, error_proto, exception_methods)) { return NULL; } return error_proto; }
JSBool gjs_define_interface_class(JSContext *context, JSObject *in_object, GIInterfaceInfo *info, JSObject **prototype_p) { Interface *priv; const char *constructor_name; JSObject *constructor; JSObject *prototype; jsval value; constructor_name = g_base_info_get_name((GIBaseInfo*)info); gjs_object_get_property(context, in_object, constructor_name, &value); if (!JSVAL_IS_VOID(value)) { JSObject *constructor; if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "Existing property '%s' does not look like a constructor", constructor_name); return JS_FALSE; } constructor = JSVAL_TO_OBJECT(value); gjs_object_get_property(context, constructor, "prototype", &value); if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "prototype property does not appear to exist or has wrong type"); return JS_FALSE; } else { if (prototype_p) *prototype_p = JSVAL_TO_OBJECT(value); return JS_TRUE; } return JS_TRUE; } if (!gjs_init_class_dynamic(context, in_object, NULL, g_base_info_get_namespace((GIBaseInfo*)info), constructor_name, &gjs_interface_class, gjs_interface_constructor, 0, /* props of prototype */ &gjs_interface_proto_props[0], /* funcs of prototype */ &gjs_interface_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ NULL, &prototype, &constructor)) { gjs_fatal("Can't init class %s", constructor_name); } GJS_INC_COUNTER(interface); priv = g_slice_new0(Interface); priv->info = info; priv->gtype = g_registered_type_info_get_g_type(priv->info); g_base_info_ref((GIBaseInfo*)priv->info); JS_SetPrivate(context, prototype, priv); gjs_define_static_methods(context, constructor, priv->gtype, priv->info); value = OBJECT_TO_JSVAL(gjs_gtype_create_gtype_wrapper(context, priv->gtype)); JS_DefineProperty(context, constructor, "$gtype", value, NULL, NULL, JSPROP_PERMANENT); if (prototype_p) *prototype_p = prototype; return JS_TRUE; }
int js_plugin_load(const char *id, const char *url, char *errbuf, size_t errlen) { char *sbuf; struct fa_stat fs; JSContext *cx; js_plugin_t *jsp; JSObject *pobj, *gobj, *confobj; JSScript *s; char path[PATH_MAX]; jsval val; if((sbuf = fa_quickload(url, &fs, NULL, errbuf, errlen)) == NULL) return -1; cx = js_newctx(err_reporter); JS_BeginRequest(cx); /* Remove any plugin with same URL */ LIST_FOREACH(jsp, &js_plugins, jsp_link) if(!strcmp(jsp->jsp_id, id)) break; if(jsp != NULL) js_plugin_unload(cx, jsp); jsp = calloc(1, sizeof(js_plugin_t)); jsp->jsp_url = strdup(url); jsp->jsp_id = strdup(id); LIST_INSERT_HEAD(&js_plugins, jsp, jsp_link); gobj = JS_NewObject(cx, &global_class, NULL, NULL); JS_InitStandardClasses(cx, gobj); JS_DefineProperty(cx, gobj, "showtime", OBJECT_TO_JSVAL(showtimeobj), NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT); /* Plugin object */ pobj = JS_NewObject(cx, &plugin_class, NULL, gobj); JS_AddNamedRoot(cx, &pobj, "plugin"); JS_SetPrivate(cx, pobj, jsp); JS_DefineFunctions(cx, pobj, plugin_functions); /* Plugin config object */ confobj = JS_DefineObject(cx, pobj, "config", &plugin_conf_class, NULL, 0); JS_SetPrivate(cx, confobj, jsp); val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, url)); JS_SetProperty(cx, confobj, "url", &val); if(!fa_parent(path, sizeof(path), url)) { val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, path)); JS_SetProperty(cx, confobj, "path", &val); } JS_DefineProperty(cx, confobj, "URIRouting", BOOLEAN_TO_JSVAL(1), NULL, jsp_setEnableURIRoute, JSPROP_PERMANENT); JS_DefineProperty(cx, confobj, "search", BOOLEAN_TO_JSVAL(1), NULL, jsp_setEnableSearch, JSPROP_PERMANENT); s = JS_CompileScript(cx, pobj, sbuf, fs.fs_size, url, 1); free(sbuf); if(s != NULL) { JSObject *sobj = JS_NewScriptObject(cx, s); jsval result; JS_AddNamedRoot(cx, &sobj, "script"); JS_ExecuteScript(cx, pobj, s, &result); JS_RemoveRoot(cx, &sobj); } JS_RemoveRoot(cx, &pobj); JS_EndRequest(cx); JS_GC(cx); JS_DestroyContext(cx); return 0; }
static JSBool rpmxar_enumerate(JSContext *cx, JSObject *obj, JSIterateOp op, jsval *statep, jsid *idp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmxarClass, NULL); rpmxar xar = ptr; int ix = 0; _ENUMERATE_DEBUG_ENTRY(_debug < 0); switch (op) { case JSENUMERATE_INIT: if (idp) *idp = JSVAL_ZERO; *statep = INT_TO_JSVAL(ix); if (_debug) fprintf(stderr, "\tINIT xar %p\n", xar); break; case JSENUMERATE_NEXT: ix = JSVAL_TO_INT(*statep); if (!rpmxarNext(xar)) { const char * path = rpmxarPath(xar); struct stat * st = xmalloc(sizeof(*st)); JSObject * arr = JS_NewArrayObject(cx, 0, NULL); JSBool ok = JS_AddRoot(cx, &arr); JSObject * o; jsval v; v = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, path)); ok = JS_SetElement(cx, arr, 0, &v); if (!rpmxarStat(xar, st) && (o = JS_NewObject(cx, &rpmstClass, NULL, NULL)) != NULL && JS_SetPrivate(cx, o, (void *)st)) v = OBJECT_TO_JSVAL(o); else { st = _free(st); v = JSVAL_NULL; } ok = JS_SetElement(cx, arr, 1, &v); v = OBJECT_TO_JSVAL(arr); ok = JS_DefineElement(cx, obj, ix, v, NULL, NULL, JSPROP_ENUMERATE); (void) JS_RemoveRoot(cx, &arr); if (_debug) fprintf(stderr, "\tNEXT xar %p[%u] \"%s\"\n", xar, ix, path); path = _free(path); JS_ValueToId(cx, *statep, idp); *statep = INT_TO_JSVAL(ix+1); } else *idp = JSVAL_VOID; if (*idp != JSVAL_VOID) break; /*@fallthrough@*/ case JSENUMERATE_DESTROY: ix = JSVAL_TO_INT(*statep); (void) JS_DefineProperty(cx, obj, "length", INT_TO_JSVAL(ix), NULL, NULL, JSPROP_ENUMERATE); if (_debug) fprintf(stderr, "\tFINI xar %p[%u]\n", xar, ix); *statep = JSVAL_NULL; break; } return JS_TRUE; }
static JSBool edjsdb_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { JSBool ok = JS_TRUE; JSObject *proto_obj = NULL; JSObject *ret_obj = NULL; edjsdb_private *p = NULL; JSString *type = NULL; char *mod_name = NULL; char *mod_path = NULL; struct stat *file_stat = NULL; JSBool (*db_driver_init)(JSContext *, JSObject *) = NULL; edjs_private *edjs_p = NULL; jsval path_val = JSVAL_VOID; JSObject *path_obj = NULL; JSFunctionSpec my_methods[] = { {"connect", edjsdb_connect, 1, JSPROP_ENUMERATE, 0}, {"close", edjsdb_close, 0, 0, 0}, {"query", edjsdb_query, 1, 0, 0}, {"exec", edjsdb_exec, 1, 0, 0}, {"createSequence", edjsdb_create_sequence, 1, 0, 0}, {"dropSequence", edjsdb_drop_sequence, 1, 0, 0}, {"listSequences", edjsdb_list_sequences, 0, 0, 0}, {"nextID", edjsdb_next_id, 1, 0, 0}, {"currentID", edjsdb_current_id, 1, 0, 0}, {"quote", edjsdb_quote, 1, 0, 0}, {0, 0, 0, 0, 0} }; if (argc != 1) { //report error goto error; } JS_AddRoot(cx, &type); proto_obj = JS_NewObject(cx, NULL, NULL, NULL); if (NULL == proto_obj) { //throw error goto error; } *rval = OBJECT_TO_JSVAL(proto_obj); //root proto_obj if (JS_FALSE == JS_DefineFunctions(cx, proto_obj, my_methods)) { //report error goto error; } ret_obj = JS_NewObject(cx, &edjsdb_class, proto_obj, NULL);//JS_ConstructObjectWithArguments(cx, &edjsdb_class, NULL, NULL, argc, argv); if (NULL == ret_obj) { //throw error goto error; } *rval = OBJECT_TO_JSVAL(ret_obj); //root ret_obj p = (edjsdb_private *)EDJS_malloc(cx, sizeof(edjsdb_private)); if (NULL == p) { goto error; } p->db_connection = NULL; p->lib_handle = NULL; p->finalize_func = edjsdb_finalize_stub; p->connect_func = edjsdb_connect_stub; p->close_func = edjsdb_close_stub; p->query_func = edjsdb_func_stub; p->exec_func = edjsdb_func_stub; p->create_sequence_func = edjsdb_func_stub; p->drop_sequence_func = edjsdb_func_stub; p->list_sequences_func = edjsdb_func_stub; p->next_id_func = edjsdb_func_stub; p->current_id_func = edjsdb_func_stub; p->quote_func = edjsdb_func_stub; if (JS_FALSE == JS_SetPrivate(cx, ret_obj, p)) { //report error goto error; } if (JS_FALSE == JS_DefineProperty(cx, ret_obj, "type", argv[0], NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY)) { //report error goto error; } type = JS_ValueToString(cx, *argv); if (NULL == type) { //report error goto error; } mod_name = (char *)EDJS_malloc(cx, (7 + strlen(JS_GetStringBytes(type))) * sizeof(char)); //7 for db_.so\0 strcpy(mod_name, "db_"); strcat(mod_name, JS_GetStringBytes(type)); strcat(mod_name, ".so"); edjs_p = (edjs_private *)JS_GetContextPrivate(cx); if (JS_FALSE == JS_GetProperty(cx, edjs_p->settings_obj, "include_path", &path_val)) { //EDJS_ERR(cx, EDJSERR_GET_PROPERTY, "EDJS", "include_path"); goto error; } path_obj = JSVAL_TO_OBJECT(path_val); if (JS_FALSE == EDJS_ResolveFile(cx, path_obj, NULL, mod_name, &mod_path, &file_stat)) { goto error; } if (NULL == mod_path) { //EDJS_ERR(cx, EDJSERR_FILENAME_RESOLVE, JS_GetStringBytes(include_str)); goto error; } p->lib_handle = dlopen(mod_path, RTLD_NOW); char *dl_error = NULL; //if (NULL == p->lib_handle) { if ((dl_error = dlerror()) != NULL) { p->lib_handle = NULL; JS_ReportError(cx, dl_error); goto error; } db_driver_init = dlsym(p->lib_handle, "edjsdb_driver_instance_init"); // if (NULL == db_driver_init) { if ((dl_error = dlerror()) != NULL) { JS_ReportError(cx, dl_error); //JS_ReportError(cx, "failed to load edjsdb_driver_instance_init"); goto error; } ok = db_driver_init(cx, ret_obj); if (JS_FALSE == ok) { JS_ReportError(cx, "driver failed its init method"); goto error; } goto finish; error: ok = JS_FALSE; *rval = JSVAL_VOID; finish: JS_RemoveRoot(cx, &type); return ok; }
static void StartElementHandler(void *userdata, const char *name, const char **atts) { XMLGraphCallback * cb = (XMLGraphCallback *)userdata; int i; JSObject *element, *attobj, *array; JSContext *cx = cb->cb.cx; jsval rval; if (!cb->current) { if (!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), xmljs_newObj_str, xmljs_newObj_size, "XMLGraph internal", 0, &rval)) { JS_ReportError(cx, "failed to create new Object"); return; } element = JSVAL_TO_OBJECT(rval); cb->current = element; if (!JS_DefineProperty(cx, cb->cb.obj, "graph", rval, NULL, NULL, JSPROP_ENUMERATE)) { JS_ReportError(cx, "failed to define graph prop"); return; } } if (!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), xmljs_newObj_str, xmljs_newObj_size, "XMLGraph internal", 0, &rval)) { JS_ReportError(cx, "failed to create new Object"); return; } element = JSVAL_TO_OBJECT(rval); /* populate and set __attributes__ */ if (atts[0]) { JSString *attstr; if (!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), xmljs_newObj_str, xmljs_newObj_size, "XMLGraph internal", 0, &rval)) return; attobj = JSVAL_TO_OBJECT(rval); for (i = 0; atts[i]; i+=2) { /* * if we have an attribute that matches nameBy, use * the value of that attribute to name the node */ if (cb->nameBy && !strcmp(cb->nameBy, atts[i])) name = atts[i+1]; attstr = JS_NewStringCopyZ(cx, atts[i+1]); if (!attstr || !JS_DefineProperty(cx, attobj, atts[i], STRING_TO_JSVAL(attstr), NULL, NULL, JSPROP_ENUMERATE)) return; } if (!JS_DefineProperty(cx, element, "__attributes__", OBJECT_TO_JSVAL(attobj), NULL, NULL, 0)) return; } /* Check for existing property with this name */ if (!JS_GetProperty(cx, cb->current, name, &rval)) return; if (JSVAL_IS_OBJECT(rval)) { JSObject *existing = JSVAL_TO_OBJECT(rval); if (JS_IsArrayObject(cx, existing)) { /* already an array, so append */ jsuint length; if (!JS_GetArrayLength(cx, existing, &length) || !JS_DefineElement(cx, existing, (jsint)length, OBJECT_TO_JSVAL(element), NULL, NULL, JSPROP_ENUMERATE)) return; } else { /* replace with an array [current, new] */ jsval vector[2]; vector[0] = OBJECT_TO_JSVAL(existing); vector[1] = OBJECT_TO_JSVAL(element); array = JS_NewArrayObject(cx, 2, vector); if (!array || !JS_DefineProperty(cx, cb->current, name, OBJECT_TO_JSVAL(array), NULL, NULL, JSPROP_ENUMERATE)) return; } } else if (!JS_DefineProperty(cx, cb->current, name, OBJECT_TO_JSVAL(element), NULL, NULL, JSPROP_ENUMERATE)) return; /* define backpointer __up__ */ if (!JS_DefineProperty(cx, element, xmlg_up_str, OBJECT_TO_JSVAL(cb->current), NULL, NULL, 0)) return; /* * XXX DefineProperty(element, "__element__", elementstr) */ cb->current = element; }
/** * Define OS-specific constants. * * This function creates or uses JS object |OS.Constants| to store * all its constants. */ bool DefineOSFileConstants(JSContext *cx, JS::Handle<JSObject*> global) { MOZ_ASSERT(gInitialized); if (gPaths == nullptr) { // If an initialization error was ignored, we may end up with // |gInitialized == true| but |gPaths == nullptr|. We cannot // |MOZ_ASSERT| this, as this would kill precompile_cache.js, // so we simply return an error. JS_ReportErrorNumber(cx, js::GetErrorMessage, nullptr, JSMSG_CANT_OPEN, "OSFileConstants", "initialization has failed"); return false; } JS::Rooted<JSObject*> objOS(cx); if (!(objOS = GetOrCreateObjectProperty(cx, global, "OS"))) { return false; } JS::Rooted<JSObject*> objConstants(cx); if (!(objConstants = GetOrCreateObjectProperty(cx, objOS, "Constants"))) { return false; } // Build OS.Constants.libc JS::Rooted<JSObject*> objLibc(cx); if (!(objLibc = GetOrCreateObjectProperty(cx, objConstants, "libc"))) { return false; } if (!dom::DefineConstants(cx, objLibc, gLibcProperties)) { return false; } #if defined(XP_WIN) // Build OS.Constants.Win JS::Rooted<JSObject*> objWin(cx); if (!(objWin = GetOrCreateObjectProperty(cx, objConstants, "Win"))) { return false; } if (!dom::DefineConstants(cx, objWin, gWinProperties)) { return false; } #endif // defined(XP_WIN) // Build OS.Constants.Sys JS::Rooted<JSObject*> objSys(cx); if (!(objSys = GetOrCreateObjectProperty(cx, objConstants, "Sys"))) { return false; } #if defined(MOZ_WIDGET_GONK) JSString* strVersion = JS_NewStringCopyZ(cx, "Gonk"); if (!strVersion) { return false; } JS::Rooted<JS::Value> valVersion(cx, JS::StringValue(strVersion)); if (!JS_SetProperty(cx, objSys, "Name", valVersion)) { return false; } #else nsCOMPtr<nsIXULRuntime> runtime = do_GetService(XULRUNTIME_SERVICE_CONTRACTID); if (runtime) { nsAutoCString os; DebugOnly<nsresult> rv = runtime->GetOS(os); MOZ_ASSERT(NS_SUCCEEDED(rv)); JSString* strVersion = JS_NewStringCopyZ(cx, os.get()); if (!strVersion) { return false; } JS::Rooted<JS::Value> valVersion(cx, JS::StringValue(strVersion)); if (!JS_SetProperty(cx, objSys, "Name", valVersion)) { return false; } } #endif // defined(MOZ_WIDGET_GONK) #if defined(DEBUG) JS::Rooted<JS::Value> valDebug(cx, JS::TrueValue()); if (!JS_SetProperty(cx, objSys, "DEBUG", valDebug)) { return false; } #endif #if defined(HAVE_64BIT_BUILD) JS::Rooted<JS::Value> valBits(cx, JS::Int32Value(64)); #else JS::Rooted<JS::Value> valBits(cx, JS::Int32Value(32)); #endif //defined (HAVE_64BIT_BUILD) if (!JS_SetProperty(cx, objSys, "bits", valBits)) { return false; } if (!JS_DefineProperty(cx, objSys, "umask", gUserUmask, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) { return false; } // Build OS.Constants.Path JS::Rooted<JSObject*> objPath(cx); if (!(objPath = GetOrCreateObjectProperty(cx, objConstants, "Path"))) { return false; } // Locate libxul // Note that we don't actually provide the full path, only the name of the // library, which is sufficient to link to the library using js-ctypes. #if defined(XP_MACOSX) // Under MacOS X, for some reason, libxul is called simply "XUL", // and we need to provide the full path. nsAutoString libxul; libxul.Append(gPaths->libDir); libxul.AppendLiteral("/XUL"); #else // On other platforms, libxul is a library "xul" with regular // library prefix/suffix. nsAutoString libxul; libxul.AppendLiteral(DLL_PREFIX); libxul.AppendLiteral("xul"); libxul.AppendLiteral(DLL_SUFFIX); #endif // defined(XP_MACOSX) if (!SetStringProperty(cx, objPath, "libxul", libxul)) { return false; } if (!SetStringProperty(cx, objPath, "libDir", gPaths->libDir)) { return false; } if (!SetStringProperty(cx, objPath, "tmpDir", gPaths->tmpDir)) { return false; } // Configure profileDir only if it is available at this stage if (!gPaths->profileDir.IsVoid() && !SetStringProperty(cx, objPath, "profileDir", gPaths->profileDir)) { return false; } // Configure localProfileDir only if it is available at this stage if (!gPaths->localProfileDir.IsVoid() && !SetStringProperty(cx, objPath, "localProfileDir", gPaths->localProfileDir)) { return false; } if (!SetStringProperty(cx, objPath, "homeDir", gPaths->homeDir)) { return false; } if (!SetStringProperty(cx, objPath, "desktopDir", gPaths->desktopDir)) { return false; } if (!SetStringProperty(cx, objPath, "userApplicationDataDir", gPaths->userApplicationDataDir)) { return false; } #if defined(XP_WIN) if (!SetStringProperty(cx, objPath, "winAppDataDir", gPaths->winAppDataDir)) { return false; } if (!SetStringProperty(cx, objPath, "winStartMenuProgsDir", gPaths->winStartMenuProgsDir)) { return false; } #endif // defined(XP_WIN) #if defined(XP_MACOSX) if (!SetStringProperty(cx, objPath, "macUserLibDir", gPaths->macUserLibDir)) { return false; } if (!SetStringProperty(cx, objPath, "macLocalApplicationsDir", gPaths->macLocalApplicationsDir)) { return false; } if (!SetStringProperty(cx, objPath, "macTrashDir", gPaths->macTrashDir)) { return false; } #endif // defined(XP_MACOSX) // sqlite3 is linked from different places depending on the platform nsAutoString libsqlite3; #if defined(ANDROID) // On Android, we use the system's libsqlite3 libsqlite3.AppendLiteral(DLL_PREFIX); libsqlite3.AppendLiteral("sqlite3"); libsqlite3.AppendLiteral(DLL_SUFFIX); #elif defined(XP_WIN) // On Windows, for some reason, this is part of nss3.dll libsqlite3.AppendLiteral(DLL_PREFIX); libsqlite3.AppendLiteral("nss3"); libsqlite3.AppendLiteral(DLL_SUFFIX); #else // On other platforms, we link sqlite3 into libxul libsqlite3 = libxul; #endif // defined(ANDROID) || defined(XP_WIN) if (!SetStringProperty(cx, objPath, "libsqlite3", libsqlite3)) { return false; } return true; }
void jsb_register_cocos2d_config( JSContext *_cx, JSObject *cocos2d) { // Config Object JSObject *ccconfig = JS_NewObject(_cx, NULL, NULL, NULL); // config.os: The Operating system // osx, ios, android, windows, linux, etc.. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) JSString *str = JS_InternString(_cx, "ios"); #elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) JSString *str = JS_InternString(_cx, "android"); #elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) JSString *str = JS_InternString(_cx, "windows"); #elif (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE) JSString *str = JS_InternString(_cx, "marmalade"); #elif (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) JSString *str = JS_InternString(_cx, "linux"); #elif (CC_TARGET_PLATFORM == CC_PLATFORM_BADA) JSString *str = JS_InternString(_cx, "bada"); #elif (CC_TARGET_PLATFORM == CC_PLATFORM_BLACKBERRY) JSString *str = JS_InternString(_cx, "blackberry"); #elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) JSString *str = JS_InternString(_cx, "osx"); #else JSString *str = JS_InternString(_cx, "unknown"); #endif JS_DefineProperty(_cx, ccconfig, "os", STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); // config.deviceType: Device Type // 'mobile' for any kind of mobile devices, 'desktop' for PCs, 'browser' for Web Browsers // #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) // str = JS_InternString(_cx, "desktop"); // #else str = JS_InternString(_cx, "mobile"); // #endif JS_DefineProperty(_cx, ccconfig, "platform", STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); // config.engine: Type of renderer // 'cocos2d', 'cocos2d-x', 'cocos2d-html5/canvas', 'cocos2d-html5/webgl', etc.. str = JS_InternString(_cx, "cocos2d-x"); JS_DefineProperty(_cx, ccconfig, "engine", STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); // config.arch: CPU Architecture // i386, ARM, x86_64, web #ifdef __LP64__ str = JS_InternString(_cx, "x86_64"); #elif defined(__arm__) || defined(__ARM_NEON__) str = JS_InternString(_cx, "arm"); #else str = JS_InternString(_cx, "i386"); #endif JS_DefineProperty(_cx, ccconfig, "arch", STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); // config.version: Version of cocos2d + renderer str = JS_InternString(_cx, cocos2dVersion() ); JS_DefineProperty(_cx, ccconfig, "version", STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); // config.usesTypedArrays #if JSB_COMPATIBLE_WITH_COCOS2D_HTML5_BASIC_TYPES JSBool b = JS_FALSE; #else JSBool b = JS_TRUE; #endif JS_DefineProperty(_cx, ccconfig, "usesTypedArrays", BOOLEAN_TO_JSVAL(b), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); // config.debug: Debug build ? #if COCOS2D_DEBUG > 0 b = JS_TRUE; #else b = JS_FALSE; #endif JS_DefineProperty(_cx, ccconfig, "debug", BOOLEAN_TO_JSVAL(b), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); // Add "config" to "cc" JS_DefineProperty(_cx, cocos2d, "config", OBJECT_TO_JSVAL(ccconfig), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); }
BOOL DLLCALL js_CreateXtrnProgProperties(JSContext* cx, JSObject* obj, xtrn_t* xtrn) { JSString* js_str; if((js_str=JS_NewStringCopyZ(cx, xtrn->code))==NULL) return(FALSE); if(!JS_DefineProperty(cx, obj, "code", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if((js_str=JS_NewStringCopyZ(cx, xtrn->name))==NULL) return(FALSE); if(!JS_DefineProperty(cx, obj, "name", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if((js_str=JS_NewStringCopyZ(cx, xtrn->cmd))==NULL) return(FALSE); if(!JS_DefineProperty(cx, obj, "cmd", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if((js_str=JS_NewStringCopyZ(cx, xtrn->clean))==NULL) return(FALSE); if(!JS_DefineProperty(cx, obj, "clean_cmd", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if((js_str=JS_NewStringCopyZ(cx, xtrn->path))==NULL) return(FALSE); if(!JS_DefineProperty(cx, obj, "startup_dir", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if((js_str=JS_NewStringCopyZ(cx, xtrn->arstr))==NULL) return(FALSE); if(!JS_DefineProperty(cx, obj, "ars", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if((js_str=JS_NewStringCopyZ(cx, xtrn->run_arstr))==NULL) return(FALSE); if(!JS_DefineProperty(cx, obj, "execution_ars", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if(!JS_DefineProperty(cx, obj, "settings", INT_TO_JSVAL(xtrn->misc) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if(!JS_DefineProperty(cx, obj, "type", INT_TO_JSVAL(xtrn->type) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if(!JS_DefineProperty(cx, obj, "event", INT_TO_JSVAL(xtrn->event) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if(!JS_DefineProperty(cx, obj, "textra", INT_TO_JSVAL(xtrn->textra) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if(!JS_DefineProperty(cx, obj, "max_time", INT_TO_JSVAL(xtrn->maxtime) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); if(!JS_DefineProperty(cx, obj, "cost", INT_TO_JSVAL(xtrn->cost) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(FALSE); #ifdef BUILD_JSDOCS js_CreateArrayOfStrings(cx, obj, "_property_desc_list", xtrn_prog_prop_desc, JSPROP_READONLY); #endif return(TRUE); }
static JSObject * load_module_init(JSContext *context, JSObject *in_object, const char *full_path) { char *script; gsize script_len; jsval script_retval; JSObject *module_obj; /* First we check if js module has already been loaded */ if (gjs_object_has_property(context, in_object, MODULE_INIT_PROPERTY)) { jsval module_obj_val; if (gjs_object_get_property(context, in_object, MODULE_INIT_PROPERTY, &module_obj_val)) { return JSVAL_TO_OBJECT(module_obj_val); } } module_obj = JS_NewObject(context, NULL, NULL, NULL); if (module_obj == NULL) { return JS_FALSE; } /* https://bugzilla.mozilla.org/show_bug.cgi?id=599651 means we * can't just pass in the global as the parent */ JS_SetParent(context, module_obj, gjs_get_import_global (context)); /* Define module in importer for future use and to avoid module_obj * object to be garbage collected during the evaluation of the script */ JS_DefineProperty(context, in_object, MODULE_INIT_PROPERTY, OBJECT_TO_JSVAL(module_obj), NULL, NULL, GJS_MODULE_PROP_FLAGS & ~JSPROP_PERMANENT); script = NULL; script_len = 0; if (!g_file_get_contents(full_path, &script, &script_len, NULL)) { return NULL; } g_assert(script != NULL); gjs_debug(GJS_DEBUG_IMPORTER, "Importing %s", full_path); if (!JS_EvaluateScript(context, module_obj, script, script_len, full_path, 1, /* line number */ &script_retval)) { g_free(script); /* If JSOPTION_DONT_REPORT_UNCAUGHT is set then the exception * would be left set after the evaluate and not go to the error * reporter function. */ if (JS_IsExceptionPending(context)) { gjs_debug(GJS_DEBUG_IMPORTER, "Module " MODULE_INIT_FILENAME " left an exception set"); gjs_log_and_keep_exception(context, NULL); } else { gjs_throw(context, "JS_EvaluateScript() returned FALSE but did not set exception"); } return NULL; } g_free(script); return module_obj; }
JSBool xpc_qsDefineQuickStubs(JSContext *cx, JSObject *proto, uintN flags, PRUint32 ifacec, const nsIID **interfaces, PRUint32 tableSize, const xpc_qsHashEntry *table) { /* * Walk interfaces in reverse order to behave like XPConnect when a * feature is defined in more than one of the interfaces. * * XPCNativeSet::FindMethod returns the first matching feature it finds, * searching the interfaces forward. Here, definitions toward the * front of 'interfaces' overwrite those toward the back. */ PRBool definedProperty = PR_FALSE; for(uint32 i = ifacec; i-- != 0;) { const nsID &iid = *interfaces[i]; const xpc_qsHashEntry *entry = LookupInterfaceOrAncestor(tableSize, table, iid); if(entry) { for(;;) { // Define quick stubs for attributes. const xpc_qsPropertySpec *ps = entry->properties; if(ps) { for(; ps->name; ps++) { definedProperty = PR_TRUE; if(!JS_DefineProperty(cx, proto, ps->name, JSVAL_VOID, ps->getter, ps->setter, flags | JSPROP_SHARED)) return JS_FALSE; } } // Define quick stubs for methods. const xpc_qsFunctionSpec *fs = entry->functions; if(fs) { for(; fs->name; fs++) { if(!JS_DefineFunction( cx, proto, fs->name, reinterpret_cast<JSNative>(fs->native), fs->arity, flags | JSFUN_FAST_NATIVE)) return JS_FALSE; } } const xpc_qsTraceableSpec *ts = entry->traceables; if(ts) { for(; ts->name; ts++) { if(!JS_DefineFunction( cx, proto, ts->name, ts->native, ts->arity, flags | JSFUN_FAST_NATIVE | JSFUN_STUB_GSOPS | JSFUN_TRCINFO)) return JS_FALSE; } } // Next. size_t j = entry->parentInterface; if(j == XPC_QS_NULL_INDEX) break; entry = table + j; } } } static JSFunctionSpec getterfns[] = { JS_FN("__lookupGetter__", SharedLookupGetter, 1, 0), JS_FN("__lookupSetter__", SharedLookupSetter, 1, 0), JS_FN("__defineGetter__", SharedDefineGetter, 2, 0), JS_FN("__defineSetter__", SharedDefineSetter, 2, 0), JS_FS_END }; if(definedProperty && !JS_DefineFunctions(cx, proto, getterfns)) return JS_FALSE; return JS_TRUE; }
nsresult mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponent, JSObject **aGlobal, char **aLocation) { nsresult rv; JSPrincipals* jsPrincipals = nsnull; JSCLContextHelper cx(mContext); #ifndef XPCONNECT_STANDALONE rv = mSystemPrincipal->GetJSPrincipals(cx, &jsPrincipals); NS_ENSURE_SUCCESS(rv, rv); JSPrincipalsHolder princHolder(mContext, jsPrincipals); #endif nsCOMPtr<nsIXPCScriptable> backstagePass; rv = mRuntimeService->GetBackstagePass(getter_AddRefs(backstagePass)); NS_ENSURE_SUCCESS(rv, rv); JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter); nsCOMPtr<nsIXPConnect> xpc = do_GetService(kXPConnectServiceContractID, &rv); NS_ENSURE_SUCCESS(rv, rv); // Make sure InitClassesWithNewWrappedGlobal() installs the // backstage pass as the global in our compilation context. JS_SetGlobalObject(cx, nsnull); nsCOMPtr<nsIXPConnectJSObjectHolder> holder; rv = xpc->InitClassesWithNewWrappedGlobal(cx, backstagePass, NS_GET_IID(nsISupports), nsIXPConnect:: FLAG_SYSTEM_GLOBAL_OBJECT, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); JSObject *global; rv = holder->GetJSObject(&global); NS_ENSURE_SUCCESS(rv, rv); if (!JS_DefineFunctions(cx, global, gGlobalFun)) { return NS_ERROR_FAILURE; } nsCOMPtr<nsIXPConnectJSObjectHolder> locationHolder; rv = xpc->WrapNative(cx, global, aComponent, NS_GET_IID(nsILocalFile), getter_AddRefs(locationHolder)); NS_ENSURE_SUCCESS(rv, rv); JSObject *locationObj; rv = locationHolder->GetJSObject(&locationObj); NS_ENSURE_SUCCESS(rv, rv); if (!JS_DefineProperty(cx, global, "__LOCATION__", OBJECT_TO_JSVAL(locationObj), nsnull, nsnull, 0)) { return NS_ERROR_FAILURE; } nsCAutoString nativePath; // Quick hack to unbust XPCONNECT_STANDALONE. // This leaves the jsdebugger with a non-URL pathname in the // XPCONNECT_STANDALONE case - but at least it builds and runs otherwise. // See: http://bugzilla.mozilla.org/show_bug.cgi?id=121438 #ifdef XPCONNECT_STANDALONE localFile->GetNativePath(nativePath); #else NS_GetURLSpecFromFile(aComponent, nativePath); #endif // Before compiling the script, first check to see if we have it in // the fastload file. Note: as a rule, fastload errors are not fatal // to loading the script, since we can always slow-load. nsCOMPtr<nsIFastLoadService> flSvc = do_GetFastLoadService(&rv); // Save the old state and restore it upon return FastLoadStateHolder flState(flSvc); PRBool fastLoading = PR_FALSE; if (NS_SUCCEEDED(rv)) { rv = StartFastLoad(flSvc); if (NS_SUCCEEDED(rv)) { fastLoading = PR_TRUE; } } nsCOMPtr<nsIURI> uri; rv = NS_NewURI(getter_AddRefs(uri), nativePath); NS_ENSURE_SUCCESS(rv, rv); JSScript *script = nsnull; if (fastLoading) { rv = ReadScript(flSvc, nativePath.get(), uri, cx, &script); if (NS_SUCCEEDED(rv)) { LOG(("Successfully loaded %s from fastload\n", nativePath.get())); fastLoading = PR_FALSE; // no need to write out the script } else if (rv == NS_ERROR_NOT_AVAILABLE) { // This is ok, it just means the script is not yet in the // fastload file. rv = NS_OK; } else { LOG(("Failed to deserialize %s\n", nativePath.get())); // Remove the fastload file, it may be corrupted. LOG(("Invalid fastload file detected, removing it\n")); nsCOMPtr<nsIObjectOutputStream> objectOutput; flSvc->GetOutputStream(getter_AddRefs(objectOutput)); if (objectOutput) { flSvc->SetOutputStream(nsnull); objectOutput->Close(); } nsCOMPtr<nsIObjectInputStream> objectInput; flSvc->GetInputStream(getter_AddRefs(objectInput)); if (objectInput) { flSvc->SetInputStream(nsnull); objectInput->Close(); } if (mFastLoadFile) { mFastLoadFile->Remove(PR_FALSE); } fastLoading = PR_FALSE; } } if (!script || NS_FAILED(rv)) { // The script wasn't in the fastload cache, so compile it now. LOG(("Slow loading %s\n", nativePath.get())); #ifdef HAVE_PR_MEMMAP PRInt64 fileSize; rv = aComponent->GetFileSize(&fileSize); if (NS_FAILED(rv)) return rv; PRInt64 maxSize; LL_UI2L(maxSize, PR_UINT32_MAX); if (LL_CMP(fileSize, >, maxSize)) { NS_ERROR("file too large"); return NS_ERROR_FAILURE; } PRFileDesc *fileHandle; rv = aComponent->OpenNSPRFileDesc(PR_RDONLY, 0, &fileHandle); NS_ENSURE_SUCCESS(rv, rv); // Make sure the file is closed, no matter how we return. FileAutoCloser fileCloser(fileHandle); PRFileMap *map = PR_CreateFileMap(fileHandle, fileSize, PR_PROT_READONLY); if (!map) { NS_ERROR("Failed to create file map"); return NS_ERROR_FAILURE; } // Make sure the file map is closed, no matter how we return. FileMapAutoCloser mapCloser(map); PRUint32 fileSize32; LL_L2UI(fileSize32, fileSize); char *buf = static_cast<char*>(PR_MemMap(map, 0, fileSize32)); if (!buf) { NS_WARNING("Failed to map file"); return NS_ERROR_FAILURE; } script = JS_CompileScriptForPrincipals(cx, global, jsPrincipals, buf, fileSize32, nativePath.get(), 1); PR_MemUnmap(buf, fileSize32); #else /* HAVE_PR_MEMMAP */ /** * No memmap implementation, so fall back to using * JS_CompileFileHandleForPrincipals(). */ FILE *fileHandle; rv = aComponent->OpenANSIFileDesc("r", &fileHandle); NS_ENSURE_SUCCESS(rv, rv); script = JS_CompileFileHandleForPrincipals(cx, global, nativePath.get(), fileHandle, jsPrincipals); /* JS will close the filehandle after compilation is complete. */ #endif /* HAVE_PR_MEMMAP */ }
int ExecShellScript(const char * file, int argc, char** argv, JSContext * context, JSObject * env, jsval * vp) { register FILE * filep; register int c; filep = fopen(file, "rb"); if (!filep) { JS_ReportError(context, "%s: %s", file, "No such file or directory"); return 0; } if (getc(filep) == '#' && getc(filep) == '!') { c = 1; while (c != EOF && c != '\n') c = getc(filep); ungetc(c, filep); } else { fclose(filep); JS_ReportError(context, "%s: %s", file, "is not a shell script"); return 0; } JSObject* argsObj = JS_NewArrayObject(context, 0, NULL); JS_DefineProperty(context, env, "parameter", OBJECT_TO_JSVAL(argsObj), NULL, NULL, 0); JSString* str = JS_NewStringCopyZ(context, file); JS_DefineElement(context, argsObj, 0, STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE); int i; for (i = 0; i < argc; i++) { str = JS_NewStringCopyZ(context, argv[i]); JS_DefineElement(context, argsObj, i + 1, STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE); } setenv(SMASH_RESOURCE_PATH_ENV_ID, GET_STRING_DEF(SMASH_RESOURCE_PATH), 0); JS_InitCTypesClass(context, env); JS_DefineFunctions(context, env, shell_functions); JS_DefineProperties(context, env, shell_properties); jsval fun; JS_GetProperty(context, env, "system", &fun); JS_DefineFunction(context, JSVAL_TO_OBJECT(fun), "read", ShellSystemRead, 1, JSPROP_ENUMERATE); JS_DefineFunction(context, JSVAL_TO_OBJECT(fun), "write", ShellSystemWrite, 2, JSPROP_ENUMERATE); jsval fun2; JS_GetProperty(context, env, "echo", &fun2); JS_DefineFunction(context, JSVAL_TO_OBJECT(fun2), "error", ShellEchoError, 1, JSPROP_ENUMERATE); jsval fun3; JS_GetProperty(context, env, "setFileContent", &fun3); JS_DefineFunction(context, JSVAL_TO_OBJECT(fun3), "append", ShellSetFileContentAppend, 2, JSPROP_ENUMERATE); #ifdef SMASH_MAIN_LOADER //ExecScriptFile(context, env, GET_STRING_DEF(SMASH_MAIN_LOADER), NULL); #endif #ifdef SMASH_SHELL_LOADER ExecScriptFile(context, env, GET_STRING_DEF(SMASH_SHELL_LOADER), NULL); #endif JSObject * jsTemp = JS_CompileFileHandle(context, env, file, filep); fclose(filep); if (jsTemp) { return JS_ExecuteScript(context, env, jsTemp, vp); } else { JS_ReportPendingException(context); return 1; } }
JSObject * LM_ReflectEmbed(MWContext *context, LO_EmbedStruct *lo_embed, PA_Tag * tag, int32 layer_id, uint index) { JSObject *obj, *array_obj, *outer_obj, *document; MochaDecoder *decoder; JSContext *cx; char *name; int i; obj = lo_embed->mocha_object; if (obj) return obj; decoder = LM_GetMochaDecoder(context); if (!decoder) return NULL; cx = decoder->js_context; /* get the name */ name = 0; for (i = 0; i < lo_embed->attribute_cnt; i++) { if (!XP_STRCASECMP(lo_embed->attribute_list[i], "name")) { name = strdup(lo_embed->value_list[i]); break; } } /* Get the document object that will hold this applet */ document = lm_GetDocumentFromLayerId(decoder, layer_id); if (!document) { LM_PutMochaDecoder(decoder); return NULL; } array_obj = lm_GetEmbedArray(decoder, document); if (!array_obj) { LM_PutMochaDecoder(decoder); return NULL; } /* XXX should pass thru ReallyReflectApplet to whatever calls NewObject */ outer_obj = lm_GetOuterObject(decoder); /* this function does the real work */ obj = lm_ReallyReflectEmbed(context, lo_embed, layer_id, index); if (!obj) goto out; /* put it in the embed array */ if (!lm_AddObjectToArray(cx, array_obj, name, index, obj)) { obj = NULL; goto out; } /* put it in the document scope */ if (name && !JS_DefineProperty(cx, outer_obj, name, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY)) { PR_LOG(Moja, warn, ("failed to define embed 0x%x as %s\n", lo_embed, name)); /* XXX remove it altogether? */ } /* cache it in layout data structure */ lo_embed->mocha_object = obj; out: LM_PutMochaDecoder(decoder); return obj; }
NS_IMETHODIMP TelemetryImpl::GetChromeHangs(JSContext *cx, jsval *ret) { MutexAutoLock hangReportMutex(mHangReportsMutex); JSObject *reportArray = JS_NewArrayObject(cx, 0, nsnull); if (!reportArray) { return NS_ERROR_FAILURE; } *ret = OBJECT_TO_JSVAL(reportArray); // Each hang report is an object in the 'chromeHangs' array for (size_t i = 0; i < mHangReports.Length(); ++i) { JSObject *reportObj = JS_NewObject(cx, NULL, NULL, NULL); if (!reportObj) { return NS_ERROR_FAILURE; } jsval reportObjVal = OBJECT_TO_JSVAL(reportObj); if (!JS_SetElement(cx, reportArray, i, &reportObjVal)) { return NS_ERROR_FAILURE; } // Record the hang duration (expressed in seconds) JSBool ok = JS_DefineProperty(cx, reportObj, "duration", INT_TO_JSVAL(mHangReports[i].duration), NULL, NULL, JSPROP_ENUMERATE); if (!ok) { return NS_ERROR_FAILURE; } // Represent call stack PCs as strings // (JS can't represent all 64-bit integer values) JSObject *pcArray = JS_NewArrayObject(cx, 0, nsnull); if (!pcArray) { return NS_ERROR_FAILURE; } ok = JS_DefineProperty(cx, reportObj, "stack", OBJECT_TO_JSVAL(pcArray), NULL, NULL, JSPROP_ENUMERATE); if (!ok) { return NS_ERROR_FAILURE; } const uint32_t pcCount = mHangReports[i].callStack.Length(); for (size_t pcIndex = 0; pcIndex < pcCount; ++pcIndex) { nsCAutoString pcString; pcString.AppendPrintf("0x%p", mHangReports[i].callStack[pcIndex]); JSString *str = JS_NewStringCopyZ(cx, pcString.get()); if (!str) { return NS_ERROR_FAILURE; } jsval v = STRING_TO_JSVAL(str); if (!JS_SetElement(cx, pcArray, pcIndex, &v)) { return NS_ERROR_FAILURE; } } // Record memory map info JSObject *moduleArray = JS_NewArrayObject(cx, 0, nsnull); if (!moduleArray) { return NS_ERROR_FAILURE; } ok = JS_DefineProperty(cx, reportObj, "memoryMap", OBJECT_TO_JSVAL(moduleArray), NULL, NULL, JSPROP_ENUMERATE); if (!ok) { return NS_ERROR_FAILURE; } #if defined(MOZ_ENABLE_PROFILER_SPS) const uint32_t moduleCount = mHangReports[i].moduleMap.GetSize(); for (size_t moduleIndex = 0; moduleIndex < moduleCount; ++moduleIndex) { // Current module const SharedLibrary &module = mHangReports[i].moduleMap.GetEntry(moduleIndex); JSObject *moduleInfoArray = JS_NewArrayObject(cx, 0, nsnull); if (!moduleInfoArray) { return NS_ERROR_FAILURE; } jsval val = OBJECT_TO_JSVAL(moduleInfoArray); if (!JS_SetElement(cx, moduleArray, moduleIndex, &val)) { return NS_ERROR_FAILURE; } // Start address nsCAutoString addressString; addressString.AppendPrintf("0x%p", module.GetStart()); JSString *str = JS_NewStringCopyZ(cx, addressString.get()); if (!str) { return NS_ERROR_FAILURE; } val = STRING_TO_JSVAL(str); if (!JS_SetElement(cx, moduleInfoArray, 0, &val)) { return NS_ERROR_FAILURE; } // Module name str = JS_NewStringCopyZ(cx, module.GetName()); if (!str) { return NS_ERROR_FAILURE; } val = STRING_TO_JSVAL(str); if (!JS_SetElement(cx, moduleInfoArray, 1, &val)) { return NS_ERROR_FAILURE; } // Module size in memory val = INT_TO_JSVAL(int32_t(module.GetEnd() - module.GetStart())); if (!JS_SetElement(cx, moduleInfoArray, 2, &val)) { return NS_ERROR_FAILURE; } // "PDB Age" identifier val = INT_TO_JSVAL(0); #if defined(MOZ_PROFILING) && defined(XP_WIN) val = INT_TO_JSVAL(module.GetPdbAge()); #endif if (!JS_SetElement(cx, moduleInfoArray, 3, &val)) { return NS_ERROR_FAILURE; } // "PDB Signature" GUID char guidString[NSID_LENGTH] = { 0 }; #if defined(MOZ_PROFILING) && defined(XP_WIN) module.GetPdbSignature().ToProvidedString(guidString); #endif str = JS_NewStringCopyZ(cx, guidString); if (!str) { return NS_ERROR_FAILURE; } val = STRING_TO_JSVAL(str); if (!JS_SetElement(cx, moduleInfoArray, 4, &val)) { return NS_ERROR_FAILURE; } // Name of associated PDB file const char *pdbName = ""; #if defined(MOZ_PROFILING) && defined(XP_WIN) pdbName = module.GetPdbName(); #endif str = JS_NewStringCopyZ(cx, pdbName); if (!str) { return NS_ERROR_FAILURE; } val = STRING_TO_JSVAL(str); if (!JS_SetElement(cx, moduleInfoArray, 5, &val)) { return NS_ERROR_FAILURE; } } #endif } return NS_OK; }
JSObject* DLLCALL js_CreateXtrnAreaObject(JSContext* cx, JSObject* parent, scfg_t* cfg ,user_t* user, client_t* client) { JSObject* areaobj; JSObject* allsec; JSObject* allprog; JSObject* secobj; JSObject* progobj; JSObject* eventobj; JSObject* event_array; JSObject* xeditobj; JSObject* xedit_array; JSObject* sec_list; JSObject* prog_list; JSString* js_str; jsval val; jsuint sec_index; jsuint prog_index; uint l,d; /* Return existing object if it's already been created */ if(JS_GetProperty(cx,parent,"xtrn_area",&val) && val!=JSVAL_VOID) areaobj = JSVAL_TO_OBJECT(val); else areaobj = JS_DefineObject(cx, parent, "xtrn_area", NULL , NULL, JSPROP_ENUMERATE|JSPROP_READONLY); if(areaobj==NULL) return(NULL); #ifdef BUILD_JSDOCS js_DescribeSyncObject(cx,areaobj,"External Program Areas",310); #endif /* xtrn_area.sec[] */ if((allsec=JS_NewObject(cx,NULL,NULL,areaobj))==NULL) return(NULL); val=OBJECT_TO_JSVAL(allsec); if(!JS_SetProperty(cx, areaobj, "sec", &val)) return(NULL); /* xtrn_area.prog[] */ if((allprog=JS_NewObject(cx,NULL,NULL,areaobj))==NULL) return(NULL); val=OBJECT_TO_JSVAL(allprog); if(!JS_SetProperty(cx, areaobj, "prog", &val)) return(NULL); /* xtrn_area.sec_list[] */ if((sec_list=JS_NewArrayObject(cx, 0, NULL))==NULL) return(NULL); val=OBJECT_TO_JSVAL(sec_list); if(!JS_SetProperty(cx, areaobj, "sec_list", &val)) return(NULL); for(l=0;l<cfg->total_xtrnsecs;l++) { if((secobj=JS_NewObject(cx, NULL, NULL, NULL))==NULL) return(NULL); sec_index=-1; if(user==NULL || chk_ar(cfg,cfg->xtrnsec[l]->ar,user,client)) { if(!JS_GetArrayLength(cx, sec_list, &sec_index)) return(NULL); val=OBJECT_TO_JSVAL(secobj); if(!JS_SetElement(cx, sec_list, sec_index, &val)) return(NULL); } /* Add as property (associative array element) */ if(!JS_DefineProperty(cx, allsec, cfg->xtrnsec[l]->code, val ,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE)) return(NULL); val=INT_TO_JSVAL(sec_index); if(!JS_SetProperty(cx, secobj, "index", &val)) return(NULL); val=INT_TO_JSVAL(l); if(!JS_SetProperty(cx, secobj, "number", &val)) return(NULL); if((js_str=JS_NewStringCopyZ(cx, cfg->xtrnsec[l]->code))==NULL) return(NULL); val=STRING_TO_JSVAL(js_str); if(!JS_SetProperty(cx, secobj, "code", &val)) return(NULL); if((js_str=JS_NewStringCopyZ(cx, cfg->xtrnsec[l]->name))==NULL) return(NULL); val=STRING_TO_JSVAL(js_str); if(!JS_SetProperty(cx, secobj, "name", &val)) return(NULL); if((js_str=JS_NewStringCopyZ(cx, cfg->xtrnsec[l]->arstr))==NULL) return(NULL); val=STRING_TO_JSVAL(js_str); if(!JS_SetProperty(cx, secobj, "ars", &val)) return(NULL); if(user==NULL || chk_ar(cfg,cfg->xtrnsec[l]->ar,user,client)) val=JSVAL_TRUE; else val=JSVAL_FALSE; if(!JS_SetProperty(cx, secobj, "can_access", &val)) return(NULL); /* prog_list[] */ if((prog_list=JS_NewArrayObject(cx, 0, NULL))==NULL) return(NULL); val=OBJECT_TO_JSVAL(prog_list); if(!JS_SetProperty(cx, secobj, "prog_list", &val)) return(NULL); #ifdef BUILD_JSDOCS js_DescribeSyncObject(cx,secobj,"Online Program (door) Sections (current user has access to)",310); #endif for(d=0;d<cfg->total_xtrns;d++) { if(cfg->xtrn[d]->sec!=l) continue; if((progobj=JS_NewObject(cx, NULL, NULL, NULL))==NULL) return(NULL); prog_index=-1; if((user==NULL || chk_ar(cfg,cfg->xtrn[d]->ar,user,client)) && !(cfg->xtrn[d]->event && cfg->xtrn[d]->misc&EVENTONLY)) { if(!JS_GetArrayLength(cx, prog_list, &prog_index)) return(NULL); val=OBJECT_TO_JSVAL(progobj); if(!JS_SetElement(cx, prog_list, prog_index, &val)) return(NULL); } /* Add as property (associative array element) */ if(!JS_DefineProperty(cx, allprog, cfg->xtrn[d]->code, val ,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE)) return(NULL); val=INT_TO_JSVAL(prog_index); if(!JS_SetProperty(cx, progobj, "index", &val)) return(NULL); val=INT_TO_JSVAL(d); if(!JS_SetProperty(cx, progobj, "number", &val)) return(NULL); val=INT_TO_JSVAL(sec_index); if(!JS_SetProperty(cx, progobj, "sec_index", &val)) return(NULL); val=INT_TO_JSVAL(l); if(!JS_SetProperty(cx, progobj, "sec_number", &val)) return(NULL); val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,cfg->xtrnsec[l]->code)); if(!JS_SetProperty(cx, progobj, "sec_code", &val)) return(NULL); if(!js_CreateXtrnProgProperties(cx, progobj, cfg->xtrn[d])) return(NULL); if(user==NULL || chk_ar(cfg,cfg->xtrn[d]->ar,user,client)) val=JSVAL_TRUE; else val=JSVAL_FALSE; if(!JS_SetProperty(cx, progobj, "can_access", &val)) return(NULL); if(user==NULL || chk_ar(cfg,cfg->xtrn[d]->run_ar,user,client)) val=JSVAL_TRUE; else val=JSVAL_FALSE; if(!JS_SetProperty(cx, progobj, "can_run", &val)) return(NULL); #ifdef BUILD_JSDOCS js_DescribeSyncObject(cx,progobj,"Online External Programs (doors) (current user has access to)",310); #endif } #ifdef BUILD_JSDOCS js_CreateArrayOfStrings(cx, secobj, "_property_desc_list", xtrn_sec_prop_desc, JSPROP_READONLY); #endif } #ifdef BUILD_JSDOCS js_DescribeSyncObject(cx,allsec,"Associative array of all external program sections (use internal code as index)",312); JS_DefineProperty(cx,allsec,"_dont_document",JSVAL_TRUE,NULL,NULL,JSPROP_READONLY); js_DescribeSyncObject(cx,allprog,"Associative array of all external programs (use internal code as index)",311); JS_DefineProperty(cx,allprog,"_dont_document",JSVAL_TRUE,NULL,NULL,JSPROP_READONLY); #endif /* Create event property */ if((event_array=JS_NewObject(cx,NULL,NULL,areaobj))==NULL) return(NULL); val=OBJECT_TO_JSVAL(event_array); if(!JS_SetProperty(cx, areaobj, "event", &val)) return(NULL); for(l=0;l<cfg->total_events;l++) { if((eventobj=JS_NewObject(cx, NULL, NULL, NULL))==NULL) return(NULL); if(!JS_DefineProperty(cx, event_array, cfg->event[l]->code, OBJECT_TO_JSVAL(eventobj) ,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE)) return(NULL); if((js_str=JS_NewStringCopyZ(cx, cfg->event[l]->cmd))==NULL) return(NULL); if(!JS_DefineProperty(cx, eventobj, "cmd", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if((js_str=JS_NewStringCopyZ(cx, cfg->event[l]->dir))==NULL) return(NULL); if(!JS_DefineProperty(cx, eventobj, "startup_dir", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if(!JS_DefineProperty(cx, eventobj, "node_num", INT_TO_JSVAL(cfg->event[l]->node) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if(!JS_DefineProperty(cx, eventobj, "time", INT_TO_JSVAL(cfg->event[l]->time) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if(!JS_DefineProperty(cx, eventobj, "freq", INT_TO_JSVAL(cfg->event[l]->freq) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if(!JS_DefineProperty(cx, eventobj, "days", INT_TO_JSVAL(cfg->event[l]->days) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if(!JS_DefineProperty(cx, eventobj, "mdays", INT_TO_JSVAL(cfg->event[l]->mdays) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if(!JS_DefineProperty(cx, eventobj, "months", INT_TO_JSVAL(cfg->event[l]->months) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if(!JS_DefineProperty(cx, eventobj, "last_run", INT_TO_JSVAL(cfg->event[l]->last) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if(!JS_DefineProperty(cx, eventobj, "settings", INT_TO_JSVAL(cfg->event[l]->misc) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); #ifdef BUILD_JSDOCS js_CreateArrayOfStrings(cx, eventobj, "_property_desc_list", event_prop_desc, JSPROP_READONLY); #endif } #ifdef BUILD_JSDOCS js_DescribeSyncObject(cx,event_array,"Associative array of all timed events (use internal code as index)",311); JS_DefineProperty(cx,event_array,"_assoc_array",JSVAL_TRUE,NULL,NULL,JSPROP_READONLY); #endif /* Create editor property */ if((xedit_array=JS_NewObject(cx,NULL,NULL,areaobj))==NULL) return(NULL); val=OBJECT_TO_JSVAL(xedit_array); if(!JS_SetProperty(cx, areaobj, "editor", &val)) return(NULL); for(l=0;l<cfg->total_xedits;l++) { if(user!=NULL && !chk_ar(cfg,cfg->xedit[l]->ar,user,client)) continue; if((xeditobj=JS_NewObject(cx, NULL, NULL, NULL))==NULL) return(NULL); if(!JS_DefineProperty(cx, xedit_array, cfg->xedit[l]->code, OBJECT_TO_JSVAL(xeditobj) ,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE)) return(NULL); if((js_str=JS_NewStringCopyZ(cx, cfg->xedit[l]->name))==NULL) return(NULL); if(!JS_DefineProperty(cx, xeditobj, "name", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if((js_str=JS_NewStringCopyZ(cx, cfg->xedit[l]->rcmd))==NULL) return(NULL); if(!JS_DefineProperty(cx, xeditobj, "cmd", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if((js_str=JS_NewStringCopyZ(cx, cfg->xedit[l]->arstr))==NULL) return(NULL); if(!JS_DefineProperty(cx, xeditobj, "ars", STRING_TO_JSVAL(js_str) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if(!JS_DefineProperty(cx, xeditobj, "settings", INT_TO_JSVAL(cfg->xedit[l]->misc) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); if(!JS_DefineProperty(cx, xeditobj, "type", INT_TO_JSVAL(cfg->xedit[l]->type) ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY)) return(NULL); #ifdef BUILD_JSDOCS js_CreateArrayOfStrings(cx, xeditobj, "_property_desc_list", xedit_prop_desc, JSPROP_READONLY); #endif } #ifdef BUILD_JSDOCS js_DescribeSyncObject(cx,xedit_array,"Associative array of all external editors (use internal code as index)",311); JS_DefineProperty(cx,xedit_array,"_assoc_array",JSVAL_TRUE,NULL,NULL,JSPROP_READONLY); #endif return(areaobj); }
static JSBool go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen) { CurlState state; char* referer; JSString* jsbody; JSBool ret = JS_FALSE; jsval tmp; state.cx = cx; state.http = http; state.sendbuf = body; state.sendlen = bodylen; state.sent = 0; state.sent_once = 0; state.recvbuf = NULL; state.recvlen = 0; state.read = 0; if(HTTP_HANDLE == NULL) { HTTP_HANDLE = curl_easy_init(); curl_easy_setopt(HTTP_HANDLE, CURLOPT_READFUNCTION, send_body); curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKFUNCTION, (curl_seek_callback) seek_body); curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header); curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body); curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF); curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, ""); curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT, "CouchHTTP Client - Relax"); } if(!HTTP_HANDLE) { JS_ReportError(cx, "Failed to initialize cURL handle."); goto done; } if(!JS_GetReservedSlot(cx, obj, 0, &tmp)) { JS_ReportError(cx, "Failed to readreserved slot."); goto done; } if(!(referer = enc_string(cx, tmp, NULL))) { JS_ReportError(cx, "Failed to encode referer."); goto done; } curl_easy_setopt(HTTP_HANDLE, CURLOPT_REFERER, referer); free(referer); if(http->method < 0 || http->method > OPTIONS) { JS_ReportError(cx, "INTERNAL: Unknown method."); goto done; } curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]); curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0); if(http->method == HEAD) { curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0); } else if(http->method == POST || http->method == PUT) { curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0); } if(body && bodylen) { curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, bodylen); } else { curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0); } // curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1); curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url); curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers); curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state); curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state); curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state); curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state); if(curl_easy_perform(HTTP_HANDLE) != 0) { JS_ReportError(cx, "Failed to execute HTTP request: %s", ERRBUF); goto done; } if(!state.resp_headers) { JS_ReportError(cx, "Failed to recieve HTTP headers."); goto done; } tmp = OBJECT_TO_JSVAL(state.resp_headers); if(!JS_DefineProperty( cx, obj, "_headers", tmp, NULL, NULL, JSPROP_READONLY )) { JS_ReportError(cx, "INTERNAL: Failed to set response headers."); goto done; } if(state.recvbuf) { state.recvbuf[state.read] = '\0'; jsbody = dec_string(cx, state.recvbuf, state.read+1); if(!jsbody) { // If we can't decode the body as UTF-8 we forcefully // convert it to a string by just forcing each byte // to a jschar. jsbody = str_from_binary(cx, state.recvbuf, state.read); if(!jsbody) { if(!JS_IsExceptionPending(cx)) { JS_ReportError(cx, "INTERNAL: Failed to decode body."); } goto done; } } tmp = STRING_TO_JSVAL(jsbody); } else { tmp = JS_GetEmptyStringValue(cx); } if(!JS_DefineProperty( cx, obj, "responseText", tmp, NULL, NULL, JSPROP_READONLY )) { JS_ReportError(cx, "INTERNAL: Failed to set responseText."); goto done; } ret = JS_TRUE; done: if(state.recvbuf) JS_free(cx, state.recvbuf); return ret; }
JSObject* gjs_init_class_dynamic(JSContext *context, JSObject *in_object, JSObject *parent_proto, const char *ns_name, const char *class_name, JSClass *clasp, JSNative constructor, uintN nargs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs) { jsval value; char *private_name; JSObject *global; JSObject *prototype; if (clasp->name != NULL) { g_warning("Dynamic class should not have a name in the JSClass struct"); return NULL; } JS_BeginRequest(context); /* We use a special "fake" global object to store our constructors * in for future use. Using the actual global object of the context would * result in different contexts having different class definitions for * the same GObject class; since the proxies are shared between all * contexts, this would produce confusing results. */ global = gjs_get_import_global(context); /* JS_InitClass() wants to define the constructor in the global object, so * we give it a private and namespaced name... passing in the namespace * object instead of global object seems to break JS_ConstructObject() * which then can't find the constructor for the class. I am probably * missing something. */ private_name = g_strdup_printf("_private_%s_%s", ns_name, class_name); prototype = NULL; if (gjs_object_get_property(context, global, private_name, &value) && JSVAL_IS_OBJECT(value)) { jsval proto_val; g_free(private_name); /* don't need it anymore */ if (!gjs_object_require_property(context, JSVAL_TO_OBJECT(value), NULL, "prototype", &proto_val) || !JSVAL_IS_OBJECT(proto_val)) { gjs_throw(context, "prototype was not defined or not an object?"); goto error; } prototype = JSVAL_TO_OBJECT(proto_val); } else { DynamicJSClass *class_copy; RuntimeData *rd; rd = get_data_from_context(context); class_copy = g_slice_new0(DynamicJSClass); class_copy->base = *clasp; class_copy->base.name = private_name; /* Pass ownership of memory */ class_copy->static_class = clasp; /* record the allocated class to be destroyed with the runtime and so * we can do an IS_DYNAMIC_CLASS check */ g_hash_table_replace(rd->dynamic_classes, class_copy, class_copy); gjs_debug(GJS_DEBUG_GREPO, "Initializing dynamic class %s %p", class_name, class_copy); prototype = JS_InitClass(context, global, parent_proto, &class_copy->base, constructor, nargs, ps, fs, static_ps, static_fs); if (prototype == NULL) goto error; /* Retrieve the property again so we can define it in * in_object */ if (!gjs_object_require_property(context, global, NULL, class_copy->base.name, &value)) goto error; } g_assert(!JSVAL_IS_VOID(value)); g_assert(prototype != NULL); /* Now manually define our constructor with a sane name, in the * namespace object. */ if (!JS_DefineProperty(context, in_object, class_name, value, NULL, NULL, GJS_MODULE_PROP_FLAGS)) goto error; JS_EndRequest(context); return prototype; error: JS_EndRequest(context); return NULL; }
void KeyframeEffectReadOnly::GetKeyframes(JSContext*& aCx, nsTArray<JSObject*>& aResult, ErrorResult& aRv) { MOZ_ASSERT(aResult.IsEmpty()); MOZ_ASSERT(!aRv.Failed()); if (!aResult.SetCapacity(mKeyframes.Length(), mozilla::fallible)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } for (const Keyframe& keyframe : mKeyframes) { // Set up a dictionary object for the explicit members BaseComputedKeyframe keyframeDict; if (keyframe.mOffset) { keyframeDict.mOffset.SetValue(keyframe.mOffset.value()); } MOZ_ASSERT(keyframe.mComputedOffset != Keyframe::kComputedOffsetNotSet, "Invalid computed offset"); keyframeDict.mComputedOffset.Construct(keyframe.mComputedOffset); if (keyframe.mTimingFunction) { keyframeDict.mEasing.Truncate(); keyframe.mTimingFunction.ref().AppendToString(keyframeDict.mEasing); } // else if null, leave easing as its default "linear". JS::Rooted<JS::Value> keyframeJSValue(aCx); if (!ToJSValue(aCx, keyframeDict, &keyframeJSValue)) { aRv.Throw(NS_ERROR_FAILURE); return; } JS::Rooted<JSObject*> keyframeObject(aCx, &keyframeJSValue.toObject()); for (const PropertyValuePair& propertyValue : keyframe.mPropertyValues) { const char* name = nsCSSProps::PropertyIDLName(propertyValue.mProperty); // nsCSSValue::AppendToString does not accept shorthands properties but // works with token stream values if we pass eCSSProperty_UNKNOWN as // the property. nsCSSPropertyID propertyForSerializing = nsCSSProps::IsShorthand(propertyValue.mProperty) ? eCSSProperty_UNKNOWN : propertyValue.mProperty; nsAutoString stringValue; if (propertyValue.mServoDeclarationBlock) { Servo_DeclarationBlock_SerializeOneValue( propertyValue.mServoDeclarationBlock, &stringValue); } else { propertyValue.mValue.AppendToString( propertyForSerializing, stringValue, nsCSSValue::eNormalized); } JS::Rooted<JS::Value> value(aCx); if (!ToJSValue(aCx, stringValue, &value) || !JS_DefineProperty(aCx, keyframeObject, name, value, JSPROP_ENUMERATE)) { aRv.Throw(NS_ERROR_FAILURE); return; } } aResult.AppendElement(keyframeObject); } }
JSBool gjs_define_param_class(JSContext *context, JSObject *in_object, JSObject **prototype_p) { const char *constructor_name; JSObject *prototype; jsval value; JSObject *constructor; constructor_name = "ParamSpec"; gjs_object_get_property(context, in_object, constructor_name, &value); if (!JSVAL_IS_VOID(value)) { if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "Existing property '%s' does not look like a constructor", constructor_name); return JS_FALSE; } constructor = JSVAL_TO_OBJECT(value); gjs_object_get_property(context, constructor, "prototype", &value); if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "prototype property does not appear to exist or has wrong type"); return JS_FALSE; } else { if (prototype_p) *prototype_p = JSVAL_TO_OBJECT(value); return JS_TRUE; } return JS_TRUE; } /* we could really just use JS_InitClass for this since we have one class instead of * N classes on-demand. But, this deals with namespacing and such for us. */ prototype = gjs_init_class_dynamic(context, in_object, /* parent prototype JSObject* for * prototype; NULL for * Object.prototype */ NULL, "GObject", constructor_name, &gjs_param_class, /* constructor for instances (NULL for * none - just name the prototype like * Math - rarely correct) */ gjs_param_constructor, /* number of constructor args */ 0, /* props of prototype */ &gjs_param_proto_props[0], /* funcs of prototype */ &gjs_param_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ gjs_param_constructor_funcs); if (prototype == NULL) gjs_fatal("Can't init class %s", constructor_name); constructor = NULL; gjs_object_get_property(context, in_object, constructor_name, &value); if (value != JSVAL_VOID) { if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "Property '%s' does not look like a constructor", constructor_name); return JS_FALSE; } } constructor = JSVAL_TO_OBJECT(value); value = OBJECT_TO_JSVAL(gjs_gtype_create_gtype_wrapper(context, G_TYPE_PARAM)); JS_DefineProperty(context, constructor, "$gtype", value, NULL, NULL, JSPROP_PERMANENT); if (prototype_p) *prototype_p = prototype; gjs_debug(GJS_DEBUG_GPARAM, "Defined class %s prototype is %p class %p in object %p", constructor_name, prototype, JS_GET_CLASS(context, prototype), in_object); return JS_TRUE; }
static GObject* gjs_context_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_params) { GObject *object; GjsContext *js_context; guint32 options_flags; JSVersion js_version; object = (* G_OBJECT_CLASS (gjs_context_parent_class)->constructor) (type, n_construct_properties, construct_params); js_context = GJS_CONTEXT(object); if (js_context->runtime == NULL) { js_context->runtime = JS_NewRuntime(32*1024*1024 /* max bytes */); if (js_context->runtime == NULL) gjs_fatal("Failed to create javascript runtime"); JS_SetGCParameter(js_context->runtime, JSGC_MAX_BYTES, 0xffffffff); js_context->we_own_runtime = TRUE; gjs_runtime_init(js_context->runtime); } js_context->context = JS_NewContext(js_context->runtime, 8192 /* stack chunk size */); if (js_context->context == NULL) gjs_fatal("Failed to create javascript context"); JS_BeginRequest(js_context->context); /* same as firefox, see discussion at * https://bugzilla.mozilla.org/show_bug.cgi?id=420869 */ JS_SetScriptStackQuota(js_context->context, 100*1024*1024); /* JSOPTION_DONT_REPORT_UNCAUGHT: Don't send exceptions to our * error report handler; instead leave them set. This allows us * to get at the exception object. * * JSOPTION_STRICT: Report warnings to error reporter function. */ options_flags = JSOPTION_DONT_REPORT_UNCAUGHT | JSOPTION_STRICT; if (!g_getenv("GJS_DISABLE_JIT")) { gjs_debug(GJS_DEBUG_CONTEXT, "Enabling JIT"); options_flags |= JSOPTION_METHODJIT; } JS_SetOptions(js_context->context, JS_GetOptions(js_context->context) | options_flags); JS_SetLocaleCallbacks(js_context->context, &gjs_locale_callbacks); JS_SetErrorReporter(js_context->context, gjs_error_reporter); /* set ourselves as the private data */ JS_SetContextPrivate(js_context->context, js_context); js_version = JS_StringToVersion(js_context->jsversion_string); /* It doesn't make sense to throw here; just use the default if we * don't know. */ if (js_version == JSVERSION_UNKNOWN) js_version = JSVERSION_DEFAULT; /* Set the version if we need to. */ if (js_version != JSVERSION_DEFAULT && JS_GetVersion(js_context->context) != js_version) { gjs_debug(GJS_DEBUG_CONTEXT, "Changing JavaScript version to %s from %s", JS_VersionToString(js_version), JS_VersionToString(JS_GetVersion(js_context->context))); JS_SetVersion(js_context->context, js_version); } if (!gjs_init_context_standard(js_context->context)) gjs_fatal("Failed to initialize context"); js_context->global = JS_GetGlobalObject(js_context->context); if (!JS_DefineProperty(js_context->context, js_context->global, "window", OBJECT_TO_JSVAL(js_context->global), NULL, NULL, JSPROP_READONLY | JSPROP_PERMANENT)) gjs_fatal("No memory to export global object as 'window'"); /* Define a global function called log() */ if (!JS_DefineFunction(js_context->context, js_context->global, "log", (JSNative)gjs_log, 1, GJS_MODULE_PROP_FLAGS)) gjs_fatal("Failed to define log function"); if (!JS_DefineFunction(js_context->context, js_context->global, "logError", (JSNative)gjs_log_error, 2, GJS_MODULE_PROP_FLAGS)) gjs_fatal("Failed to define logError function"); /* Define global functions called print() and printerr() */ if (!JS_DefineFunction(js_context->context, js_context->global, "print", (JSNative)gjs_print, 3, GJS_MODULE_PROP_FLAGS)) gjs_fatal("Failed to define print function"); if (!JS_DefineFunction(js_context->context, js_context->global, "printerr", (JSNative)gjs_printerr, 4, GJS_MODULE_PROP_FLAGS)) gjs_fatal("Failed to define printerr function"); /* We need to know what the default context is, since it's the context whose * global object is used to load imported JS modules. We currently say that * it's the context of the runtime's owner, but if we needed to support * externally created runtimes, we could define it in some other fashion. */ if (js_context->we_own_runtime) { gjs_runtime_set_default_context(js_context->runtime, js_context->context); } else { if (gjs_runtime_get_default_context(js_context->runtime) == NULL) gjs_fatal("GjsContext created for a runtime not owned by GJS"); } /* We create the global-to-runtime root importer with the * passed-in search path. If someone else already created * the root importer, this is a no-op. */ if (!gjs_create_root_importer(js_context->context, js_context->search_path ? (const char**) js_context->search_path : NULL, TRUE)) gjs_fatal("Failed to create root importer"); /* Now copy the global root importer (which we just created, * if it didn't exist) to our global object */ if (!gjs_define_root_importer(js_context->context, js_context->global, "imports")) gjs_fatal("Failed to point 'imports' property at root importer"); if (js_context->we_own_runtime) { js_context->profiler = gjs_profiler_new(js_context->runtime); } if (!gjs_is_registered_native_module(js_context->context, NULL, "gi")) gjs_register_native_module("gi", gjs_define_gi_stuff, GJS_NATIVE_SUPPLIES_MODULE_OBJ); /* For GjsDBus */ { char *priv_typelib_dir = g_build_filename (PKGLIBDIR, "girepository-1.0", NULL); g_irepository_prepend_search_path(priv_typelib_dir); g_free (priv_typelib_dir); } if (js_context->gc_notifications_enabled) JS_SetGCCallback(js_context->context, gjs_on_context_gc); JS_EndRequest(js_context->context); g_static_mutex_lock (&contexts_lock); all_contexts = g_list_prepend(all_contexts, object); g_static_mutex_unlock (&contexts_lock); return object; }
bool rs::jsapi::Global::DefineProperty(Context& cx, const char* name, JSNative getter, JSNative setter, unsigned attrs) { JSAutoRequest ar(cx); return JS_DefineProperty(cx, cx.getGlobal(), name, JS::NullHandleValue, attrs, getter, setter); }
static int ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc) { int i, j, length; JSObject *argsObj; char *filename = NULL; JSBool isInteractive = JS_TRUE; JSBool forceTTY = JS_FALSE; /* * Scan past all optional arguments so we can create the arguments object * before processing any -f options, which must interleave properly with * -v and -w options. This requires two passes, and without getopt, we'll * have to keep the option logic here and in the second for loop in sync. */ for (i = 0; i < argc; i++) { if (argv[i][0] != '-' || argv[i][1] == '\0') { ++i; break; } switch (argv[i][1]) { case 'b': case 'c': case 'f': case 'e': case 'v': case 'S': ++i; break; default:; } } /* * Create arguments early and define it to root it, so it's safe from any * GC calls nested below, and so it is available to -f <file> arguments. */ argsObj = JS_NewArrayObject(cx, 0, NULL); if (!argsObj) return 1; if (!JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj), NULL, NULL, 0)) { return 1; } length = argc - i; for (j = 0; j < length; j++) { JSString *str = JS_NewStringCopyZ(cx, argv[i++]); if (!str) return 1; if (!JS_DefineElement(cx, argsObj, j, STRING_TO_JSVAL(str), NULL, NULL, JSPROP_ENUMERATE)) { return 1; } } for (i = 0; i < argc; i++) { if (argv[i][0] != '-' || argv[i][1] == '\0') { filename = argv[i++]; isInteractive = JS_FALSE; break; } switch (argv[i][1]) { case 'v': if (++i == argc) return usage(); JS_SetVersion(cx, (JSVersion) atoi(argv[i])); break; case 'w': reportWarnings = JS_TRUE; break; case 'W': reportWarnings = JS_FALSE; break; case 's': JS_ToggleOptions(cx, JSOPTION_STRICT); break; case 'E': JS_ToggleOptions(cx, JSOPTION_RELIMIT); break; case 'x': JS_ToggleOptions(cx, JSOPTION_XML); break; case 'o': if (++i == argc) return usage(); for (j = 0; js_options[j].name; ++j) { if (strcmp(js_options[j].name, argv[i]) == 0) { JS_ToggleOptions(cx, js_options[j].flag); break; } } break; case 'c': /* set stack chunk size */ gStackChunkSize = atoi(argv[++i]); break; case 'f': if (++i == argc) return usage(); Process(cx, obj, argv[i], JS_FALSE); /* * XXX: js -f foo.js should interpret foo.js and then * drop into interactive mode, but that breaks the test * harness. Just execute foo.js for now. */ isInteractive = JS_FALSE; break; case 'e': { jsval rval; if (++i == argc) return usage(); /* Pass a filename of -e to imitate PERL */ JS_EvaluateScript(cx, obj, argv[i], SG_STRLEN(argv[i]), "-e", 1, &rval); isInteractive = JS_FALSE; break; } case 'C': compileOnly = JS_TRUE; isInteractive = JS_FALSE; break; case 'i': isInteractive = forceTTY = JS_TRUE; break; case 'S': if (++i == argc) return usage(); /* Set maximum stack size. */ gMaxStackSize = atoi(argv[i]); break; #ifdef MOZ_SHARK case 'k': JS_ConnectShark(); break; #endif default: return usage(); } } if (filename || isInteractive) Process(cx, obj, filename, forceTTY); return gExitCode; }
JSBool setSeen( JSContext *cx, JSObject *seen, SV *ref, jsval rval ) { /* a string rep of a pointer to the object */ char hkey[32]; int klen = snprintf(hkey, 32, "%p", ref); return JS_DefineProperty(cx, seen, hkey, rval, NULL, NULL, JSPROP_ENUMERATE); }
static JSBool do_import(JSContext *context, JSObject *obj, Importer *priv, const char *name) { char *filename; char *full_path; char *dirname = NULL; jsval search_path_val; JSObject *search_path; JSObject *module_obj = NULL; guint32 search_path_len; guint32 i; JSBool result; GPtrArray *directories; jsid search_path_name; GFile *gfile; gboolean exists; search_path_name = gjs_context_get_const_string(context, GJS_STRING_SEARCH_PATH); if (!gjs_object_require_property(context, obj, "importer", search_path_name, &search_path_val)) { return JS_FALSE; } if (!JSVAL_IS_OBJECT(search_path_val)) { gjs_throw(context, "searchPath property on importer is not an object"); return JS_FALSE; } search_path = JSVAL_TO_OBJECT(search_path_val); if (!JS_IsArrayObject(context, search_path)) { gjs_throw(context, "searchPath property on importer is not an array"); return JS_FALSE; } if (!JS_GetArrayLength(context, search_path, &search_path_len)) { gjs_throw(context, "searchPath array has no length"); return JS_FALSE; } result = JS_FALSE; filename = g_strdup_printf("%s.js", name); full_path = NULL; directories = NULL; /* First try importing an internal module like byteArray */ if (priv->is_root && gjs_is_registered_native_module(context, obj, name) && import_native_file(context, obj, name)) { gjs_debug(GJS_DEBUG_IMPORTER, "successfully imported module '%s'", name); result = JS_TRUE; goto out; } for (i = 0; i < search_path_len; ++i) { jsval elem; elem = JSVAL_VOID; if (!JS_GetElement(context, search_path, i, &elem)) { /* this means there was an exception, while elem == JSVAL_VOID * means no element found */ goto out; } if (JSVAL_IS_VOID(elem)) continue; if (!JSVAL_IS_STRING(elem)) { gjs_throw(context, "importer searchPath contains non-string"); goto out; } g_free(dirname); dirname = NULL; if (!gjs_string_to_utf8(context, elem, &dirname)) goto out; /* Error message already set */ /* Ignore empty path elements */ if (dirname[0] == '\0') continue; /* Try importing __init__.js and loading the symbol from it */ if (full_path) g_free(full_path); full_path = g_build_filename(dirname, MODULE_INIT_FILENAME, NULL); module_obj = load_module_init(context, obj, full_path); if (module_obj != NULL) { jsval obj_val; if (JS_GetProperty(context, module_obj, name, &obj_val)) { if (!JSVAL_IS_VOID(obj_val) && JS_DefineProperty(context, obj, name, obj_val, NULL, NULL, GJS_MODULE_PROP_FLAGS & ~JSPROP_PERMANENT)) { result = JS_TRUE; goto out; } } } /* Second try importing a directory (a sub-importer) */ if (full_path) g_free(full_path); full_path = g_build_filename(dirname, name, NULL); gfile = g_file_new_for_commandline_arg(full_path); if (g_file_query_file_type(gfile, (GFileQueryInfoFlags) 0, NULL) == G_FILE_TYPE_DIRECTORY) { gjs_debug(GJS_DEBUG_IMPORTER, "Adding directory '%s' to child importer '%s'", full_path, name); if (directories == NULL) { directories = g_ptr_array_new(); } g_ptr_array_add(directories, full_path); /* don't free it twice - pass ownership to ptr array */ full_path = NULL; } g_object_unref(gfile); /* If we just added to directories, we know we don't need to * check for a file. If we added to directories on an earlier * iteration, we want to ignore any files later in the * path. So, always skip the rest of the loop block if we have * directories. */ if (directories != NULL) { continue; } /* Third, if it's not a directory, try importing a file */ g_free(full_path); full_path = g_build_filename(dirname, filename, NULL); gfile = g_file_new_for_commandline_arg(full_path); exists = g_file_query_exists(gfile, NULL); if (!exists) { gjs_debug(GJS_DEBUG_IMPORTER, "JS import '%s' not found in %s", name, dirname); g_object_unref(gfile); continue; } if (import_file_on_module (context, obj, name, gfile)) { gjs_debug(GJS_DEBUG_IMPORTER, "successfully imported module '%s'", name); result = JS_TRUE; } g_object_unref(gfile); /* Don't keep searching path if we fail to load the file for * reasons other than it doesn't exist... i.e. broken files * block searching for nonbroken ones */ goto out; } if (directories != NULL) { /* NULL-terminate the char** */ g_ptr_array_add(directories, NULL); if (import_directory(context, obj, name, (const char**) directories->pdata)) { gjs_debug(GJS_DEBUG_IMPORTER, "successfully imported directory '%s'", name); result = JS_TRUE; } } out: if (directories != NULL) { char **str_array; /* NULL-terminate the char** * (maybe for a second time, but doesn't matter) */ g_ptr_array_add(directories, NULL); str_array = (char**) directories->pdata; g_ptr_array_free(directories, FALSE); g_strfreev(str_array); } g_free(full_path); g_free(filename); g_free(dirname); if (!result && !JS_IsExceptionPending(context)) { /* If no exception occurred, the problem is just that we got to the * end of the path. Be sure an exception is set. */ gjs_throw(context, "No JS module '%s' found in search path", name); } return result; }
static JSBool InitExceptionObject(JSContext *cx, JSObject *obj, JSString *message, JSString *filename, uintN lineno) { JSCheckAccessOp checkAccess; JSErrorReporter older; JSExceptionState *state; jschar *stackbuf; size_t stacklen, stackmax; JSStackFrame *fp; jsval callerid, v; JSBool ok; JSString *argsrc, *stack; uintN i, ulineno; const char *cp; char ulnbuf[11]; if (!JS_DefineProperty(cx, obj, js_message_str, STRING_TO_JSVAL(message), NULL, NULL, JSPROP_ENUMERATE)) { return JS_FALSE; } if (!JS_DefineProperty(cx, obj, js_filename_str, STRING_TO_JSVAL(filename), NULL, NULL, JSPROP_ENUMERATE)) { return JS_FALSE; } if (!JS_DefineProperty(cx, obj, js_lineno_str, INT_TO_JSVAL(lineno), NULL, NULL, JSPROP_ENUMERATE)) { return JS_FALSE; } /* * Set the 'stack' property. * * First, set aside any error reporter for cx and save its exception state * so we can suppress any checkAccess failures. Such failures should stop * the backtrace procedure, not result in a failure of this constructor. */ checkAccess = cx->runtime->checkObjectAccess; if (checkAccess) { older = JS_SetErrorReporter(cx, NULL); state = JS_SaveExceptionState(cx); } #ifdef __GNUC__ /* suppress bogus gcc warnings */ else { older = NULL; state = NULL; } #endif callerid = ATOM_KEY(cx->runtime->atomState.callerAtom); /* * Prepare to allocate a jschar buffer at stackbuf, where stacklen indexes * the next free jschar slot, and with room for at most stackmax non-null * jschars. If stackbuf is non-null, it always contains an extra slot for * the null terminator we'll store at the end, as a backstop. * * All early returns must goto done after this point, till the after-loop * cleanup code has run! */ stackbuf = NULL; stacklen = stackmax = 0; ok = JS_TRUE; #define APPEND_CHAR_TO_STACK(c) \ JS_BEGIN_MACRO \ if (stacklen == stackmax) { \ void *ptr_; \ stackmax = stackmax ? 2 * stackmax : 64; \ ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar)); \ if (!ptr_) { \ ok = JS_FALSE; \ goto done; \ } \ stackbuf = ptr_; \ } \ stackbuf[stacklen++] = (c); \ JS_END_MACRO #define APPEND_STRING_TO_STACK(str) \ JS_BEGIN_MACRO \ JSString *str_ = str; \ size_t length_ = JSSTRING_LENGTH(str_); \ if (stacklen + length_ > stackmax) { \ void *ptr_; \ stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_)); \ ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar)); \ if (!ptr_) { \ ok = JS_FALSE; \ goto done; \ } \ stackbuf = ptr_; \ } \ js_strncpy(stackbuf + stacklen, JSSTRING_CHARS(str_), length_); \ stacklen += length_; \ JS_END_MACRO for (fp = cx->fp; fp; fp = fp->down) { if (checkAccess) { v = (fp->fun && fp->argv) ? fp->argv[-2] : JSVAL_NULL; if (!JSVAL_IS_PRIMITIVE(v)) { ok = checkAccess(cx, fp->fun->object, callerid, JSACC_READ, &v); if (!ok) { ok = JS_TRUE; break; } } } if (fp->fun) { if (fp->fun->atom) APPEND_STRING_TO_STACK(ATOM_TO_STRING(fp->fun->atom)); APPEND_CHAR_TO_STACK('('); for (i = 0; i < fp->argc; i++) { /* Avoid toSource bloat and fallibility for object types. */ v = fp->argv[i]; if (JSVAL_IS_PRIMITIVE(v)) { argsrc = js_ValueToSource(cx, v); } else if (JSVAL_IS_FUNCTION(cx, v)) { /* XXX Avoid function decompilation bloat for now. */ argsrc = JS_GetFunctionId(JS_ValueToFunction(cx, v)); if (!argsrc) argsrc = js_ValueToSource(cx, v); } else { /* XXX Avoid toString on objects, it takes too long and uses too much memory, for too many classes (see Mozilla bug 166743). */ char buf[100]; JS_snprintf(buf, sizeof buf, "[object %s]", OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v))->name); argsrc = JS_NewStringCopyZ(cx, buf); } if (!argsrc) { ok = JS_FALSE; goto done; } if (i > 0) APPEND_CHAR_TO_STACK(','); APPEND_STRING_TO_STACK(argsrc); } APPEND_CHAR_TO_STACK(')'); } APPEND_CHAR_TO_STACK('@'); if (fp->script && fp->script->filename) { for (cp = fp->script->filename; *cp; cp++) APPEND_CHAR_TO_STACK(*cp); } APPEND_CHAR_TO_STACK(':'); if (fp->script && fp->pc) { ulineno = js_PCToLineNumber(fp->script, fp->pc); JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", ulineno); for (cp = ulnbuf; *cp; cp++) APPEND_CHAR_TO_STACK(*cp); } else { APPEND_CHAR_TO_STACK('0'); } APPEND_CHAR_TO_STACK('\n'); } #undef APPEND_CHAR_TO_STACK #undef APPEND_STRING_TO_STACK done: if (checkAccess) { if (ok) JS_RestoreExceptionState(cx, state); else JS_DropExceptionState(cx, state); JS_SetErrorReporter(cx, older); } if (!ok) { JS_free(cx, stackbuf); return JS_FALSE; } if (!stackbuf) { stack = cx->runtime->emptyString; } else { /* NB: if stackbuf was allocated, it has room for the terminator. */ JS_ASSERT(stacklen <= stackmax); if (stacklen < stackmax) { /* * Realloc can fail when shrinking on some FreeBSD versions, so * don't use JS_realloc here; simply let the oversized allocation * be owned by the string in that rare case. */ void *shrunk = realloc(stackbuf, (stacklen+1) * sizeof(jschar)); if (shrunk) stackbuf = shrunk; } stackbuf[stacklen] = 0; stack = js_NewString(cx, stackbuf, stacklen, 0); if (!stack) { JS_free(cx, stackbuf); return JS_FALSE; } } return JS_DefineProperty(cx, obj, js_stack_str, STRING_TO_JSVAL(stack), NULL, NULL, JSPROP_ENUMERATE); }
JSObject * js_InitExceptionClasses(JSContext *cx, JSObject *obj) { JSObject *obj_proto, *protos[JSEXN_LIMIT]; int i; /* * If lazy class initialization occurs for any Error subclass, then all * classes are initialized, starting with Error. To avoid reentry and * redundant initialization, we must not pass a null proto parameter to * js_NewObject below, when called for the Error superclass. We need to * ensure that Object.prototype is the proto of Error.prototype. * * See the equivalent code to ensure that parent_proto is non-null when * JS_InitClass calls js_NewObject, in jsapi.c. */ if (!js_GetClassPrototype(cx, obj, INT_TO_JSID(JSProto_Object), &obj_proto)) { return NULL; } if (!js_EnterLocalRootScope(cx)) return NULL; /* Initialize the prototypes first. */ for (i = 0; exceptions[i].name != 0; i++) { JSAtom *atom; JSFunction *fun; JSString *nameString; int protoIndex = exceptions[i].protoIndex; /* Make the prototype for the current constructor name. */ protos[i] = js_NewObject(cx, &js_ErrorClass, (protoIndex != JSEXN_NONE) ? protos[protoIndex] : obj_proto, obj, 0); if (!protos[i]) break; /* So exn_finalize knows whether to destroy private data. */ STOBJ_SET_SLOT(protos[i], JSSLOT_PRIVATE, JSVAL_VOID); /* Make a constructor function for the current name. */ atom = cx->runtime->atomState.classAtoms[exceptions[i].key]; fun = js_DefineFunction(cx, obj, atom, exceptions[i].native, 3, 0); if (!fun) break; /* Make this constructor make objects of class Exception. */ fun->u.n.clasp = &js_ErrorClass; /* Make the prototype and constructor links. */ if (!js_SetClassPrototype(cx, FUN_OBJECT(fun), protos[i], JSPROP_READONLY | JSPROP_PERMANENT)) { break; } /* proto bootstrap bit from JS_InitClass omitted. */ nameString = JS_NewStringCopyZ(cx, exceptions[i].name); if (!nameString) break; /* Add the name property to the prototype. */ if (!JS_DefineProperty(cx, protos[i], js_name_str, STRING_TO_JSVAL(nameString), NULL, NULL, JSPROP_ENUMERATE)) { break; } /* Finally, stash the constructor for later uses. */ if (!js_SetClassObject(cx, obj, exceptions[i].key, FUN_OBJECT(fun))) break; } js_LeaveLocalRootScope(cx); if (exceptions[i].name) return NULL; /* * Add an empty message property. (To Exception.prototype only, * because this property will be the same for all the exception * protos.) */ if (!JS_DefineProperty(cx, protos[0], js_message_str, STRING_TO_JSVAL(cx->runtime->emptyString), NULL, NULL, JSPROP_ENUMERATE)) { return NULL; } if (!JS_DefineProperty(cx, protos[0], js_fileName_str, STRING_TO_JSVAL(cx->runtime->emptyString), NULL, NULL, JSPROP_ENUMERATE)) { return NULL; } if (!JS_DefineProperty(cx, protos[0], js_lineNumber_str, INT_TO_JSVAL(0), NULL, NULL, JSPROP_ENUMERATE)) { return NULL; } /* * Add methods only to Exception.prototype, because ostensibly all * exception types delegate to that. */ if (!JS_DefineFunctions(cx, protos[0], exception_methods)) return NULL; return protos[0]; }
JSObject * js_InitExceptionClasses(JSContext *cx, JSObject *obj) { int i; JSObject *protos[JSEXN_LIMIT]; /* Initialize the prototypes first. */ for (i = 0; exceptions[i].name != 0; i++) { JSAtom *atom; JSFunction *fun; JSString *nameString; int protoIndex = exceptions[i].protoIndex; /* Make the prototype for the current constructor name. */ protos[i] = js_NewObject(cx, &ExceptionClass, (protoIndex != JSEXN_NONE) ? protos[protoIndex] : NULL, obj); if (!protos[i]) return NULL; /* So exn_finalize knows whether to destroy private data. */ OBJ_SET_SLOT(cx, protos[i], JSSLOT_PRIVATE, JSVAL_VOID); atom = js_Atomize(cx, exceptions[i].name, strlen(exceptions[i].name), 0); if (!atom) return NULL; /* Make a constructor function for the current name. */ fun = js_DefineFunction(cx, obj, atom, exceptions[i].native, 3, 0); if (!fun) return NULL; /* Make this constructor make objects of class Exception. */ fun->clasp = &ExceptionClass; /* Make the prototype and constructor links. */ if (!js_SetClassPrototype(cx, fun->object, protos[i], JSPROP_READONLY | JSPROP_PERMANENT)) { return NULL; } /* proto bootstrap bit from JS_InitClass omitted. */ nameString = JS_NewStringCopyZ(cx, exceptions[i].name); if (!nameString) return NULL; /* Add the name property to the prototype. */ if (!JS_DefineProperty(cx, protos[i], js_name_str, STRING_TO_JSVAL(nameString), NULL, NULL, JSPROP_ENUMERATE)) { return NULL; } } /* * Add an empty message property. (To Exception.prototype only, * because this property will be the same for all the exception * protos.) */ if (!JS_DefineProperty(cx, protos[0], js_message_str, STRING_TO_JSVAL(cx->runtime->emptyString), NULL, NULL, JSPROP_ENUMERATE)) { return NULL; } if (!JS_DefineProperty(cx, protos[0], js_filename_str, STRING_TO_JSVAL(cx->runtime->emptyString), NULL, NULL, JSPROP_ENUMERATE)) { return NULL; } if (!JS_DefineProperty(cx, protos[0], js_lineno_str, INT_TO_JSVAL(0), NULL, NULL, JSPROP_ENUMERATE)) { return NULL; } /* * Add methods only to Exception.prototype, because ostensibly all * exception types delegate to that. */ if (!JS_DefineFunctions(cx, protos[0], exception_methods)) return NULL; return protos[0]; }
JSBool gjs_define_boxed_class(JSContext *context, JSObject *in_object, GIBoxedInfo *info, JSObject **constructor_p, JSObject **prototype_p) { const char *constructor_name; JSObject *prototype; JSObject *constructor; jsval value; Boxed *priv; /* See the comment in gjs_define_object_class() for an * explanation of how this all works; Boxed is pretty much the * same as Object. */ constructor_name = g_base_info_get_name( (GIBaseInfo*) info); if (gjs_object_get_property(context, in_object, constructor_name, &value)) { JSObject *constructor; if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "Existing property '%s' does not look like a constructor", constructor_name); return JS_FALSE; } constructor = JSVAL_TO_OBJECT(value); gjs_object_get_property(context, constructor, "prototype", &value); if (!JSVAL_IS_OBJECT(value)) { gjs_throw(context, "boxed %s prototype property does not appear to exist or has wrong type", constructor_name); return JS_FALSE; } else { if (prototype_p) *prototype_p = JSVAL_TO_OBJECT(value); if (constructor_p) *constructor_p = constructor; return JS_TRUE; } } if (!gjs_init_class_dynamic(context, in_object, NULL, /* parent prototype */ g_base_info_get_namespace( (GIBaseInfo*) info), constructor_name, &gjs_boxed_class, gjs_boxed_constructor, 1, /* props of prototype */ &gjs_boxed_proto_props[0], /* funcs of prototype */ &gjs_boxed_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ NULL, &prototype, &constructor)) { gjs_log_exception(context, NULL); gjs_fatal("Can't init class %s", constructor_name); } GJS_INC_COUNTER(boxed); priv = g_slice_new0(Boxed); priv->info = info; boxed_fill_prototype_info(priv); g_base_info_ref( (GIBaseInfo*) priv->info); priv->gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*) priv->info); JS_SetPrivate(context, prototype, priv); gjs_debug(GJS_DEBUG_GBOXED, "Defined class %s prototype is %p class %p in object %p", constructor_name, prototype, JS_GET_CLASS(context, prototype), in_object); priv->can_allocate_directly = struct_is_simple (priv->info); define_boxed_class_fields (context, priv, prototype); gjs_define_static_methods (context, constructor, priv->gtype, priv->info); value = OBJECT_TO_JSVAL(gjs_gtype_create_gtype_wrapper(context, priv->gtype)); JS_DefineProperty(context, constructor, "$gtype", value, NULL, NULL, JSPROP_PERMANENT); if (constructor_p) *constructor_p = constructor; if (prototype_p) *prototype_p = prototype; return JS_TRUE; }
static JSBool jsReadDir( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ) { *rval = JSVAL_FALSE ; if( ( 1 == argc ) && JSVAL_IS_STRING( argv[0] ) ) { JSString *sDirName = JSVAL_TO_STRING( argv[0] ); char const *dirName = JS_GetStringBytes( sDirName ); DIR *dir = opendir( dirName ); if( dir ) { JSObject *returnObj = JS_NewObject( cx, &jsDirClass_, NULL, NULL ); if( returnObj ) { *rval = OBJECT_TO_JSVAL( returnObj ); // root stringVector_t subDirs ; struct dirent *de ; while( 0 != ( de = readdir( dir ) ) ) { if( ( 0 != strcmp( ".", de->d_name ) ) && ( 0 != strcmp( "..", de->d_name ) ) ) { char fullPath[PATH_MAX]; sprintf( fullPath, "%s/%s", dirName, de->d_name ); struct stat st ; int stResult = stat( fullPath, &st ); if( 0 == stResult ) { if( !S_ISLNK( st.st_mode ) ) { if( !S_ISDIR( st.st_mode ) ) { JSObject *fileObj = JS_NewObject( cx, &jsDirClass_, NULL, NULL ); if( fileObj ) { if( !JS_DefineProperty( cx, returnObj, de->d_name, OBJECT_TO_JSVAL( fileObj ), 0, 0, JSPROP_ENUMERATE ) ) JS_ReportError( cx, "Attaching %s to %s", de->d_name, dirName ); if( !JS_DefineProperty( cx, fileObj, "mode", INT_TO_JSVAL( st.st_mode ), 0, 0, JSPROP_ENUMERATE ) ) JS_ReportError( cx, "Defining mode for %s/%s", dirName, de->d_name ); if( !JS_DefineProperty( cx, fileObj, "size", INT_TO_JSVAL( st.st_size ), 0, 0, JSPROP_ENUMERATE ) ) JS_ReportError( cx, "Defining size for %s/%s", dirName, de->d_name ); if( !JS_DefineProperty( cx, fileObj, "time", INT_TO_JSVAL( st.st_mtime ), 0, 0, JSPROP_ENUMERATE ) ) JS_ReportError( cx, "Defining time for %s/%s", dirName, de->d_name ); } else JS_ReportError( cx, "allocating fileObj" ); } // file else { subDirs.push_back( de->d_name ); } // directory } // skip symlinks else { printf( "--> ignoring symlink %s/%s: mode 0x%X\n", dirName, de->d_name, st.st_mode ); } } else perror( fullPath ); } } // for each entry in this directory closedir( dir ); // free this dir handle for( unsigned i = 0 ; i < subDirs.size(); i++ ) { // // can't attach until we have one. // jsval sSubdir = JSVAL_FALSE ; JS_AddRoot( cx, &sSubdir ); char fullPath[PATH_MAX]; int const len = sprintf( fullPath, "%s/%s", dirName, subDirs[i].c_str() ); JSString * const sPath = JS_NewStringCopyN( cx, fullPath, len ); jsval param = STRING_TO_JSVAL( sPath ); JS_AddRoot( cx, ¶m ); JSBool worked = jsReadDir( cx, obj, 1, ¶m, &sSubdir ); if( worked ) { if( !JS_DefineProperty( cx, returnObj, subDirs[i].c_str(), sSubdir, 0, 0, JSPROP_ENUMERATE ) ) JS_ReportError( cx, "Attaching %s to %s", subDirs[i].c_str(), dirName ); } JS_RemoveRoot( cx, ¶m ); JS_RemoveRoot( cx, &sSubdir ); } } else { JS_ReportError( cx, "allocating dirObject" ); closedir( dir ); } } else JS_ReportError( cx, "%m reading dir <%s>\n", dirName ); } else JS_ReportError( cx, "Usage: stat( fileName )" ); return JS_TRUE ; }