diff --git a/js/moz.configure b/js/moz.configure index 85998f7efb47..af11416ec2ab 100644 --- a/js/moz.configure +++ b/js/moz.configure @@ -78,22 +78,6 @@ def js_disable_shell(value): set_config("JS_DISABLE_SHELL", js_disable_shell) -option( - "--enable-js-shell-wizer", - default=False, - when=js_standalone, - help="{Support|Do not support} wizening of the JS shell", -) - - -@depends("--enable-js-shell-wizer", when=js_standalone) -def js_shell_wizer(value): - if value: - return True - - -set_define("JS_SHELL_WIZER", js_shell_wizer) - set_define("JS_64BIT", depends(target)(lambda t: t.bitness == 64 or None)) set_define("JS_PUNBOX64", depends(target)(lambda t: t.bitness == 64 or None)) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 2c842b57e893..6c64dde263b8 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -40,7 +40,6 @@ #endif #include #include -#include #ifndef __wasi__ # include #endif @@ -10723,8 +10722,7 @@ static void SetWorkerContextOptions(JSContext* cx) { return true; } -static int Shell(JSContext* cx, OptionParser* op, - MutableHandleObject lastGlobal) { +static int Shell(JSContext* cx, OptionParser* op) { #ifdef JS_STRUCTURED_SPEW cx->spewer().enableSpewing(); #endif @@ -10783,7 +10781,6 @@ static int Shell(JSContext* cx, OptionParser* op, if (!glob) { return 1; } - lastGlobal.set(glob.get()); JSAutoRealm ar(cx, glob); @@ -11026,8 +11023,7 @@ static bool SetGCParameterFromArg(JSContext* cx, char* arg) { return true; } -Variant js::shell::ShellMain(int argc, char** argv, - bool retainContext) { +int main(int argc, char** argv) { PreInit(); sArgc = argc; @@ -11053,33 +11049,33 @@ Variant js::shell::ShellMain(int argc, char** argv, OptionParser op("Usage: {progname} [options] [[script] scriptArgs*]"); if (!InitOptionParser(op)) { - return AsVariant(EXIT_FAILURE); + return EXIT_FAILURE; } switch (op.parseArgs(argc, argv)) { case OptionParser::EarlyExit: - return AsVariant(EXIT_SUCCESS); + return EXIT_SUCCESS; case OptionParser::ParseError: op.printHelp(argv[0]); - return AsVariant(EXIT_FAILURE); + return EXIT_FAILURE; case OptionParser::Fail: - return AsVariant(EXIT_FAILURE); + return EXIT_FAILURE; case OptionParser::Okay: break; } if (op.getHelpOption()) { - return AsVariant(EXIT_SUCCESS); + return EXIT_SUCCESS; } if (!SetGlobalOptionsPreJSInit(op)) { - return AsVariant(EXIT_FAILURE); + return EXIT_FAILURE; } // Start the engine. if (const char* message = JS_InitWithFailureDiagnostic()) { fprintf(gErrFile->fp, "JS_Init failed: %s\n", message); - return AsVariant(1); + return 1; } // `selfHostedXDRBuffer` contains XDR buffer of the self-hosted JS. @@ -11091,7 +11087,7 @@ Variant js::shell::ShellMain(int argc, char** argv, auto shutdownEngine = MakeScopeExit([] { JS_ShutDown(); }); if (!SetGlobalOptionsPostJSInit(op)) { - return AsVariant(EXIT_FAILURE); + return EXIT_FAILURE; } // Record aggregated telemetry data on disk. Do this as early as possible such @@ -11107,7 +11103,7 @@ Variant js::shell::ShellMain(int argc, char** argv, }); if (!InitSharedObjectMailbox()) { - return AsVariant(EXIT_FAILURE); + return EXIT_FAILURE; } JS::SetProcessBuildIdOp(ShellBuildId); @@ -11115,7 +11111,7 @@ Variant js::shell::ShellMain(int argc, char** argv, /* Use the same parameters as the browser in xpcjsruntime.cpp. */ JSContext* const cx = JS_NewContext(JS::DefaultHeapMaxBytes); if (!cx) { - return AsVariant(1); + return 1; } // Register telemetry callbacks, if needed. @@ -11127,7 +11123,7 @@ Variant js::shell::ShellMain(int argc, char** argv, UniquePtr sc = MakeUnique(cx); if (!sc) { - return AsVariant(1); + return 1; } auto destroyShellContext = MakeScopeExit([cx, &sc] { // Must clear out some of sc's pointer containers before JS_DestroyContext. @@ -11148,7 +11144,7 @@ Variant js::shell::ShellMain(int argc, char** argv, JS::SetWarningReporter(cx, WarningReporter); if (!SetContextOptions(cx, op)) { - return AsVariant(1); + return 1; } JS_SetTrustedPrincipals(cx, &ShellPrincipals::fullyTrusted); @@ -11165,7 +11161,7 @@ Variant js::shell::ShellMain(int argc, char** argv, bufferStreamState = js_new>( mutexid::BufferStreamState); if (!bufferStreamState) { - return AsVariant(1); + return 1; } auto shutdownBufferStreams = MakeScopeExit([] { ShutdownBufferStreams(); @@ -11212,7 +11208,7 @@ Variant js::shell::ShellMain(int argc, char** argv, } if (!JS::InitSelfHostedCode(cx, xdrSpan, xdrWriter)) { - return AsVariant(1); + return 1; } EnvironmentPreparer environmentPreparer(cx); @@ -11229,14 +11225,13 @@ Variant js::shell::ShellMain(int argc, char** argv, if (!WasmCompileAndSerialize(cx)) { // Errors have been printed directly to stderr. MOZ_ASSERT(!cx->isExceptionPending()); - return AsVariant(EXIT_FAILURE); + return EXIT_FAILURE; } #endif - return AsVariant(EXIT_SUCCESS); + return EXIT_SUCCESS; } - RootedObject lastGlobal(cx); - result = Shell(cx, &op, &lastGlobal); + result = Shell(cx, &op); #ifdef DEBUG if (OOM_printAllocationCount) { @@ -11244,35 +11239,9 @@ Variant js::shell::ShellMain(int argc, char** argv, } #endif - if (retainContext) { - shutdownEngine.release(); - destroyCx.release(); - destroyShellContext.release(); - resetGrayGCRootsTracer.release(); - shutdownBufferStreams.release(); - shutdownShellThreads.release(); - - JSAndShellContext ret{cx, - lastGlobal.get(), - std::move(sc), - std::move(selfHostedXDRBuffer), - std::move(rcStdout), - std::move(rcStderr)}; - return AsVariant(std::move(ret)); - } else { - return AsVariant(result); - } + return result; } -// N.B.: When Wizer support is enabled, a separate main() is used. -#ifndef JS_SHELL_WIZER - -int main(int argc, char** argv) { - return ShellMain(argc, argv, /* returnContext = */ false).as(); -} - -#endif // !JS_SHELL_WIZER - bool InitOptionParser(OptionParser& op) { op.setDescription( "The SpiderMonkey shell provides a command line interface to the " @@ -11860,12 +11829,6 @@ bool SetGlobalOptionsPostJSInit(const OptionParser& op) { JS::DelazificationOption::ParseEverythingEagerly; } - // Likewise, if we have Wizer support built into the shell, we - // unconditionally parse everything eagerly. -#ifdef JS_SHELL_WIZER - defaultDelazificationMode = JS::DelazificationOption::ParseEverythingEagerly; -#endif - if (const char* xdr = op.getStringOption("selfhosted-xdr-path")) { shell::selfHostedXDRPath = xdr; } diff --git a/js/src/shell/jsshell.h b/js/src/shell/jsshell.h index 5d4abfcd74a7..e6566a6da2b3 100644 --- a/js/src/shell/jsshell.h +++ b/js/src/shell/jsshell.h @@ -19,7 +19,6 @@ #include "threading/LockGuard.h" #include "threading/Mutex.h" #include "threading/Thread.h" -#include "util/CompleteFile.h" // js::FileContents #include "vm/GeckoProfiler.h" #include "vm/Monitor.h" @@ -253,27 +252,11 @@ struct ShellContext { JS::PersistentRooted finalizationRegistryCleanupCallbacks; }; -// A JSContext, the associated global object, the ShellContext, and -// other miscellaneous bits that need to live as long as the -// shell. This is used to wrap up the shell state when it needs to be -// persisted (e.g., in a Wizer snapshot). -struct JSAndShellContext { - JSContext* cx; - JSObject* glob; - UniquePtr shellCx; - mozilla::Maybe selfHostedXDRBuffer; - RCFile rcStdout; - RCFile rcStderr; -}; - extern ShellContext* GetShellContext(JSContext* cx); [[nodiscard]] extern bool PrintStackTrace(JSContext* cx, JS::Handle stackObj); -mozilla::Variant ShellMain(int argc, char** argv, - bool retainContext); - } /* namespace shell */ } /* namespace js */ diff --git a/js/src/shell/moz.build b/js/src/shell/moz.build index 416daead4419..ed8551f1ec6d 100644 --- a/js/src/shell/moz.build +++ b/js/src/shell/moz.build @@ -22,7 +22,6 @@ UNIFIED_SOURCES += [ "OSObject.cpp", "ShellModuleObjectWrapper.cpp", "WasmTesting.cpp", - "wizer.cpp", ] if CONFIG["FUZZING_INTERFACES"]: @@ -39,7 +38,6 @@ DEFINES["EXPORT_JS_API"] = True LOCAL_INCLUDES += [ "!..", "..", - "/third_party/wizer", ] OS_LIBS += CONFIG["EDITLINE_LIBS"] diff --git a/js/src/shell/wizer.cpp b/js/src/shell/wizer.cpp deleted file mode 100644 index 9a22bb2bd98e..000000000000 --- a/js/src/shell/wizer.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sts=2 et sw=2 tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Support for Wizer-based snapshotting of the JS shell, when built - * for a Wasm target (i.e., running inside a Wasm module). */ - -#include "js/CallAndConstruct.h" // JS_CallFunctionName -#include "shell/jsshell.h" - -using namespace js; -using namespace js::shell; - -#ifdef JS_SHELL_WIZER - -# include - -static std::optional wizenedContext; - -static void WizerInit() { - const int argc = 1; - char* argv[2] = {strdup("js"), NULL}; - - auto ret = ShellMain(argc, argv, /* retainContext = */ true); - if (!ret.is()) { - fprintf(stderr, "Could not execute shell main during Wizening!\n"); - abort(); - } - - wizenedContext = std::move(ret.as()); -} - -WIZER_INIT(WizerInit); - -int main(int argc, char** argv) { - (void)argc; - (void)argv; - - if (wizenedContext) { - JSContext* cx = wizenedContext.value().cx; - RootedObject glob(cx, wizenedContext.value().glob); - - JSAutoRealm ar(cx, glob); - - // Look up a function called "main" in the global. - JS::Rooted ret(cx); - if (!JS_CallFunctionName(cx, cx->global(), "main", - JS::HandleValueArray::empty(), &ret)) { - fprintf(stderr, "Failed to call main() in Wizened JS source!\n"); - abort(); - } - } -} - -#endif // JS_SHELL_WIZER diff --git a/third_party/wizer/wizer.h b/third_party/wizer/wizer.h deleted file mode 100644 index e374a5c96062..000000000000 --- a/third_party/wizer/wizer.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Wizer interface for Wasm module to be initialized. - * - * This header provides several macros that allow a Wasm module written in C/C++ - * to declare an initializer function, and ensure that global constructors (in - * C++'s case) are run at initialization time rather than on startup of the - * pre-initialized module. - */ -#ifndef _WIZER_H_ -#define _WIZER_H_ - -#ifdef __cplusplus -#define __WIZER_EXTERN_C extern "C" -#else -#define __WIZER_EXTERN_C extern -#endif - -#ifdef __clang_major__ -// wasi-sdk-16 was the first wasi-sdk version that shipped with a version of -// wasi-libc that did not include __original_main. However, wasi-sdk-15 shipped -// with clang-14.0.0. To correctly identify the boundary where __original_main -// no longer exists, we check for either clang-15+ or specifically clang-14.0.4. -// -// wasi-sdk-17 ships with clang-15.0.6 -// wasi-sdk-16 ships with clang-14.0.4 -#if __clang_major__ >= 15 || (__clang_major__ == 14 && __clang_patchlevel__ == 4) -#define WIZER_MAIN_VOID __main_void -#else -#define WIZER_MAIN_VOID __original_main -#endif -#endif - -// We default to assuming that the compiler is new enough to provide -// __main_void. -#ifndef WIZER_MAIN_VOID -#define WIZER_MAIN_VOID __main_void -#endif - -/* - * This macro inserts the exported functions necessary to allow Wizer to - * pre-initialize a Wasm module. - * - * To use, simply invoke the macro in exactly one compilation unit (C/C++ file) - * that is compiled into the Wasm module to be pre-initialized: - * - * static void my_init_function() { ... } - * - * WIZER_INIT(my_init_function); - * - * (The macro refers to the provided init function, so it must have been defined - * or must have a forward declaration at the point the macro is used.) - * - * The resulting module should be processed by Wizer as follows: - * - * $ wizer -r _start=wizer.resume -o out.wasm in.wasm - * - * The result of this will be the following behavior: - * - * - If the `in.wasm` (the direct compilation output of a program including this - * macro invocation) is run directly according to the WASI ABI (i.e., by - * invoking `_start`), then nothing changes: global constructors are run, - * `main()` is invoked, then global destructors are run. The initialization - * function is *not* run in this case. - * - * - During pre-initialization (i.e., during this `wizer` invocation), global - * constructors will run, and then the provided initialization function will - * run. The module's memory and global-variable state is then snapshotted and - * saved into `out.wasm`. - * - * All other Wizer restrictions apply (see Wizer documentation for details): - * for example, WASI hostcalls may be blocked, depending on options, and - * invoking any other imported function will result in an immediate trap - * and failure of the Wizer run. - * - * - If the resulting `out.wasm` is then run using the WASI ABI, the program's - * global constructors are *not* re-run. Instead, execution starts directly at - * `main()`, using the heap and global-variable state left by the global - * constructor and initialization function execution during the Wizer - * invocation. - * - * If no initialization function is needed (i.e., only C++ global constructors - * should be run), use `WIZER_DEFAULT_INIT()` instead. - */ -#define WIZER_INIT(init_func) \ - __WIZER_EXTERN_C void __wasm_call_ctors(); \ - __WIZER_EXTERN_C void __wasm_call_dtors(); \ - __WIZER_EXTERN_C int WIZER_MAIN_VOID(); \ - /* This function's export name `wizer.initialize` is specially */ \ - /* recognized by Wizer. It is the direct entry point for pre-init. */ \ - __attribute__((export_name("wizer.initialize"))) void \ - __wizer_initialize() { \ - /* `__wasm_call_ctors()` is generated by `wasm-ld` and invokes all */ \ - /* of the global constructors. It is safe (and in fact necessary) */ \ - /* to manually invoke it here because `wizer.initialize` is the */ \ - /* direct entry point, and no libc startup (crt1.o or equivalent) */ \ - /* is executed before this code does. */ \ - __wasm_call_ctors(); \ - /* We now invoke the provided init function before returning. */ \ - init_func(); \ - } \ - /* This function replaces `_start` (the WASI-specified entry point) in */ \ - /* the pre-initialized Wasm module. */ \ - __attribute__((export_name("wizer.resume"))) void __wizer_resume() { \ - /* `__main_void()` is defined by the WASI SDK toolchain due to */ \ - /* special semantics in C/C++ for the `main()` function, i.e., ito */ \ - /* can either take argc/argv or not. It collects arguments using */ \ - /* the appropriate WASI calls and then invokes the user program's */ \ - /* `main()`. This may change in the future; when it does, we will */ \ - /* coordinate with the WASI-SDK toolchain to implement this entry */ \ - /* point in an alternate way. */ \ - WIZER_MAIN_VOID(); \ - /* Because we are replacing `_start()`, we need to manually invoke */ \ - /* destructors as well. */ \ - __wasm_call_dtors(); \ - } - -/* - * This macro is like `WIZER_INIT()`, but takes no initialization function. - * Instead, the pre-initialization phase only executes C++ global constructors - * before snapshotting the module state. - * - * See documentation for `WIZER_INIT()` for more details and usage instructions. - */ -#define WIZER_DEFAULT_INIT() \ - static void __empty_init() {} \ - WIZER_INIT(__empty_init) - -#endif // _WIZER_H_