static bool CloneValue(JSContext *cx, HandleValue selfHostedValue, MutableHandleValue vp) { if (selfHostedValue.isObject()) { RootedObject selfHostedObject(cx, &selfHostedValue.toObject()); JSObject *clone = CloneObject(cx, selfHostedObject); if (!clone) return false; vp.setObject(*clone); } else if (selfHostedValue.isBoolean() || selfHostedValue.isNumber() || selfHostedValue.isNullOrUndefined()) { // Nothing to do here: these are represented inline in the value. vp.set(selfHostedValue); } else if (selfHostedValue.isString()) { if (!selfHostedValue.toString()->isFlat()) MOZ_CRASH(); JSFlatString *selfHostedString = &selfHostedValue.toString()->asFlat(); JSString *clone = js_NewStringCopyN<CanGC>(cx, selfHostedString->chars(), selfHostedString->length()); if (!clone) return false; vp.setString(clone); } else { MOZ_CRASH("Self-hosting CloneValue can't clone given value."); } return true; }
JSObject* Library::Create(JSContext* cx, jsval path, JSCTypesCallbacks* callbacks) { JSObject* libraryObj = JS_NewObject(cx, &sLibraryClass, NULL, NULL); if (!libraryObj) return NULL; js::AutoObjectRooter root(cx, libraryObj); // initialize the library if (!JS_SetReservedSlot(cx, libraryObj, SLOT_LIBRARY, PRIVATE_TO_JSVAL(NULL))) return NULL; // attach API functions if (!JS_DefineFunctions(cx, libraryObj, sLibraryFunctions)) return NULL; if (!JSVAL_IS_STRING(path)) { JS_ReportError(cx, "open takes a string argument"); return NULL; } PRLibSpec libSpec; JSFlatString* pathStr = JS_FlattenString(cx, JSVAL_TO_STRING(path)); if (!pathStr) return NULL; #ifdef XP_WIN // On Windows, converting to native charset may corrupt path string. // So, we have to use Unicode path directly. const PRUnichar* pathChars = JS_GetFlatStringChars(pathStr); if (!pathChars) return NULL; libSpec.value.pathname_u = pathChars; libSpec.type = PR_LibSpec_PathnameU; #else // Convert to platform native charset if the appropriate callback has been // provided. char* pathBytes; if (callbacks && callbacks->unicodeToNative) { pathBytes = callbacks->unicodeToNative(cx, pathStr->chars(), pathStr->length()); if (!pathBytes) return NULL; } else { // Fallback: assume the platform native charset is UTF-8. This is true // for Mac OS X, Android, and probably Linux. size_t nbytes = js_GetDeflatedUTF8StringLength(cx, pathStr->chars(), pathStr->length()); if (nbytes == (size_t) -1) return NULL; pathBytes = static_cast<char*>(JS_malloc(cx, nbytes + 1)); if (!pathBytes) return NULL; ASSERT_OK(js_DeflateStringToUTF8Buffer(cx, pathStr->chars(), pathStr->length(), pathBytes, &nbytes)); pathBytes[nbytes] = 0; } libSpec.value.pathname = pathBytes; libSpec.type = PR_LibSpec_Pathname; #endif PRLibrary* library = PR_LoadLibraryWithFlags(libSpec, 0); #ifndef XP_WIN JS_free(cx, pathBytes); #endif if (!library) { JS_ReportError(cx, "couldn't open library"); return NULL; } // stash the library if (!JS_SetReservedSlot(cx, libraryObj, SLOT_LIBRARY, PRIVATE_TO_JSVAL(library))) return NULL; return libraryObj; }