diff options
author | 2022-02-24 00:59:19 -0800 | |
---|---|---|
committer | 2022-02-24 00:59:19 -0800 | |
commit | 8effa394100b26805cc9ca298659f1a5a7c3dda9 (patch) | |
tree | 54fda1f4ab7b8d901c984d25b8d1c3c407a0349b | |
parent | 5f50de2b390ef1ddfe2e108d285024ef45d4c421 (diff) | |
download | bun-8effa394100b26805cc9ca298659f1a5a7c3dda9.tar.gz bun-8effa394100b26805cc9ca298659f1a5a7c3dda9.tar.zst bun-8effa394100b26805cc9ca298659f1a5a7c3dda9.zip |
[bun.js] Add `ShadowRealm`
-rw-r--r-- | integration/bunjs-only-snippets/fetch.js | 17 | ||||
-rw-r--r-- | integration/bunjs-only-snippets/fetch.test.js | 22 | ||||
-rw-r--r-- | integration/bunjs-only-snippets/shadow.test.js | 10 | ||||
-rw-r--r-- | integration/bunjs-only-snippets/text-encoder.test.js | 9 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/ZigGlobalObject.cpp | 21 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/ZigGlobalObject.h | 2 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/exports.zig | 7 |
7 files changed, 70 insertions, 18 deletions
diff --git a/integration/bunjs-only-snippets/fetch.js b/integration/bunjs-only-snippets/fetch.js deleted file mode 100644 index bb4345659..000000000 --- a/integration/bunjs-only-snippets/fetch.js +++ /dev/null @@ -1,17 +0,0 @@ -import fs from "fs"; - -const urls = ["https://example.com", "http://example.com"]; -for (let url of urls) { - const response = await fetch(url); - const text = await response.text(); - - if ( - fs.readFileSync( - import.meta.path.substring(0, import.meta.path.lastIndexOf("/")) + - "/fetch.js.txt", - "utf8" - ) !== text - ) { - throw new Error("Expected fetch.js.txt to match snapshot"); - } -} diff --git a/integration/bunjs-only-snippets/fetch.test.js b/integration/bunjs-only-snippets/fetch.test.js new file mode 100644 index 000000000..72b80cd35 --- /dev/null +++ b/integration/bunjs-only-snippets/fetch.test.js @@ -0,0 +1,22 @@ +import { it, describe } from "bun:test"; +import fs from "fs"; + +describe("fetch", () => { + const urls = ["https://example.com", "http://example.com"]; + for (let url of urls) { + it(url, async () => { + const response = await fetch(url); + const text = await response.text(); + + if ( + fs.readFileSync( + import.meta.path.substring(0, import.meta.path.lastIndexOf("/")) + + "/fetch.js.txt", + "utf8" + ) !== text + ) { + throw new Error("Expected fetch.js.txt to match snapshot"); + } + }); + } +}); diff --git a/integration/bunjs-only-snippets/shadow.test.js b/integration/bunjs-only-snippets/shadow.test.js new file mode 100644 index 000000000..3fffcac90 --- /dev/null +++ b/integration/bunjs-only-snippets/shadow.test.js @@ -0,0 +1,10 @@ +import { describe, it, expect } from "bun:test"; + +it("shadow realm works", () => { + const red = new ShadowRealm(); + globalThis.someValue = 1; + // Affects only the ShadowRealm's global + const result = red.evaluate("globalThis.someValue = 2;"); + expect(globalThis.someValue).toBe(1); + expect(result).toBe(2); +}); diff --git a/integration/bunjs-only-snippets/text-encoder.test.js b/integration/bunjs-only-snippets/text-encoder.test.js index 3b0c1f971..e4bf35059 100644 --- a/integration/bunjs-only-snippets/text-encoder.test.js +++ b/integration/bunjs-only-snippets/text-encoder.test.js @@ -69,6 +69,15 @@ describe("TextEncoder", () => { } }); + it("should encode long latin1 text", () => { + const text = "Hello World!".repeat(1000); + const encoder = new TextEncoder(); + const encoded = encoder.encode(text); + expect(encoded instanceof Uint8Array).toBe(true); + expect(encoded.length).toBe(text.length); + expect(new TextDecoder().decode(encoded)).toBe(text); + }); + it("should encode latin1 rope text", () => { var text = "Hello"; text += " "; diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp index 3ab654dda..352669b1d 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp +++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp @@ -229,6 +229,25 @@ namespace Zig { const JSC::ClassInfo GlobalObject::s_info = { "GlobalObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(GlobalObject) }; +extern "C" JSClassRef* Zig__getAPIGlobals(size_t* count); + +static JSGlobalObject* deriveShadowRealmGlobalObject(JSGlobalObject* globalObject) +{ + auto& vm = globalObject->vm(); + Zig::GlobalObject* shadow = Zig::GlobalObject::create(vm, Zig::GlobalObject::createStructure(vm, JSC::jsNull())); + shadow->setConsole(shadow); + size_t count = 0; + JSClassRef* globalObjectClass; + globalObjectClass = Zig__getAPIGlobals(&count); + + shadow->setConsole(shadow); + if (count > 0) { + shadow->installAPIGlobals(globalObjectClass, count); + } + + return shadow; +} + const JSC::GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = { &supportsRichSourceInfo, &shouldInterruptScript, @@ -247,6 +266,8 @@ const JSC::GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = { nullptr, // defaultLanguage nullptr, // compileStreaming nullptr, // instantiateStreaming + nullptr, + &Zig::deriveShadowRealmGlobalObject }; void GlobalObject::reportUncaughtExceptionAtEventLoop(JSGlobalObject* globalObject, diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.h b/src/javascript/jsc/bindings/ZigGlobalObject.h index edc250ecb..e2464b99e 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.h +++ b/src/javascript/jsc/bindings/ZigGlobalObject.h @@ -48,7 +48,7 @@ public: } static void reportUncaughtExceptionAtEventLoop(JSGlobalObject*, JSC::Exception*); - + static JSGlobalObject* deriveShadowRealmGlobalObject(JSGlobalObject* globalObject); static void queueMicrotaskToEventLoop(JSC::JSGlobalObject& global, Ref<JSC::Microtask>&& task); static JSC::JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSString* moduleNameValue, diff --git a/src/javascript/jsc/bindings/exports.zig b/src/javascript/jsc/bindings/exports.zig index 6179ad203..a7d281299 100644 --- a/src/javascript/jsc/bindings/exports.zig +++ b/src/javascript/jsc/bindings/exports.zig @@ -241,6 +241,12 @@ export fn ZigString__free_global(ptr: [*]const u8, len: usize) void { default_allocator.free(str); } +export fn Zig__getAPIGlobals(count: *usize) [*]JSC.C.JSClassRef { + var globals = JSC.VirtualMachine.getAPIGlobals(); + count.* = globals.len; + return globals.ptr; +} + pub const JSErrorCode = enum(u8) { Error = 0, EvalError = 1, @@ -1855,6 +1861,7 @@ comptime { if (!is_bindgen) { _ = Process.getTitle; _ = Process.setTitle; + _ = Zig__getAPIGlobals; std.testing.refAllDecls(NodeReadableStream); std.testing.refAllDecls(Bun.Timer); std.testing.refAllDecls(NodeWritableStream); |