Skip to content

Commit

Permalink
Fix regression with TOML & JSONC (#10573)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner authored Apr 27, 2024
1 parent 3b1311a commit 4cbd215
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/bun.js/bindings/ModuleLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,19 @@ JSValue fetchCommonJSModule(
RELEASE_AND_RETURN(scope, {});
}

target->putDirect(vm, WebCore::clientData(vm)->builtinNames().exportsPublicName(), value, 0);
target->hasEvaluated = true;
RELEASE_AND_RETURN(scope, target);

}
// TOML and JSONC may go through here
else if (res->result.value.tag == SyntheticModuleType::ExportsObject) {
JSC::JSValue value = JSC::JSValue::decode(res->result.value.jsvalue_for_export);
if (!value) {
JSC::throwException(globalObject, scope, JSC::createSyntaxError(globalObject, "Failed to parse Object"_s));
RELEASE_AND_RETURN(scope, {});
}

target->putDirect(vm, WebCore::clientData(vm)->builtinNames().exportsPublicName(), value, 0);
target->hasEvaluated = true;
RELEASE_AND_RETURN(scope, target);
Expand Down Expand Up @@ -807,6 +820,23 @@ static JSValue fetchESMSourceCode(
JSC::ensureStillAliveHere(value);
return rejectOrResolve(JSSourceCode::create(globalObject->vm(), WTFMove(source)));
}
// TOML and JSONC may go through here
else if (res->result.value.tag == SyntheticModuleType::ExportsObject) {
JSC::JSValue value = JSC::JSValue::decode(res->result.value.jsvalue_for_export);
if (!value) {
return reject(JSC::JSValue(JSC::createSyntaxError(globalObject, "Failed to parse Object"_s)));
}

// JSON can become strings, null, numbers, booleans so we must handle "export default 123"
auto function = generateJSValueModuleSourceCode(
globalObject,
value);
auto source = JSC::SourceCode(
JSC::SyntheticSourceProvider::create(WTFMove(function),
JSC::SourceOrigin(), specifier->toWTFString(BunString::ZeroCopy)));
JSC::ensureStillAliveHere(value);
return rejectOrResolve(JSSourceCode::create(globalObject->vm(), WTFMove(source)));
}

return rejectOrResolve(JSC::JSSourceCode::create(vm,
JSC::SourceCode(Zig::SourceProvider::create(globalObject, res->result.value))));
Expand Down
2 changes: 2 additions & 0 deletions src/bun.js/bindings/exports.zig
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ pub const ResolvedSource = extern struct {

allocator: ?*anyopaque = null,

jsvalue_for_export: JSC.JSValue = .zero,

tag: Tag = Tag.javascript,

/// This is for source_code
Expand Down
1 change: 1 addition & 0 deletions src/bun.js/bindings/headers-handwritten.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ typedef struct ResolvedSource {
uint32_t commonJSExportsLen;
uint32_t hash;
void* allocator;
JSC::EncodedJSValue jsvalue_for_export;
uint32_t tag;
bool needsDeref;
} ResolvedSource;
Expand Down
12 changes: 12 additions & 0 deletions src/bun.js/module_loader.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,7 @@ pub const ModuleLoader = struct {
.dont_bundle_twice = true,
.allow_commonjs = true,
.inject_jest_globals = jsc_vm.bundler.options.rewrite_jest_for_tests and is_main,
.keep_json_and_toml_as_one_statement = true,
.set_breakpoint_on_first_line = is_main and
jsc_vm.debugger != null and
jsc_vm.debugger.?.set_breakpoint_on_first_line and
Expand Down Expand Up @@ -1778,6 +1779,17 @@ pub const ModuleLoader = struct {
};
}

if (loader == .json or loader == .toml) {
return ResolvedSource{
.allocator = null,
.specifier = input_specifier,
.source_url = input_specifier.createIfDifferent(path.text),
.hash = 0,
.jsvalue_for_export = parse_result.ast.parts.@"[0]"().stmts[0].data.s_expr.value.toJS(allocator, globalObject orelse jsc_vm.global) catch @panic("Unexpected JS error"),
.tag = .exports_object,
};
}

if (parse_result.already_bundled) {
return ResolvedSource{
.allocator = null,
Expand Down
10 changes: 10 additions & 0 deletions src/bundler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,8 @@ pub const Bundler = struct {
allow_commonjs: bool = false,

runtime_transpiler_cache: ?*bun.JSC.RuntimeTranspilerCache = null,

keep_json_and_toml_as_one_statement: bool = false,
};

pub fn parse(
Expand Down Expand Up @@ -1485,6 +1487,14 @@ pub const Bundler = struct {
var symbols: []js_ast.Symbol = &.{};

const parts = brk: {
if (this_parse.keep_json_and_toml_as_one_statement) {
var stmts = allocator.alloc(js_ast.Stmt, 1) catch unreachable;
stmts[0] = js_ast.Stmt.allocate(allocator, js_ast.S.SExpr, js_ast.S.SExpr{ .value = expr }, logger.Loc{ .start = 0 });
var parts_ = allocator.alloc(js_ast.Part, 1) catch unreachable;
parts_[0] = js_ast.Part{ .stmts = stmts };
break :brk parts_;
}

if (expr.data == .e_object) {
const properties: []js_ast.G.Property = expr.data.e_object.properties.slice();
if (properties.len > 0) {
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/bundle-modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ pub const ResolvedSourceTag = enum(u32) {
file = 4,
esm = 5,
json_for_object_loader = 6,
exports_object = 7,
// Built in modules are loaded through InternalModuleRegistry by numerical ID.
// In this enum are represented as \`(1 << 9) & id\`
Expand All @@ -396,6 +397,7 @@ writeIfNotChanged(
File = 4,
ESM = 5,
JSONForObjectLoader = 6,
ExportsObject = 7,
// Built in modules are loaded through InternalModuleRegistry by numerical ID.
// In this enum are represented as \`(1 << 9) & id\`
Expand Down

0 comments on commit 4cbd215

Please sign in to comment.