aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bun.js/api/bun.zig10
-rw-r--r--src/bun.js/api/transpiler.classes.ts40
-rw-r--r--src/bun.js/api/transpiler.zig394
3 files changed, 243 insertions, 201 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig
index d8506b6b5..d70de3aa9 100644
--- a/src/bun.js/api/bun.zig
+++ b/src/bun.js/api/bun.zig
@@ -2328,15 +2328,7 @@ pub fn getTranspilerConstructor(
_: js.JSStringRef,
_: js.ExceptionRef,
) js.JSValueRef {
- var existing = ctx.ptr().getCachedObject(ZigString.static("BunTranspiler"));
- if (existing.isEmpty()) {
- return ctx.ptr().putCachedObject(
- &ZigString.init("BunTranspiler"),
- JSC.JSValue.fromRef(Transpiler.Constructor.constructor(ctx)),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
+ return JSC.API.Bun.Transpiler.getConstructor(ctx).asObjectRef();
}
pub fn getFileSystemRouter(
diff --git a/src/bun.js/api/transpiler.classes.ts b/src/bun.js/api/transpiler.classes.ts
new file mode 100644
index 000000000..d10090f35
--- /dev/null
+++ b/src/bun.js/api/transpiler.classes.ts
@@ -0,0 +1,40 @@
+import { define } from "../scripts/class-definitions";
+
+export default [
+ define({
+ name: "Transpiler",
+ construct: true,
+ finalize: true,
+ hasPendingActivity: false,
+ klass: {},
+ JSType: "0b11101110",
+ proto: {
+ scanImports: {
+ fn: "scanImports",
+ length: 2,
+ },
+ scan: {
+ fn: "scan",
+ length: 2,
+ },
+ transform: {
+ fn: "transform",
+ length: 2,
+ },
+ transformSync: {
+ fn: "transformSync",
+ length: 2,
+ },
+ },
+ custom: {
+ onLoadPlugins: {
+ extraHeaderIncludes: ["BunPlugin.h"],
+ impl: "JSTranspiler+BunPlugin-impl.h",
+ type: `WTF::Vector<std::unique_ptr<BunPlugin::OnLoad>>`,
+ },
+ onResolvePlugins: {
+ type: `WTF::Vector<std::unique_ptr<BunPlugin::OnResolve>>`,
+ },
+ },
+ }),
+];
diff --git a/src/bun.js/api/transpiler.zig b/src/bun.js/api/transpiler.zig
index 715c5137e..eb070b6bc 100644
--- a/src/bun.js/api/transpiler.zig
+++ b/src/bun.js/api/transpiler.zig
@@ -43,47 +43,14 @@ const Runtime = @import("../../runtime.zig").Runtime;
const JSLexer = bun.js_lexer;
const Expr = JSAst.Expr;
+pub usingnamespace JSC.Codegen.JSTranspiler;
+
bundler: Bundler.Bundler,
arena: std.heap.ArenaAllocator,
transpiler_options: TranspilerOptions,
scan_pass_result: ScanPassResult,
buffer_writer: ?JSPrinter.BufferWriter = null,
-pub const Class = NewClass(
- Transpiler,
- .{ .name = "Transpiler" },
- .{
- .scanImports = .{
- .rfn = scanImports,
- },
- .scan = .{
- .rfn = scan,
- },
- .transform = .{
- .rfn = transform,
- },
- .transformSync = .{
- .rfn = transformSync,
- },
- // .resolve = .{
- // .rfn = resolve,
- // },
- // .buildSync = .{
- // .rfn = buildSync,
- // },
- .finalize = finalize,
- },
- .{},
-);
-
-pub const Constructor = JSC.NewConstructor(
- @This(),
- .{
- .constructor = .{ .rfn = constructor },
- },
- .{},
-);
-
const default_transform_options: Api.TransformOptions = brk: {
var opts = std.mem.zeroes(Api.TransformOptions);
opts.disable_hmr = true;
@@ -130,11 +97,11 @@ pub const TransformTask = struct {
pub const AsyncTransformTask = JSC.ConcurrentPromiseTask(TransformTask);
pub const AsyncTransformEventLoopTask = AsyncTransformTask.EventLoopTask;
- pub fn create(transpiler: *Transpiler, protected_input_value: JSC.C.JSValueRef, globalThis: *JSGlobalObject, input_code: ZigString, loader: Loader) !*AsyncTransformTask {
+ pub fn create(transpiler: *Transpiler, protected_input_value: JSC.JSValue, globalThis: *JSGlobalObject, input_code: ZigString, loader: Loader) !*AsyncTransformTask {
var transform_task = try bun.default_allocator.create(TransformTask);
transform_task.* = .{
.input_code = input_code,
- .protected_input_value = if (protected_input_value != null) JSC.JSValue.fromRef(protected_input_value) else @intToEnum(JSC.JSValue, 0),
+ .protected_input_value = protected_input_value,
.bundler = undefined,
.global = globalThis,
.macro_map = transpiler.transpiler_options.macro_map,
@@ -335,8 +302,8 @@ fn exportReplacementValue(value: JSValue, globalThis: *JSGlobalObject) ?JSAst.Ex
return null;
}
-fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allocator, args: *JSC.Node.ArgumentsSlice, exception: JSC.C.ExceptionRef) !TranspilerOptions {
- var globalThis = ctx.ptr();
+fn transformOptionsFromJSC(globalObject: JSC.C.JSContextRef, temp_allocator: std.mem.Allocator, args: *JSC.Node.ArgumentsSlice, exception: JSC.C.ExceptionRef) !TranspilerOptions {
+ var globalThis = globalObject;
const object = args.next() orelse return TranspilerOptions{ .log = logger.Log.init(temp_allocator) };
if (object.isUndefinedOrNull()) return TranspilerOptions{ .log = logger.Log.init(temp_allocator) };
@@ -351,18 +318,18 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
transpiler.log.level = .warn;
if (!object.isObject()) {
- JSC.throwInvalidArguments("Expected an object", .{}, ctx, exception);
+ JSC.throwInvalidArguments("Expected an object", .{}, globalObject, exception);
return transpiler;
}
- if (object.getIfPropertyExists(ctx.ptr(), "define")) |define| {
+ if (object.getIfPropertyExists(globalObject, "define")) |define| {
define: {
if (define.isUndefinedOrNull()) {
break :define;
}
if (!define.isObject()) {
- JSC.throwInvalidArguments("define must be an object", .{}, ctx, exception);
+ JSC.throwInvalidArguments("define must be an object", .{}, globalObject, exception);
return transpiler;
}
@@ -384,7 +351,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
const value_type = property_value.jsType();
if (!value_type.isStringLike()) {
- JSC.throwInvalidArguments("define \"{s}\" must be a JSON string", .{prop}, ctx, exception);
+ JSC.throwInvalidArguments("define \"{s}\" must be a JSON string", .{prop}, globalObject, exception);
return transpiler;
}
@@ -425,7 +392,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
var i: usize = 0;
while (iter.next()) |entry| {
if (!entry.jsType().isStringLike()) {
- JSC.throwInvalidArguments("external must be a string or string[]", .{}, ctx, exception);
+ JSC.throwInvalidArguments("external must be a string or string[]", .{}, globalObject, exception);
return transpiler;
}
@@ -438,7 +405,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
transpiler.transform.external = externals[0..i];
} else {
- JSC.throwInvalidArguments("external must be a string or string[]", .{}, ctx, exception);
+ JSC.throwInvalidArguments("external must be a string or string[]", .{}, globalObject, exception);
return transpiler;
}
}
@@ -447,7 +414,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
if (object.get(globalThis, "loader")) |loader| {
if (Loader.fromJS(globalThis, loader, exception)) |resolved| {
if (!resolved.isJavaScriptLike()) {
- JSC.throwInvalidArguments("only JavaScript-like loaders supported for now", .{}, ctx, exception);
+ JSC.throwInvalidArguments("only JavaScript-like loaders supported for now", .{}, globalObject, exception);
return transpiler;
}
@@ -476,7 +443,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
var out = JSC.ZigString.init("");
if (kind.isArray()) {
- JSC.throwInvalidArguments("tsconfig must be a string or object", .{}, ctx, exception);
+ JSC.throwInvalidArguments("tsconfig must be a string or object", .{}, globalObject, exception);
return transpiler;
}
@@ -514,7 +481,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
const kind = macros.jsType();
const is_object = kind.isObject();
if (!(kind.isStringLike() or is_object)) {
- JSC.throwInvalidArguments("macro must be an object", .{}, ctx, exception);
+ JSC.throwInvalidArguments("macro must be an object", .{}, globalObject, exception);
return transpiler;
}
@@ -554,7 +521,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
transpiler.runtime.jsx_optimization_hoist = flag.toBoolean();
if (!transpiler.runtime.jsx_optimization_inline and transpiler.runtime.jsx_optimization_hoist) {
- JSC.throwInvalidArguments("jsxOptimizationHoist requires jsxOptimizationInline", .{}, ctx, exception);
+ JSC.throwInvalidArguments("jsxOptimizationHoist requires jsxOptimizationInline", .{}, globalObject, exception);
return transpiler;
}
}
@@ -579,7 +546,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
if (options.SourceMapOption.map.get(sourcemap.slice())) |source| {
transpiler.transform.source_map = source.toAPI();
} else {
- JSC.throwInvalidArguments("sourcemap must be one of \"inline\", \"external\", or \"none\"", .{}, ctx, exception);
+ JSC.throwInvalidArguments("sourcemap must be one of \"inline\", \"external\", or \"none\"", .{}, globalObject, exception);
return transpiler;
}
}
@@ -597,7 +564,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
if (object.getTruthy(globalThis, "exports")) |exports| {
if (!exports.isObject()) {
- JSC.throwInvalidArguments("exports must be an object", .{}, ctx, exception);
+ JSC.throwInvalidArguments("exports must be an object", .{}, globalObject, exception);
return transpiler;
}
@@ -606,7 +573,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
if (exports.getTruthy(globalThis, "eliminate")) |eliminate| {
if (!eliminate.jsType().isArray()) {
- JSC.throwInvalidArguments("exports.eliminate must be an array", .{}, ctx, exception);
+ JSC.throwInvalidArguments("exports.eliminate must be an array", .{}, globalObject, exception);
return transpiler;
}
@@ -634,7 +601,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
var str = value.getZigString(globalThis);
if (str.len == 0) continue;
const name = std.fmt.bufPrint(buf.items.ptr[buf.items.len..buf.capacity], "{}", .{str}) catch {
- JSC.throwInvalidArguments("Error reading exports.eliminate. TODO: utf-16", .{}, ctx, exception);
+ JSC.throwInvalidArguments("Error reading exports.eliminate. TODO: utf-16", .{}, globalObject, exception);
return transpiler;
};
buf.items.len += name.len;
@@ -648,7 +615,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
if (exports.getTruthy(globalThis, "replace")) |replace| {
if (!replace.isObject()) {
- JSC.throwInvalidArguments("replace must be an object", .{}, ctx, exception);
+ JSC.throwInvalidArguments("replace must be an object", .{}, globalObject, exception);
return transpiler;
}
@@ -678,7 +645,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
var key = try key_.toOwnedSlice(bun.default_allocator);
if (!JSLexer.isIdentifier(key)) {
- JSC.throwInvalidArguments("\"{s}\" is not a valid ECMAScript identifier", .{key}, ctx, exception);
+ JSC.throwInvalidArguments("\"{s}\" is not a valid ECMAScript identifier", .{key}, globalObject, exception);
bun.default_allocator.free(key);
return transpiler;
}
@@ -690,7 +657,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
continue;
}
- if (value.isObject() and value.getLengthOfArray(ctx.ptr()) == 2) {
+ if (value.isObject() and value.getLengthOfArray(globalObject) == 2) {
const replacementValue = JSC.JSObject.getIndex(value, globalThis, 1);
if (exportReplacementValue(replacementValue, globalThis)) |to_replace| {
const replacementKey = JSC.JSObject.getIndex(value, globalThis, 0);
@@ -698,7 +665,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
var replacement_name = slice.slice();
if (!JSLexer.isIdentifier(replacement_name)) {
- JSC.throwInvalidArguments("\"{s}\" is not a valid ECMAScript identifier", .{replacement_name}, ctx, exception);
+ JSC.throwInvalidArguments("\"{s}\" is not a valid ECMAScript identifier", .{replacement_name}, globalObject, exception);
slice.deinit();
return transpiler;
}
@@ -713,7 +680,7 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
}
}
- JSC.throwInvalidArguments("exports.replace values can only be string, null, undefined, number or boolean", .{}, ctx, exception);
+ JSC.throwInvalidArguments("exports.replace values can only be string, null, undefined, number or boolean", .{}, globalObject, exception);
return transpiler;
}
}
@@ -730,48 +697,60 @@ fn transformOptionsFromJSC(ctx: JSC.C.JSContextRef, temp_allocator: std.mem.Allo
}
pub fn constructor(
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) js.JSObjectRef {
- var temp = std.heap.ArenaAllocator.init(getAllocator(ctx));
- var args = JSC.Node.ArgumentsSlice.init(ctx.bunVM(), @ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]);
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) ?*Transpiler {
+ var temp = std.heap.ArenaAllocator.init(getAllocator(globalThis));
+ const arguments = callframe.arguments(3);
+ var args = JSC.Node.ArgumentsSlice.init(
+ globalThis.bunVM(),
+ arguments.ptr[0..arguments.len],
+ );
+
defer temp.deinit();
+ var exception_ref = [_]JSC.C.JSValueRef{null};
+ var exception = &exception_ref[0];
const transpiler_options: TranspilerOptions = if (arguments.len > 0)
- transformOptionsFromJSC(ctx, temp.allocator(), &args, exception) catch {
- JSC.throwInvalidArguments("Failed to create transpiler", .{}, ctx, exception);
+ transformOptionsFromJSC(globalThis, temp.allocator(), &args, exception) catch {
+ JSC.throwInvalidArguments("Failed to create transpiler", .{}, globalThis, exception);
return null;
}
else
- TranspilerOptions{ .log = logger.Log.init(getAllocator(ctx)) };
+ TranspilerOptions{ .log = logger.Log.init(getAllocator(globalThis)) };
if (exception.* != null) {
+ globalThis.throwValue(JSC.JSValue.c(exception.*));
return null;
}
+ const allocator = getAllocator(globalThis);
+
if ((transpiler_options.log.warnings + transpiler_options.log.errors) > 0) {
- var out_exception = transpiler_options.log.toJS(ctx.ptr(), getAllocator(ctx), "Failed to create transpiler");
- exception.* = out_exception.asObjectRef();
+ globalThis.throwValue(
+ transpiler_options.log.toJS(globalThis.ptr(), allocator, "Failed to create transpiler"),
+ );
+
return null;
}
- var log = getAllocator(ctx).create(logger.Log) catch unreachable;
+ var log = allocator.create(logger.Log) catch unreachable;
log.* = transpiler_options.log;
var bundler = Bundler.Bundler.init(
- getAllocator(ctx),
+ allocator,
log,
transpiler_options.transform,
null,
JavaScript.VirtualMachine.get().bundler.env,
) catch |err| {
if ((log.warnings + log.errors) > 0) {
- var out_exception = log.toJS(ctx.ptr(), getAllocator(ctx), "Failed to create transpiler");
- exception.* = out_exception.asObjectRef();
+ globalThis.throwValue(
+ log.toJS(globalThis.ptr(), allocator, "Failed to create transpiler"),
+ );
+
return null;
}
- JSC.throwInvalidArguments("Error creating transpiler: {s}", .{@errorName(err)}, ctx, exception);
+ globalThis.throwError(err, "Error creating transpiler");
return null;
};
@@ -779,12 +758,14 @@ pub fn constructor(
bundler.options.env.behavior = .disable;
bundler.configureDefines() catch |err| {
if ((log.warnings + log.errors) > 0) {
- var out_exception = log.toJS(ctx.ptr(), getAllocator(ctx), "Failed to load define");
- exception.* = out_exception.asObjectRef();
+ globalThis.throwValue(
+ log.toJS(globalThis.ptr(), allocator, "Failed to load define"),
+ );
+
return null;
}
- JSC.throwInvalidArguments("Failed to load define: {s}", .{@errorName(err)}, ctx, exception);
+ globalThis.throwError(err, "Failed to load define");
return null;
};
@@ -802,20 +783,20 @@ pub fn constructor(
bundler.options.jsx.supports_fast_refresh = bundler.options.hot_module_reloading and
bundler.options.allow_runtime and transpiler_options.runtime.react_fast_refresh;
- var transpiler = getAllocator(ctx).create(Transpiler) catch unreachable;
+ var transpiler = allocator.create(Transpiler) catch unreachable;
transpiler.* = Transpiler{
.transpiler_options = transpiler_options,
.bundler = bundler,
.arena = args.arena,
- .scan_pass_result = ScanPassResult.init(getAllocator(ctx)),
+ .scan_pass_result = ScanPassResult.init(allocator),
};
- return Class.make(ctx, transpiler);
+ return transpiler;
}
pub fn finalize(
this: *Transpiler,
-) void {
+) callconv(.C) void {
this.bundler.log.deinit();
this.scan_pass_result.named_imports.deinit();
this.scan_pass_result.import_records.deinit();
@@ -827,6 +808,7 @@ pub fn finalize(
// bun.default_allocator.free(this.transpiler_options.tsconfig_buf);
// bun.default_allocator.free(this.transpiler_options.macros_buf);
this.arena.deinit();
+ JSC.VirtualMachine.get().allocator.destroy(this);
}
fn getParseResult(this: *Transpiler, allocator: std.mem.Allocator, code: []const u8, loader: ?Loader, macro_js_ctx: Bundler.MacroJSValueType) ?Bundler.ParseResult {
@@ -869,37 +851,41 @@ fn getParseResult(this: *Transpiler, allocator: std.mem.Allocator, code: []const
pub fn scan(
this: *Transpiler,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) JSC.C.JSObjectRef {
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
JSC.markBinding(@src());
- var args = JSC.Node.ArgumentsSlice.init(ctx.bunVM(), @ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]);
+ const arguments = callframe.arguments(3);
+ var args = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments.ptr[0..arguments.len]);
defer args.arena.deinit();
const code_arg = args.next() orelse {
- JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception);
- return null;
+ globalThis.throwInvalidArgumentType("scan", "code", "string or Uint8Array");
+ return .zero;
};
- const code_holder = JSC.Node.StringOrBuffer.fromJS(ctx.ptr(), args.arena.allocator(), code_arg, exception) orelse {
- if (exception.* == null) JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception);
- return null;
+ const code_holder = JSC.Node.SliceOrBuffer.fromJS(globalThis, args.arena.allocator(), code_arg) orelse {
+ globalThis.throwInvalidArgumentType("scan", "code", "string or Uint8Array");
+ return .zero;
};
const code = code_holder.slice();
args.eat();
+ var exception_ref = [_]JSC.C.JSValueRef{null};
+ var exception: JSC.C.ExceptionRef = &exception_ref;
+
const loader: ?Loader = brk: {
if (args.next()) |arg| {
args.eat();
- break :brk Loader.fromJS(ctx.ptr(), arg, exception);
+ break :brk Loader.fromJS(globalThis, arg, exception);
}
break :brk null;
};
- if (exception.* != null) return null;
+ if (exception.* != null) {
+ globalThis.throwValue(JSC.JSValue.c(exception.*));
+ return .zero;
+ }
var arena = Mimalloc.Arena.init() catch unreachable;
var prev_allocator = this.bundler.allocator;
@@ -920,34 +906,36 @@ pub fn scan(
const parse_result = getParseResult(this, arena.allocator(), code, loader, Bundler.MacroJSValueType.zero) orelse {
if ((this.bundler.log.warnings + this.bundler.log.errors) > 0) {
- var out_exception = this.bundler.log.toJS(ctx.ptr(), getAllocator(ctx), "Parse error");
- exception.* = out_exception.asObjectRef();
- return null;
+ globalThis.throwValue(this.bundler.log.toJS(globalThis, globalThis.allocator(), "Parse error"));
+ return .zero;
}
- JSC.throwInvalidArguments("Failed to parse", .{}, ctx, exception);
- return null;
+ globalThis.throw("Failed to parse", .{});
+ return .zero;
};
if ((this.bundler.log.warnings + this.bundler.log.errors) > 0) {
- var out_exception = this.bundler.log.toJS(ctx.ptr(), getAllocator(ctx), "Parse error");
- exception.* = out_exception.asObjectRef();
- return null;
+ globalThis.throwValue(this.bundler.log.toJS(globalThis, globalThis.allocator(), "Parse error"));
+ return .zero;
}
- const exports_label = JSC.ZigString.init("exports");
- const imports_label = JSC.ZigString.init("imports");
+ const exports_label = JSC.ZigString.static("exports");
+ const imports_label = JSC.ZigString.static("imports");
const named_imports_value = namedImportsToJS(
- ctx.ptr(),
+ globalThis,
parse_result.ast.import_records,
exception,
);
- if (exception.* != null) return null;
- var named_exports_value = namedExportsToJS(
- ctx.ptr(),
+ if (exception.* != null) {
+ globalThis.throwValue(JSC.JSValue.c(exception.*));
+ return .zero;
+ }
+
+ const named_exports_value = namedExportsToJS(
+ globalThis,
parse_result.ast.named_exports,
);
- return JSC.JSValue.createObject2(ctx.ptr(), &imports_label, &exports_label, named_imports_value, named_exports_value).asObjectRef();
+ return JSC.JSValue.createObject2(globalThis, imports_label, exports_label, named_imports_value, named_exports_value);
}
// pub fn build(
@@ -961,24 +949,23 @@ pub fn scan(
pub fn transform(
this: *Transpiler,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) JSC.C.JSObjectRef {
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
JSC.markBinding(@src());
-
- var args = JSC.Node.ArgumentsSlice.init(ctx.bunVM(), @ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]);
+ var exception_ref = [_]JSC.C.JSValueRef{null};
+ var exception: JSC.C.ExceptionRef = &exception_ref;
+ const arguments = callframe.arguments(3);
+ var args = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments.ptr[0..arguments.len]);
defer args.arena.deinit();
const code_arg = args.next() orelse {
- JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception);
- return null;
+ globalThis.throwInvalidArgumentType("transform", "code", "string or Uint8Array");
+ return .zero;
};
- const code_holder = JSC.Node.StringOrBuffer.fromJS(ctx.ptr(), this.arena.allocator(), code_arg, exception) orelse {
- if (exception.* == null) JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception);
- return null;
+ const code_holder = JSC.Node.StringOrBuffer.fromJS(globalThis, this.arena.allocator(), code_arg, exception) orelse {
+ globalThis.throwInvalidArgumentType("transform", "code", "string or Uint8Array");
+ return .zero;
};
const code = code_holder.slice();
@@ -986,47 +973,62 @@ pub fn transform(
const loader: ?Loader = brk: {
if (args.next()) |arg| {
args.eat();
- break :brk Loader.fromJS(ctx.ptr(), arg, exception);
+ break :brk Loader.fromJS(globalThis, arg, exception);
}
break :brk null;
};
- if (exception.* != null) return null;
+ if (exception.* != null) {
+ globalThis.throwValue(JSC.JSValue.c(exception.*));
+ return .zero;
+ }
+
if (code_holder == .string) {
- JSC.C.JSValueProtect(ctx, arguments[0]);
+ arguments.ptr[0].ensureStillAlive();
}
- var task = TransformTask.create(this, if (code_holder == .string) arguments[0] else null, ctx.ptr(), ZigString.init(code), loader orelse this.transpiler_options.default_loader) catch return null;
+ var task = TransformTask.create(
+ this,
+ if (code_holder == .string) arguments.ptr[0] else .zero,
+ globalThis,
+ ZigString.init(code),
+ loader orelse this.transpiler_options.default_loader,
+ ) catch {
+ globalThis.throw("Out of memory", .{});
+ return .zero;
+ };
task.schedule();
- return task.promise.value().asObjectRef();
+ return task.promise.value();
}
pub fn transformSync(
this: *Transpiler,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) JSC.C.JSObjectRef {
- var args = JSC.Node.ArgumentsSlice.init(ctx.bunVM(), @ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]);
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
+ JSC.markBinding(@src());
+ var exception_value = [_]JSC.C.JSValueRef{null};
+ var exception: JSC.C.ExceptionRef = &exception_value;
+ const arguments = callframe.arguments(3);
+
+ var args = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments.ptr[0..arguments.len]);
defer args.arena.deinit();
const code_arg = args.next() orelse {
- JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception);
- return null;
+ globalThis.throwInvalidArgumentType("transformSync", "code", "string or Uint8Array");
+ return .zero;
};
var arena = Mimalloc.Arena.init() catch unreachable;
defer arena.deinit();
- const code_holder = JSC.Node.StringOrBuffer.fromJS(ctx.ptr(), arena.allocator(), code_arg, exception) orelse {
- if (exception.* == null) JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception);
- return null;
+ const code_holder = JSC.Node.StringOrBuffer.fromJS(globalThis, arena.allocator(), code_arg, exception) orelse {
+ globalThis.throwInvalidArgumentType("transformSync", "code", "string or Uint8Array");
+ return .zero;
};
const code = code_holder.slice();
- JSC.JSValue.c(arguments[0]).ensureStillAlive();
- defer JSC.JSValue.c(arguments[0]).ensureStillAlive();
+ arguments.ptr[0].ensureStillAlive();
+ defer arguments.ptr[0].ensureStillAlive();
args.eat();
var js_ctx_value: JSC.JSValue = JSC.JSValue.zero;
@@ -1034,7 +1036,7 @@ pub fn transformSync(
if (args.next()) |arg| {
args.eat();
if (arg.isNumber() or arg.isString()) {
- break :brk Loader.fromJS(ctx.ptr(), arg, exception);
+ break :brk Loader.fromJS(globalThis, arg, exception);
}
if (arg.isObject()) {
@@ -1050,8 +1052,8 @@ pub fn transformSync(
if (arg.isObject()) {
js_ctx_value = arg;
} else {
- JSC.throwInvalidArguments("Expected a Loader or object", .{}, ctx, exception);
- return null;
+ globalThis.throwInvalidArgumentType("transformSync", "context", "object or loader");
+ return .zero;
}
}
if (!js_ctx_value.isEmpty()) {
@@ -1064,7 +1066,10 @@ pub fn transformSync(
}
}
- if (exception.* != null) return null;
+ if (exception.* != null) {
+ globalThis.throwValue(JSC.JSValue.c(exception.*));
+ return .zero;
+ }
JSAst.Stmt.Data.Store.reset();
JSAst.Expr.Data.Store.reset();
@@ -1090,25 +1095,23 @@ pub fn transformSync(
if (comptime JSC.is_bindgen) Bundler.MacroJSValueType.zero else js_ctx_value,
) orelse {
if ((this.bundler.log.warnings + this.bundler.log.errors) > 0) {
- var out_exception = this.bundler.log.toJS(ctx.ptr(), getAllocator(ctx), "Parse error");
- exception.* = out_exception.asObjectRef();
- return null;
+ globalThis.throwValue(this.bundler.log.toJS(globalThis, globalThis.allocator(), "Parse error"));
+ return .zero;
}
- JSC.throwInvalidArguments("Failed to parse", .{}, ctx, exception);
- return null;
+ globalThis.throw("Failed to parse code", .{});
+ return .zero;
};
if ((this.bundler.log.warnings + this.bundler.log.errors) > 0) {
- var out_exception = this.bundler.log.toJS(ctx.ptr(), getAllocator(ctx), "Parse error");
- exception.* = out_exception.asObjectRef();
- return null;
+ globalThis.throwValue(this.bundler.log.toJS(globalThis, globalThis.allocator(), "Parse error"));
+ return .zero;
}
var buffer_writer = this.buffer_writer orelse brk: {
var writer = JSPrinter.BufferWriter.init(arena.backingAllocator()) catch {
- JSC.throwInvalidArguments("Failed to create BufferWriter", .{}, ctx, exception);
- return null;
+ globalThis.throw("Failed to create BufferWriter", .{});
+ return .zero;
};
writer.buffer.growIfNeeded(code.len) catch unreachable;
@@ -1123,18 +1126,16 @@ pub fn transformSync(
buffer_writer.reset();
var printer = JSPrinter.BufferPrinter.init(buffer_writer);
_ = this.bundler.print(parse_result, @TypeOf(&printer), &printer, .esm_ascii) catch |err| {
- JSC.JSError(bun.default_allocator, "Failed to print code: {s}", .{@errorName(err)}, ctx, exception);
-
- return null;
+ globalThis.throwError(err, "Failed to print code");
+ return .zero;
};
// TODO: benchmark if pooling this way is faster or moving is faster
buffer_writer = printer.ctx;
var out = JSC.ZigString.init(buffer_writer.written);
- out.mark();
out.setOutputEncoding();
- return out.toValueGC(ctx.ptr()).asObjectRef();
+ return out.toValueGC(globalThis);
}
fn namedExportsToJS(global: *JSGlobalObject, named_exports: JSAst.Ast.NamedExports) JSC.JSValue {
@@ -1169,8 +1170,8 @@ fn namedImportsToJS(
var allocator = stack_fallback.get();
var i: usize = 0;
- const path_label = JSC.ZigString.init("path");
- const kind_label = JSC.ZigString.init("kind");
+ const path_label = JSC.ZigString.static("path");
+ const kind_label = JSC.ZigString.static("kind");
var array_items = allocator.alloc(
JSC.C.JSValueRef,
import_records.len,
@@ -1182,7 +1183,7 @@ fn namedImportsToJS(
const path = JSC.ZigString.init(record.path.text).toValueGC(global);
const kind = JSC.ZigString.init(record.kind.label()).toValue(global);
- array_items[i] = JSC.JSValue.createObject2(global, &path_label, &kind_label, path, kind).asObjectRef();
+ array_items[i] = JSC.JSValue.createObject2(global, path_label, kind_label, path, kind).asObjectRef();
i += 1;
}
@@ -1191,39 +1192,47 @@ fn namedImportsToJS(
pub fn scanImports(
this: *Transpiler,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) JSC.C.JSObjectRef {
- var args = JSC.Node.ArgumentsSlice.init(ctx.bunVM(), @ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]);
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2);
+ var exception_val = [_]JSC.C.JSValueRef{null};
+ var exception: JSC.C.ExceptionRef = &exception_val;
+ var args = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments.ptr[0..arguments.len]);
const code_arg = args.next() orelse {
- JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception);
- return null;
+ globalThis.throwInvalidArgumentType("scanImports", "code", "string or Uint8Array");
+ return .zero;
};
- const code_holder = JSC.Node.StringOrBuffer.fromJS(ctx.ptr(), args.arena.allocator(), code_arg, exception) orelse {
- if (exception.* == null) JSC.throwInvalidArguments("Expected a string or Uint8Array", .{}, ctx, exception);
- return null;
+ const code_holder = JSC.Node.StringOrBuffer.fromJS(globalThis, args.arena.allocator(), code_arg, exception) orelse {
+ if (exception.* == null) {
+ globalThis.throwInvalidArgumentType("scanImports", "code", "string or Uint8Array");
+ } else {
+ globalThis.throwValue(JSC.JSValue.c(exception.*));
+ }
+
+ return .zero;
};
args.eat();
const code = code_holder.slice();
var loader: Loader = this.transpiler_options.default_loader;
if (args.next()) |arg| {
- if (Loader.fromJS(ctx.ptr(), arg, exception)) |_loader| {
+ if (Loader.fromJS(globalThis, arg, exception)) |_loader| {
loader = _loader;
}
args.eat();
}
if (!loader.isJavaScriptLike()) {
- JSC.throwInvalidArguments("Only JavaScript-like files support this fast path", .{}, ctx, exception);
- return null;
+ globalThis.throwInvalidArguments("Only JavaScript-like files support this fast path", .{});
+ return .zero;
}
- if (exception.* != null) return null;
+ if (exception.* != null) {
+ globalThis.throwValue(JSC.JSValue.c(exception.*));
+ return .zero;
+ }
var arena = Mimalloc.Arena.init() catch unreachable;
var prev_allocator = this.bundler.allocator;
@@ -1268,28 +1277,29 @@ pub fn scanImports(
) catch |err| {
defer this.scan_pass_result.reset();
if ((log.warnings + log.errors) > 0) {
- var out_exception = log.toJS(ctx.ptr(), getAllocator(ctx), "Failed to scan imports");
- exception.* = out_exception.asObjectRef();
- return null;
+ globalThis.throwValue(log.toJS(globalThis, globalThis.allocator(), "Failed to scan imports"));
+ return .zero;
}
- JSC.throwInvalidArguments("Failed to scan imports: {s}", .{@errorName(err)}, ctx, exception);
- return null;
+ globalThis.throwError(err, "Failed to scan imports");
+ return .zero;
};
defer this.scan_pass_result.reset();
if ((log.warnings + log.errors) > 0) {
- var out_exception = log.toJS(ctx.ptr(), getAllocator(ctx), "Failed to scan imports");
- exception.* = out_exception.asObjectRef();
- return null;
+ globalThis.throwValue(log.toJS(globalThis, globalThis.allocator(), "Failed to scan imports"));
+ return .zero;
}
const named_imports_value = namedImportsToJS(
- ctx.ptr(),
+ globalThis,
this.scan_pass_result.import_records.items,
exception,
);
- if (exception.* != null) return null;
- return named_imports_value.asObjectRef();
+ if (exception.* != null) {
+ globalThis.throwValue(JSC.JSValue.c(exception.*));
+ return .zero;
+ }
+ return named_imports_value;
}