aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-02-24 00:59:19 -0800
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-02-24 00:59:19 -0800
commit8effa394100b26805cc9ca298659f1a5a7c3dda9 (patch)
tree54fda1f4ab7b8d901c984d25b8d1c3c407a0349b
parent5f50de2b390ef1ddfe2e108d285024ef45d4c421 (diff)
downloadbun-8effa394100b26805cc9ca298659f1a5a7c3dda9.tar.gz
bun-8effa394100b26805cc9ca298659f1a5a7c3dda9.tar.zst
bun-8effa394100b26805cc9ca298659f1a5a7c3dda9.zip
[bun.js] Add `ShadowRealm`
-rw-r--r--integration/bunjs-only-snippets/fetch.js17
-rw-r--r--integration/bunjs-only-snippets/fetch.test.js22
-rw-r--r--integration/bunjs-only-snippets/shadow.test.js10
-rw-r--r--integration/bunjs-only-snippets/text-encoder.test.js9
-rw-r--r--src/javascript/jsc/bindings/ZigGlobalObject.cpp21
-rw-r--r--src/javascript/jsc/bindings/ZigGlobalObject.h2
-rw-r--r--src/javascript/jsc/bindings/exports.zig7
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);