Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/build/deps/webkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* for local mode. Override via `--webkit-version=<hash>` to test a branch.
* From https://github.com/oven-sh/WebKit releases.
*/
export const WEBKIT_VERSION = "c6cfe90c6064bd80a1916b844c2f092735cfc720";
export const WEBKIT_VERSION = "autobuild-preview-pr-455-8fc20b18";
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
Comment thread
robobun marked this conversation as resolved.
Outdated

/**
* WebKit (JavaScriptCore) — the JS engine.
Expand Down
7 changes: 5 additions & 2 deletions src/js_printer/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,17 @@ pub mod analyze_transpiled_module {
Self(value.0)
}
/// JSC `ScriptFetchParameters::Type` value. `None` maps to `JavaScript`
/// (NodesAnalyzeModule's no-attribute default).
/// (NodesAnalyzeModule's no-attribute default). JSC's `Text` (4) is never
/// produced: with BUN_JSC_ADDITIONS `type: "text"` is host-defined like
/// every other non-json/wasm type. Pinned by the static_asserts in
/// BunAnalyzeTranspiledModule.cpp.
#[inline]
pub fn to_script_fetch_parameters_type(self) -> u8 {
match self {
Self::None | Self::Javascript => 1,
Self::Webassembly => 2,
Self::Json => 3,
_ => 4,
_ => 5,
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/jsc/bindings/BunAnalyzeTranspiledModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ extern "C" void JSC_JSModuleRecord__addRequestedModuleHostDefined(JSModuleRecord
static_assert(static_cast<uint8_t>(JSC::ScriptFetchParameters::Type::JavaScript) == 1, "ScriptFetchParameters::Type tag drift vs to_script_fetch_parameters_type()");
static_assert(static_cast<uint8_t>(JSC::ScriptFetchParameters::Type::WebAssembly) == 2, "ScriptFetchParameters::Type tag drift vs to_script_fetch_parameters_type()");
static_assert(static_cast<uint8_t>(JSC::ScriptFetchParameters::Type::JSON) == 3, "ScriptFetchParameters::Type tag drift vs to_script_fetch_parameters_type()");
static_assert(static_cast<uint8_t>(JSC::ScriptFetchParameters::Type::HostDefined) == 4, "ScriptFetchParameters::Type tag drift vs to_script_fetch_parameters_type()");
static_assert(static_cast<uint8_t>(JSC::ScriptFetchParameters::Type::Text) == 4, "ScriptFetchParameters::Type tag drift vs to_script_fetch_parameters_type()");
static_assert(static_cast<uint8_t>(JSC::ScriptFetchParameters::Type::HostDefined) == 5, "ScriptFetchParameters::Type tag drift vs to_script_fetch_parameters_type()");

extern "C" void JSC_JSModuleRecord__addImportEntrySingle(JSModuleRecord* moduleRecord, Identifier* identifierArray, uint32_t importName, uint32_t localName, uint32_t moduleName, uint8_t moduleRequestType)
{
Expand Down
4 changes: 4 additions & 0 deletions src/jsc/bindings/NodeVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ static JSValue scriptFetchParametersToImportAttributes(JSGlobalObject* globalObj
case JSC::ScriptFetchParameters::Type::JavaScript:
obj->putDirect(vm, vm.propertyNames->type, jsNontrivialString(vm, "javascript"_s));
break;
case JSC::ScriptFetchParameters::Type::Text:
// Unreachable with BUN_JSC_ADDITIONS (`type: "text"` parses as HostDefined); kept so the switch stays exhaustive.
obj->putDirect(vm, vm.propertyNames->type, jsNontrivialString(vm, "text"_s));
break;
case JSC::ScriptFetchParameters::Type::HostDefined:
obj->putDirect(vm, vm.propertyNames->type, jsString(vm, params->hostDefinedImportType()));
break;
Expand Down
4 changes: 3 additions & 1 deletion src/jsc/bindings/NodeVMSyntheticModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ void NodeVMSyntheticModule::createModuleRecord(JSGlobalObject* globalObject)
{
VM& vm = globalObject->vm();

SyntheticModuleRecord* moduleRecord = SyntheticModuleRecord::create(globalObject, vm, globalObject->syntheticModuleRecordStructure(), Identifier::fromString(vm, identifier()));
// The source type only feeds AbstractModuleRecord::moduleType(), which the loader attaches to
// errors as the failing module's kind; a vm.SyntheticModule is a JavaScript module in that sense.
SyntheticModuleRecord* moduleRecord = SyntheticModuleRecord::create(globalObject, vm, globalObject->syntheticModuleRecordStructure(), Identifier::fromString(vm, identifier()), SourceProviderSourceType::Module);

m_moduleRecord.set(vm, this, moduleRecord);

Expand Down
2 changes: 1 addition & 1 deletion src/jsc/bindings/root.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
#include <JavaScriptCore/JSCJSValue.h>
#include <wtf/text/MakeString.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/HandleSet.h>
#include <JavaScriptCore/StrongSet.h>
#include <wtf/Ref.h>
#include <wtf/ThreadSafeRefCounted.h>
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/jsc/bindings/wtf-bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ static thread_local WTF::StackBounds stackBoundsForCurrentThread = WTF::StackBou

extern "C" [[ZIG_EXPORT(nothrow)]] void Bun__StackCheck__initialize()
{
stackBoundsForCurrentThread = WTF::StackBounds::currentThreadStackBounds();
stackBoundsForCurrentThread = WTF::StackBounds::currentThreadStackBoundsForEmbedder();
}

extern "C" [[ZIG_EXPORT(nothrow)]] __attribute__((__always_inline__)) void* Bun__StackCheck__getMaxStack()
Expand Down
141 changes: 141 additions & 0 deletions test/js/bun/jsc/webkit-upgrade-47f72501.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { describe, expect, test } from "bun:test";
import { bunEnv, bunExe, tempDir } from "harness";

// Coverage for the WebKit 47f7250137c6 sync. The RegExp case pins a behavior
// that only the new WebKit has; the import attribute cases pin the fork-side
// resolution of upstream's new ScriptFetchParameters::Type::Text (with
// BUN_JSC_ADDITIONS `type: "text"` must stay a host-defined import type, on
// both the JSC ModuleAnalyzer path and the BunTranspiledModule path).

describe.concurrent("WebKit 47f7250137c6 upgrade", () => {
test("Iterator.prototype.chunks / windows / join and Iterator.zip / zipKeyed are enabled by default (webkit.org/b/321272)", () => {
expect([1, 2, 3, 4, 5].values().chunks(2).toArray()).toEqual([[1, 2], [3, 4], [5]]);
expect([1, 2, 3].values().windows(2).toArray()).toEqual([
[1, 2],
[2, 3],
]);
expect(["a", undefined, "c"].values().join("-")).toBe("a--c");
expect(
Iterator.zip([
[1, 2],
["a", "b"],
]).toArray(),
).toEqual([
[1, "a"],
[2, "b"],
]);
expect(Iterator.zipKeyed({ n: [1, 2], s: ["a", "b"] }).toArray()).toEqual([
{ n: 1, s: "a" },
{ n: 2, s: "b" },
]);
// Spec alignment that came with the flag flip: a non-integral size throws instead of being coerced.
expect(() => [1].values().chunks("2" as any)).toThrow(TypeError);
});

test("intl-era-monthcode: the calendar list is the proposal's fixed set, islamic / islamic-rgsa are gone (webkit.org/b/319855)", () => {
expect(Intl.supportedValuesOf("calendar")).toEqual([
"buddhist",
"chinese",
"coptic",
"dangi",
"ethioaa",
"ethiopic",
"gregory",
"hebrew",
"indian",
"islamic-civil",
"islamic-tbla",
"islamic-umalqura",
"iso8601",
"japanese",
"persian",
"roc",
]);
expect(() => Temporal.PlainDate.from({ year: 2024, month: 1, day: 1, calendar: "islamic" })).toThrow(RangeError);
expect(Temporal.PlainDate.from({ year: 2024, month: 1, day: 1, calendar: "islamic-civil" }).calendarId).toBe(
"islamic-civil",
);
});

test("NUMBER_OF_PROCESSORS does not change the reported core count", async () => {
// Upstream WTF::numberOfProcessorCores() started honoring this variable; the fork keeps that out of
// Bun builds because navigator.hardwareConcurrency / os.availableParallelism() are derived from it.
await using proc = Bun.spawn({
cmd: [bunExe(), "-p", `navigator.hardwareConcurrency + " " + require("os").availableParallelism()`],
env: { ...bunEnv, NUMBER_OF_PROCESSORS: "1234" },
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(stderr).toBe("");
const [hardwareConcurrency, availableParallelism] = stdout.trim().split(" ").map(Number);
expect(hardwareConcurrency).toBeGreaterThan(0);
expect(hardwareConcurrency).not.toBe(1234);
expect(availableParallelism).not.toBe(1234);
expect(exitCode).toBe(0);
});

test("v-mode && / -- apply to class strings when the operand is an inverted property escape (webkit.org/b/321252)", () => {
// The complement has no strings, so an intersection must drop the strings
// accumulated on the left and a subtraction must keep them.
expect(/^[\q{ab|c|1}&&\P{L}]$/v.test("ab")).toBe(false);
expect(/^[\q{ab|c|1}&&\P{L}]$/v.test("c")).toBe(false);
expect(/^[\q{ab|c|1}&&\P{L}]$/v.test("1")).toBe(true);
expect(/^[\q{ab|c|1}--\P{L}]$/v.test("ab")).toBe(true);
expect(/^[\q{ab|c|1}--\P{L}]$/v.test("c")).toBe(true);
expect(/^[\q{ab|c|1}--\P{L}]$/v.test("1")).toBe(false);
expect(/^[\p{L}&&\P{Lu}]$/v.test("A")).toBe(false);
expect(/^[\p{L}&&\P{Lu}]$/v.test("a")).toBe(true);
});

test('import ... with { type: "text" } of a .js file still returns its source', async () => {
using dir = tempDir("wk-text-attr", {
"mod.js": `export default "evaluated";`,
"entry.mjs": `
import source from "./mod.js" with { type: "text" };
import evaluated from "./mod.js";
process.stdout.write(JSON.stringify({ source, evaluated }));
`,
});
await using proc = Bun.spawn({
cmd: [bunExe(), "entry.mjs"],
env: bunEnv,
cwd: String(dir),
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(stderr).toBe("");
expect(JSON.parse(stdout)).toEqual({ source: `export default "evaluated";`, evaluated: "evaluated" });
expect(exitCode).toBe(0);
});

test('import ... with { type: "text" } of a .js file under bun test --isolate', async () => {
// --isolate takes the BunTranspiledModule path, where Bun's transpiler
// emits the ScriptFetchParameters::Type ordinal itself (HostDefined moved
// behind upstream's new Text member). In debug builds a wrong ordinal fails
// the record comparison with "Imports different"; in release the import
// would not resolve.
using dir = tempDir("wk-text-attr-isolate", {
"mod.js": `export default "evaluated";`,
"text.test.ts": `
import source from "./mod.js" with { type: "text" };
import evaluated from "./mod.js";
import { test, expect } from "bun:test";
test("text attribute", () => {
expect(source).toBe('export default "evaluated";');
expect(evaluated).toBe("evaluated");
});
`,
});
await using proc = Bun.spawn({
cmd: [bunExe(), "test", "--isolate", "text.test.ts"],
env: { ...bunEnv, BUN_RUNTIME_TRANSPILER_CACHE_PATH: "0" },
cwd: String(dir),
stderr: "pipe",
stdout: "pipe",
});
const [, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(stderr).toContain("1 pass");
expect(stderr).not.toContain("Imports different");
expect(exitCode).toBe(0);
});
});
Loading