diff --git a/src/bun.js/bindings/NodeVM.cpp b/src/bun.js/bindings/NodeVM.cpp index bcf870de11..8f5a505469 100644 --- a/src/bun.js/bindings/NodeVM.cpp +++ b/src/bun.js/bindings/NodeVM.cpp @@ -19,6 +19,7 @@ #include "JavaScriptCore/FunctionPrototype.h" #include "JavaScriptCore/FunctionConstructor.h" +#include "JavaScriptCore/GlobalObjectMethodTable.h" #include "JavaScriptCore/HeapAnalyzer.h" #include "JavaScriptCore/JSDestructibleObjectHeapCellType.h" @@ -65,6 +66,7 @@ namespace Bun { using namespace WebCore; +using JSGlobalObject = JSC::JSGlobalObject; static JSInternalPromise* moduleLoaderImportModuleInner(NodeVMGlobalObject* globalObject, JSC::JSModuleLoader* moduleLoader, JSC::JSString* moduleName, JSC::JSValue parameters, const JSC::SourceOrigin& sourceOrigin); @@ -702,7 +704,7 @@ void NodeVMSpecialSandbox::finishCreation(VM& vm) const JSC::ClassInfo NodeVMSpecialSandbox::s_info = { "NodeVMSpecialSandbox"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(NodeVMSpecialSandbox) }; NodeVMGlobalObject::NodeVMGlobalObject(JSC::VM& vm, JSC::Structure* structure, NodeVMContextOptions contextOptions, JSValue importer) - : Base(vm, structure, &globalObjectMethodTable()) + : Base(vm, structure) // Don't override method table , m_dynamicImportCallback(vm, this, importer) , m_contextOptions(contextOptions) { @@ -734,34 +736,36 @@ Structure* NodeVMGlobalObject::createStructure(JSC::VM& vm, JSC::JSValue prototy return JSC::Structure::create(vm, nullptr, prototype, JSC::TypeInfo(JSC::GlobalObjectType, StructureFlags & ~IsImmutablePrototypeExoticObject), info()); } -const JSC::GlobalObjectMethodTable& NodeVMGlobalObject::globalObjectMethodTable() -{ - static const JSC::GlobalObjectMethodTable table { - &supportsRichSourceInfo, - &shouldInterruptScript, - &javaScriptRuntimeFlags, - nullptr, // queueTaskToEventLoop - nullptr, // shouldInterruptScriptBeforeTimeout, - &moduleLoaderImportModule, - nullptr, // moduleLoaderResolve - nullptr, // moduleLoaderFetch - nullptr, // moduleLoaderCreateImportMetaProperties - nullptr, // moduleLoaderEvaluate - nullptr, // promiseRejectionTracker - &reportUncaughtExceptionAtEventLoop, - ¤tScriptExecutionOwner, - &scriptExecutionStatus, - nullptr, // reportViolationForUnsafeEval - nullptr, // defaultLanguage - nullptr, // compileStreaming - nullptr, // instantiateStreaming - nullptr, - &codeForEval, - &canCompileStrings, - &trustedScriptStructure, - }; - return table; -} +// const JSC::GlobalObjectMethodTable& NodeVMGlobalObject::globalObjectMethodTable() +// { +// // Just copy exactly what ZigGlobalObject does - don't define any functions, +// // just reference them and let the linker find them +// static const JSC::GlobalObjectMethodTable table { +// nullptr, // supportsRichSourceInfo +// nullptr, // shouldInterruptScript +// nullptr, // javaScriptRuntimeFlags +// nullptr, // queueTaskToEventLoop +// nullptr, // shouldInterruptScriptBeforeTimeout, +// &moduleLoaderImportModule, // Override for module imports +// nullptr, // moduleLoaderResolve +// nullptr, // moduleLoaderFetch +// nullptr, // moduleLoaderCreateImportMetaProperties +// nullptr, // moduleLoaderEvaluate +// nullptr, // promiseRejectionTracker +// nullptr, // reportUncaughtExceptionAtEventLoop +// nullptr, // currentScriptExecutionOwner +// nullptr, // scriptExecutionStatus +// nullptr, // reportViolationForUnsafeEval +// nullptr, // defaultLanguage +// nullptr, // compileStreaming +// nullptr, // instantiateStreaming +// nullptr, // deriveShadowRealmGlobalObject +// nullptr, // codeForEval +// nullptr, // canCompileStrings +// nullptr // trustedScriptStructure +// }; +// return table; +// } void NodeVMGlobalObject::finishCreation(JSC::VM& vm) { diff --git a/src/bun.js/bindings/NodeVM.h b/src/bun.js/bindings/NodeVM.h index 797af6aa4f..5bf83a4b41 100644 --- a/src/bun.js/bindings/NodeVM.h +++ b/src/bun.js/bindings/NodeVM.h @@ -111,7 +111,7 @@ public: template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm); static NodeVMGlobalObject* create(JSC::VM& vm, JSC::Structure* structure, NodeVMContextOptions options, JSValue importer); static Structure* createStructure(JSC::VM& vm, JSC::JSValue prototype); - static const JSC::GlobalObjectMethodTable& globalObjectMethodTable(); + // static const JSC::GlobalObjectMethodTable& globalObjectMethodTable(); DECLARE_INFO; DECLARE_VISIT_CHILDREN; diff --git a/test/js/node/test/parallel/test-vm-codegen.js b/test/js/node/test/parallel/test-vm-codegen.js new file mode 100644 index 0000000000..90b37c741a --- /dev/null +++ b/test/js/node/test/parallel/test-vm-codegen.js @@ -0,0 +1,101 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); + +const { createContext, runInContext, runInNewContext } = require('vm'); + +const WASM_BYTES = Buffer.from( + [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]); + +{ + const ctx = createContext({ WASM_BYTES }); + const test = 'eval(""); new WebAssembly.Module(WASM_BYTES);'; + runInContext(test, ctx); + + runInNewContext(test, { WASM_BYTES }, { + contextCodeGeneration: undefined, + }); +} + +{ + const ctx = createContext({}, { + codeGeneration: { + strings: false, + }, + }); + + const EvalError = runInContext('EvalError', ctx); + assert.throws(() => { + runInContext('eval("x")', ctx); + }, EvalError); +} + +{ + const ctx = createContext({ WASM_BYTES }, { + codeGeneration: { + wasm: false, + }, + }); + + const CompileError = runInContext('WebAssembly.CompileError', ctx); + assert.throws(() => { + runInContext('new WebAssembly.Module(WASM_BYTES)', ctx); + }, CompileError); +} + +assert.throws(() => { + runInNewContext('eval("x")', {}, { + contextCodeGeneration: { + strings: false, + }, + }); +}, { + name: 'EvalError' +}); + +assert.throws(() => { + runInNewContext('new WebAssembly.Module(WASM_BYTES)', { WASM_BYTES }, { + contextCodeGeneration: { + wasm: false, + }, + }); +}, { + name: 'CompileError' +}); + +assert.throws(() => { + createContext({}, { + codeGeneration: { + strings: 0, + }, + }); +}, { + code: 'ERR_INVALID_ARG_TYPE', +}); + +assert.throws(() => { + runInNewContext('eval("x")', {}, { + contextCodeGeneration: { + wasm: 1, + }, + }); +}, { + code: 'ERR_INVALID_ARG_TYPE' +}); + +assert.throws(() => { + createContext({}, { + codeGeneration: 1, + }); +}, { + code: 'ERR_INVALID_ARG_TYPE', +}); + +assert.throws(() => { + createContext({}, { + codeGeneration: null, + }); +}, { + code: 'ERR_INVALID_ARG_TYPE', +});