aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/api/bun.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-08-18 19:58:03 -0700
committerGravatar GitHub <noreply@github.com> 2023-08-18 19:58:03 -0700
commit943a6642243cbc8a180ab7108279dd7110ab1eaf (patch)
tree3382acb2c41536e942b8bf09f5f9fd4c97e551f8 /src/bun.js/api/bun.zig
parentd0664f83773fc39b8bd6b9ecdfc52833c7ce6b81 (diff)
downloadbun-943a6642243cbc8a180ab7108279dd7110ab1eaf.tar.gz
bun-943a6642243cbc8a180ab7108279dd7110ab1eaf.tar.zst
bun-943a6642243cbc8a180ab7108279dd7110ab1eaf.zip
Remove most C API usages, add debugger pretty printers for `Headers`, `URLSearchParams`, `FormData`, `Worker`, `EventTarget` (#4187)
* Add pretty printers for `Headers`, `URLSearchParams`, and `FormData` * [untested] Add way to code generate getInternalProperties * bump * Bump Webkit * Ref the event loop while loaded * wip * checkpoint * another checkpoint * The code has been written * Fixup exports * Fix all the errors * Fix bug * [console.log] Fix bug when printing non-reified types missing values * Fix loading hash table * fix plugin * Fix ref & unref * auto-unref * various fixes * Update bun.zig * Set toStringTag * Delete code for macro JSX * Delete code for `bun dev` HTTP JS * Move Bun.serve to C++ API * Delete JSC C API code * :scissors: :skull: code * Use JSC C++ for `confirm`, `Crypto`, `prompt`, `alert` * more dead code * Update exports.zig * Use JSC C++ API for FFI * Remove remaining usages * Remove remaining usages * Update ffi.ts * Update InternalModuleRegistryConstants.h * draw the rest of the owl * Update webcore.zig * bind it * Fix performance regression in crypto.randomUIUD() * Update js_parser.zig --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js/api/bun.zig')
-rw-r--r--src/bun.js/api/bun.zig2038
1 files changed, 711 insertions, 1327 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig
index 7685b8f80..e98151fb1 100644
--- a/src/bun.js/api/bun.zig
+++ b/src/bun.js/api/bun.zig
@@ -1,3 +1,158 @@
+/// How to add a new function or property to the Bun global
+///
+/// - Add a callback or property to the below struct
+/// - @export it in the appropriate place
+/// - Update "@begin bunObjectTable" in BunObject.cpp
+/// - Update "BunObject+exports.h"
+/// - Run "make dev"
+///
+pub const BunObject = struct {
+ // --- Callbacks ---
+ pub const DO_NOT_USE_OR_YOU_WILL_BE_FIRED_mimalloc_dump = dump_mimalloc;
+ pub const _Os = Bun._Os;
+ pub const _Path = Bun._Path;
+ pub const allocUnsafe = Bun.allocUnsafe;
+ pub const build = Bun.JSBundler.buildFn;
+ pub const connect = JSC.wrapStaticMethod(JSC.API.Listener, "connect", false);
+ pub const deflateSync = JSC.wrapStaticMethod(JSZlib, "deflateSync", true);
+ pub const file = WebCore.Blob.constructFile;
+ pub const fs = Bun.fs;
+ pub const gc = Bun.runGC;
+ pub const generateHeapSnapshot = Bun.generateHeapSnapshot;
+ pub const getImportedStyles = Bun.getImportedStyles;
+ pub const getPublicPath = Bun.getPublicPathJS;
+ pub const gunzipSync = JSC.wrapStaticMethod(JSZlib, "gunzipSync", true);
+ pub const gzipSync = JSC.wrapStaticMethod(JSZlib, "gzipSync", true);
+ pub const indexOfLine = Bun.indexOfLine;
+ pub const inflateSync = JSC.wrapStaticMethod(JSZlib, "inflateSync", true);
+ pub const inspect = Bun.inspect;
+ pub const jest = @import("../test/jest.zig").Jest.call;
+ pub const listen = JSC.wrapStaticMethod(JSC.API.Listener, "listen", false);
+ pub const mmap = Bun.mmapFile;
+ pub const nanoseconds = Bun.nanoseconds;
+ pub const openInEditor = Bun.openInEditor;
+ pub const registerMacro = Bun.registerMacro;
+ pub const resolve = Bun.resolve;
+ pub const resolveSync = Bun.resolveSync;
+ pub const serve = Bun.serve;
+ pub const sha = JSC.wrapStaticMethod(Crypto.SHA512_256, "hash_", true);
+ pub const shrink = Bun.shrink;
+ pub const sleepSync = Bun.sleepSync;
+ pub const spawn = JSC.wrapStaticMethod(JSC.Subprocess, "spawn", false);
+ pub const spawnSync = JSC.wrapStaticMethod(JSC.Subprocess, "spawnSync", false);
+ pub const which = Bun.which;
+ pub const write = JSC.WebCore.Blob.writeFile;
+ // --- Callbacks ---
+
+ // --- Getters ---
+ pub const CryptoHasher = Crypto.CryptoHasher.getter;
+ pub const FFI = Bun.FFIObject.getter;
+ pub const FileSystemRouter = Bun.getFileSystemRouter;
+ pub const MD4 = Crypto.MD4.getter;
+ pub const MD5 = Crypto.MD5.getter;
+ pub const SHA1 = Crypto.SHA1.getter;
+ pub const SHA224 = Crypto.SHA224.getter;
+ pub const SHA256 = Crypto.SHA256.getter;
+ pub const SHA384 = Crypto.SHA384.getter;
+ pub const SHA512 = Crypto.SHA512.getter;
+ pub const SHA512_256 = Crypto.SHA512_256.getter;
+ pub const TOML = Bun.getTOMLObject;
+ pub const Transpiler = Bun.getTranspilerConstructor;
+ pub const argv = Bun.getArgv;
+ pub const assetPrefix = Bun.getAssetPrefix;
+ pub const cwd = Bun.getCWD;
+ pub const enableANSIColors = Bun.enableANSIColors;
+ pub const hash = Bun.getHashObject;
+ pub const main = Bun.getMain;
+ pub const origin = Bun.getOrigin;
+ pub const stderr = Bun.getStderr;
+ pub const stdin = Bun.getStdin;
+ pub const stdout = Bun.getStdout;
+ pub const unsafe = Bun.getUnsafe;
+ // --- Getters ---
+
+ fn getterName(comptime baseName: anytype) [:0]const u8 {
+ return "BunObject_getter_" ++ baseName;
+ }
+
+ fn callbackName(comptime baseName: anytype) [:0]const u8 {
+ return "BunObject_callback_" ++ baseName;
+ }
+
+ pub fn exportAll() void {
+ if (!@inComptime()) {
+ @compileError("Must be comptime");
+ }
+
+ if (JSC.is_bindgen) {
+ return;
+ }
+
+ // --- Getters ---
+ @export(BunObject.CryptoHasher, .{ .name = getterName("CryptoHasher") });
+ @export(BunObject.FFI, .{ .name = getterName("FFI") });
+ @export(BunObject.FileSystemRouter, .{ .name = getterName("FileSystemRouter") });
+ @export(BunObject.MD4, .{ .name = getterName("MD4") });
+ @export(BunObject.MD5, .{ .name = getterName("MD5") });
+ @export(BunObject.SHA1, .{ .name = getterName("SHA1") });
+ @export(BunObject.SHA224, .{ .name = getterName("SHA224") });
+ @export(BunObject.SHA256, .{ .name = getterName("SHA256") });
+ @export(BunObject.SHA384, .{ .name = getterName("SHA384") });
+ @export(BunObject.SHA512, .{ .name = getterName("SHA512") });
+ @export(BunObject.SHA512_256, .{ .name = getterName("SHA512_256") });
+ @export(BunObject.TOML, .{ .name = getterName("TOML") });
+ @export(BunObject.Transpiler, .{ .name = getterName("Transpiler") });
+ @export(BunObject.argv, .{ .name = getterName("argv") });
+ @export(BunObject.assetPrefix, .{ .name = getterName("assetPrefix") });
+ @export(BunObject.cwd, .{ .name = getterName("cwd") });
+ @export(BunObject.enableANSIColors, .{ .name = getterName("enableANSIColors") });
+ @export(BunObject.hash, .{ .name = getterName("hash") });
+ @export(BunObject.main, .{ .name = getterName("main") });
+ @export(BunObject.origin, .{ .name = getterName("origin") });
+ @export(BunObject.stderr, .{ .name = getterName("stderr") });
+ @export(BunObject.stdin, .{ .name = getterName("stdin") });
+ @export(BunObject.stdout, .{ .name = getterName("stdout") });
+ @export(BunObject.unsafe, .{ .name = getterName("unsafe") });
+ // --- Getters --
+
+ // -- Callbacks --
+ @export(BunObject.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_mimalloc_dump, .{ .name = callbackName("DO_NOT_USE_OR_YOU_WILL_BE_FIRED_mimalloc_dump") });
+ @export(BunObject._Os, .{ .name = callbackName("_Os") });
+ @export(BunObject._Path, .{ .name = callbackName("_Path") });
+ @export(BunObject.allocUnsafe, .{ .name = callbackName("allocUnsafe") });
+ @export(BunObject.build, .{ .name = callbackName("build") });
+ @export(BunObject.connect, .{ .name = callbackName("connect") });
+ @export(BunObject.deflateSync, .{ .name = callbackName("deflateSync") });
+ @export(BunObject.file, .{ .name = callbackName("file") });
+ @export(BunObject.fs, .{ .name = callbackName("fs") });
+ @export(BunObject.gc, .{ .name = callbackName("gc") });
+ @export(BunObject.generateHeapSnapshot, .{ .name = callbackName("generateHeapSnapshot") });
+ @export(BunObject.getImportedStyles, .{ .name = callbackName("getImportedStyles") });
+ @export(BunObject.gunzipSync, .{ .name = callbackName("gunzipSync") });
+ @export(BunObject.gzipSync, .{ .name = callbackName("gzipSync") });
+ @export(BunObject.indexOfLine, .{ .name = callbackName("indexOfLine") });
+ @export(BunObject.inflateSync, .{ .name = callbackName("inflateSync") });
+ @export(BunObject.inspect, .{ .name = callbackName("inspect") });
+ @export(BunObject.jest, .{ .name = callbackName("jest") });
+ @export(BunObject.listen, .{ .name = callbackName("listen") });
+ @export(BunObject.mmap, .{ .name = callbackName("mmap") });
+ @export(BunObject.nanoseconds, .{ .name = callbackName("nanoseconds") });
+ @export(BunObject.openInEditor, .{ .name = callbackName("openInEditor") });
+ @export(BunObject.registerMacro, .{ .name = callbackName("registerMacro") });
+ @export(BunObject.resolve, .{ .name = callbackName("resolve") });
+ @export(BunObject.resolveSync, .{ .name = callbackName("resolveSync") });
+ @export(BunObject.serve, .{ .name = callbackName("serve") });
+ @export(BunObject.sha, .{ .name = callbackName("sha") });
+ @export(BunObject.shrink, .{ .name = callbackName("shrink") });
+ @export(BunObject.sleepSync, .{ .name = callbackName("sleepSync") });
+ @export(BunObject.spawn, .{ .name = callbackName("spawn") });
+ @export(BunObject.spawnSync, .{ .name = callbackName("spawnSync") });
+ @export(BunObject.which, .{ .name = callbackName("which") });
+ @export(BunObject.write, .{ .name = callbackName("write") });
+ // -- Callbacks --
+ }
+};
+
const Bun = @This();
const default_allocator = @import("root").bun.default_allocator;
const bun = @import("root").bun;
@@ -41,15 +196,14 @@ const Request = WebCore.Request;
const Response = WebCore.Response;
const Headers = WebCore.Headers;
const Fetch = WebCore.Fetch;
-const FetchEvent = WebCore.FetchEvent;
const js = @import("root").bun.JSC.C;
const JSC = @import("root").bun.JSC;
const JSError = @import("../base.zig").JSError;
-const d = @import("../base.zig").d;
+
const MarkedArrayBuffer = @import("../base.zig").MarkedArrayBuffer;
const getAllocator = @import("../base.zig").getAllocator;
const JSValue = @import("root").bun.JSC.JSValue;
-const NewClass = @import("../base.zig").NewClass;
+
const Microtask = @import("root").bun.JSC.Microtask;
const JSGlobalObject = @import("root").bun.JSC.JSGlobalObject;
const ExceptionValueRef = @import("root").bun.JSC.ExceptionValueRef;
@@ -131,22 +285,16 @@ pub fn getCSSImports() []ZigString {
}
pub fn which(
- // this
- _: void,
- globalThis: js.JSContextRef,
- // function
- _: js.JSObjectRef,
- // thisObject
- _: js.JSObjectRef,
- arguments_: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) js.JSValueRef {
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
+ const arguments_ = callframe.arguments(2);
var path_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
- var arguments = JSC.Node.ArgumentsSlice.from(globalThis.bunVM(), arguments_);
+ var arguments = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments_.slice());
defer arguments.deinit();
const path_arg = arguments.nextEat() orelse {
- JSC.throwInvalidArguments("which: expected 1 argument, got 0", .{}, globalThis, exception);
- return JSC.JSValue.jsUndefined().asObjectRef();
+ globalThis.throw("which: expected 1 argument, got 0", .{});
+ return JSC.JSValue.jsUndefined();
};
var path_str: ZigString.Slice = ZigString.Slice.empty;
@@ -159,18 +307,18 @@ pub fn which(
}
if (path_arg.isEmptyOrUndefinedOrNull()) {
- return JSC.JSValue.jsNull().asObjectRef();
+ return JSC.JSValue.jsNull();
}
bin_str = path_arg.toSlice(globalThis, globalThis.bunVM().allocator);
if (bin_str.len >= bun.MAX_PATH_BYTES) {
- JSC.throwInvalidArguments("bin path is too long", .{}, globalThis, exception);
- return JSC.JSValue.jsUndefined().asObjectRef();
+ globalThis.throw("bin path is too long", .{});
+ return JSC.JSValue.jsUndefined();
}
if (bin_str.len == 0) {
- return JSC.JSValue.jsNull().asObjectRef();
+ return JSC.JSValue.jsNull();
}
path_str = ZigString.Slice.fromUTF8NeverFree(
@@ -198,32 +346,26 @@ pub fn which(
cwd_str.slice(),
bin_str.slice(),
)) |bin_path| {
- return ZigString.init(bin_path).withEncoding().toValueGC(globalThis).asObjectRef();
+ return ZigString.init(bin_path).withEncoding().toValueGC(globalThis);
}
- return JSC.JSValue.jsNull().asObjectRef();
+ return JSC.JSValue.jsNull();
}
pub fn inspect(
- // this
- _: void,
- ctx: js.JSContextRef,
- // function
- _: js.JSObjectRef,
- // thisObject
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(4).slice();
if (arguments.len == 0)
- return ZigString.Empty.toValue(ctx.ptr()).asObjectRef();
+ return bun.String.empty.toJSConst(globalThis);
for (arguments) |arg| {
- JSC.C.JSValueProtect(ctx, arg);
+ arg.protect();
}
defer {
for (arguments) |arg| {
- JSC.C.JSValueUnprotect(ctx, arg);
+ arg.unprotect();
}
}
@@ -235,18 +377,18 @@ pub fn inspect(
.quote_strings = true,
.ordered_properties = false,
};
- var value = JSC.JSValue.fromRef(arguments[0]);
+ const value = arguments[0];
if (arguments.len > 1) {
- var arg1: JSC.JSValue = JSC.JSValue.fromRef(arguments[1]);
+ const arg1 = arguments[1];
if (arg1.isObject()) {
- if (arg1.getTruthy(ctx, "depth")) |opt| {
+ if (arg1.getTruthy(globalThis, "depth")) |opt| {
if (opt.isInt32()) {
const arg = opt.toInt32();
if (arg < 0) {
- ctx.throwInvalidArguments("expected depth to be greater than or equal to 0, got {d}", .{arg});
- return null;
+ globalThis.throwInvalidArguments("expected depth to be greater than or equal to 0, got {d}", .{arg});
+ return .zero;
}
formatOptions.max_depth = @as(u16, @truncate(@as(u32, @intCast(@min(arg, std.math.maxInt(u16))))));
} else if (opt.isNumber()) {
@@ -254,26 +396,26 @@ pub fn inspect(
if (std.math.isInf(v)) {
formatOptions.max_depth = std.math.maxInt(u16);
} else {
- ctx.throwInvalidArguments("expected depth to be an integer, got {d}", .{v});
- return null;
+ globalThis.throwInvalidArguments("expected depth to be an integer, got {d}", .{v});
+ return .zero;
}
}
}
- if (arg1.getOptional(ctx, "colors", bool) catch return null) |opt| {
+ if (arg1.getOptional(globalThis, "colors", bool) catch return .zero) |opt| {
formatOptions.enable_colors = opt;
}
- if (arg1.getOptional(ctx, "sorted", bool) catch return null) |opt| {
+ if (arg1.getOptional(globalThis, "sorted", bool) catch return .zero) |opt| {
formatOptions.ordered_properties = opt;
}
} else {
// formatOptions.show_hidden = arg1.toBoolean();
if (arguments.len > 2) {
- var depthArg = JSC.JSValue.fromRef(arguments[1]);
+ var depthArg = arguments[1];
if (depthArg.isInt32()) {
const arg = depthArg.toInt32();
if (arg < 0) {
- ctx.throwInvalidArguments("expected depth to be greater than or equal to 0, got {d}", .{arg});
- return null;
+ globalThis.throwInvalidArguments("expected depth to be greater than or equal to 0, got {d}", .{arg});
+ return .zero;
}
formatOptions.max_depth = @as(u16, @truncate(@as(u32, @intCast(@min(arg, std.math.maxInt(u16))))));
} else if (depthArg.isNumber()) {
@@ -281,19 +423,19 @@ pub fn inspect(
if (std.math.isInf(v)) {
formatOptions.max_depth = std.math.maxInt(u16);
} else {
- ctx.throwInvalidArguments("expected depth to be an integer, got {d}", .{v});
- return null;
+ globalThis.throwInvalidArguments("expected depth to be an integer, got {d}", .{v});
+ return .zero;
}
}
if (arguments.len > 3) {
- formatOptions.enable_colors = JSC.JSValue.fromRef(arguments[2]).toBoolean();
+ formatOptions.enable_colors = arguments[2].toBoolean();
}
}
}
}
// very stable memory address
- var array = MutableString.init(getAllocator(ctx), 0) catch unreachable;
+ var array = MutableString.init(getAllocator(globalThis), 0) catch unreachable;
var buffered_writer_ = MutableString.BufferedWriter{ .context = &array };
var buffered_writer = &buffered_writer_;
@@ -303,7 +445,7 @@ pub fn inspect(
// when it's under 4096, we want to avoid the dynamic allocation
ZigConsoleClient.format(
.Debug,
- ctx.ptr(),
+ globalThis,
@as([*]const JSValue, @ptrCast(&value)),
1,
Writer,
@@ -312,390 +454,136 @@ pub fn inspect(
formatOptions,
);
buffered_writer.flush() catch {
- return JSC.C.JSValueMakeUndefined(ctx);
+ return .undefined;
};
// we are going to always clone to keep things simple for now
// the common case here will be stack-allocated, so it should be fine
var out = ZigString.init(array.toOwnedSliceLeaky()).withEncoding();
- const ret = out.toValueGC(ctx);
+ const ret = out.toValueGC(globalThis);
array.deinit();
- return ret.asObjectRef();
-
- // // when it's a small thing, rely on GC to manage the memory
- // if (writer.context.pos < 2048 and array.list.items.len == 0) {
- // var slice = writer.context.buffer[0..writer.context.pos];
- // if (slice.len == 0) {
- // return ZigString.Empty.toValue(ctx.ptr()).asObjectRef();
- // }
-
- // var zig_str =
- // return zig_str.toValueGC(ctx.ptr()).asObjectRef();
- // }
-
- // // when it's a big thing, we will manage it
- // {
- // writer.context.flush() catch {};
- // var slice =try writer.context.context.toOwnedSlice();
-
- // var zig_str = ZigString.init(slice).withEncoding();
- // if (!zig_str.isUTF8()) {
- // return zig_str.toExternalValue(ctx.ptr()).asObjectRef();
- // } else {
- // return zig_str.toValueGC(ctx.ptr()).asObjectRef();
- // }
- // }
+ return ret;
}
pub fn registerMacro(
- // this
- _: void,
- ctx: js.JSContextRef,
- // function
- _: js.JSObjectRef,
- // thisObject
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) js.JSValueRef {
- if (arguments.len != 2 or !js.JSValueIsNumber(ctx, arguments[0])) {
- JSError(getAllocator(ctx), "Internal error registering macros: invalid args", .{}, ctx, exception);
- return js.JSValueMakeUndefined(ctx);
+ globalObject: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
+ const arguments_ = callframe.arguments(2);
+ const arguments = arguments_.slice();
+ if (arguments.len != 2 or !arguments[0].isNumber()) {
+ globalObject.throwInvalidArguments("Internal error registering macros: invalid args", .{});
+ return .undefined;
}
- // TODO: make this faster
- const id = @as(i32, @truncate(@as(i64, @intFromFloat(js.JSValueToNumber(ctx, arguments[0], exception)))));
+ const id = arguments[0].toInt32();
if (id == -1 or id == 0) {
- JSError(getAllocator(ctx), "Internal error registering macros: invalid id", .{}, ctx, exception);
- return js.JSValueMakeUndefined(ctx);
+ globalObject.throwInvalidArguments("Internal error registering macros: invalid id", .{});
+ return .undefined;
}
- if (!arguments[1].?.value().isCell() or !arguments[1].?.value().isCallable(ctx.vm())) {
- JSError(getAllocator(ctx), "Macro must be a function. Received: {s}", .{@tagName(js.JSValueGetType(ctx, arguments[1]))}, ctx, exception);
- return js.JSValueMakeUndefined(ctx);
+ if (!arguments[1].isCell() or !arguments[1].isCallable(globalObject.vm())) {
+ // TODO: add "toTypeOf" helper
+ globalObject.throw("Macro must be a function", .{});
+ return .undefined;
}
var get_or_put_result = VirtualMachine.get().macros.getOrPut(id) catch unreachable;
if (get_or_put_result.found_existing) {
- js.JSValueUnprotect(ctx, get_or_put_result.value_ptr.*);
+ get_or_put_result.value_ptr.*.?.value().unprotect();
}
- js.JSValueProtect(ctx, arguments[1]);
- get_or_put_result.value_ptr.* = arguments[1];
+ arguments[1].protect();
+ get_or_put_result.value_ptr.* = arguments[1].asObjectRef();
- return js.JSValueMakeUndefined(ctx);
+ return .undefined;
}
pub fn getCWD(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- return ZigString.init(VirtualMachine.get().bundler.fs.top_level_dir).toValue(ctx.ptr()).asRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ return ZigString.init(VirtualMachine.get().bundler.fs.top_level_dir).toValueGC(globalThis);
}
pub fn getOrigin(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- return ZigString.init(VirtualMachine.get().origin.origin).toValue(ctx.ptr()).asRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ return ZigString.init(VirtualMachine.get().origin.origin).toValueGC(globalThis);
}
pub fn getStdin(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- var existing = ctx.ptr().getCachedObject(ZigString.static("BunSTDIN"));
- if (existing.isEmpty()) {
- var rare_data = JSC.VirtualMachine.get().rareData();
- var store = rare_data.stdin();
- var blob = bun.default_allocator.create(JSC.WebCore.Blob) catch unreachable;
- blob.* = JSC.WebCore.Blob.initWithStore(store, ctx.ptr());
-
- return ctx.ptr().putCachedObject(
- ZigString.static("BunSTDIN"),
- blob.toJS(ctx),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ var rare_data = globalThis.bunVM().rareData();
+ var store = rare_data.stdin();
+ store.ref();
+ var blob = bun.default_allocator.create(JSC.WebCore.Blob) catch unreachable;
+ blob.* = JSC.WebCore.Blob.initWithStore(store, globalThis);
+ return blob.toJS(globalThis);
}
pub fn getStderr(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- var existing = ctx.ptr().getCachedObject(ZigString.static("BunSTDERR"));
- if (existing.isEmpty()) {
- var rare_data = JSC.VirtualMachine.get().rareData();
- var store = rare_data.stderr();
- var blob = bun.default_allocator.create(JSC.WebCore.Blob) catch unreachable;
- blob.* = JSC.WebCore.Blob.initWithStore(store, ctx.ptr());
-
- return ctx.ptr().putCachedObject(
- ZigString.static("BunSTDERR"),
- blob.toJS(ctx),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ var rare_data = globalThis.bunVM().rareData();
+ var store = rare_data.stderr();
+ store.ref();
+ var blob = bun.default_allocator.create(JSC.WebCore.Blob) catch unreachable;
+ blob.* = JSC.WebCore.Blob.initWithStore(store, globalThis);
+ return blob.toJS(globalThis);
}
pub fn getStdout(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- var existing = ctx.ptr().getCachedObject(ZigString.static("BunSTDOUT"));
- if (existing.isEmpty()) {
- var rare_data = JSC.VirtualMachine.get().rareData();
- var store = rare_data.stdout();
- var blob = bun.default_allocator.create(JSC.WebCore.Blob) catch unreachable;
- blob.* = JSC.WebCore.Blob.initWithStore(store, ctx.ptr());
-
- return ctx.ptr().putCachedObject(
- &ZigString.init("BunSTDOUT"),
- blob.toJS(ctx),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ var rare_data = globalThis.bunVM().rareData();
+ var store = rare_data.stdout();
+ store.ref();
+ var blob = bun.default_allocator.create(JSC.WebCore.Blob) catch unreachable;
+ blob.* = JSC.WebCore.Blob.initWithStore(store, globalThis);
+ return blob.toJS(globalThis);
}
pub fn enableANSIColors(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- return js.JSValueMakeBoolean(ctx, Output.enable_ansi_colors);
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ _ = globalThis;
+ return JSValue.jsBoolean(Output.enable_ansi_colors);
}
pub fn getMain(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- return ZigString.init(VirtualMachine.get().main).toValue(ctx.ptr()).asRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ return ZigString.init(globalThis.bunVM().main).toValueGC(globalThis);
}
pub fn getAssetPrefix(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- return ZigString.init(VirtualMachine.get().bundler.options.routes.asset_prefix_path).toValueGC(ctx.ptr()).asRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ return ZigString.init(VirtualMachine.get().bundler.options.routes.asset_prefix_path).toValueGC(globalThis);
}
pub fn getArgv(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- // TODO: cache this
- return JSC.Node.Process.getArgv(ctx).asObjectRef();
-}
-
-pub fn getRoutesDir(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- if (!VirtualMachine.get().bundler.options.routes.routes_enabled or VirtualMachine.get().bundler.options.routes.dir.len == 0) {
- return js.JSValueMakeUndefined(ctx);
- }
-
- return ZigString.init(VirtualMachine.get().bundler.options.routes.dir).toValue(ctx.ptr()).asRef();
-}
-
-pub fn getFilePath(ctx: js.JSContextRef, arguments: []const js.JSValueRef, buf: []u8, exception: js.ExceptionRef) ?string {
- if (arguments.len != 1) {
- JSError(getAllocator(ctx), "Expected a file path as a string or an array of strings to be part of a file path.", .{}, ctx, exception);
- return null;
- }
-
- const value = arguments[0];
- if (JSC.JSValue.c(value).isString()) {
- const out = JSC.JSValue.c(value).toSlice(ctx, bun.default_allocator);
- defer out.deinit();
-
- // The dots are kind of unnecessary. They'll be normalized.
- if (out.len == 0 or std.mem.eql(u8, out.slice(), "..") or std.mem.eql(u8, out.slice(), "../")) {
- JSError(getAllocator(ctx), "Expected a file path as a string or an array of strings to be part of a file path.", .{}, ctx, exception);
- return null;
- }
-
- var parts = [_]string{out.slice()};
- // This does the equivalent of Node's path.normalize(path.join(cwd, out_slice))
- var res = VirtualMachine.get().bundler.fs.absBuf(&parts, buf);
-
- return res;
- } else if (js.JSValueIsArray(ctx, value)) {
- var temp_strings_list: [32]string = undefined;
- var temp_strings_list_len: u8 = 0;
- defer {
- for (temp_strings_list[0..temp_strings_list_len], 0..) |_, i| {
- temp_strings_list[i] = "";
- }
- }
-
- var iter = JSValue.fromRef(value).arrayIterator(ctx.ptr());
- while (iter.next()) |item| {
- if (temp_strings_list_len >= temp_strings_list.len) {
- break;
- }
-
- if (!item.isString()) {
- JSError(getAllocator(ctx), "Expected a file path as a string or an array of strings to be part of a file path.", .{}, ctx, exception);
- return null;
- }
-
- const out = JSC.JSValue.c(value).toSlice(ctx, bun.default_allocator);
- defer out.deinit();
-
- // The dots are kind of unnecessary. They'll be normalized.
- if (out.len == 0 or std.mem.eql(u8, out.slice(), "..") or std.mem.eql(u8, out.slice(), "../")) {
- JSError(getAllocator(ctx), "Expected a file path as a string or an array of strings to be part of a file path.", .{}, ctx, exception);
- return null;
- }
-
- const out_slice = out.slice();
-
- temp_strings_list[temp_strings_list_len] = out_slice;
- // The dots are kind of unnecessary. They'll be normalized.
- if (out.len == 0 or @intFromPtr(out.ptr) == 0 or std.mem.eql(u8, out_slice, ".") or std.mem.eql(u8, out_slice, "..") or std.mem.eql(u8, out_slice, "../")) {
- JSError(getAllocator(ctx), "Expected a file path as a string or an array of strings to be part of a file path.", .{}, ctx, exception);
- return null;
- }
- temp_strings_list_len += 1;
- }
-
- if (temp_strings_list_len == 0) {
- JSError(getAllocator(ctx), "Expected a file path as a string or an array of strings to be part of a file path.", .{}, ctx, exception);
- return null;
- }
-
- return VirtualMachine.get().bundler.fs.absBuf(temp_strings_list[0..temp_strings_list_len], buf);
- } else {
- JSError(getAllocator(ctx), "Expected a file path as a string or an array of strings to be part of a file path.", .{}, ctx, exception);
- return null;
- }
-}
-
-pub fn getImportedStyles(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- _: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- defer flushCSSImports();
- const styles = getCSSImports();
- if (styles.len == 0) {
- return js.JSObjectMakeArray(ctx, 0, null, null);
- }
-
- return JSValue.createStringArray(ctx.ptr(), styles.ptr, styles.len, true).asRef();
-}
-
-pub fn newOs(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- _: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- return Node.Os.create(ctx.ptr()).asObjectRef();
-}
-
-pub fn newPath(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- args: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- const is_windows = args.len == 1 and JSValue.fromRef(args[0]).toBoolean();
- return Node.Path.create(ctx.ptr(), is_windows).asObjectRef();
-}
-
-pub fn getRouteFiles(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- _: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- if (VirtualMachine.get().bundler.router == null) return js.JSObjectMakeArray(ctx, 0, null, null);
-
- const router = &VirtualMachine.get().bundler.router.?;
- const list = router.getPublicPaths() catch unreachable;
-
- for (routes_list_strings[0..@min(list.len, routes_list_strings.len)], 0..) |_, i| {
- routes_list_strings[i] = ZigString.init(list[i]);
- }
-
- const ref = JSValue.createStringArray(ctx.ptr(), &routes_list_strings, list.len, true).asRef();
- return ref;
-}
-
-pub fn getRouteNames(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- _: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- if (VirtualMachine.get().bundler.router == null) return js.JSObjectMakeArray(ctx, 0, null, null);
-
- const router = &VirtualMachine.get().bundler.router.?;
- const list = router.getNames() catch unreachable;
-
- for (routes_list_strings[0..@min(list.len, routes_list_strings.len)], 0..) |_, i| {
- routes_list_strings[i] = ZigString.init(list[i]);
- }
-
- const ref = JSValue.createStringArray(ctx.ptr(), &routes_list_strings, list.len, true).asRef();
- return ref;
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ return JSC.Node.Process.getArgv(globalThis);
}
const Editor = @import("../../open.zig").Editor;
pub fn openInEditor(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- args: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) js.JSValueRef {
+ globalThis: js.JSContextRef,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSValue {
var edit = &VirtualMachine.get().rareData().editor_context;
-
- var arguments = JSC.Node.ArgumentsSlice.from(ctx.bunVM(), args);
+ const args = callframe.arguments(4);
+ var arguments = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), args.slice());
defer arguments.deinit();
var path: string = "";
var editor_choice: ?Editor = null;
@@ -703,13 +591,13 @@ pub fn openInEditor(
var column: ?string = null;
if (arguments.nextEat()) |file_path_| {
- path = file_path_.toSlice(ctx.ptr(), bun.default_allocator).slice();
+ path = file_path_.toSlice(globalThis, arguments.arena.allocator()).slice();
}
if (arguments.nextEat()) |opts| {
if (!opts.isUndefinedOrNull()) {
- if (opts.getTruthy(ctx.ptr(), "editor")) |editor_val| {
- var sliced = editor_val.toSlice(ctx.ptr(), bun.default_allocator);
+ if (opts.getTruthy(globalThis, "editor")) |editor_val| {
+ var sliced = editor_val.toSlice(globalThis, arguments.arena.allocator());
var prev_name = edit.name;
if (!strings.eqlLong(prev_name, sliced.slice(), true)) {
@@ -719,21 +607,21 @@ pub fn openInEditor(
editor_choice = edit.editor;
if (editor_choice == null) {
edit.* = prev;
- JSError(getAllocator(ctx), "Could not find editor \"{s}\"", .{sliced.slice()}, ctx, exception);
- return js.JSValueMakeUndefined(ctx);
+ globalThis.throw("Could not find editor \"{s}\"", .{sliced.slice()});
+ return .undefined;
} else if (edit.name.ptr == edit.path.ptr) {
- edit.name = bun.default_allocator.dupe(u8, edit.path) catch unreachable;
+ edit.name = arguments.arena.allocator().dupe(u8, edit.path) catch unreachable;
edit.path = edit.path;
}
}
}
- if (opts.getTruthy(ctx.ptr(), "line")) |line_| {
- line = line_.toSlice(ctx.ptr(), bun.default_allocator).slice();
+ if (opts.getTruthy(globalThis, "line")) |line_| {
+ line = line_.toSlice(globalThis, arguments.arena.allocator()).slice();
}
- if (opts.getTruthy(ctx.ptr(), "column")) |column_| {
- column = column_.toSlice(ctx.ptr(), bun.default_allocator).slice();
+ if (opts.getTruthy(globalThis, "column")) |column_| {
+ column = column_.toSlice(globalThis, arguments.arena.allocator()).slice();
}
}
}
@@ -741,24 +629,24 @@ pub fn openInEditor(
const editor = editor_choice orelse edit.editor orelse brk: {
edit.autoDetectEditor(VirtualMachine.get().bundler.env);
if (edit.editor == null) {
- JSC.JSError(bun.default_allocator, "Failed to auto-detect editor", .{}, ctx, exception);
- return null;
+ globalThis.throw("Failed to auto-detect editor", .{});
+ return .zero;
}
break :brk edit.editor.?;
};
if (path.len == 0) {
- JSError(getAllocator(ctx), "No file path specified", .{}, ctx, exception);
- return js.JSValueMakeUndefined(ctx);
+ globalThis.throw("No file path specified", .{});
+ return .zero;
}
- editor.open(edit.path, path, line, column, bun.default_allocator) catch |err| {
- JSC.JSError(bun.default_allocator, "Opening editor failed {s}", .{@errorName(err)}, ctx, exception);
- return null;
+ editor.open(edit.path, path, line, column, arguments.arena.allocator()) catch |err| {
+ globalThis.throw("Opening editor failed {s}", .{@errorName(err)});
+ return .zero;
};
- return JSC.JSValue.jsUndefined().asObjectRef();
+ return JSC.JSValue.jsUndefined();
}
pub fn getPublicPath(to: string, origin: URL, comptime Writer: type, writer: Writer) void {
@@ -794,117 +682,72 @@ pub fn getPublicPathWithAssetPrefix(to: string, dir: string, origin: URL, asset_
}
}
-pub fn sleepSync(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- // This function always returns undefined
- const ret = js.JSValueMakeUndefined(ctx);
+pub fn sleepSync(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(1);
// Expect at least one argument. We allow more than one but ignore them; this
// is useful for supporting things like `[1, 2].map(sleepSync)`
if (arguments.len < 1) {
- ctx.throwInvalidArguments("expected one argument, got {}", .{arguments.len});
- return ret;
+ globalObject.throwNotEnoughArguments("sleepSync", 1, 0);
+ return .undefined;
}
- const arg = JSValue.fromRef(arguments[0]);
+ const arg = arguments.slice()[0];
// The argument must be a number
if (!arg.isNumber()) {
- ctx.throwInvalidArguments("argument to sleepSync must be a number, got {}", .{arg.jsTypeLoose()});
- return ret;
+ globalObject.throwInvalidArgumentType("sleepSync", "milliseconds", "number");
+ return .undefined;
}
//NOTE: if argument is > max(i32) then it will be truncated
- const milliseconds = arg.coerce(i32, ctx);
+ const milliseconds = arg.coerce(i32, globalObject);
if (milliseconds < 0) {
- ctx.throwInvalidArguments("argument to sleepSync must not be negative, got {}", .{milliseconds});
- return ret;
+ globalObject.throwInvalidArguments("argument to sleepSync must not be negative, got {d}", .{milliseconds});
+ return .undefined;
}
std.time.sleep(@as(u64, @intCast(milliseconds)) * std.time.ns_per_ms);
- return ret;
-}
-
-pub fn createNodeFS(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- _: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- var module = ctx.allocator().create(JSC.Node.NodeJSFS) catch unreachable;
- module.* = .{};
- var vm = ctx.bunVM();
- if (vm.standalone_module_graph != null)
- module.node_fs.vm = vm;
-
- return module.toJS(ctx).asObjectRef();
+ return .undefined;
}
-pub fn generateHeapSnapshot(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- _: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- return ctx.ptr().generateHeapSnapshot().asObjectRef();
+pub fn generateHeapSnapshot(globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ return globalObject.generateHeapSnapshot();
}
-pub fn runGC(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- return ctx.bunVM().garbageCollect(arguments.len > 0 and JSC.JSValue.c(arguments[0]).toBoolean()).asObjectRef();
+pub fn runGC(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments_ = callframe.arguments(1);
+ const arguments = arguments_.slice();
+ return globalObject.bunVM().garbageCollect(arguments.len > 0 and arguments[0].isBoolean() and arguments[0].toBoolean());
}
-
-pub fn shrink(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- _: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- ctx.ptr().vm().shrinkFootprint();
- return JSValue.jsUndefined().asRef();
+pub fn shrink(globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ globalObject.vm().shrinkFootprint();
+ return .undefined;
}
fn doResolve(
- ctx: js.JSContextRef,
- arguments: []const js.JSValueRef,
+ globalThis: *JSC.JSGlobalObject,
+ arguments: []const JSValue,
exception: js.ExceptionRef,
) ?JSC.JSValue {
- var args = JSC.Node.ArgumentsSlice.from(ctx.bunVM(), arguments);
+ var args = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments);
defer args.deinit();
const specifier = args.protectEatNext() orelse {
- JSC.throwInvalidArguments("Expected a specifier and a from path", .{}, ctx, exception);
+ JSC.throwInvalidArguments("Expected a specifier and a from path", .{}, globalThis, exception);
return null;
};
if (specifier.isUndefinedOrNull()) {
- JSC.throwInvalidArguments("specifier must be a string", .{}, ctx, exception);
+ JSC.throwInvalidArguments("specifier must be a string", .{}, globalThis, exception);
return null;
}
const from = args.protectEatNext() orelse {
- JSC.throwInvalidArguments("Expected a from path", .{}, ctx, exception);
+ JSC.throwInvalidArguments("Expected a from path", .{}, globalThis, exception);
return null;
};
if (from.isUndefinedOrNull()) {
- JSC.throwInvalidArguments("from must be a string", .{}, ctx, exception);
+ JSC.throwInvalidArguments("from must be a string", .{}, globalThis, exception);
return null;
}
@@ -913,12 +756,12 @@ fn doResolve(
if (next.isBoolean()) {
is_esm = next.toBoolean();
} else {
- JSC.throwInvalidArguments("esm must be a boolean", .{}, ctx, exception);
+ JSC.throwInvalidArguments("esm must be a boolean", .{}, globalThis, exception);
return null;
}
}
- return doResolveWithArgs(ctx, specifier.toBunString(ctx.ptr()), from.toBunString(ctx.ptr()), exception, is_esm, false);
+ return doResolveWithArgs(globalThis, specifier.toBunString(globalThis), from.toBunString(globalThis), exception, is_esm, false);
}
fn doResolveWithArgs(
@@ -976,32 +819,27 @@ fn doResolveWithArgs(
return errorable.result.value.toJS(ctx);
}
-pub fn resolveSync(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) js.JSValueRef {
- const value = doResolve(ctx, arguments, exception) orelse return null;
- return value.asObjectRef();
+pub fn resolveSync(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ var exception_ = [1]JSC.JSValueRef{null};
+ var exception = &exception_;
+ const arguments = callframe.arguments(3);
+ const result = doResolve(globalObject, arguments.slice(), exception);
+
+ if (exception_[0] != null) {
+ globalObject.throwValue(exception_[0].?.value());
+ }
+
+ return result orelse .zero;
}
-pub fn resolve(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) js.JSValueRef {
- const value = doResolve(ctx, arguments, exception) orelse {
- var exception_value = exception.*.?;
- exception.* = null;
- return JSC.JSPromise.rejectedPromiseValue(ctx.ptr(), JSC.JSValue.fromRef(exception_value)).asObjectRef();
+pub fn resolve(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ var exception_ = [1]JSC.JSValueRef{null};
+ var exception = &exception_;
+ const arguments = callframe.arguments(3);
+ const value = doResolve(globalObject, arguments.slice(), exception) orelse {
+ return JSC.JSPromise.rejectedPromiseValue(globalObject, exception_[0].?.value());
};
- return JSC.JSPromise.resolvedPromiseValue(ctx.ptr(), value).asObjectRef();
+ return JSC.JSPromise.resolvedPromiseValue(globalObject, value);
}
export fn Bun__resolve(
@@ -1013,7 +851,7 @@ export fn Bun__resolve(
var exception_ = [1]JSC.JSValueRef{null};
var exception = &exception_;
const value = doResolveWithArgs(global, specifier.toBunString(global), source.toBunString(global), exception, is_esm, true) orelse {
- return JSC.JSPromise.rejectedPromiseValue(global, JSC.JSValue.fromRef(exception[0]));
+ return JSC.JSPromise.rejectedPromiseValue(global, exception_[0].?.value());
};
return JSC.JSPromise.resolvedPromiseValue(global, value);
}
@@ -1052,278 +890,68 @@ comptime {
}
}
-var public_path_temp_str: [bun.MAX_PATH_BYTES]u8 = undefined;
-
-pub fn getPublicPathJS(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- var zig_str: ZigString = ZigString.Empty;
- JSValue.toZigString(JSValue.fromRef(arguments[0]), &zig_str, ctx.ptr());
-
- const to = zig_str.slice();
+pub fn getPublicPathJS(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(1).slice();
+ if (arguments.len < 1) {
+ return bun.String.empty.toJSConst(globalObject);
+ }
+ var public_path_temp_str: [bun.MAX_PATH_BYTES]u8 = undefined;
+ const to = arguments[0].toSlice(globalObject, bun.default_allocator);
+ defer to.deinit();
var stream = std.io.fixedBufferStream(&public_path_temp_str);
var writer = stream.writer();
- getPublicPath(to, VirtualMachine.get().origin, @TypeOf(&writer), &writer);
+ getPublicPath(to.slice(), VirtualMachine.get().origin, @TypeOf(&writer), &writer);
- return ZigString.init(stream.buffer[0..stream.pos]).toValueGC(ctx.ptr()).asObjectRef();
+ return ZigString.init(stream.buffer[0..stream.pos]).toValueGC(globalObject);
}
-pub const Class = NewClass(
- void,
- .{
- .name = "Bun",
- .read_only = true,
- },
- .{
- // Private
- // TODO: We should remove _Os, _Path, and make registerMacro and fs be private builtins
- .DO_NOT_USE_OR_YOU_WILL_BE_FIRED_mimalloc_dump = .{
- .rfn = &dump_mimalloc,
- .enumerable = false,
- },
- ._Os = .{
- .rfn = &Bun.newOs,
- .enumerable = false,
- },
- ._Path = .{
- .rfn = &Bun.newPath,
- .enumerable = false,
- },
- .registerMacro = .{
- .rfn = &Bun.registerMacro,
- .enumerable = false,
- },
- .fs = .{
- .rfn = &Bun.createNodeFS,
- .enumerable = false,
- },
- .jest = .{
- .rfn = &@import("../test/jest.zig").Jest.call,
- .enumerable = false,
- },
+fn fs(globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ var module = globalObject.allocator().create(JSC.Node.NodeJSFS) catch unreachable;
+ module.* = .{};
+ var vm = globalObject.bunVM();
+ if (vm.standalone_module_graph != null)
+ module.node_fs.vm = vm;
- // TODO: remove these deprecated methods before 1.0
- .getImportedStyles = .{
- .rfn = &Bun.getImportedStyles,
- .enumerable = false,
- },
- .getRouteFiles = .{
- .rfn = &Bun.getRouteFiles,
- .enumerable = false,
- },
- .match = .{
- .rfn = &Router.deprecatedBunGlobalMatch,
- .enumerable = false,
- },
- .getRouteNames = .{
- .rfn = &Bun.getRouteNames,
- .enumerable = false,
- },
+ return module.toJS(globalObject);
+}
- // Public API
- .sleepSync = .{
- .rfn = &sleepSync,
- },
- // .fetch = .{
- // .rfn = &Fetch.call,
- // },
- .inspect = .{
- .rfn = &Bun.inspect,
- },
- .resolveSync = .{
- .rfn = &Bun.resolveSync,
- },
- .resolve = .{
- .rfn = &Bun.resolve,
- },
- .getPublicPath = .{
- .rfn = &Bun.getPublicPathJS,
- },
- .indexOfLine = .{
- .rfn = &Bun.indexOfLine,
- },
- .gc = .{
- .rfn = &Bun.runGC,
- },
- .allocUnsafe = .{
- .rfn = &Bun.allocUnsafe,
- },
- .mmap = .{
- .rfn = &Bun.mmapFile,
- },
- .generateHeapSnapshot = .{
- .rfn = &Bun.generateHeapSnapshot,
- },
- .shrink = .{
- .rfn = &Bun.shrink,
- },
- .openInEditor = .{
- .rfn = &Bun.openInEditor,
- },
- .serve = .{
- .rfn = &Bun.serve,
- },
- .file = .{
- .rfn = &JSC.WebCore.Blob.constructFile,
- },
- .write = .{
- .rfn = &JSC.WebCore.Blob.writeFile,
- },
- .sha = .{
- .rfn = &JSC.wrapWithHasContainer(Crypto.SHA512_256, "hash_", false, false, true),
- },
- .nanoseconds = .{
- .rfn = &nanoseconds,
- },
- .gzipSync = .{
- .rfn = &JSC.wrapWithHasContainer(JSZlib, "gzipSync", false, false, true),
- },
- .deflateSync = .{
- .rfn = &JSC.wrapWithHasContainer(JSZlib, "deflateSync", false, false, true),
- },
- .gunzipSync = .{
- .rfn = &JSC.wrapWithHasContainer(JSZlib, "gunzipSync", false, false, true),
- },
- .inflateSync = .{
- .rfn = &JSC.wrapWithHasContainer(JSZlib, "inflateSync", false, false, true),
- },
- .which = .{
- .rfn = &which,
- },
- .spawn = .{
- .rfn = &JSC.wrapWithHasContainer(JSC.Subprocess, "spawn", false, false, false),
- },
- .spawnSync = .{
- .rfn = &JSC.wrapWithHasContainer(JSC.Subprocess, "spawnSync", false, false, false),
- },
- .build = .{
- .rfn = &Bun.JSBundler.buildFn,
- },
- .listen = .{
- .rfn = &JSC.wrapWithHasContainer(JSC.API.Listener, "listen", false, false, false),
- },
- .connect = .{
- .rfn = &JSC.wrapWithHasContainer(JSC.API.Listener, "connect", false, false, false),
- },
- },
- .{
- .main = .{
- .get = getMain,
- },
- // TODO: decide what we want to do
- .cwd = .{
- .get = getCWD,
- .enumerable = false,
- },
- .origin = .{
- .get = getOrigin,
- },
- .stdin = .{
- .get = getStdin,
- },
- .stdout = .{
- .get = getStdout,
- },
- .stderr = .{
- .get = getStderr,
- },
- // TODO: remove this before 1.0
- .routesDir = .{
- .get = getRoutesDir,
- .enumerable = false,
- },
- // TODO: remove this before 1.0
- .assetPrefix = .{
- .get = getAssetPrefix,
- .enumerable = false,
- },
- .argv = .{
- .get = getArgv,
- },
- .enableANSIColors = .{
- .get = enableANSIColors,
- },
- .Transpiler = .{
- .get = getTranspilerConstructor,
- },
- .hash = .{
- .get = getHashObject,
- },
- .TOML = .{
- .get = getTOMLObject,
- },
- .unsafe = .{
- .get = getUnsafe,
- },
- .SHA1 = .{
- .get = Crypto.SHA1.getter,
- },
- .MD5 = .{
- .get = Crypto.MD5.getter,
- },
- .MD4 = .{
- .get = Crypto.MD4.getter,
- },
- .SHA224 = .{
- .get = Crypto.SHA224.getter,
- },
- .SHA512 = .{
- .get = Crypto.SHA512.getter,
- },
- .SHA384 = .{
- .get = Crypto.SHA384.getter,
- },
- .SHA256 = .{
- .get = Crypto.SHA256.getter,
- },
- .SHA512_256 = .{
- .get = Crypto.SHA512_256.getter,
- },
- .CryptoHasher = .{
- .get = Crypto.CryptoHasher.getter,
- },
- .FFI = .{
- .get = FFI.getter,
- },
- .FileSystemRouter = .{
- .get = getFileSystemRouter,
- },
- },
-);
-
-fn dump_mimalloc(
- _: void,
- globalThis: JSC.C.JSContextRef,
- _: JSC.C.JSObjectRef,
- _: JSC.C.JSObjectRef,
- _: []const JSC.C.JSValueRef,
- _: JSC.C.ExceptionRef,
-) JSC.C.JSValueRef {
- globalThis.bunVM().arena.dumpStats();
- return JSC.JSValue.jsUndefined().asObjectRef();
+fn _Os(globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ return Node.Os.create(globalObject);
+}
+
+fn _Path(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(1);
+ const args = arguments.slice();
+ const is_windows = args.len == 1 and args[0].toBoolean();
+ return Node.Path.create(globalObject, is_windows);
+}
+
+/// @deprecated
+fn getImportedStyles(globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ defer flushCSSImports();
+ const styles = getCSSImports();
+ if (styles.len == 0) {
+ return JSC.JSValue.createEmptyArray(globalObject, 0);
+ }
+
+ return JSValue.createStringArray(globalObject, styles.ptr, styles.len, true);
}
-pub fn indexOfLine(
- _: void,
- globalThis: JSC.C.JSContextRef,
- _: JSC.C.JSObjectRef,
- _: JSC.C.JSObjectRef,
- args: []const JSC.C.JSValueRef,
- _: JSC.C.ExceptionRef,
-) JSC.C.JSValueRef {
- const arguments = bun.cast([]const JSC.JSValue, args);
+pub fn dump_mimalloc(globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ globalObject.bunVM().arena.dumpStats();
+ return .undefined;
+}
+
+pub fn indexOfLine(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
+ const arguments_ = callframe.arguments(2);
+ const arguments = arguments_.slice();
if (arguments.len == 0) {
- return JSC.JSValue.jsNumberFromInt32(-1).asObjectRef();
+ return JSC.JSValue.jsNumberFromInt32(-1);
}
var buffer = arguments[0].asArrayBuffer(globalThis) orelse {
- return JSC.JSValue.jsNumberFromInt32(-1).asObjectRef();
+ return JSC.JSValue.jsNumberFromInt32(-1);
};
var offset: usize = 0;
@@ -1351,10 +979,10 @@ pub fn indexOfLine(
if (byte == '\r') {
if (i + 1 < bytes.len and bytes[i + 1] == '\n') {
- return JSC.JSValue.jsNumber(i + 1).asObjectRef();
+ return JSC.JSValue.jsNumber(i + 1);
}
} else if (byte == '\n') {
- return JSC.JSValue.jsNumber(i).asObjectRef();
+ return JSC.JSValue.jsNumber(i);
}
current_offset = i + 1;
@@ -1363,7 +991,7 @@ pub fn indexOfLine(
}
}
- return JSC.JSValue.jsNumberFromInt32(-1).asObjectRef();
+ return JSC.JSValue.jsNumberFromInt32(-1);
}
pub const Crypto = struct {
@@ -1882,22 +1510,22 @@ pub const Crypto = struct {
object.put(
globalObject,
ZigString.static("hash"),
- JSC.NewFunction(globalObject, ZigString.static("hash"), 2, JSPasswordObject__hash, false),
+ JSC.createCallback(globalObject, ZigString.static("hash"), 2, JSPasswordObject__hash),
);
object.put(
globalObject,
ZigString.static("hashSync"),
- JSC.NewFunction(globalObject, ZigString.static("hashSync"), 2, JSPasswordObject__hashSync, false),
+ JSC.createCallback(globalObject, ZigString.static("hashSync"), 2, JSPasswordObject__hashSync),
);
object.put(
globalObject,
ZigString.static("verify"),
- JSC.NewFunction(globalObject, ZigString.static("verify"), 2, JSPasswordObject__verify, false),
+ JSC.createCallback(globalObject, ZigString.static("verify"), 2, JSPasswordObject__verify),
);
object.put(
globalObject,
ZigString.static("verifySync"),
- JSC.NewFunction(globalObject, ZigString.static("verifySync"), 2, JSPasswordObject__verifySync, false),
+ JSC.createCallback(globalObject, ZigString.static("verifySync"), 2, JSPasswordObject__verifySync),
);
return object;
}
@@ -2508,13 +2136,10 @@ pub const Crypto = struct {
}
pub fn getter(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
- ) js.JSValueRef {
- return CryptoHasher.getConstructor(ctx).asObjectRef();
+ globalObject: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+ ) callconv(.C) JSC.JSValue {
+ return CryptoHasher.getConstructor(globalObject);
}
pub fn update(this: *CryptoHasher, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
@@ -2522,7 +2147,7 @@ pub const Crypto = struct {
const arguments = callframe.arguments(2);
const input = arguments.ptr[0];
const encoding = arguments.ptr[1];
- const buffer = JSC.Node.SliceOrBuffer.fromJSWithEncoding(globalThis.ptr(), globalThis.bunVM().allocator, input, encoding) orelse {
+ const buffer = JSC.Node.SliceOrBuffer.fromJSWithEncoding(globalThis, globalThis.bunVM().allocator, input, encoding) orelse {
globalThis.throwInvalidArguments("expected string or buffer", .{});
return JSC.JSValue.zero;
};
@@ -2725,19 +2350,16 @@ pub const Crypto = struct {
}
pub fn getter(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
- ) js.JSValueRef {
- return ThisHasher.getConstructor(ctx).asObjectRef();
+ globalObject: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+ ) callconv(.C) JSC.JSValue {
+ return ThisHasher.getConstructor(globalObject);
}
pub fn update(this: *@This(), globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSC.JSValue {
const thisValue = callframe.this();
const input = callframe.argument(0);
- const buffer = JSC.Node.SliceOrBuffer.fromJS(globalThis.ptr(), globalThis.bunVM().allocator, input) orelse {
+ const buffer = JSC.Node.SliceOrBuffer.fromJS(globalThis, globalThis.bunVM().allocator, input) orelse {
globalThis.throwInvalidArguments("expected string or buffer", .{});
return JSC.JSValue.zero;
};
@@ -2840,87 +2462,100 @@ pub const Crypto = struct {
};
pub fn nanoseconds(
- _: void,
- _: JSC.C.JSContextRef,
- _: JSC.C.JSObjectRef,
- _: JSC.C.JSObjectRef,
- _: []const JSC.C.JSValueRef,
- _: JSC.C.ExceptionRef,
-) JSC.C.JSValueRef {
- const ns = JSC.VirtualMachine.get().origin_timer.read();
- return JSC.JSValue.jsNumberFromUint64(ns).asObjectRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
+ const ns = globalThis.bunVM().origin_timer.read();
+ return JSC.JSValue.jsNumberFromUint64(ns);
}
pub fn serve(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) js.JSValueRef {
- var args = JSC.Node.ArgumentsSlice.from(ctx.bunVM(), arguments);
- const config = JSC.API.ServerConfig.fromJS(ctx.ptr(), &args, exception);
- if (exception.* != null) {
- return null;
- }
+ globalObject: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2).slice();
+ const config: JSC.API.ServerConfig = brk: {
+ var exception_ = [1]JSC.JSValueRef{null};
+ var exception = &exception_;
+
+ var args = JSC.Node.ArgumentsSlice.init(globalObject.bunVM(), arguments);
+ const config_ = JSC.API.ServerConfig.fromJS(globalObject.ptr(), &args, exception);
+ if (exception[0] != null) {
+ globalObject.throwValue(exception_[0].?.value());
+ return .undefined;
+ }
+
+ break :brk config_;
+ };
+
+ var exception_value: *JSC.JSValue = undefined;
// Listen happens on the next tick!
// This is so we can return a Server object
if (config.ssl_config != null) {
if (config.development) {
- var server = JSC.API.DebugSSLServer.init(config, ctx.ptr());
+ var server = JSC.API.DebugHTTPSServer.init(config, globalObject.ptr());
+ exception_value = &server.thisObject;
server.listen();
if (!server.thisObject.isEmpty()) {
- exception.* = server.thisObject.asObjectRef();
+ exception_value.unprotect();
+ globalObject.throwValue(server.thisObject);
server.thisObject = JSC.JSValue.zero;
server.deinit();
- return null;
+ return .zero;
}
- var obj = JSC.API.DebugSSLServer.Class.make(ctx, server);
- JSC.C.JSValueProtect(ctx, obj);
- server.thisObject = JSValue.c(obj);
+ const obj = server.toJS(globalObject);
+ obj.protect();
+
+ server.thisObject = obj;
return obj;
} else {
- var server = JSC.API.SSLServer.init(config, ctx.ptr());
+ var server = JSC.API.HTTPSServer.init(config, globalObject.ptr());
+ exception_value = &server.thisObject;
server.listen();
- if (!server.thisObject.isEmpty()) {
- exception.* = server.thisObject.asObjectRef();
+ if (!exception_value.isEmpty()) {
+ exception_value.unprotect();
+ globalObject.throwValue(exception_value.*);
server.thisObject = JSC.JSValue.zero;
server.deinit();
- return null;
+ return .zero;
}
- var obj = JSC.API.SSLServer.Class.make(ctx, server);
- JSC.C.JSValueProtect(ctx, obj);
- server.thisObject = JSValue.c(obj);
+ const obj = server.toJS(globalObject);
+ obj.protect();
+ server.thisObject = obj;
return obj;
}
} else {
if (config.development) {
- var server = JSC.API.DebugServer.init(config, ctx.ptr());
+ var server = JSC.API.DebugHTTPServer.init(config, globalObject.ptr());
+ exception_value = &server.thisObject;
server.listen();
- if (!server.thisObject.isEmpty()) {
- exception.* = server.thisObject.asObjectRef();
+ if (!exception_value.isEmpty()) {
+ exception_value.unprotect();
+ globalObject.throwValue(exception_value.*);
server.thisObject = JSC.JSValue.zero;
server.deinit();
- return null;
+ return .zero;
}
- var obj = JSC.API.DebugServer.Class.make(ctx, server);
- JSC.C.JSValueProtect(ctx, obj);
- server.thisObject = JSValue.c(obj);
+ const obj = server.toJS(globalObject);
+ obj.protect();
+ server.thisObject = obj;
return obj;
} else {
- var server = JSC.API.Server.init(config, ctx.ptr());
+ var server = JSC.API.HTTPServer.init(config, globalObject.ptr());
+ exception_value = &server.thisObject;
server.listen();
- if (!server.thisObject.isEmpty()) {
- exception.* = server.thisObject.asObjectRef();
+ if (!exception_value.isEmpty()) {
+ exception_value.unprotect();
+ globalObject.throwValue(exception_value.*);
server.thisObject = JSC.JSValue.zero;
server.deinit();
- return null;
+ return .zero;
}
- var obj = JSC.API.Server.Class.make(ctx, server);
- JSC.C.JSValueProtect(ctx, obj);
- server.thisObject = JSValue.c(obj);
+ const obj = server.toJS(globalObject);
+ obj.protect();
+
+ server.thisObject = obj;
return obj;
}
}
@@ -3021,47 +2656,43 @@ comptime {
}
pub fn allocUnsafe(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) js.JSValueRef {
- var args = JSC.Node.ArgumentsSlice.from(ctx.bunVM(), arguments);
-
- const length = @as(
- usize,
- @intCast(@min(
- @max(1, (args.nextEat() orelse JSC.JSValue.jsNumber(@as(i32, 1))).toInt32()),
- std.math.maxInt(i32),
- )),
- );
- var bytes = bun.default_allocator.alloc(u8, length) catch {
- JSC.JSError(bun.default_allocator, "OOM! Out of memory", .{}, ctx, exception);
- return null;
- };
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(1);
+ const size = arguments.ptr[0];
+ if (!size.isUInt32AsAnyInt()) {
+ globalThis.throwInvalidArguments("Expected a positive number", .{});
+ return JSC.JSValue.zero;
+ }
- return JSC.MarkedArrayBuffer.fromBytes(
- bytes,
- bun.default_allocator,
- .Uint8Array,
- ).toJSObjectRef(ctx, null);
+ return JSC.JSValue.createUninitializedUint8Array(globalThis, size.toUInt64NoTruncate());
}
pub fn mmapFile(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
-) js.JSValueRef {
- var args = JSC.Node.ArgumentsSlice.from(ctx.bunVM(), arguments);
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+) callconv(.C) JSC.JSValue {
+ const arguments_ = callframe.arguments(2);
+ var args = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments_.slice());
+ defer args.deinit();
var buf: [bun.MAX_PATH_BYTES]u8 = undefined;
- const path = getFilePath(ctx, arguments[0..@min(1, arguments.len)], &buf, exception) orelse return null;
- args.eat();
+ const path = brk: {
+ if (args.nextEat()) |path| {
+ if (path.isString()) {
+ const path_str = path.toSlice(globalThis, args.arena.allocator());
+ if (path_str.len > bun.MAX_PATH_BYTES) {
+ globalThis.throwInvalidArguments("Path too long", .{});
+ return JSC.JSValue.zero;
+ }
+ const paths = &[_]string{path_str.slice()};
+ break :brk bun.path.joinAbsStringBuf(bun.fs.FileSystem.instance.top_level_dir, &buf, paths, .auto);
+ }
+ }
+ globalThis.throwInvalidArguments("Expected a path", .{});
+ return JSC.JSValue.zero;
+ };
buf[path.len] = 0;
@@ -3076,16 +2707,16 @@ pub fn mmapFile(
var map_size: ?usize = null;
if (args.nextEat()) |opts| {
- const sync = opts.get(ctx.ptr(), "sync") orelse JSC.JSValue.jsBoolean(false);
- const shared = opts.get(ctx.ptr(), "shared") orelse JSC.JSValue.jsBoolean(true);
+ const sync = opts.get(globalThis, "sync") orelse JSC.JSValue.jsBoolean(false);
+ const shared = opts.get(globalThis, "shared") orelse JSC.JSValue.jsBoolean(true);
flags |= @as(u32, if (sync.toBoolean()) sync_flags else 0);
flags |= @as(u32, if (shared.toBoolean()) std.os.MAP.SHARED else std.os.MAP.PRIVATE);
- if (opts.get(ctx.ptr(), "size")) |value| {
+ if (opts.get(globalThis, "size")) |value| {
map_size = @as(usize, @intCast(value.toInt64()));
}
- if (opts.get(ctx.ptr(), "offset")) |value| {
+ if (opts.get(globalThis, "offset")) |value| {
offset = @as(usize, @intCast(value.toInt64()));
offset = std.mem.alignBackwardAnyAlign(offset, std.mem.page_size);
}
@@ -3097,115 +2728,85 @@ pub fn mmapFile(
.result => |map| map,
.err => |err| {
- exception.* = err.toJS(ctx);
- return null;
+ globalThis.throwValue(err.toJSC(globalThis));
+ return .zero;
},
};
- return JSC.C.JSObjectMakeTypedArrayWithBytesNoCopy(ctx, JSC.C.JSTypedArrayType.kJSTypedArrayTypeUint8Array, @as(?*anyopaque, @ptrCast(map.ptr)), map.len, struct {
+ return JSC.C.JSObjectMakeTypedArrayWithBytesNoCopy(globalThis, JSC.C.JSTypedArrayType.kJSTypedArrayTypeUint8Array, @as(?*anyopaque, @ptrCast(map.ptr)), map.len, struct {
pub fn x(ptr: ?*anyopaque, size: ?*anyopaque) callconv(.C) void {
_ = JSC.Node.Syscall.munmap(@as([*]align(std.mem.page_size) u8, @ptrCast(@alignCast(ptr)))[0..@intFromPtr(size)]);
}
- }.x, @as(?*anyopaque, @ptrFromInt(map.len)), exception);
+ }.x, @as(?*anyopaque, @ptrFromInt(map.len)), null).?.value();
}
pub fn getTranspilerConstructor(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- return JSC.API.JSTranspiler.getConstructor(ctx).asObjectRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ return JSC.API.JSTranspiler.getConstructor(globalThis);
}
pub fn getFileSystemRouter(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- return JSC.API.FileSystemRouter.getConstructor(ctx).asObjectRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ return JSC.API.FileSystemRouter.getConstructor(globalThis);
}
pub fn getHashObject(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- var existing = ctx.ptr().getCachedObject(ZigString.static("BunHash"));
- if (existing.isEmpty()) {
- return ctx.ptr().putCachedObject(
- &ZigString.init("BunHash"),
- JSC.JSValue.fromRef(JSC.C.JSObjectMake(ctx, Hash.Class.get().*, null)),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ return HashObject.create(globalThis);
}
-pub const Hash = struct {
- pub const Class = NewClass(
- void,
- .{
- .name = "Hash",
- },
- .{
- .call = .{
- .rfn = call,
- },
- .wyhash = .{
- .rfn = hashWrap(std.hash.Wyhash).hash,
- },
- .adler32 = .{
- .rfn = hashWrap(std.hash.Adler32).hash,
- },
- .crc32 = .{
- .rfn = hashWrap(std.hash.Crc32).hash,
- },
- .cityHash32 = .{
- .rfn = hashWrap(std.hash.CityHash32).hash,
- },
- .cityHash64 = .{
- .rfn = hashWrap(std.hash.CityHash64).hash,
- },
- .murmur32v2 = .{
- .rfn = hashWrap(std.hash.murmur.Murmur2_32).hash,
- },
- .murmur32v3 = .{
- .rfn = hashWrap(std.hash.murmur.Murmur3_32).hash,
- },
- .murmur64v2 = .{
- .rfn = hashWrap(std.hash.murmur.Murmur2_64).hash,
- },
- },
- .{},
- );
+const HashObject = struct {
+ pub const wyhash = hashWrap(std.hash.Wyhash).hash;
+ pub const adler32 = hashWrap(std.hash.Adler32).hash;
+ pub const crc32 = hashWrap(std.hash.Crc32).hash;
+ pub const cityHash32 = hashWrap(std.hash.CityHash32).hash;
+ pub const cityHash64 = hashWrap(std.hash.CityHash64).hash;
+ pub const murmur32v2 = hashWrap(std.hash.murmur.Murmur2_32).hash;
+ pub const murmur32v3 = hashWrap(std.hash.murmur.Murmur3_32).hash;
+ pub const murmur64v2 = hashWrap(std.hash.murmur.Murmur2_64).hash;
+
+ pub fn create(globalThis: *JSC.JSGlobalObject) JSC.JSValue {
+ const function = JSC.createCallback(globalThis, ZigString.static("hash"), 1, &wyhash);
+ const fns = comptime .{
+ "wyhash",
+ "adler32",
+ "crc32",
+ "cityHash32",
+ "cityHash64",
+ "murmur32v2",
+ "murmur32v3",
+ "murmur64v2",
+ };
+ inline for (fns) |name| {
+ const value = JSC.createCallback(
+ globalThis,
+ ZigString.static(name),
+ 1,
+ &@field(HashObject, name),
+ );
+ function.put(globalThis, comptime ZigString.static(name), value);
+ }
- pub fn call(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSObjectRef {
- return hashWrap(std.hash.Wyhash).hash({}, ctx, null, null, arguments, exception);
+ return function;
}
- fn hashWrap(comptime Hasher: anytype) type {
+
+ fn hashWrap(comptime Hasher_: anytype) type {
return struct {
+ const Hasher = Hasher_;
pub fn hash(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- var args = JSC.Node.ArgumentsSlice.from(ctx.bunVM(), arguments);
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
+ const arguments = callframe.arguments(2).slice();
+ var args = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments);
+ defer args.deinit();
+
var input: []const u8 = "";
var input_slice = ZigString.Slice.empty;
defer input_slice.deinit();
@@ -3229,14 +2830,14 @@ pub const Hash = struct {
.BigUint64Array,
.DataView,
=> {
- var array_buffer = arg.asArrayBuffer(ctx.ptr()) orelse {
- JSC.throwInvalidArguments("ArrayBuffer conversion error", .{}, ctx, exception);
- return null;
+ var array_buffer = arg.asArrayBuffer(globalThis) orelse {
+ globalThis.throwInvalidArguments("ArrayBuffer conversion error", .{});
+ return .zero;
};
input = array_buffer.byteSlice();
},
else => {
- input_slice = arg.toSlice(ctx.ptr(), bun.default_allocator);
+ input_slice = arg.toSlice(globalThis, bun.default_allocator);
input = input_slice.slice();
},
}
@@ -3248,7 +2849,7 @@ pub const Hash = struct {
const Function = if (@hasDecl(Hasher, "hashWithSeed")) Hasher.hashWithSeed else Hasher.hash;
var function_args: std.meta.ArgsTuple(@TypeOf(Function)) = undefined;
if (comptime std.meta.fields(std.meta.ArgsTuple(@TypeOf(Function))).len == 1) {
- return JSC.JSValue.jsNumber(Function(input)).asObjectRef();
+ return JSC.JSValue.jsNumber(Function(input));
} else {
var seed: u64 = 0;
if (args.nextEat()) |arg| {
@@ -3267,9 +2868,9 @@ pub const Hash = struct {
const value = @call(.auto, Function, function_args);
if (@TypeOf(value) == u32) {
- return JSC.JSValue.jsNumber(@as(u32, @bitCast(value))).asObjectRef();
+ return JSC.JSValue.jsNumber(@as(u32, @bitCast(value)));
}
- return JSC.JSValue.fromUInt64NoTruncate(ctx.ptr(), value).asObjectRef();
+ return JSC.JSValue.fromUInt64NoTruncate(globalThis, value);
}
}
};
@@ -3277,66 +2878,45 @@ pub const Hash = struct {
};
pub fn getTOMLObject(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- var existing = ctx.ptr().getCachedObject(ZigString.static("TOML"));
- if (existing.isEmpty()) {
- return ctx.ptr().putCachedObject(
- &ZigString.init("TOML"),
- JSValue.fromRef(js.JSObjectMake(ctx, TOML.Class.get().?[0], null)),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ return TOMLObject.create(globalThis);
}
pub fn getUnsafe(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef {
- var existing = ctx.ptr().getCachedObject(ZigString.static("Unsafe"));
- if (existing.isEmpty()) {
- return ctx.ptr().putCachedObject(
- &ZigString.init("Unsafe"),
- JSValue.fromRef(js.JSObjectMake(ctx, Unsafe.Class.get().?[0], null)),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
+ globalThis: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+) callconv(.C) JSC.JSValue {
+ return UnsafeObject.create(globalThis);
}
-pub const Unsafe = struct {
- pub const Class = NewClass(
- void,
- .{ .name = "Unsafe", .read_only = true },
- .{
- .segfault = .{
- .rfn = __debug__doSegfault,
- },
- .arrayBufferToString = .{
- .rfn = arrayBufferToString,
- },
- .gcAggressionLevel = .{
- .rfn = &JSC.wrapWithHasContainer(Unsafe, "gcAggressionLevel", false, false, false),
- },
- },
- .{},
- );
+const UnsafeObject = struct {
+ pub fn create(globalThis: *JSC.JSGlobalObject) JSC.JSValue {
+ const object = JSValue.createEmptyObject(globalThis, 3);
+ const fields = comptime .{
+ .gcAggressionLevel = &gcAggressionLevel,
+ .segfault = &__debug__doSegfault,
+ .arrayBufferToString = &arrayBufferToString,
+ };
+ inline for (comptime std.meta.fieldNames(@TypeOf(fields))) |name| {
+ object.put(
+ globalThis,
+ comptime ZigString.static(name),
+ JSC.createCallback(globalThis, comptime ZigString.static(name), 1, comptime @field(fields, name)),
+ );
+ }
+ return object;
+ }
pub fn gcAggressionLevel(
globalThis: *JSC.JSGlobalObject,
- value_: ?JSValue,
- ) JSValue {
+ callframe: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
const ret = JSValue.jsNumber(@as(i32, @intFromEnum(globalThis.bunVM().aggressive_garbage_collection)));
+ const value = callframe.arguments(1).ptr[0];
- if (value_) |value| {
+ if (!value.isEmptyOrUndefinedOrNull()) {
switch (value.coerce(i32, globalThis)) {
1 => globalThis.bunVM().aggressive_garbage_collection = .mild,
2 => globalThis.bunVM().aggressive_garbage_collection = .aggressive,
@@ -3349,212 +2929,87 @@ pub const Unsafe = struct {
// For testing the segfault handler
pub fn __debug__doSegfault(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- _: []const js.JSValueRef,
- _: js.ExceptionRef,
- ) js.JSValueRef {
- _ = ctx;
+ _: *JSC.JSGlobalObject,
+ _: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
const Reporter = @import("../../report.zig");
Reporter.globalError(error.SegfaultTest, null);
}
pub fn arrayBufferToString(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- args: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- const array_buffer = JSC.ArrayBuffer.fromTypedArray(ctx, JSC.JSValue.fromRef(args[0]), exception);
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
+ const args = callframe.arguments(2).slice();
+ const array_buffer = JSC.ArrayBuffer.fromTypedArray(globalThis, args[0]);
switch (array_buffer.typed_array_type) {
.Uint16Array, .Int16Array => {
var zig_str = ZigString.init("");
zig_str._unsafe_ptr_do_not_use = @as([*]const u8, @ptrCast(@alignCast(array_buffer.ptr)));
zig_str.len = array_buffer.len;
zig_str.markUTF16();
- // the deinitializer for string causes segfaults
- // if we don't clone it
- return ZigString.toValueGC(&zig_str, ctx.ptr()).asObjectRef();
+ return zig_str.toValueGC(globalThis);
},
else => {
- // the deinitializer for string causes segfaults
- // if we don't clone it
- return ZigString.init(array_buffer.slice()).toValueGC(ctx.ptr()).asObjectRef();
+ return ZigString.init(array_buffer.slice()).toValueGC(globalThis);
},
}
}
};
-// pub const Lockfile = struct {
-// const BunLockfile = @import("../../install/install.zig").Lockfile;
-// lockfile: *BunLockfile,
-
-// pub const RefCountedLockfile = bun.RefCount(Lockfile, true);
-
-// pub const StaticClass = NewClass(
-// void,
-// .{
-// .name = "Lockfile",
-// .read_only = true,
-// },
-// .{
-// .load = .{
-// .rfn = &BunLockfile.load,
-// },
-// },
-// .{},
-// );
-
-// pub const Class = NewClass(
-// RefCountedLockfile,
-// .{
-// .name = "Lockfile",
-// .read_only = true,
-// },
-// .{
-// .findPackagesByName = .{
-// .rfn = &BunLockfile.load,
-// },
-// .dependencies = .{
-// .rfn = &BunLockfile.load,
-// },
-// },
-// .{},
-// );
-
-// pub fn deinit(this: *Lockfile) void {
-// this.lockfile.deinit();
-// }
-
-// pub fn load(
-// // this
-// _: void,
-// ctx: js.JSContextRef,
-// // function
-// _: js.JSObjectRef,
-// // thisObject
-// _: js.JSObjectRef,
-// arguments: []const js.JSValueRef,
-// exception: js.ExceptionRef,
-// ) js.JSValueRef {
-// if (arguments.len == 0) {
-// JSError(undefined, "Expected file path string or buffer", .{}, ctx, exception);
-// return null;
-// }
-
-// var lockfile: *BunLockfile = getAllocator(ctx).create(BunLockfile) catch return JSValue.jsUndefined().asRef();
-
-// var log = logger.Log.init(default_allocator);
-// var args_slice = @ptrCast([*]const JSValue, arguments.ptr)[0..arguments.len];
-
-// var arguments_slice = Node.ArgumentsSlice.init(args_slice);
-// var path_or_buffer = Node.PathLike.fromJS(ctx, &arguments_slice, exception) orelse {
-// getAllocator(ctx).destroy(lockfile);
-// JSError(undefined, "Expected file path string or buffer", .{}, ctx, exception);
-// return null;
-// };
-
-// const load_from_disk_result = switch (path_or_buffer) {
-// Node.PathLike.Tag.string => lockfile.loadFromDisk(getAllocator(ctx), &log, path_or_buffer.string),
-// Node.PathLike.Tag.buffer => lockfile.loadFromBytes(getAllocator(ctx), path_or_buffer.buffer.slice(), &log),
-// else => {
-// getAllocator(ctx).destroy(lockfile);
-// JSError(undefined, "Expected file path string or buffer", .{}, ctx, exception);
-// return null;
-// },
-// };
-
-// switch (load_from_disk_result) {
-// .err => |cause| {
-// defer getAllocator(ctx).destroy(lockfile);
-// switch (cause.step) {
-// .open_file => {
-// JSError(undefined, "error opening lockfile: {s}", .{
-// @errorName(cause.value),
-// }, ctx, exception);
-// return null;
-// },
-// .parse_file => {
-// JSError(undefined, "error parsing lockfile: {s}", .{
-// @errorName(cause.value),
-// }, ctx, exception);
-// return null;
-// },
-// .read_file => {
-// JSError(undefined, "error reading lockfile: {s}", .{
-// @errorName(cause.value),
-// }, ctx, exception);
-// return null;
-// },
-// }
-// },
-// .ok => {},
-// }
-// }
-// };
-
-pub const TOML = struct {
+const TOMLObject = struct {
const TOMLParser = @import("../../toml/toml_parser.zig").TOML;
- pub const Class = NewClass(
- void,
- .{
- .name = "TOML",
- .read_only = true,
- },
- .{
- .parse = .{
- .rfn = TOML.parse,
- },
- },
- .{},
- );
+
+ pub fn create(globalThis: *JSC.JSGlobalObject) JSC.JSValue {
+ const object = JSValue.createEmptyObject(globalThis, 1);
+ object.put(
+ globalThis,
+ ZigString.static("parse"),
+ JSC.createCallback(
+ globalThis,
+ ZigString.static("parse"),
+ 1,
+ &parse,
+ ),
+ );
+
+ return object;
+ }
pub fn parse(
- // this
- _: void,
- ctx: js.JSContextRef,
- // function
- _: js.JSObjectRef,
- // thisObject
- _: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- var arena = @import("root").bun.ArenaAllocator.init(getAllocator(ctx));
+ globalThis: *JSC.JSGlobalObject,
+ callframe: *JSC.CallFrame,
+ ) callconv(.C) JSC.JSValue {
+ var arena = @import("root").bun.ArenaAllocator.init(globalThis.allocator());
var allocator = arena.allocator();
defer arena.deinit();
var log = logger.Log.init(default_allocator);
- var input_str = ZigString.init("");
- JSValue.fromRef(arguments[0]).toZigString(&input_str, ctx.ptr());
- var needs_deinit = false;
- var input = input_str.slice();
- if (input_str.is16Bit()) {
- input = std.fmt.allocPrint(allocator, "{}", .{input_str}) catch unreachable;
- needs_deinit = true;
- }
- var source = logger.Source.initPathString("input.toml", input);
+ const arguments = callframe.arguments(1).slice();
+
+ var input_slice = arguments[0].toSlice(globalThis, bun.default_allocator);
+ defer input_slice.deinit();
+ var source = logger.Source.initPathString("input.toml", input_slice.slice());
var parse_result = TOMLParser.parse(&source, &log, allocator) catch {
- exception.* = log.toJS(ctx.ptr(), default_allocator, "Failed to parse toml").asObjectRef();
- return null;
+ globalThis.throwValue(log.toJS(globalThis, default_allocator, "Failed to parse toml"));
+ return .zero;
};
// for now...
- var buffer_writer = try js_printer.BufferWriter.init(allocator);
+ var buffer_writer = js_printer.BufferWriter.init(allocator) catch {
+ globalThis.throwValue(log.toJS(globalThis, default_allocator, "Failed to print toml"));
+ return .zero;
+ };
var writer = js_printer.BufferPrinter.init(buffer_writer);
_ = js_printer.printJSON(*js_printer.BufferPrinter, &writer, parse_result, &source) catch {
- exception.* = log.toJS(ctx.ptr(), default_allocator, "Failed to print toml").asObjectRef();
- return null;
+ globalThis.throwValue(log.toJS(globalThis, default_allocator, "Failed to print toml"));
+ return .zero;
};
var slice = writer.ctx.buffer.toOwnedSliceLeaky();
- var out = ZigString.init(slice);
+ var out = bun.String.fromUTF8(slice);
+ defer out.deref();
- const out_value = js.JSValueMakeFromJSONString(ctx, out.toJSStringRef());
- return out_value;
+ return out.toJSForParseJSON(globalThis);
}
};
@@ -4284,65 +3739,76 @@ pub const Timer = struct {
}
};
-pub const FFI = struct {
- pub const Class = NewClass(
- void,
- .{ .name = "FFI", .has_dom_calls = true },
- .{
- .viewSource = .{
- .rfn = &JSC.wrapWithHasContainer(JSC.FFI, "print", false, false, true),
- },
- .dlopen = .{
- .rfn = &JSC.wrapWithHasContainer(JSC.FFI, "open", false, false, true),
- },
- .callback = .{
- .rfn = &JSC.wrapWithHasContainer(JSC.FFI, "callback", false, false, false),
- },
- .linkSymbols = .{
- .rfn = &JSC.wrapWithHasContainer(JSC.FFI, "linkSymbols", false, false, false),
- },
- .ptr = JSC.DOMCall("FFI", @This(), "ptr", f64, JSC.DOMEffect.forRead(.TypedArrayProperties)),
+pub const FFIObject = struct {
+ const fields = .{
+ .viewSource = JSC.wrapStaticMethod(
+ JSC.FFI,
+ "print",
+ false,
+ ),
+ .dlopen = JSC.wrapStaticMethod(JSC.FFI, "open", false),
+ .callback = JSC.wrapStaticMethod(JSC.FFI, "callback", false),
+ .linkSymbols = JSC.wrapStaticMethod(JSC.FFI, "linkSymbols", false),
+ .toBuffer = JSC.wrapStaticMethod(@This(), "toBuffer", false),
+ .toArrayBuffer = JSC.wrapStaticMethod(@This(), "toArrayBuffer", false),
+ .closeCallback = JSC.wrapStaticMethod(JSC.FFI, "closeCallback", false),
+ .CString = JSC.wrapStaticMethod(Bun.FFIObject, "newCString", false),
+ };
- .toBuffer = .{
- .rfn = &JSC.wrapWithHasContainer(@This(), "toBuffer", false, false, true),
- },
- .toArrayBuffer = .{
- .rfn = &JSC.wrapWithHasContainer(@This(), "toArrayBuffer", false, false, true),
- },
- .closeCallback = .{
- .rfn = &JSC.wrapWithHasContainer(JSC.FFI, "closeCallback", false, false, false),
- },
- },
- .{
- .read = .{
- .get = FFI.Reader.getter,
+ pub fn newCString(globalThis: *JSGlobalObject, value: JSValue, byteOffset: ?JSValue, lengthValue: ?JSValue) JSC.JSValue {
+ switch (FFIObject.getPtrSlice(globalThis, value, byteOffset, lengthValue)) {
+ .err => |err| {
+ return err;
},
- .CString = .{
- .get = UnsafeCString.getter,
+ .slice => |slice| {
+ return WebCore.Encoder.toString(slice.ptr, slice.len, globalThis, .utf8);
},
- },
- );
+ }
+ }
+
+ pub const dom_call = JSC.DOMCall("FFI", @This(), "ptr", f64, JSC.DOMEffect.forRead(.TypedArrayProperties));
+
+ pub fn toJS(globalObject: *JSC.JSGlobalObject) JSC.JSValue {
+ const object = JSC.JSValue.createEmptyObject(globalObject, comptime std.meta.fieldNames(@TypeOf(fields)).len + 2);
+ inline for (comptime std.meta.fieldNames(@TypeOf(fields))) |field| {
+ object.put(
+ globalObject,
+ comptime ZigString.static(field),
+ JSC.createCallback(globalObject, comptime ZigString.static(field), 1, comptime @field(fields, field)),
+ );
+ }
+
+ dom_call.put(globalObject, object);
+ object.put(globalObject, ZigString.static("read"), Reader.toJS(globalObject));
+
+ return object;
+ }
pub const Reader = struct {
- pub const Class = NewClass(
- void,
- .{ .name = "FFI", .has_dom_calls = true },
- .{
- .u8 = JSC.DOMCall("Reader", @This(), "u8", i32, JSC.DOMEffect.forRead(.World)),
- .u16 = JSC.DOMCall("Reader", @This(), "u16", i32, JSC.DOMEffect.forRead(.World)),
- .u32 = JSC.DOMCall("Reader", @This(), "u32", i32, JSC.DOMEffect.forRead(.World)),
- .ptr = JSC.DOMCall("Reader", @This(), "ptr", i52, JSC.DOMEffect.forRead(.World)),
- .i8 = JSC.DOMCall("Reader", @This(), "i8", i32, JSC.DOMEffect.forRead(.World)),
- .i16 = JSC.DOMCall("Reader", @This(), "i16", i32, JSC.DOMEffect.forRead(.World)),
- .i32 = JSC.DOMCall("Reader", @This(), "i32", i32, JSC.DOMEffect.forRead(.World)),
- .i64 = JSC.DOMCall("Reader", @This(), "i64", i64, JSC.DOMEffect.forRead(.World)),
- .u64 = JSC.DOMCall("Reader", @This(), "u64", u64, JSC.DOMEffect.forRead(.World)),
- .intptr = JSC.DOMCall("Reader", @This(), "intptr", i52, JSC.DOMEffect.forRead(.World)),
- .f32 = JSC.DOMCall("Reader", @This(), "f32", f64, JSC.DOMEffect.forRead(.World)),
- .f64 = JSC.DOMCall("Reader", @This(), "f64", f64, JSC.DOMEffect.forRead(.World)),
- },
- .{},
- );
+ pub const DOMCalls = .{
+ .u8 = JSC.DOMCall("Reader", @This(), "u8", i32, JSC.DOMEffect.forRead(.World)),
+ .u16 = JSC.DOMCall("Reader", @This(), "u16", i32, JSC.DOMEffect.forRead(.World)),
+ .u32 = JSC.DOMCall("Reader", @This(), "u32", i32, JSC.DOMEffect.forRead(.World)),
+ .ptr = JSC.DOMCall("Reader", @This(), "ptr", i52, JSC.DOMEffect.forRead(.World)),
+ .i8 = JSC.DOMCall("Reader", @This(), "i8", i32, JSC.DOMEffect.forRead(.World)),
+ .i16 = JSC.DOMCall("Reader", @This(), "i16", i32, JSC.DOMEffect.forRead(.World)),
+ .i32 = JSC.DOMCall("Reader", @This(), "i32", i32, JSC.DOMEffect.forRead(.World)),
+ .i64 = JSC.DOMCall("Reader", @This(), "i64", i64, JSC.DOMEffect.forRead(.World)),
+ .u64 = JSC.DOMCall("Reader", @This(), "u64", u64, JSC.DOMEffect.forRead(.World)),
+ .intptr = JSC.DOMCall("Reader", @This(), "intptr", i52, JSC.DOMEffect.forRead(.World)),
+ .f32 = JSC.DOMCall("Reader", @This(), "f32", f64, JSC.DOMEffect.forRead(.World)),
+ .f64 = JSC.DOMCall("Reader", @This(), "f64", f64, JSC.DOMEffect.forRead(.World)),
+ };
+
+ pub fn toJS(globalThis: *JSC.JSGlobalObject) JSC.JSValue {
+ const obj = JSC.JSValue.createEmptyObject(globalThis, std.meta.fieldNames(@TypeOf(Reader.DOMCalls)).len);
+
+ inline for (comptime std.meta.fieldNames(@TypeOf(Reader.DOMCalls))) |field| {
+ @field(Reader.DOMCalls, field).put(globalThis, obj);
+ }
+
+ return obj;
+ }
pub fn @"u8"(
_: *JSGlobalObject,
@@ -4581,28 +4047,6 @@ pub const FFI = struct {
const value = @as(*align(1) i64, @ptrFromInt(addr)).*;
return JSValue.fromInt64NoTruncate(global, value);
}
-
- pub fn getter(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
- ) js.JSValueRef {
- var existing = ctx.ptr().getCachedObject(ZigString.static("FFIReader"));
- if (existing.isEmpty()) {
- var prototype = JSC.C.JSObjectMake(ctx, FFI.Reader.Class.get().?[0], null);
- var base = JSC.C.JSObjectMake(ctx, null, null);
- JSC.C.JSObjectSetPrototype(ctx, base, prototype);
- FFI.Reader.Class.putDOMCalls(ctx, JSC.JSValue.c(base));
- return ctx.ptr().putCachedObject(
- ZigString.static("FFIReader"),
- JSValue.fromRef(base),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
- }
};
pub fn ptr(
@@ -4879,71 +4323,10 @@ pub const FFI = struct {
}
pub fn getter(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
- ) js.JSValueRef {
- var existing = ctx.ptr().getCachedObject(ZigString.static("FFI"));
- if (existing.isEmpty()) {
- var prototype = JSC.C.JSObjectMake(ctx, FFI.Class.get().?[0], null);
- var base = JSC.C.JSObjectMake(ctx, null, null);
- JSC.C.JSObjectSetPrototype(ctx, base, prototype);
- FFI.Class.putDOMCalls(ctx, JSC.JSValue.c(base));
- return ctx.ptr().putCachedObject(
- ZigString.static("FFI"),
- JSValue.fromRef(base),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
- }
-};
-
-pub const UnsafeCString = struct {
- pub fn constructor(
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- len: usize,
- args: [*c]const js.JSValueRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSObjectRef {
- if (len == 0) {
- JSC.throwInvalidArguments("Expected a ptr", .{}, ctx, exception);
- return null;
- }
-
- return newCString(ctx.ptr(), JSC.JSValue.fromRef(args[0]), if (len > 1) JSC.JSValue.fromRef(args[1]) else null, if (len > 2) JSC.JSValue.fromRef(args[2]) else null).asObjectRef();
- }
-
- pub fn newCString(globalThis: *JSGlobalObject, value: JSValue, byteOffset: ?JSValue, lengthValue: ?JSValue) JSC.JSValue {
- switch (FFI.getPtrSlice(globalThis, value, byteOffset, lengthValue)) {
- .err => |err| {
- return err;
- },
- .slice => |slice| {
- return WebCore.Encoder.toString(slice.ptr, slice.len, globalThis, .utf8);
- },
- }
- }
-
- pub fn getter(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
- ) js.JSValueRef {
- var existing = ctx.ptr().getCachedObject(ZigString.static("UnsafeCString"));
- if (existing.isEmpty()) {
- return ctx.ptr().putCachedObject(
- ZigString.static("UnsafeCString"),
- JSValue.fromRef(JSC.C.JSObjectMakeConstructor(ctx, null, constructor)),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
+ globalObject: *JSC.JSGlobalObject,
+ _: *JSC.JSObject,
+ ) callconv(.C) JSC.JSValue {
+ return FFIObject.toJS(globalObject);
}
};
@@ -5144,5 +4527,6 @@ pub usingnamespace @import("./bun/subprocess.zig");
comptime {
if (!JSC.is_bindgen) {
_ = Crypto.JSPasswordObject.JSPasswordObject__create;
+ BunObject.exportAll();
}
}