mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 23:18:47 +00:00
Compare commits
1 Commits
claude/htt
...
jarred/spl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3810f61c58 |
180
src/bun.js/bindings/AbortSignal.zig
Normal file
180
src/bun.js/bindings/AbortSignal.zig
Normal file
@@ -0,0 +1,180 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
const JSGlobalObject = JSC.JSGlobalObject;
|
||||
const VM = JSC.VM;
|
||||
const ZigString = JSC.ZigString;
|
||||
const CommonStrings = JSC.CommonStrings;
|
||||
const URL = JSC.URL;
|
||||
const WTF = JSC.WTF;
|
||||
const JSString = JSC.JSString;
|
||||
const JSObject = JSC.JSObject;
|
||||
const JSValue = JSC.JSValue;
|
||||
const GetterSetter = JSC.GetterSetter;
|
||||
const CustomGetterSetter = JSC.CustomGetterSetter;
|
||||
|
||||
pub const AbortSignal = extern opaque {
|
||||
extern fn WebCore__AbortSignal__aborted(arg0: *AbortSignal) bool;
|
||||
extern fn WebCore__AbortSignal__abortReason(arg0: *AbortSignal) JSValue;
|
||||
extern fn WebCore__AbortSignal__addListener(arg0: *AbortSignal, arg1: ?*anyopaque, ArgFn2: ?*const fn (?*anyopaque, JSValue) callconv(.C) void) *AbortSignal;
|
||||
extern fn WebCore__AbortSignal__cleanNativeBindings(arg0: *AbortSignal, arg1: ?*anyopaque) void;
|
||||
extern fn WebCore__AbortSignal__create(arg0: *JSGlobalObject) JSValue;
|
||||
extern fn WebCore__AbortSignal__fromJS(JSValue0: JSValue) ?*AbortSignal;
|
||||
extern fn WebCore__AbortSignal__ref(arg0: *AbortSignal) *AbortSignal;
|
||||
extern fn WebCore__AbortSignal__toJS(arg0: *AbortSignal, arg1: *JSGlobalObject) JSValue;
|
||||
extern fn WebCore__AbortSignal__unref(arg0: *AbortSignal) void;
|
||||
|
||||
pub fn listen(
|
||||
this: *AbortSignal,
|
||||
comptime Context: type,
|
||||
ctx: *Context,
|
||||
comptime cb: *const fn (*Context, JSValue) void,
|
||||
) *AbortSignal {
|
||||
const Wrapper = struct {
|
||||
const call = cb;
|
||||
pub fn callback(
|
||||
ptr: ?*anyopaque,
|
||||
reason: JSValue,
|
||||
) callconv(.C) void {
|
||||
const val = bun.cast(*Context, ptr.?);
|
||||
call(val, reason);
|
||||
}
|
||||
};
|
||||
|
||||
return this.addListener(@as(?*anyopaque, @ptrCast(ctx)), Wrapper.callback);
|
||||
}
|
||||
|
||||
pub fn addListener(
|
||||
this: *AbortSignal,
|
||||
ctx: ?*anyopaque,
|
||||
callback: *const fn (?*anyopaque, JSValue) callconv(.C) void,
|
||||
) *AbortSignal {
|
||||
return WebCore__AbortSignal__addListener(this, ctx, callback);
|
||||
}
|
||||
|
||||
pub fn cleanNativeBindings(this: *AbortSignal, ctx: ?*anyopaque) void {
|
||||
return WebCore__AbortSignal__cleanNativeBindings(this, ctx);
|
||||
}
|
||||
|
||||
extern fn WebCore__AbortSignal__signal(*AbortSignal, *JSC.JSGlobalObject, CommonAbortReason) void;
|
||||
|
||||
pub fn signal(
|
||||
this: *AbortSignal,
|
||||
globalObject: *JSC.JSGlobalObject,
|
||||
reason: CommonAbortReason,
|
||||
) void {
|
||||
bun.Analytics.Features.abort_signal += 1;
|
||||
return WebCore__AbortSignal__signal(this, globalObject, reason);
|
||||
}
|
||||
|
||||
extern fn WebCore__AbortSignal__incrementPendingActivity(*AbortSignal) void;
|
||||
extern fn WebCore__AbortSignal__decrementPendingActivity(*AbortSignal) void;
|
||||
|
||||
pub fn pendingActivityRef(this: *AbortSignal) void {
|
||||
return WebCore__AbortSignal__incrementPendingActivity(this);
|
||||
}
|
||||
|
||||
pub fn pendingActivityUnref(this: *AbortSignal) void {
|
||||
return WebCore__AbortSignal__decrementPendingActivity(this);
|
||||
}
|
||||
|
||||
/// This function is not threadsafe. aborted is a boolean, not an atomic!
|
||||
pub fn aborted(this: *AbortSignal) bool {
|
||||
return WebCore__AbortSignal__aborted(this);
|
||||
}
|
||||
|
||||
/// This function is not threadsafe. JSValue cannot safely be passed between threads.
|
||||
pub fn abortReason(this: *AbortSignal) JSValue {
|
||||
return WebCore__AbortSignal__abortReason(this);
|
||||
}
|
||||
|
||||
extern fn WebCore__AbortSignal__reasonIfAborted(*AbortSignal, *JSC.JSGlobalObject, *u8) JSValue;
|
||||
|
||||
pub const AbortReason = union(enum) {
|
||||
common: CommonAbortReason,
|
||||
js: JSValue,
|
||||
|
||||
pub fn toBodyValueError(this: AbortReason, globalObject: *JSC.JSGlobalObject) JSC.WebCore.Body.Value.ValueError {
|
||||
return switch (this) {
|
||||
.common => |reason| .{ .AbortReason = reason },
|
||||
.js => |value| .{ .JSValue = JSC.Strong.create(value, globalObject) },
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toJS(this: AbortReason, global: *JSC.JSGlobalObject) JSValue {
|
||||
return switch (this) {
|
||||
.common => |reason| reason.toJS(global),
|
||||
.js => |value| value,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn reasonIfAborted(this: *AbortSignal, global: *JSC.JSGlobalObject) ?AbortReason {
|
||||
var reason: u8 = 0;
|
||||
const js_reason = WebCore__AbortSignal__reasonIfAborted(this, global, &reason);
|
||||
if (reason > 0) {
|
||||
bun.debugAssert(js_reason == .undefined);
|
||||
return .{ .common = @enumFromInt(reason) };
|
||||
}
|
||||
if (js_reason == .zero) {
|
||||
return null; // not aborted
|
||||
}
|
||||
return .{ .js = js_reason };
|
||||
}
|
||||
|
||||
pub fn ref(this: *AbortSignal) *AbortSignal {
|
||||
return WebCore__AbortSignal__ref(this);
|
||||
}
|
||||
|
||||
pub fn unref(this: *AbortSignal) void {
|
||||
WebCore__AbortSignal__unref(this);
|
||||
}
|
||||
|
||||
pub fn detach(this: *AbortSignal, ctx: ?*anyopaque) void {
|
||||
this.cleanNativeBindings(ctx);
|
||||
this.unref();
|
||||
}
|
||||
|
||||
pub fn fromJS(value: JSValue) ?*AbortSignal {
|
||||
return WebCore__AbortSignal__fromJS(value);
|
||||
}
|
||||
|
||||
pub fn toJS(this: *AbortSignal, global: *JSGlobalObject) JSValue {
|
||||
return WebCore__AbortSignal__toJS(this, global);
|
||||
}
|
||||
|
||||
pub fn create(global: *JSGlobalObject) JSValue {
|
||||
return WebCore__AbortSignal__create(global);
|
||||
}
|
||||
|
||||
extern fn WebCore__AbortSignal__new(*JSGlobalObject) *AbortSignal;
|
||||
pub fn new(global: *JSGlobalObject) *AbortSignal {
|
||||
JSC.markBinding(@src());
|
||||
return WebCore__AbortSignal__new(global);
|
||||
}
|
||||
};
|
||||
116
src/bun.js/bindings/CachedBytecode.zig
Normal file
116
src/bun.js/bindings/CachedBytecode.zig
Normal file
@@ -0,0 +1,116 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const CachedBytecode = opaque {
|
||||
extern fn generateCachedModuleByteCodeFromSourceCode(sourceProviderURL: *bun.String, input_code: [*]const u8, inputSourceCodeSize: usize, outputByteCode: *?[*]u8, outputByteCodeSize: *usize, cached_bytecode: *?*CachedBytecode) bool;
|
||||
extern fn generateCachedCommonJSProgramByteCodeFromSourceCode(sourceProviderURL: *bun.String, input_code: [*]const u8, inputSourceCodeSize: usize, outputByteCode: *?[*]u8, outputByteCodeSize: *usize, cached_bytecode: *?*CachedBytecode) bool;
|
||||
|
||||
pub fn generateForESM(sourceProviderURL: *bun.String, input: []const u8) ?struct { []const u8, *CachedBytecode } {
|
||||
var this: ?*CachedBytecode = null;
|
||||
|
||||
var input_code_size: usize = 0;
|
||||
var input_code_ptr: ?[*]u8 = null;
|
||||
if (generateCachedModuleByteCodeFromSourceCode(sourceProviderURL, input.ptr, input.len, &input_code_ptr, &input_code_size, &this)) {
|
||||
return .{ input_code_ptr.?[0..input_code_size], this.? };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn generateForCJS(sourceProviderURL: *bun.String, input: []const u8) ?struct { []const u8, *CachedBytecode } {
|
||||
var this: ?*CachedBytecode = null;
|
||||
var input_code_size: usize = 0;
|
||||
var input_code_ptr: ?[*]u8 = null;
|
||||
if (generateCachedCommonJSProgramByteCodeFromSourceCode(sourceProviderURL, input.ptr, input.len, &input_code_ptr, &input_code_size, &this)) {
|
||||
return .{ input_code_ptr.?[0..input_code_size], this.? };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
extern "c" fn CachedBytecode__deref(this: *CachedBytecode) void;
|
||||
pub fn deref(this: *CachedBytecode) void {
|
||||
return CachedBytecode__deref(this);
|
||||
}
|
||||
|
||||
pub fn generate(format: bun.options.Format, input: []const u8, source_provider_url: *bun.String) ?struct { []const u8, *CachedBytecode } {
|
||||
return switch (format) {
|
||||
.esm => generateForESM(source_provider_url, input),
|
||||
.cjs => generateForCJS(source_provider_url, input),
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
pub const VTable = &std.mem.Allocator.VTable{
|
||||
.alloc = struct {
|
||||
pub fn alloc(ctx: *anyopaque, len: usize, ptr_align: u8, ret_addr: usize) ?[*]u8 {
|
||||
_ = ctx; // autofix
|
||||
_ = len; // autofix
|
||||
_ = ptr_align; // autofix
|
||||
_ = ret_addr; // autofix
|
||||
@panic("Unexpectedly called CachedBytecode.alloc");
|
||||
}
|
||||
}.alloc,
|
||||
.resize = struct {
|
||||
pub fn resize(ctx: *anyopaque, buf: []u8, buf_align: u8, new_len: usize, ret_addr: usize) bool {
|
||||
_ = ctx; // autofix
|
||||
_ = buf; // autofix
|
||||
_ = buf_align; // autofix
|
||||
_ = new_len; // autofix
|
||||
_ = ret_addr; // autofix
|
||||
return false;
|
||||
}
|
||||
}.resize,
|
||||
.free = struct {
|
||||
pub fn free(ctx: *anyopaque, buf: []u8, buf_align: u8, _: usize) void {
|
||||
_ = buf; // autofix
|
||||
_ = buf_align; // autofix
|
||||
CachedBytecode__deref(@ptrCast(ctx));
|
||||
}
|
||||
}.free,
|
||||
};
|
||||
|
||||
pub fn allocator(this: *CachedBytecode) std.mem.Allocator {
|
||||
return .{
|
||||
.ptr = this,
|
||||
.vtable = VTable,
|
||||
};
|
||||
}
|
||||
};
|
||||
223
src/bun.js/bindings/CallFrame.zig
Normal file
223
src/bun.js/bindings/CallFrame.zig
Normal file
@@ -0,0 +1,223 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
|
||||
pub const CallFrame = opaque {
|
||||
/// A slice of all passed arguments to this function call.
|
||||
pub fn arguments(self: *const CallFrame) []const JSValue {
|
||||
return self.asUnsafeJSValueArray()[offset_first_argument..][0..self.argumentsCount()];
|
||||
}
|
||||
|
||||
/// Usage: `const arg1, const arg2 = call_frame.argumentsAsArray(2);`
|
||||
pub fn argumentsAsArray(call_frame: *const CallFrame, comptime count: usize) [count]JSValue {
|
||||
const slice = call_frame.arguments();
|
||||
var value: [count]JSValue = .{.undefined} ** count;
|
||||
const n = @min(call_frame.argumentsCount(), count);
|
||||
@memcpy(value[0..n], slice[0..n]);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// This function protects out-of-bounds access by returning `JSValue.undefined`
|
||||
pub fn argument(self: *const CallFrame, i: usize) JSC.JSValue {
|
||||
return if (self.argumentsCount() > i) self.arguments()[i] else .undefined;
|
||||
}
|
||||
|
||||
pub fn argumentsCount(self: *const CallFrame) u32 {
|
||||
return self.argumentCountIncludingThis() - 1;
|
||||
}
|
||||
|
||||
/// When this CallFrame belongs to a constructor, this value is not the `this`
|
||||
/// value, but instead the value of `new.target`.
|
||||
pub fn this(self: *const CallFrame) JSC.JSValue {
|
||||
return self.asUnsafeJSValueArray()[offset_this_argument];
|
||||
}
|
||||
|
||||
/// `JSValue` for the current function being called.
|
||||
pub fn callee(self: *const CallFrame) JSC.JSValue {
|
||||
return self.asUnsafeJSValueArray()[offset_callee];
|
||||
}
|
||||
|
||||
/// From JavaScriptCore/interpreter/CallFrame.h
|
||||
///
|
||||
/// | ...... | |
|
||||
/// +----------------------------+ |
|
||||
/// | argN | v lower address
|
||||
/// +----------------------------+
|
||||
/// | arg1 |
|
||||
/// +----------------------------+
|
||||
/// | arg0 |
|
||||
/// +----------------------------+
|
||||
/// | this |
|
||||
/// +----------------------------+
|
||||
/// | argumentCountIncludingThis |
|
||||
/// +----------------------------+
|
||||
/// | callee |
|
||||
/// +----------------------------+
|
||||
/// | codeBlock |
|
||||
/// +----------------------------+
|
||||
/// | return-address |
|
||||
/// +----------------------------+
|
||||
/// | callerFrame |
|
||||
/// +----------------------------+ <- callee's cfr is pointing this address
|
||||
/// | local0 |
|
||||
/// +----------------------------+
|
||||
/// | local1 |
|
||||
/// +----------------------------+
|
||||
/// | localN |
|
||||
/// +----------------------------+
|
||||
/// | ...... |
|
||||
///
|
||||
/// The proper return type of this should be []Register, but
|
||||
inline fn asUnsafeJSValueArray(self: *const CallFrame) [*]const JSC.JSValue {
|
||||
return @ptrCast(@alignCast(self));
|
||||
}
|
||||
|
||||
// These constants are from JSC::CallFrameSlot in JavaScriptCore/interpreter/CallFrame.h
|
||||
const offset_code_block = 2;
|
||||
const offset_callee = offset_code_block + 1;
|
||||
const offset_argument_count_including_this = offset_callee + 1;
|
||||
const offset_this_argument = offset_argument_count_including_this + 1;
|
||||
const offset_first_argument = offset_this_argument + 1;
|
||||
|
||||
/// This function is manually ported from JSC's equivalent function in C++
|
||||
/// See JavaScriptCore/interpreter/CallFrame.h
|
||||
fn argumentCountIncludingThis(self: *const CallFrame) u32 {
|
||||
// Register defined in JavaScriptCore/interpreter/Register.h
|
||||
const Register = extern union {
|
||||
value: JSValue, // EncodedJSValue
|
||||
call_frame: *CallFrame,
|
||||
code_block: *anyopaque, // CodeBlock*
|
||||
/// EncodedValueDescriptor defined in JavaScriptCore/runtime/JSCJSValue.h
|
||||
encoded_value: extern union {
|
||||
ptr: JSValue, // JSCell*
|
||||
as_bits: extern struct {
|
||||
payload: i32,
|
||||
tag: i32,
|
||||
},
|
||||
},
|
||||
number: f64, // double
|
||||
integer: i64, // integer
|
||||
};
|
||||
const registers: [*]const Register = @alignCast(@ptrCast(self));
|
||||
// argumentCountIncludingThis takes the register at the defined offset, then
|
||||
// calls 'ALWAYS_INLINE int32_t Register::unboxedInt32() const',
|
||||
// which in turn calls 'ALWAYS_INLINE int32_t Register::payload() const'
|
||||
// which accesses `.encodedValue.asBits.payload`
|
||||
// JSC stores and works with value as signed, but it is always 1 or more.
|
||||
return @intCast(registers[offset_argument_count_including_this].encoded_value.as_bits.payload);
|
||||
}
|
||||
|
||||
fn Arguments(comptime max: usize) type {
|
||||
return struct {
|
||||
ptr: [max]JSC.JSValue,
|
||||
len: usize,
|
||||
|
||||
pub inline fn init(comptime i: usize, ptr: [*]const JSC.JSValue) @This() {
|
||||
var args: [max]JSC.JSValue = std.mem.zeroes([max]JSC.JSValue);
|
||||
args[0..i].* = ptr[0..i].*;
|
||||
|
||||
return @This(){
|
||||
.ptr = args,
|
||||
.len = i,
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn initUndef(comptime i: usize, ptr: [*]const JSC.JSValue) @This() {
|
||||
var args = [1]JSC.JSValue{.undefined} ** max;
|
||||
args[0..i].* = ptr[0..i].*;
|
||||
return @This(){ .ptr = args, .len = i };
|
||||
}
|
||||
|
||||
pub inline fn slice(self: *const @This()) []const JSValue {
|
||||
return self.ptr[0..self.len];
|
||||
}
|
||||
|
||||
pub inline fn mut(self: *@This()) []JSValue {
|
||||
return self.ptr[0..];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Do not use this function. Migration path:
|
||||
/// arguments(n).ptr[k] -> argumentsAsArray(n)[k]
|
||||
/// arguments(n).slice() -> arguments()
|
||||
/// arguments(n).mut() -> `var args = argumentsAsArray(n); &args`
|
||||
pub fn arguments_old(self: *const CallFrame, comptime max: usize) Arguments(max) {
|
||||
const slice = self.arguments();
|
||||
comptime bun.assert(max <= 14);
|
||||
return switch (@as(u4, @min(slice.len, max))) {
|
||||
0 => .{ .ptr = undefined, .len = 0 },
|
||||
inline 1...14 => |count| Arguments(max).init(comptime @min(count, max), slice.ptr),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
/// Do not use this function. Migration path:
|
||||
/// argumentsAsArray(n)
|
||||
pub fn argumentsUndef(self: *const CallFrame, comptime max: usize) Arguments(max) {
|
||||
const slice = self.arguments();
|
||||
comptime bun.assert(max <= 9);
|
||||
return switch (@as(u4, @min(slice.len, max))) {
|
||||
0 => .{ .ptr = .{.undefined} ** max, .len = 0 },
|
||||
inline 1...9 => |count| Arguments(max).initUndef(@min(count, max), slice.ptr),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
extern fn Bun__CallFrame__isFromBunMain(*const CallFrame, *const VM) bool;
|
||||
pub const isFromBunMain = Bun__CallFrame__isFromBunMain;
|
||||
|
||||
extern fn Bun__CallFrame__getCallerSrcLoc(*const CallFrame, *JSGlobalObject, *bun.String, *c_uint, *c_uint) void;
|
||||
pub const CallerSrcLoc = struct {
|
||||
str: bun.String,
|
||||
line: c_uint,
|
||||
column: c_uint,
|
||||
};
|
||||
pub fn getCallerSrcLoc(call_frame: *const CallFrame, globalThis: *JSGlobalObject) CallerSrcLoc {
|
||||
var str: bun.String = undefined;
|
||||
var line: c_uint = undefined;
|
||||
var column: c_uint = undefined;
|
||||
Bun__CallFrame__getCallerSrcLoc(call_frame, globalThis, &str, &line, &column);
|
||||
return .{
|
||||
.str = str,
|
||||
.line = line,
|
||||
.column = column,
|
||||
};
|
||||
}
|
||||
};
|
||||
72
src/bun.js/bindings/CommonStrings.zig
Normal file
72
src/bun.js/bindings/CommonStrings.zig
Normal file
@@ -0,0 +1,72 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
const JSGlobalObject = JSC.JSGlobalObject;
|
||||
const VM = JSC.VM;
|
||||
const ZigString = JSC.ZigString;
|
||||
const URL = JSC.URL;
|
||||
const WTF = JSC.WTF;
|
||||
const JSString = JSC.JSString;
|
||||
const JSObject = JSC.JSObject;
|
||||
const JSValue = JSC.JSValue;
|
||||
pub const CommonStrings = struct {
|
||||
globalObject: *JSC.JSGlobalObject,
|
||||
|
||||
pub inline fn IPv4(this: CommonStrings) JSValue {
|
||||
return this.getString("IPv4");
|
||||
}
|
||||
pub inline fn IPv6(this: CommonStrings) JSValue {
|
||||
return this.getString("IPv6");
|
||||
}
|
||||
pub inline fn @"127.0.0.1"(this: CommonStrings) JSValue {
|
||||
return this.getString("IN4Loopback");
|
||||
}
|
||||
pub inline fn @"::"(this: CommonStrings) JSValue {
|
||||
return this.getString("IN6Any");
|
||||
}
|
||||
|
||||
inline fn getString(this: CommonStrings, comptime name: anytype) JSValue {
|
||||
JSC.markMemberBinding("CommonStrings", @src());
|
||||
const str: JSC.JSValue = @call(
|
||||
.auto,
|
||||
@field(CommonStrings, "JSC__JSGlobalObject__commonStrings__get" ++ name),
|
||||
.{this.globalObject},
|
||||
);
|
||||
bun.assert(str != .zero);
|
||||
if (comptime bun.Environment.isDebug) {
|
||||
bun.assertWithLocation(str != .zero, @src());
|
||||
bun.assertWithLocation(str.isStringLiteral(), @src());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
extern "C" fn JSC__JSGlobalObject__commonStrings__getIPv4(global: *JSC.JSGlobalObject) JSC.JSValue;
|
||||
extern "C" fn JSC__JSGlobalObject__commonStrings__getIPv6(global: *JSC.JSGlobalObject) JSC.JSValue;
|
||||
extern "C" fn JSC__JSGlobalObject__commonStrings__getIN4Loopback(global: *JSC.JSGlobalObject) JSC.JSValue;
|
||||
extern "C" fn JSC__JSGlobalObject__commonStrings__getIN6Any(global: *JSC.JSGlobalObject) JSC.JSValue;
|
||||
};
|
||||
46
src/bun.js/bindings/CustomGetterSetter.zig
Normal file
46
src/bun.js/bindings/CustomGetterSetter.zig
Normal file
@@ -0,0 +1,46 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
|
||||
pub const CustomGetterSetter = extern struct {
|
||||
pub const shim = Shimmer("JSC", "CustomGetterSetter", @This());
|
||||
bytes: shim.Bytes,
|
||||
const cppFn = shim.cppFn;
|
||||
pub const include = "JavaScriptCore/CustomGetterSetter.h";
|
||||
pub const name = "JSC::CustomGetterSetter";
|
||||
pub const namespace = "JSC";
|
||||
|
||||
pub fn isGetterNull(this: *CustomGetterSetter) bool {
|
||||
return shim.cppFn("isGetterNull", .{this});
|
||||
}
|
||||
|
||||
pub fn isSetterNull(this: *CustomGetterSetter) bool {
|
||||
return shim.cppFn("isSetterNull", .{this});
|
||||
}
|
||||
};
|
||||
171
src/bun.js/bindings/DOMFormData.zig
Normal file
171
src/bun.js/bindings/DOMFormData.zig
Normal file
@@ -0,0 +1,171 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const DOMFormData = opaque {
|
||||
extern fn WebCore__DOMFormData__cast_(JSValue0: JSValue, arg1: *VM) ?*DOMFormData;
|
||||
extern fn WebCore__DOMFormData__create(arg0: *JSGlobalObject) JSValue;
|
||||
extern fn WebCore__DOMFormData__createFromURLQuery(arg0: *JSGlobalObject, arg1: *ZigString) JSValue;
|
||||
extern fn WebCore__DOMFormData__toQueryString(arg0: *DOMFormData, arg1: *anyopaque, arg2: *const fn (arg0: *anyopaque, *ZigString) callconv(.C) void) void;
|
||||
extern fn WebCore__DOMFormData__fromJS(JSValue0: JSValue) ?*DOMFormData;
|
||||
extern fn WebCore__DOMFormData__append(arg0: *DOMFormData, arg1: *ZigString, arg2: *ZigString) void;
|
||||
extern fn WebCore__DOMFormData__appendBlob(arg0: *DOMFormData, arg1: *JSGlobalObject, arg2: *ZigString, arg3: *anyopaque, arg4: *ZigString) void;
|
||||
extern fn WebCore__DOMFormData__count(arg0: *DOMFormData) usize;
|
||||
|
||||
pub fn create(
|
||||
global: *JSGlobalObject,
|
||||
) JSValue {
|
||||
return WebCore__DOMFormData__create(global);
|
||||
}
|
||||
|
||||
pub fn createFromURLQuery(
|
||||
global: *JSGlobalObject,
|
||||
query: *ZigString,
|
||||
) JSValue {
|
||||
return WebCore__DOMFormData__createFromURLQuery(global, query);
|
||||
}
|
||||
|
||||
extern fn DOMFormData__toQueryString(
|
||||
*DOMFormData,
|
||||
ctx: *anyopaque,
|
||||
callback: *const fn (ctx: *anyopaque, *ZigString) callconv(.C) void,
|
||||
) void;
|
||||
|
||||
pub fn toQueryString(
|
||||
this: *DOMFormData,
|
||||
comptime Ctx: type,
|
||||
ctx: Ctx,
|
||||
comptime callback: fn (ctx: Ctx, ZigString) callconv(.C) void,
|
||||
) void {
|
||||
const Wrapper = struct {
|
||||
const cb = callback;
|
||||
pub fn run(c: *anyopaque, str: *ZigString) callconv(.C) void {
|
||||
cb(@as(Ctx, @ptrCast(c)), str.*);
|
||||
}
|
||||
};
|
||||
|
||||
WebCore__DOMFormData__toQueryString(this, ctx, &Wrapper.run);
|
||||
}
|
||||
|
||||
pub fn fromJS(value: JSValue) ?*DOMFormData {
|
||||
return WebCore__DOMFormData__fromJS(value);
|
||||
}
|
||||
|
||||
pub fn append(
|
||||
this: *DOMFormData,
|
||||
name_: *ZigString,
|
||||
value_: *ZigString,
|
||||
) void {
|
||||
WebCore__DOMFormData__append(this, name_, value_);
|
||||
}
|
||||
|
||||
pub fn appendBlob(
|
||||
this: *DOMFormData,
|
||||
global: *JSC.JSGlobalObject,
|
||||
name_: *ZigString,
|
||||
blob: *anyopaque,
|
||||
filename_: *ZigString,
|
||||
) void {
|
||||
return WebCore__DOMFormData__appendBlob(this, global, name_, blob, filename_);
|
||||
}
|
||||
|
||||
pub fn count(
|
||||
this: *DOMFormData,
|
||||
) usize {
|
||||
return WebCore__DOMFormData__count(this);
|
||||
}
|
||||
|
||||
const ForEachFunction = *const fn (
|
||||
ctx_ptr: ?*anyopaque,
|
||||
name: *ZigString,
|
||||
value_ptr: *anyopaque,
|
||||
filename: ?*ZigString,
|
||||
is_blob: u8,
|
||||
) callconv(.C) void;
|
||||
|
||||
extern fn DOMFormData__forEach(*DOMFormData, ?*anyopaque, ForEachFunction) void;
|
||||
pub const FormDataEntry = union(enum) {
|
||||
string: ZigString,
|
||||
file: struct {
|
||||
blob: *JSC.WebCore.Blob,
|
||||
filename: ZigString,
|
||||
},
|
||||
};
|
||||
pub fn forEach(
|
||||
this: *DOMFormData,
|
||||
comptime Context: type,
|
||||
ctx: *Context,
|
||||
comptime callback_wrapper: *const fn (ctx: *Context, name: ZigString, value: FormDataEntry) void,
|
||||
) void {
|
||||
const Wrap = struct {
|
||||
const wrapper = callback_wrapper;
|
||||
pub fn forEachWrapper(
|
||||
ctx_ptr: ?*anyopaque,
|
||||
name_: *ZigString,
|
||||
value_ptr: *anyopaque,
|
||||
filename: ?*ZigString,
|
||||
is_blob: u8,
|
||||
) callconv(.C) void {
|
||||
const ctx_ = bun.cast(*Context, ctx_ptr.?);
|
||||
const value = if (is_blob == 0)
|
||||
FormDataEntry{ .string = bun.cast(*ZigString, value_ptr).* }
|
||||
else
|
||||
FormDataEntry{
|
||||
.file = .{
|
||||
.blob = bun.cast(*JSC.WebCore.Blob, value_ptr),
|
||||
.filename = (filename orelse &ZigString.Empty).*,
|
||||
},
|
||||
};
|
||||
|
||||
wrapper(ctx_, name_.*, value);
|
||||
}
|
||||
};
|
||||
JSC.markBinding(@src());
|
||||
DOMFormData__forEach(this, ctx, Wrap.forEachWrapper);
|
||||
}
|
||||
|
||||
pub const Extern = [_][]const u8{
|
||||
"create",
|
||||
"fromJS",
|
||||
"append",
|
||||
"appendBlob",
|
||||
"count",
|
||||
"createFromURLQuery",
|
||||
};
|
||||
};
|
||||
92
src/bun.js/bindings/DOMURL.zig
Normal file
92
src/bun.js/bindings/DOMURL.zig
Normal file
@@ -0,0 +1,92 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const DOMURL = opaque {
|
||||
pub extern fn WebCore__DOMURL__cast_(JSValue0: JSValue, arg1: *VM) ?*DOMURL;
|
||||
pub extern fn WebCore__DOMURL__href_(arg0: ?*DOMURL, arg1: *ZigString) void;
|
||||
pub extern fn WebCore__DOMURL__pathname_(arg0: ?*DOMURL, arg1: *ZigString) void;
|
||||
|
||||
pub fn cast_(value: JSValue, vm: *VM) ?*DOMURL {
|
||||
return WebCore__DOMURL__cast_(value, vm);
|
||||
}
|
||||
|
||||
pub fn cast(value: JSValue) ?*DOMURL {
|
||||
return cast_(value, JSC.VirtualMachine.get().global.vm());
|
||||
}
|
||||
|
||||
pub fn href_(this: *DOMURL, out: *ZigString) void {
|
||||
return WebCore__DOMURL__href_(this, out);
|
||||
}
|
||||
|
||||
pub fn href(this: *DOMURL) ZigString {
|
||||
var out = ZigString.Empty;
|
||||
this.href_(&out);
|
||||
return out;
|
||||
}
|
||||
|
||||
extern fn WebCore__DOMURL__fileSystemPath(arg0: *DOMURL, error_code: *c_int) bun.String;
|
||||
pub const ToFileSystemPathError = error{
|
||||
NotFileUrl,
|
||||
InvalidPath,
|
||||
InvalidHost,
|
||||
};
|
||||
pub fn fileSystemPath(this: *DOMURL) ToFileSystemPathError!bun.String {
|
||||
var error_code: c_int = 0;
|
||||
const path = WebCore__DOMURL__fileSystemPath(this, &error_code);
|
||||
switch (error_code) {
|
||||
1 => return ToFileSystemPathError.InvalidHost,
|
||||
2 => return ToFileSystemPathError.InvalidPath,
|
||||
3 => return ToFileSystemPathError.NotFileUrl,
|
||||
else => {},
|
||||
}
|
||||
bun.assert(path.tag != .Dead);
|
||||
return path;
|
||||
}
|
||||
|
||||
pub fn pathname_(this: *DOMURL, out: *ZigString) void {
|
||||
return WebCore__DOMURL__pathname_(this, out);
|
||||
}
|
||||
|
||||
pub fn pathname(this: *DOMURL) ZigString {
|
||||
var out = ZigString.Empty;
|
||||
this.pathname_(&out);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
65
src/bun.js/bindings/DeferredError.zig
Normal file
65
src/bun.js/bindings/DeferredError.zig
Normal file
@@ -0,0 +1,65 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const DeferredError = struct {
|
||||
kind: Kind,
|
||||
code: JSC.Node.ErrorCode,
|
||||
msg: bun.String,
|
||||
|
||||
pub const Kind = enum { plainerror, typeerror, rangeerror };
|
||||
|
||||
pub fn from(kind: Kind, code: JSC.Node.ErrorCode, comptime fmt: [:0]const u8, args: anytype) DeferredError {
|
||||
return .{
|
||||
.kind = kind,
|
||||
.code = code,
|
||||
.msg = bun.String.createFormat(fmt, args) catch bun.outOfMemory(),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toError(this: *const DeferredError, globalThis: *JSGlobalObject) JSValue {
|
||||
const err = switch (this.kind) {
|
||||
.plainerror => this.msg.toErrorInstance(globalThis),
|
||||
.typeerror => this.msg.toTypeErrorInstance(globalThis),
|
||||
.rangeerror => this.msg.toRangeErrorInstance(globalThis),
|
||||
};
|
||||
err.put(globalThis, ZigString.static("code"), ZigString.init(@tagName(this.code)).toJS(globalThis));
|
||||
return err;
|
||||
}
|
||||
};
|
||||
465
src/bun.js/bindings/FetchHeaders.zig
Normal file
465
src/bun.js/bindings/FetchHeaders.zig
Normal file
@@ -0,0 +1,465 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const FetchHeaders = opaque {
|
||||
extern fn WebCore__FetchHeaders__append(arg0: *FetchHeaders, arg1: *const ZigString, arg2: *const ZigString, arg3: *JSGlobalObject) void;
|
||||
extern fn WebCore__FetchHeaders__cast_(JSValue0: JSValue, arg1: *VM) ?*FetchHeaders;
|
||||
extern fn WebCore__FetchHeaders__clone(arg0: *FetchHeaders, arg1: *JSGlobalObject) JSValue;
|
||||
extern fn WebCore__FetchHeaders__cloneThis(arg0: *FetchHeaders, arg1: *JSGlobalObject) *FetchHeaders;
|
||||
extern fn WebCore__FetchHeaders__copyTo(arg0: *FetchHeaders, arg1: [*]StringPointer, arg2: [*]StringPointer, arg3: [*]u8) void;
|
||||
extern fn WebCore__FetchHeaders__count(arg0: *FetchHeaders, arg1: *u32, arg2: *u32) void;
|
||||
extern fn WebCore__FetchHeaders__createEmpty() *FetchHeaders;
|
||||
extern fn WebCore__FetchHeaders__createFromPicoHeaders_(arg0: ?*const anyopaque) *FetchHeaders;
|
||||
extern fn WebCore__FetchHeaders__createFromUWS(arg1: *anyopaque) *FetchHeaders;
|
||||
extern fn WebCore__FetchHeaders__createValue(arg0: *JSGlobalObject, arg1: [*c]StringPointer, arg2: [*c]StringPointer, arg3: [*c]const ZigString, arg4: u32) JSValue;
|
||||
extern fn WebCore__FetchHeaders__deref(arg0: *FetchHeaders) void;
|
||||
extern fn WebCore__FetchHeaders__fastGet_(arg0: *FetchHeaders, arg1: u8, arg2: [*c]ZigString) void;
|
||||
extern fn WebCore__FetchHeaders__fastHas_(arg0: *FetchHeaders, arg1: u8) bool;
|
||||
extern fn WebCore__FetchHeaders__fastRemove_(arg0: *FetchHeaders, arg1: u8) void;
|
||||
extern fn WebCore__FetchHeaders__get_(arg0: *FetchHeaders, arg1: [*c]const ZigString, arg2: [*c]ZigString, arg3: *JSGlobalObject) void;
|
||||
extern fn WebCore__FetchHeaders__has(arg0: *FetchHeaders, arg1: [*c]const ZigString, arg2: *JSGlobalObject) bool;
|
||||
extern fn WebCore__FetchHeaders__isEmpty(arg0: *FetchHeaders) bool;
|
||||
extern fn WebCore__FetchHeaders__put_(arg0: *FetchHeaders, arg1: [*c]const ZigString, arg2: [*c]const ZigString, arg3: *JSGlobalObject) void;
|
||||
extern fn WebCore__FetchHeaders__remove(arg0: *FetchHeaders, arg1: [*c]const ZigString, arg2: *JSGlobalObject) void;
|
||||
extern fn WebCore__FetchHeaders__toJS(arg0: *FetchHeaders, arg1: *JSGlobalObject) JSValue;
|
||||
extern fn WebCore__FetchHeaders__toUWSResponse(arg0: *FetchHeaders, arg1: bool, arg2: ?*anyopaque) void;
|
||||
|
||||
pub fn createValue(
|
||||
global: *JSGlobalObject,
|
||||
names: [*c]Api.StringPointer,
|
||||
values: [*c]Api.StringPointer,
|
||||
buf: *const ZigString,
|
||||
count_: u32,
|
||||
) JSValue {
|
||||
return WebCore__FetchHeaders__createValue(
|
||||
global,
|
||||
names,
|
||||
values,
|
||||
buf,
|
||||
count_,
|
||||
);
|
||||
}
|
||||
|
||||
extern "c" fn WebCore__FetchHeaders__createFromJS(*JSC.JSGlobalObject, JSValue) ?*FetchHeaders;
|
||||
/// Construct a `Headers` object from a JSValue.
|
||||
///
|
||||
/// This can be:
|
||||
/// - Array<[String, String]>
|
||||
/// - Record<String, String>.
|
||||
///
|
||||
/// Throws an exception if invalid.
|
||||
///
|
||||
/// If empty, returns null.
|
||||
pub fn createFromJS(
|
||||
global: *JSGlobalObject,
|
||||
value: JSValue,
|
||||
) ?*FetchHeaders {
|
||||
return WebCore__FetchHeaders__createFromJS(global, value);
|
||||
}
|
||||
|
||||
pub fn putDefault(this: *FetchHeaders, name_: HTTPHeaderName, value: []const u8, global: *JSGlobalObject) void {
|
||||
if (this.fastHas(name_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.put(name_, value, global);
|
||||
}
|
||||
|
||||
pub fn from(
|
||||
global: *JSGlobalObject,
|
||||
names: [*c]Api.StringPointer,
|
||||
values: [*c]Api.StringPointer,
|
||||
buf: *const ZigString,
|
||||
count_: u32,
|
||||
) JSValue {
|
||||
return WebCore__FetchHeaders__createValue(
|
||||
global,
|
||||
names,
|
||||
values,
|
||||
buf,
|
||||
count_,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn isEmpty(this: *FetchHeaders) bool {
|
||||
return WebCore__FetchHeaders__isEmpty(this);
|
||||
}
|
||||
|
||||
pub fn createFromUWS(
|
||||
uws_request: *anyopaque,
|
||||
) *FetchHeaders {
|
||||
return WebCore__FetchHeaders__createFromUWS(
|
||||
uws_request,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn toUWSResponse(
|
||||
headers: *FetchHeaders,
|
||||
is_ssl: bool,
|
||||
uws_response: *anyopaque,
|
||||
) void {
|
||||
return WebCore__FetchHeaders__toUWSResponse(
|
||||
headers,
|
||||
is_ssl,
|
||||
uws_response,
|
||||
);
|
||||
}
|
||||
|
||||
const PicoHeaders = extern struct {
|
||||
ptr: ?*const anyopaque,
|
||||
len: usize,
|
||||
};
|
||||
|
||||
pub fn createEmpty() *FetchHeaders {
|
||||
return WebCore__FetchHeaders__createEmpty();
|
||||
}
|
||||
|
||||
pub fn createFromPicoHeaders(
|
||||
pico_headers: anytype,
|
||||
) *FetchHeaders {
|
||||
const out = PicoHeaders{ .ptr = pico_headers.list.ptr, .len = pico_headers.list.len };
|
||||
const result = WebCore__FetchHeaders__createFromPicoHeaders_(
|
||||
&out,
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn createFromPicoHeaders_(
|
||||
pico_headers: *const anyopaque,
|
||||
) *FetchHeaders {
|
||||
return WebCore__FetchHeaders__createFromPicoHeaders_(pico_headers);
|
||||
}
|
||||
|
||||
pub fn append(
|
||||
this: *FetchHeaders,
|
||||
name_: *const ZigString,
|
||||
value: *const ZigString,
|
||||
global: *JSGlobalObject,
|
||||
) void {
|
||||
return WebCore__FetchHeaders__append(
|
||||
this,
|
||||
name_,
|
||||
value,
|
||||
global,
|
||||
);
|
||||
}
|
||||
|
||||
extern fn WebCore__FetchHeaders__put(this: *FetchHeaders, name_: HTTPHeaderName, value: *const ZigString, global: *JSGlobalObject) void;
|
||||
|
||||
pub fn put(
|
||||
this: *FetchHeaders,
|
||||
name_: HTTPHeaderName,
|
||||
value: []const u8,
|
||||
global: *JSGlobalObject,
|
||||
) void {
|
||||
WebCore__FetchHeaders__put(this, name_, &ZigString.init(value), global);
|
||||
}
|
||||
|
||||
pub fn get_(
|
||||
this: *FetchHeaders,
|
||||
name_: *const ZigString,
|
||||
out: *ZigString,
|
||||
global: *JSGlobalObject,
|
||||
) void {
|
||||
WebCore__FetchHeaders__get_(
|
||||
this,
|
||||
name_,
|
||||
out,
|
||||
global,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn get(
|
||||
this: *FetchHeaders,
|
||||
name_: []const u8,
|
||||
global: *JSGlobalObject,
|
||||
) ?[]const u8 {
|
||||
var out = ZigString.Empty;
|
||||
get_(this, &ZigString.init(name_), &out, global);
|
||||
if (out.len > 0) {
|
||||
return out.slice();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn has(
|
||||
this: *FetchHeaders,
|
||||
name_: *const ZigString,
|
||||
global: *JSGlobalObject,
|
||||
) bool {
|
||||
return WebCore__FetchHeaders__has(
|
||||
this,
|
||||
name_,
|
||||
global,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn fastHas(
|
||||
this: *FetchHeaders,
|
||||
name_: HTTPHeaderName,
|
||||
) bool {
|
||||
return fastHas_(this, @intFromEnum(name_));
|
||||
}
|
||||
|
||||
pub fn fastGet(
|
||||
this: *FetchHeaders,
|
||||
name_: HTTPHeaderName,
|
||||
) ?ZigString {
|
||||
var str = ZigString.init("");
|
||||
fastGet_(this, @intFromEnum(name_), &str);
|
||||
if (str.len == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
pub fn fastHas_(
|
||||
this: *FetchHeaders,
|
||||
name_: u8,
|
||||
) bool {
|
||||
return WebCore__FetchHeaders__fastHas_(
|
||||
this,
|
||||
name_,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn fastGet_(
|
||||
this: *FetchHeaders,
|
||||
name_: u8,
|
||||
str: *ZigString,
|
||||
) void {
|
||||
return WebCore__FetchHeaders__fastGet_(
|
||||
this,
|
||||
name_,
|
||||
str,
|
||||
);
|
||||
}
|
||||
|
||||
pub const HTTPHeaderName = enum(u8) {
|
||||
Accept,
|
||||
AcceptCharset,
|
||||
AcceptEncoding,
|
||||
AcceptLanguage,
|
||||
AcceptRanges,
|
||||
AccessControlAllowCredentials,
|
||||
AccessControlAllowHeaders,
|
||||
AccessControlAllowMethods,
|
||||
AccessControlAllowOrigin,
|
||||
AccessControlExposeHeaders,
|
||||
AccessControlMaxAge,
|
||||
AccessControlRequestHeaders,
|
||||
AccessControlRequestMethod,
|
||||
Age,
|
||||
Authorization,
|
||||
CacheControl,
|
||||
Connection,
|
||||
ContentDisposition,
|
||||
ContentEncoding,
|
||||
ContentLanguage,
|
||||
ContentLength,
|
||||
ContentLocation,
|
||||
ContentRange,
|
||||
ContentSecurityPolicy,
|
||||
ContentSecurityPolicyReportOnly,
|
||||
ContentType,
|
||||
Cookie,
|
||||
Cookie2,
|
||||
CrossOriginEmbedderPolicy,
|
||||
CrossOriginEmbedderPolicyReportOnly,
|
||||
CrossOriginOpenerPolicy,
|
||||
CrossOriginOpenerPolicyReportOnly,
|
||||
CrossOriginResourcePolicy,
|
||||
DNT,
|
||||
Date,
|
||||
DefaultStyle,
|
||||
ETag,
|
||||
Expect,
|
||||
Expires,
|
||||
Host,
|
||||
IcyMetaInt,
|
||||
IcyMetadata,
|
||||
IfMatch,
|
||||
IfModifiedSince,
|
||||
IfNoneMatch,
|
||||
IfRange,
|
||||
IfUnmodifiedSince,
|
||||
KeepAlive,
|
||||
LastEventID,
|
||||
LastModified,
|
||||
Link,
|
||||
Location,
|
||||
Origin,
|
||||
PingFrom,
|
||||
PingTo,
|
||||
Pragma,
|
||||
ProxyAuthorization,
|
||||
Purpose,
|
||||
Range,
|
||||
Referer,
|
||||
ReferrerPolicy,
|
||||
Refresh,
|
||||
ReportTo,
|
||||
SecFetchDest,
|
||||
SecFetchMode,
|
||||
SecWebSocketAccept,
|
||||
SecWebSocketExtensions,
|
||||
SecWebSocketKey,
|
||||
SecWebSocketProtocol,
|
||||
SecWebSocketVersion,
|
||||
ServerTiming,
|
||||
ServiceWorker,
|
||||
ServiceWorkerAllowed,
|
||||
ServiceWorkerNavigationPreload,
|
||||
SetCookie,
|
||||
SetCookie2,
|
||||
SourceMap,
|
||||
StrictTransportSecurity,
|
||||
TE,
|
||||
TimingAllowOrigin,
|
||||
Trailer,
|
||||
TransferEncoding,
|
||||
Upgrade,
|
||||
UpgradeInsecureRequests,
|
||||
UserAgent,
|
||||
Vary,
|
||||
Via,
|
||||
XContentTypeOptions,
|
||||
XDNSPrefetchControl,
|
||||
XFrameOptions,
|
||||
XSourceMap,
|
||||
XTempTablet,
|
||||
XXSSProtection,
|
||||
};
|
||||
|
||||
pub fn fastRemove(
|
||||
this: *FetchHeaders,
|
||||
header: HTTPHeaderName,
|
||||
) void {
|
||||
return fastRemove_(this, @intFromEnum(header));
|
||||
}
|
||||
|
||||
pub fn fastRemove_(
|
||||
this: *FetchHeaders,
|
||||
header: u8,
|
||||
) void {
|
||||
return WebCore__FetchHeaders__fastRemove_(
|
||||
this,
|
||||
header,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn remove(
|
||||
this: *FetchHeaders,
|
||||
name_: *const ZigString,
|
||||
global: *JSGlobalObject,
|
||||
) void {
|
||||
return WebCore__FetchHeaders__remove(
|
||||
this,
|
||||
name_,
|
||||
global,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn cast_(value: JSValue, vm: *VM) ?*FetchHeaders {
|
||||
return WebCore__FetchHeaders__cast_(value, vm);
|
||||
}
|
||||
|
||||
pub fn cast(value: JSValue) ?*FetchHeaders {
|
||||
return cast_(value, JSC.VirtualMachine.get().global.vm());
|
||||
}
|
||||
|
||||
pub fn toJS(this: *FetchHeaders, globalThis: *JSGlobalObject) JSValue {
|
||||
return WebCore__FetchHeaders__toJS(this, globalThis);
|
||||
}
|
||||
|
||||
pub fn count(
|
||||
this: *FetchHeaders,
|
||||
names: *u32,
|
||||
buf_len: *u32,
|
||||
) void {
|
||||
return WebCore__FetchHeaders__count(
|
||||
this,
|
||||
names,
|
||||
buf_len,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn clone(
|
||||
this: *FetchHeaders,
|
||||
global: *JSGlobalObject,
|
||||
) JSValue {
|
||||
return WebCore__FetchHeaders__clone(
|
||||
this,
|
||||
global,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn cloneThis(
|
||||
this: *FetchHeaders,
|
||||
global: *JSGlobalObject,
|
||||
) ?*FetchHeaders {
|
||||
return WebCore__FetchHeaders__cloneThis(
|
||||
this,
|
||||
global,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn deref(
|
||||
this: *FetchHeaders,
|
||||
) void {
|
||||
return WebCore__FetchHeaders__deref(this);
|
||||
}
|
||||
|
||||
pub fn copyTo(
|
||||
this: *FetchHeaders,
|
||||
names: [*]Api.StringPointer,
|
||||
values: [*]Api.StringPointer,
|
||||
buf: [*]u8,
|
||||
) void {
|
||||
return WebCore__FetchHeaders__copyTo(
|
||||
this,
|
||||
names,
|
||||
values,
|
||||
buf,
|
||||
);
|
||||
}
|
||||
};
|
||||
44
src/bun.js/bindings/GetterSetter.zig
Normal file
44
src/bun.js/bindings/GetterSetter.zig
Normal file
@@ -0,0 +1,44 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const GetterSetter = extern struct {
|
||||
pub const shim = Shimmer("JSC", "GetterSetter", @This());
|
||||
bytes: shim.Bytes,
|
||||
const cppFn = shim.cppFn;
|
||||
pub const include = "JavaScriptCore/GetterSetter.h";
|
||||
pub const name = "JSC::GetterSetter";
|
||||
pub const namespace = "JSC";
|
||||
|
||||
pub fn isGetterNull(this: *GetterSetter) bool {
|
||||
return shim.cppFn("isGetterNull", .{this});
|
||||
}
|
||||
|
||||
pub fn isSetterNull(this: *GetterSetter) bool {
|
||||
return shim.cppFn("isSetterNull", .{this});
|
||||
}
|
||||
};
|
||||
60
src/bun.js/bindings/JSArray.zig
Normal file
60
src/bun.js/bindings/JSArray.zig
Normal file
@@ -0,0 +1,60 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const JSArrayIterator = @import("./JSArrayIterator.zig").JSArrayIterator;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
pub const JSArray = @import("./JSArray.zig").JSArray;
|
||||
|
||||
pub const JSArray = opaque {
|
||||
// TODO(@paperdave): this can throw
|
||||
extern fn JSArray__constructArray(*JSGlobalObject, [*]const JSValue, usize) JSValue;
|
||||
|
||||
pub fn create(global: *JSGlobalObject, items: []const JSValue) JSValue {
|
||||
return JSArray__constructArray(global, items.ptr, items.len);
|
||||
}
|
||||
|
||||
extern fn JSArray__constructEmptyArray(*JSGlobalObject, usize) JSValue;
|
||||
|
||||
pub fn createEmpty(global: *JSGlobalObject, len: usize) JSValue {
|
||||
return JSArray__constructEmptyArray(global, len);
|
||||
}
|
||||
|
||||
pub fn iterator(array: *JSArray, global: *JSGlobalObject) JSArrayIterator {
|
||||
return JSValue.fromCell(array).arrayIterator(global);
|
||||
}
|
||||
};
|
||||
66
src/bun.js/bindings/JSArrayIterator.zig
Normal file
66
src/bun.js/bindings/JSArrayIterator.zig
Normal file
@@ -0,0 +1,66 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const JSArray = @import("./JSArray.zig").JSArray;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
pub const JSArrayIterator = @import("./JSArrayIterator.zig").JSArrayIterator;
|
||||
|
||||
pub const JSArrayIterator = struct {
|
||||
i: u32 = 0,
|
||||
len: u32 = 0,
|
||||
array: JSValue,
|
||||
global: *JSGlobalObject,
|
||||
|
||||
pub fn init(value: JSValue, global: *JSGlobalObject) JSArrayIterator {
|
||||
return .{
|
||||
.array = value,
|
||||
.global = global,
|
||||
.len = @as(u32, @truncate(value.getLength(global))),
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: this can throw
|
||||
pub fn next(this: *JSArrayIterator) ?JSValue {
|
||||
if (!(this.i < this.len)) {
|
||||
return null;
|
||||
}
|
||||
const i = this.i;
|
||||
this.i += 1;
|
||||
return JSObject.getIndex(this.array, this.global, i);
|
||||
}
|
||||
};
|
||||
76
src/bun.js/bindings/JSCell.zig
Normal file
76
src/bun.js/bindings/JSCell.zig
Normal file
@@ -0,0 +1,76 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
|
||||
pub const JSCell = extern struct {
|
||||
pub const shim = Shimmer("JSC", "JSCell", @This());
|
||||
bytes: shim.Bytes,
|
||||
const cppFn = shim.cppFn;
|
||||
pub const include = "JavaScriptCore/JSCell.h";
|
||||
pub const name = "JSC::JSCell";
|
||||
pub const namespace = "JSC";
|
||||
|
||||
const CellType = enum(u8) { _ };
|
||||
|
||||
pub fn getObject(this: *JSCell) *JSObject {
|
||||
return shim.cppFn("getObject", .{this});
|
||||
}
|
||||
|
||||
pub fn getType(this: *JSCell) u8 {
|
||||
return shim.cppFn("getType", .{
|
||||
this,
|
||||
});
|
||||
}
|
||||
|
||||
pub const Extern = [_][]const u8{ "getObject", "getType" };
|
||||
|
||||
pub fn getGetterSetter(this: *JSCell) *GetterSetter {
|
||||
if (comptime bun.Environment.allow_assert) {
|
||||
bun.assert(JSValue.fromCell(this).isGetterSetter());
|
||||
}
|
||||
return @as(*GetterSetter, @ptrCast(@alignCast(this)));
|
||||
}
|
||||
|
||||
pub fn getCustomGetterSetter(this: *JSCell) *CustomGetterSetter {
|
||||
if (comptime bun.Environment.allow_assert) {
|
||||
bun.assert(JSValue.fromCell(this).isCustomGetterSetter());
|
||||
}
|
||||
return @as(*CustomGetterSetter, @ptrCast(@alignCast(this)));
|
||||
}
|
||||
};
|
||||
116
src/bun.js/bindings/JSFunction.zig
Normal file
116
src/bun.js/bindings/JSFunction.zig
Normal file
@@ -0,0 +1,116 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const JSFunction = extern struct {
|
||||
pub const shim = Shimmer("JSC", "JSFunction", @This());
|
||||
bytes: shim.Bytes,
|
||||
const cppFn = shim.cppFn;
|
||||
pub const include = "JavaScriptCore/JSFunction.h";
|
||||
pub const name = "JSC::JSFunction";
|
||||
pub const namespace = "JSC";
|
||||
|
||||
const ImplementationVisibility = enum(u8) {
|
||||
public,
|
||||
private,
|
||||
private_recursive,
|
||||
};
|
||||
|
||||
/// In WebKit: Intrinsic.h
|
||||
const Intrinsic = enum(u8) {
|
||||
none,
|
||||
_,
|
||||
};
|
||||
|
||||
const CreateJSFunctionOptions = struct {
|
||||
implementation_visibility: ImplementationVisibility = .public,
|
||||
intrinsic: Intrinsic = .none,
|
||||
constructor: ?*const JSHostFunctionType = null,
|
||||
};
|
||||
|
||||
extern fn JSFunction__createFromZig(
|
||||
global: *JSGlobalObject,
|
||||
fn_name: bun.String,
|
||||
implementation: *const JSHostFunctionType,
|
||||
arg_count: u32,
|
||||
implementation_visibility: ImplementationVisibility,
|
||||
intrinsic: Intrinsic,
|
||||
constructor: ?*const JSHostFunctionType,
|
||||
) JSValue;
|
||||
|
||||
pub fn create(
|
||||
global: *JSGlobalObject,
|
||||
fn_name: anytype,
|
||||
comptime implementation: JSHostZigFunction,
|
||||
function_length: u32,
|
||||
options: CreateJSFunctionOptions,
|
||||
) JSValue {
|
||||
return JSFunction__createFromZig(
|
||||
global,
|
||||
switch (@TypeOf(fn_name)) {
|
||||
bun.String => fn_name,
|
||||
else => bun.String.init(fn_name),
|
||||
},
|
||||
toJSHostFunction(implementation),
|
||||
function_length,
|
||||
options.implementation_visibility,
|
||||
options.intrinsic,
|
||||
options.constructor,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn optimizeSoon(value: JSValue) void {
|
||||
cppFn("optimizeSoon", .{value});
|
||||
}
|
||||
|
||||
extern fn JSC__JSFunction__getSourceCode(value: JSValue, out: *ZigString) bool;
|
||||
|
||||
pub fn getSourceCode(value: JSValue) ?bun.String {
|
||||
var str: ZigString = undefined;
|
||||
return if (JSC__JSFunction__getSourceCode(value, &str)) bun.String.init(str) else null;
|
||||
}
|
||||
|
||||
pub const Extern = [_][]const u8{
|
||||
"fromString",
|
||||
"getName",
|
||||
"displayName",
|
||||
"calculatedDisplayName",
|
||||
"optimizeSoon",
|
||||
};
|
||||
};
|
||||
666
src/bun.js/bindings/JSGlobalObject.zig
Normal file
666
src/bun.js/bindings/JSGlobalObject.zig
Normal file
@@ -0,0 +1,666 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
pub extern const JSC__JSObject__maxInlineCapacity: c_uint;
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
const VM = @import("./VM.zig").VM;
|
||||
const ZigString = @import("./ZigString.zig").ZigString;
|
||||
const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
const URL = @import("./URL.zig").URL;
|
||||
const WTF = @import("./WTF.zig").WTF;
|
||||
const JSString = @import("./JSString.zig").JSString;
|
||||
const JSObject = @import("./JSObject.zig").JSObject;
|
||||
const JSCell = @import("./JSCell.zig").JSCell;
|
||||
const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
const JSValue = JSC.JSValue;
|
||||
pub const JSGlobalObject = opaque {
|
||||
pub fn allocator(this: *JSGlobalObject) std.mem.Allocator {
|
||||
return this.bunVM().allocator;
|
||||
}
|
||||
extern fn JSGlobalObject__throwStackOverflow(this: *JSGlobalObject) void;
|
||||
pub fn throwStackOverflow(this: *JSGlobalObject) void {
|
||||
JSGlobalObject__throwStackOverflow(this);
|
||||
}
|
||||
extern fn JSGlobalObject__throwOutOfMemoryError(this: *JSGlobalObject) void;
|
||||
pub fn throwOutOfMemory(this: *JSGlobalObject) bun.JSError {
|
||||
JSGlobalObject__throwOutOfMemoryError(this);
|
||||
return error.JSError;
|
||||
}
|
||||
|
||||
pub fn throwOutOfMemoryValue(this: *JSGlobalObject) JSValue {
|
||||
JSGlobalObject__throwOutOfMemoryError(this);
|
||||
return .zero;
|
||||
}
|
||||
|
||||
pub fn throwTODO(this: *JSGlobalObject, msg: []const u8) bun.JSError {
|
||||
const err = this.createErrorInstance("{s}", .{msg});
|
||||
err.put(this, ZigString.static("name"), bun.String.static("TODOError").toJS(this));
|
||||
return this.throwValue(err);
|
||||
}
|
||||
|
||||
pub const throwTerminationException = JSGlobalObject__throwTerminationException;
|
||||
pub const clearTerminationException = JSGlobalObject__clearTerminationException;
|
||||
|
||||
pub fn setTimeZone(this: *JSGlobalObject, timeZone: *const ZigString) bool {
|
||||
return JSGlobalObject__setTimeZone(this, timeZone);
|
||||
}
|
||||
|
||||
pub inline fn toJSValue(globalThis: *JSGlobalObject) JSValue {
|
||||
return @enumFromInt(@intFromPtr(globalThis));
|
||||
}
|
||||
|
||||
pub fn throwInvalidArguments(this: *JSGlobalObject, comptime fmt: [:0]const u8, args: anytype) bun.JSError {
|
||||
const err = JSC.toInvalidArguments(fmt, args, this);
|
||||
return this.throwValue(err);
|
||||
}
|
||||
|
||||
pub inline fn throwMissingArgumentsValue(this: *JSGlobalObject, comptime arg_names: []const []const u8) bun.JSError {
|
||||
return switch (arg_names.len) {
|
||||
0 => @compileError("requires at least one argument"),
|
||||
1 => this.ERR_MISSING_ARGS("The \"{s}\" argument must be specified", .{arg_names[0]}).throw(),
|
||||
2 => this.ERR_MISSING_ARGS("The \"{s}\" and \"{s}\" arguments must be specified", .{ arg_names[0], arg_names[1] }).throw(),
|
||||
3 => this.ERR_MISSING_ARGS("The \"{s}\", \"{s}\", and \"{s}\" arguments must be specified", .{ arg_names[0], arg_names[1], arg_names[2] }).throw(),
|
||||
else => @compileError("implement this message"),
|
||||
};
|
||||
}
|
||||
|
||||
/// "Expected {field} to be a {typename} for '{name}'."
|
||||
pub fn createInvalidArgumentType(
|
||||
this: *JSGlobalObject,
|
||||
comptime name_: []const u8,
|
||||
comptime field: []const u8,
|
||||
comptime typename: []const u8,
|
||||
) JSC.JSValue {
|
||||
return this.ERR_INVALID_ARG_TYPE(comptime std.fmt.comptimePrint("Expected {s} to be a {s} for '{s}'.", .{ field, typename, name_ }), .{}).toJS();
|
||||
}
|
||||
|
||||
pub fn toJS(this: *JSC.JSGlobalObject, value: anytype, comptime lifetime: JSC.Lifetime) JSC.JSValue {
|
||||
return JSC.toJS(this, @TypeOf(value), value, lifetime);
|
||||
}
|
||||
|
||||
/// "Expected {field} to be a {typename} for '{name}'."
|
||||
pub fn throwInvalidArgumentType(
|
||||
this: *JSGlobalObject,
|
||||
comptime name_: []const u8,
|
||||
comptime field: []const u8,
|
||||
comptime typename: []const u8,
|
||||
) bun.JSError {
|
||||
return this.throwValue(this.createInvalidArgumentType(name_, field, typename));
|
||||
}
|
||||
|
||||
/// "The {argname} argument is invalid. Received {value}"
|
||||
pub fn throwInvalidArgumentValue(
|
||||
this: *JSGlobalObject,
|
||||
argname: []const u8,
|
||||
value: JSValue,
|
||||
) bun.JSError {
|
||||
const actual_string_value = try determineSpecificType(this, value);
|
||||
defer actual_string_value.deref();
|
||||
return this.ERR_INVALID_ARG_VALUE("The \"{s}\" argument is invalid. Received {}", .{ argname, actual_string_value }).throw();
|
||||
}
|
||||
|
||||
/// Throw an `ERR_INVALID_ARG_VALUE` when the invalid value is a property of an object.
|
||||
/// Message depends on whether `expected` is present.
|
||||
/// - "The property "{argname}" is invalid. Received {value}"
|
||||
/// - "The property "{argname}" is invalid. Expected {expected}, received {value}"
|
||||
pub fn throwInvalidArgumentPropertyValue(
|
||||
this: *JSGlobalObject,
|
||||
argname: []const u8,
|
||||
comptime expected: ?[]const u8,
|
||||
value: JSValue,
|
||||
) bun.JSError {
|
||||
const actual_string_value = try determineSpecificType(this, value);
|
||||
defer actual_string_value.deref();
|
||||
if (comptime expected) |_expected| {
|
||||
return this.ERR_INVALID_ARG_VALUE("The property \"{s}\" is invalid. Expected {s}, received {}", .{ argname, _expected, actual_string_value }).throw();
|
||||
} else {
|
||||
return this.ERR_INVALID_ARG_VALUE("The property \"{s}\" is invalid. Received {}", .{ argname, actual_string_value }).throw();
|
||||
}
|
||||
}
|
||||
|
||||
extern "c" fn Bun__ErrorCode__determineSpecificType(*JSGlobalObject, JSValue) String;
|
||||
|
||||
pub fn determineSpecificType(global: *JSGlobalObject, value: JSValue) JSError!String {
|
||||
const str = Bun__ErrorCode__determineSpecificType(global, value);
|
||||
errdefer str.deref();
|
||||
if (global.hasException()) {
|
||||
return error.JSError;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/// "The {argname} argument must be of type {typename}. Received {value}"
|
||||
pub fn throwInvalidArgumentTypeValue(
|
||||
this: *JSGlobalObject,
|
||||
argname: []const u8,
|
||||
typename: []const u8,
|
||||
value: JSValue,
|
||||
) bun.JSError {
|
||||
const actual_string_value = try determineSpecificType(this, value);
|
||||
defer actual_string_value.deref();
|
||||
return this.ERR_INVALID_ARG_TYPE("The \"{s}\" argument must be of type {s}. Received {}", .{ argname, typename, actual_string_value }).throw();
|
||||
}
|
||||
|
||||
pub fn throwInvalidArgumentRangeValue(
|
||||
this: *JSGlobalObject,
|
||||
argname: []const u8,
|
||||
typename: []const u8,
|
||||
value: i64,
|
||||
) bun.JSError {
|
||||
return this.ERR_OUT_OF_RANGE("The \"{s}\" is out of range. {s}. Received {}", .{ argname, typename, value }).throw();
|
||||
}
|
||||
|
||||
pub fn throwInvalidPropertyTypeValue(
|
||||
this: *JSGlobalObject,
|
||||
field: []const u8,
|
||||
typename: []const u8,
|
||||
value: JSValue,
|
||||
) bun.JSError {
|
||||
const ty_str = value.jsTypeString(this).toSlice(this, bun.default_allocator);
|
||||
defer ty_str.deinit();
|
||||
return this.ERR_INVALID_ARG_TYPE("The \"{s}\" property must be of type {s}. Received {s}", .{ field, typename, ty_str.slice() }).throw();
|
||||
}
|
||||
|
||||
pub fn createNotEnoughArguments(
|
||||
this: *JSGlobalObject,
|
||||
comptime name_: []const u8,
|
||||
comptime expected: usize,
|
||||
got: usize,
|
||||
) JSC.JSValue {
|
||||
return JSC.toTypeError(.ERR_MISSING_ARGS, "Not enough arguments to '" ++ name_ ++ "'. Expected {d}, got {d}.", .{ expected, got }, this);
|
||||
}
|
||||
|
||||
/// Not enough arguments passed to function named `name_`
|
||||
pub fn throwNotEnoughArguments(
|
||||
this: *JSGlobalObject,
|
||||
comptime name_: []const u8,
|
||||
comptime expected: usize,
|
||||
got: usize,
|
||||
) bun.JSError {
|
||||
return this.throwValue(this.createNotEnoughArguments(name_, expected, got));
|
||||
}
|
||||
|
||||
extern fn JSC__JSGlobalObject__reload(JSC__JSGlobalObject__ptr: *JSGlobalObject) void;
|
||||
pub fn reload(this: *JSC.JSGlobalObject) void {
|
||||
this.vm().drainMicrotasks();
|
||||
this.vm().collectAsync();
|
||||
|
||||
JSC__JSGlobalObject__reload(this);
|
||||
}
|
||||
|
||||
pub const BunPluginTarget = enum(u8) {
|
||||
bun = 0,
|
||||
node = 1,
|
||||
browser = 2,
|
||||
};
|
||||
extern fn Bun__runOnLoadPlugins(*JSC.JSGlobalObject, ?*const bun.String, *const bun.String, BunPluginTarget) JSValue;
|
||||
extern fn Bun__runOnResolvePlugins(*JSC.JSGlobalObject, ?*const bun.String, *const bun.String, *const String, BunPluginTarget) JSValue;
|
||||
|
||||
pub fn runOnLoadPlugins(this: *JSGlobalObject, namespace_: bun.String, path: bun.String, target: BunPluginTarget) ?JSValue {
|
||||
JSC.markBinding(@src());
|
||||
const result = Bun__runOnLoadPlugins(this, if (namespace_.length() > 0) &namespace_ else null, &path, target);
|
||||
if (result.isEmptyOrUndefinedOrNull()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn runOnResolvePlugins(this: *JSGlobalObject, namespace_: bun.String, path: bun.String, source: bun.String, target: BunPluginTarget) ?JSValue {
|
||||
JSC.markBinding(@src());
|
||||
|
||||
const result = Bun__runOnResolvePlugins(this, if (namespace_.length() > 0) &namespace_ else null, &path, &source, target);
|
||||
if (result.isEmptyOrUndefinedOrNull()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn createErrorInstance(this: *JSGlobalObject, comptime fmt: [:0]const u8, args: anytype) JSValue {
|
||||
if (comptime std.meta.fieldNames(@TypeOf(args)).len > 0) {
|
||||
var stack_fallback = std.heap.stackFallback(1024 * 4, this.allocator());
|
||||
var buf = bun.MutableString.init2048(stack_fallback.get()) catch unreachable;
|
||||
defer buf.deinit();
|
||||
var writer = buf.writer();
|
||||
writer.print(fmt, args) catch
|
||||
// if an exception occurs in the middle of formatting the error message, it's better to just return the formatting string than an error about an error
|
||||
return ZigString.static(fmt).toErrorInstance(this);
|
||||
|
||||
// Ensure we clone it.
|
||||
var str = ZigString.initUTF8(buf.slice());
|
||||
|
||||
return str.toErrorInstance(this);
|
||||
} else {
|
||||
if (comptime strings.isAllASCII(fmt)) {
|
||||
return String.static(fmt).toErrorInstance(this);
|
||||
} else {
|
||||
return ZigString.initUTF8(fmt).toErrorInstance(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn createTypeErrorInstance(this: *JSGlobalObject, comptime fmt: [:0]const u8, args: anytype) JSValue {
|
||||
if (comptime std.meta.fieldNames(@TypeOf(args)).len > 0) {
|
||||
var stack_fallback = std.heap.stackFallback(1024 * 4, this.allocator());
|
||||
var buf = bun.MutableString.init2048(stack_fallback.get()) catch unreachable;
|
||||
defer buf.deinit();
|
||||
var writer = buf.writer();
|
||||
writer.print(fmt, args) catch return ZigString.static(fmt).toErrorInstance(this);
|
||||
var str = ZigString.fromUTF8(buf.slice());
|
||||
return str.toTypeErrorInstance(this);
|
||||
} else {
|
||||
return ZigString.static(fmt).toTypeErrorInstance(this);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn createSyntaxErrorInstance(this: *JSGlobalObject, comptime fmt: [:0]const u8, args: anytype) JSValue {
|
||||
if (comptime std.meta.fieldNames(@TypeOf(args)).len > 0) {
|
||||
var stack_fallback = std.heap.stackFallback(1024 * 4, this.allocator());
|
||||
var buf = bun.MutableString.init2048(stack_fallback.get()) catch unreachable;
|
||||
defer buf.deinit();
|
||||
var writer = buf.writer();
|
||||
writer.print(fmt, args) catch return ZigString.static(fmt).toErrorInstance(this);
|
||||
var str = ZigString.fromUTF8(buf.slice());
|
||||
return str.toSyntaxErrorInstance(this);
|
||||
} else {
|
||||
return ZigString.static(fmt).toSyntaxErrorInstance(this);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn createRangeErrorInstance(this: *JSGlobalObject, comptime fmt: [:0]const u8, args: anytype) JSValue {
|
||||
if (comptime std.meta.fieldNames(@TypeOf(args)).len > 0) {
|
||||
var stack_fallback = std.heap.stackFallback(1024 * 4, this.allocator());
|
||||
var buf = bun.MutableString.init2048(stack_fallback.get()) catch unreachable;
|
||||
defer buf.deinit();
|
||||
var writer = buf.writer();
|
||||
writer.print(fmt, args) catch return ZigString.static(fmt).toErrorInstance(this);
|
||||
var str = ZigString.fromUTF8(buf.slice());
|
||||
return str.toRangeErrorInstance(this);
|
||||
} else {
|
||||
return ZigString.static(fmt).toRangeErrorInstance(this);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn createRangeError(this: *JSGlobalObject, comptime fmt: [:0]const u8, args: anytype) JSValue {
|
||||
const err = createErrorInstance(this, fmt, args);
|
||||
err.put(this, ZigString.static("code"), ZigString.static(@tagName(JSC.Node.ErrorCode.ERR_OUT_OF_RANGE)).toJS(this));
|
||||
return err;
|
||||
}
|
||||
|
||||
pub fn createInvalidArgs(this: *JSGlobalObject, comptime fmt: [:0]const u8, args: anytype) JSValue {
|
||||
return JSC.Error.ERR_INVALID_ARG_TYPE.fmt(this, fmt, args);
|
||||
}
|
||||
|
||||
pub const SysErrOptions = struct {
|
||||
code: JSC.Node.ErrorCode,
|
||||
errno: ?i32 = null,
|
||||
name: ?string = null,
|
||||
};
|
||||
pub fn throwSysError(
|
||||
this: *JSGlobalObject,
|
||||
opts: SysErrOptions,
|
||||
comptime message: bun.stringZ,
|
||||
args: anytype,
|
||||
) JSError {
|
||||
const err = createErrorInstance(this, message, args);
|
||||
err.put(this, ZigString.static("code"), ZigString.init(@tagName(opts.code)).toJS(this));
|
||||
if (opts.name) |name| err.put(this, ZigString.static("name"), ZigString.init(name).toJS(this));
|
||||
if (opts.errno) |errno| err.put(this, ZigString.static("errno"), JSC.toJS(this, i32, errno, .temporary));
|
||||
return this.throwValue(err);
|
||||
}
|
||||
|
||||
pub fn throw(this: *JSGlobalObject, comptime fmt: [:0]const u8, args: anytype) JSError {
|
||||
const instance = this.createErrorInstance(fmt, args);
|
||||
bun.assert(instance != .zero);
|
||||
return this.throwValue(instance);
|
||||
}
|
||||
|
||||
pub fn throwPretty(this: *JSGlobalObject, comptime fmt: [:0]const u8, args: anytype) bun.JSError {
|
||||
const instance = switch (Output.enable_ansi_colors) {
|
||||
inline else => |enabled| this.createErrorInstance(Output.prettyFmt(fmt, enabled), args),
|
||||
};
|
||||
bun.assert(instance != .zero);
|
||||
return this.throwValue(instance);
|
||||
}
|
||||
|
||||
extern fn JSC__JSGlobalObject__queueMicrotaskCallback(*JSGlobalObject, *anyopaque, Function: *const (fn (*anyopaque) callconv(.C) void)) void;
|
||||
pub fn queueMicrotaskCallback(
|
||||
this: *JSGlobalObject,
|
||||
ctx_val: anytype,
|
||||
comptime Function: fn (ctx: @TypeOf(ctx_val)) void,
|
||||
) void {
|
||||
JSC.markBinding(@src());
|
||||
const Fn = Function;
|
||||
const ContextType = @TypeOf(ctx_val);
|
||||
const Wrapper = struct {
|
||||
pub fn call(p: *anyopaque) callconv(.C) void {
|
||||
Fn(bun.cast(ContextType, p));
|
||||
}
|
||||
};
|
||||
|
||||
JSC__JSGlobalObject__queueMicrotaskCallback(this, ctx_val, &Wrapper.call);
|
||||
}
|
||||
|
||||
pub fn queueMicrotask(this: *JSGlobalObject, function: JSValue, args: []const JSC.JSValue) void {
|
||||
this.queueMicrotaskJob(
|
||||
function,
|
||||
if (args.len > 0) args[0] else .zero,
|
||||
if (args.len > 1) args[1] else .zero,
|
||||
);
|
||||
}
|
||||
|
||||
extern fn JSC__JSGlobalObject__queueMicrotaskJob(JSC__JSGlobalObject__ptr: *JSGlobalObject, JSValue, JSValue, JSValue) void;
|
||||
pub fn queueMicrotaskJob(this: *JSGlobalObject, function: JSValue, first: JSValue, second: JSValue) void {
|
||||
JSC__JSGlobalObject__queueMicrotaskJob(this, function, first, second);
|
||||
}
|
||||
|
||||
pub fn throwValue(this: *JSGlobalObject, value: JSC.JSValue) JSError {
|
||||
this.vm().throwError(this, value);
|
||||
return error.JSError;
|
||||
}
|
||||
|
||||
pub fn throwError(this: *JSGlobalObject, err: anyerror, comptime fmt: [:0]const u8) bun.JSError {
|
||||
if (err == error.OutOfMemory) {
|
||||
return this.throwOutOfMemory();
|
||||
}
|
||||
|
||||
// If we're throwing JSError, that means either:
|
||||
// - We're throwing an exception while another exception is already active
|
||||
// - We're incorrectly returning JSError from a function that did not throw.
|
||||
bun.debugAssert(err != error.JSError);
|
||||
|
||||
// Avoid tiny extra allocation
|
||||
var stack = std.heap.stackFallback(128, bun.default_allocator);
|
||||
const allocator_ = stack.get();
|
||||
const buffer = try std.fmt.allocPrint(allocator_, comptime "{s} " ++ fmt, .{@errorName(err)});
|
||||
defer allocator_.free(buffer);
|
||||
const str = ZigString.initUTF8(buffer);
|
||||
const err_value = str.toErrorInstance(this);
|
||||
this.vm().throwError(this, err_value);
|
||||
return error.JSError;
|
||||
}
|
||||
|
||||
pub fn ref(this: *JSGlobalObject) C_API.JSContextRef {
|
||||
return @as(C_API.JSContextRef, @ptrCast(this));
|
||||
}
|
||||
pub const ctx = ref;
|
||||
|
||||
extern fn JSC__JSGlobalObject__createAggregateError(*JSGlobalObject, [*]const JSValue, usize, *const ZigString) JSValue;
|
||||
pub fn createAggregateError(globalObject: *JSGlobalObject, errors: []const JSValue, message: *const ZigString) JSValue {
|
||||
return JSC__JSGlobalObject__createAggregateError(globalObject, errors.ptr, errors.len, message);
|
||||
}
|
||||
|
||||
extern fn JSC__JSGlobalObject__createAggregateErrorWithArray(*JSGlobalObject, JSValue, bun.String, JSValue) JSValue;
|
||||
pub fn createAggregateErrorWithArray(
|
||||
globalObject: *JSGlobalObject,
|
||||
message: bun.String,
|
||||
error_array: JSValue,
|
||||
) JSValue {
|
||||
if (bun.Environment.allow_assert)
|
||||
bun.assert(error_array.isArray());
|
||||
return JSC__JSGlobalObject__createAggregateErrorWithArray(globalObject, error_array, message, .undefined);
|
||||
}
|
||||
|
||||
extern fn JSC__JSGlobalObject__generateHeapSnapshot(*JSGlobalObject) JSValue;
|
||||
pub fn generateHeapSnapshot(this: *JSGlobalObject) JSValue {
|
||||
return JSC__JSGlobalObject__generateHeapSnapshot(this);
|
||||
}
|
||||
|
||||
pub fn hasException(this: *JSGlobalObject) bool {
|
||||
return JSGlobalObject__hasException(this);
|
||||
}
|
||||
|
||||
pub fn clearException(this: *JSGlobalObject) void {
|
||||
return JSGlobalObject__clearException(this);
|
||||
}
|
||||
|
||||
/// Clears the current exception and returns that value. Requires compile-time
|
||||
/// proof of an exception via `error.JSError`
|
||||
pub fn takeException(this: *JSGlobalObject, proof: bun.JSError) JSValue {
|
||||
switch (proof) {
|
||||
error.JSError => {},
|
||||
error.OutOfMemory => this.throwOutOfMemory() catch {},
|
||||
}
|
||||
|
||||
return this.tryTakeException() orelse {
|
||||
@panic("A JavaScript exception was thrown, however it was cleared before it could be read.");
|
||||
};
|
||||
}
|
||||
|
||||
pub fn tryTakeException(this: *JSGlobalObject) ?JSValue {
|
||||
const value = JSGlobalObject__tryTakeException(this);
|
||||
if (value == .zero) return null;
|
||||
return value;
|
||||
}
|
||||
|
||||
/// This is for the common scenario you are calling into JavaScript, but there is
|
||||
/// no logical way to handle a thrown exception other than to treat it as unhandled.
|
||||
///
|
||||
/// The pattern:
|
||||
///
|
||||
/// const result = value.call(...) catch |err|
|
||||
/// return global.reportActiveExceptionAsUnhandled(err);
|
||||
///
|
||||
pub fn reportActiveExceptionAsUnhandled(this: *JSGlobalObject, err: bun.JSError) void {
|
||||
_ = this.bunVM().uncaughtException(this, this.takeException(err), false);
|
||||
}
|
||||
|
||||
pub fn vm(this: *JSGlobalObject) *VM {
|
||||
return JSC__JSGlobalObject__vm(this);
|
||||
}
|
||||
|
||||
pub fn deleteModuleRegistryEntry(this: *JSGlobalObject, name_: *ZigString) void {
|
||||
return JSC__JSGlobalObject__deleteModuleRegistryEntry(this, name_);
|
||||
}
|
||||
|
||||
fn bunVMUnsafe(this: *JSGlobalObject) *anyopaque {
|
||||
return JSC__JSGlobalObject__bunVM(this);
|
||||
}
|
||||
|
||||
pub fn bunVM(this: *JSGlobalObject) *JSC.VirtualMachine {
|
||||
if (comptime bun.Environment.allow_assert) {
|
||||
// if this fails
|
||||
// you most likely need to run
|
||||
// make clean-jsc-bindings
|
||||
// make bindings -j10
|
||||
const assertion = this.bunVMUnsafe() == @as(*anyopaque, @ptrCast(JSC.VirtualMachine.get()));
|
||||
bun.assert(assertion);
|
||||
}
|
||||
return @as(*JSC.VirtualMachine, @ptrCast(@alignCast(this.bunVMUnsafe())));
|
||||
}
|
||||
|
||||
/// We can't do the threadlocal check when queued from another thread
|
||||
pub fn bunVMConcurrently(this: *JSGlobalObject) *JSC.VirtualMachine {
|
||||
return @as(*JSC.VirtualMachine, @ptrCast(@alignCast(this.bunVMUnsafe())));
|
||||
}
|
||||
|
||||
extern fn JSC__JSGlobalObject__handleRejectedPromises(*JSGlobalObject) void;
|
||||
pub fn handleRejectedPromises(this: *JSGlobalObject) void {
|
||||
return JSC__JSGlobalObject__handleRejectedPromises(this);
|
||||
}
|
||||
|
||||
extern fn ZigGlobalObject__readableStreamToArrayBuffer(*JSGlobalObject, JSValue) JSValue;
|
||||
extern fn ZigGlobalObject__readableStreamToBytes(*JSGlobalObject, JSValue) JSValue;
|
||||
extern fn ZigGlobalObject__readableStreamToText(*JSGlobalObject, JSValue) JSValue;
|
||||
extern fn ZigGlobalObject__readableStreamToJSON(*JSGlobalObject, JSValue) JSValue;
|
||||
extern fn ZigGlobalObject__readableStreamToFormData(*JSGlobalObject, JSValue, JSValue) JSValue;
|
||||
extern fn ZigGlobalObject__readableStreamToBlob(*JSGlobalObject, JSValue) JSValue;
|
||||
|
||||
pub fn readableStreamToArrayBuffer(this: *JSGlobalObject, value: JSValue) JSValue {
|
||||
return ZigGlobalObject__readableStreamToArrayBuffer(this, value);
|
||||
}
|
||||
|
||||
pub fn readableStreamToBytes(this: *JSGlobalObject, value: JSValue) JSValue {
|
||||
return ZigGlobalObject__readableStreamToBytes(this, value);
|
||||
}
|
||||
|
||||
pub fn readableStreamToText(this: *JSGlobalObject, value: JSValue) JSValue {
|
||||
return ZigGlobalObject__readableStreamToText(this, value);
|
||||
}
|
||||
|
||||
pub fn readableStreamToJSON(this: *JSGlobalObject, value: JSValue) JSValue {
|
||||
return ZigGlobalObject__readableStreamToJSON(this, value);
|
||||
}
|
||||
|
||||
pub fn readableStreamToBlob(this: *JSGlobalObject, value: JSValue) JSValue {
|
||||
return ZigGlobalObject__readableStreamToBlob(this, value);
|
||||
}
|
||||
|
||||
pub fn readableStreamToFormData(this: *JSGlobalObject, value: JSValue, content_type: JSValue) JSValue {
|
||||
return ZigGlobalObject__readableStreamToFormData(this, value, content_type);
|
||||
}
|
||||
|
||||
pub inline fn assertOnJSThread(this: *JSGlobalObject) void {
|
||||
if (bun.Environment.allow_assert) this.bunVM().assertOnJSThread();
|
||||
}
|
||||
|
||||
// returns false if it throws
|
||||
pub fn validateObject(
|
||||
this: *JSGlobalObject,
|
||||
comptime arg_name: [:0]const u8,
|
||||
value: JSValue,
|
||||
opts: struct {
|
||||
allowArray: bool = false,
|
||||
allowFunction: bool = false,
|
||||
nullable: bool = false,
|
||||
},
|
||||
) bun.JSError!void {
|
||||
if ((!opts.nullable and value.isNull()) or
|
||||
(!opts.allowArray and value.isArray()) or
|
||||
(!value.isObject() and (!opts.allowFunction or !value.isFunction())))
|
||||
{
|
||||
return this.throwInvalidArgumentTypeValue(arg_name, "object", value);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn throwRangeError(this: *JSGlobalObject, value: anytype, options: bun.fmt.OutOfRangeOptions) bun.JSError {
|
||||
// TODO:
|
||||
// This works around a Zig compiler bug
|
||||
// when using this.ERR_OUT_OF_RANGE.
|
||||
return JSC.Error.ERR_OUT_OF_RANGE.throw(this, "{}", .{bun.fmt.outOfRange(value, options)});
|
||||
}
|
||||
|
||||
pub const IntegerRange = struct {
|
||||
min: comptime_int = JSC.MIN_SAFE_INTEGER,
|
||||
max: comptime_int = JSC.MAX_SAFE_INTEGER,
|
||||
field_name: []const u8 = "",
|
||||
always_allow_zero: bool = false,
|
||||
};
|
||||
|
||||
pub fn validateIntegerRange(this: *JSGlobalObject, value: JSValue, comptime T: type, default: T, comptime range: IntegerRange) bun.JSError!T {
|
||||
if (value == .undefined or value == .zero) {
|
||||
return default;
|
||||
}
|
||||
|
||||
const min_t = comptime @max(range.min, std.math.minInt(T), JSC.MIN_SAFE_INTEGER);
|
||||
const max_t = comptime @min(range.max, std.math.maxInt(T), JSC.MAX_SAFE_INTEGER);
|
||||
|
||||
comptime {
|
||||
if (min_t > max_t) {
|
||||
@compileError("max must be less than min");
|
||||
}
|
||||
|
||||
if (max_t < min_t) {
|
||||
@compileError("max must be less than min");
|
||||
}
|
||||
}
|
||||
const field_name = comptime range.field_name;
|
||||
const always_allow_zero = comptime range.always_allow_zero;
|
||||
const min = range.min;
|
||||
const max = range.max;
|
||||
|
||||
if (value.isInt32()) {
|
||||
const int = value.toInt32();
|
||||
if (always_allow_zero and int == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (int < min_t or int > max_t) {
|
||||
return this.throwRangeError(int, .{ .field_name = field_name, .min = min, .max = max });
|
||||
}
|
||||
return @intCast(int);
|
||||
}
|
||||
|
||||
if (!value.isNumber()) {
|
||||
return this.throwInvalidPropertyTypeValue(field_name, "number", value);
|
||||
}
|
||||
const f64_val = value.asNumber();
|
||||
if (always_allow_zero and f64_val == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (std.math.isNan(f64_val)) {
|
||||
// node treats NaN as default
|
||||
return default;
|
||||
}
|
||||
if (@floor(f64_val) != f64_val) {
|
||||
return this.throwInvalidPropertyTypeValue(field_name, "integer", value);
|
||||
}
|
||||
if (f64_val < min_t or f64_val > max_t) {
|
||||
return this.throwRangeError(f64_val, .{ .field_name = comptime field_name, .min = min, .max = max });
|
||||
}
|
||||
|
||||
return @intFromFloat(f64_val);
|
||||
}
|
||||
|
||||
pub fn getInteger(this: *JSGlobalObject, obj: JSValue, comptime T: type, default: T, comptime range: IntegerRange) ?T {
|
||||
if (obj.get(this, range.field_name)) |val| {
|
||||
return this.validateIntegerRange(val, T, default, range);
|
||||
}
|
||||
if (this.hasException()) return null;
|
||||
return default;
|
||||
}
|
||||
|
||||
pub inline fn createHostFunction(
|
||||
global: *JSGlobalObject,
|
||||
comptime display_name: [:0]const u8,
|
||||
// when querying from JavaScript, 'func.name'
|
||||
comptime function: anytype,
|
||||
// when querying from JavaScript, 'func.len'
|
||||
comptime argument_count: u32,
|
||||
) JSValue {
|
||||
return NewRuntimeFunction(global, ZigString.static(display_name), argument_count, toJSHostFunction(function), false, false, null);
|
||||
}
|
||||
|
||||
/// Get a lazily-initialized `JSC::String` from `BunCommonStrings.h`.
|
||||
pub inline fn commonStrings(this: *JSC.JSGlobalObject) CommonStrings {
|
||||
JSC.markBinding(@src());
|
||||
return .{ .globalObject = this };
|
||||
}
|
||||
|
||||
pub usingnamespace @import("ErrorCode").JSGlobalObjectExtensions;
|
||||
|
||||
extern fn JSC__JSGlobalObject__bunVM(*JSGlobalObject) *VM;
|
||||
extern fn JSC__JSGlobalObject__vm(*JSGlobalObject) *VM;
|
||||
extern fn JSC__JSGlobalObject__deleteModuleRegistryEntry(*JSGlobalObject, *const ZigString) void;
|
||||
extern fn JSGlobalObject__clearException(*JSGlobalObject) void;
|
||||
extern fn JSGlobalObject__clearTerminationException(this: *JSGlobalObject) void;
|
||||
extern fn JSGlobalObject__hasException(*JSGlobalObject) bool;
|
||||
extern fn JSGlobalObject__setTimeZone(this: *JSGlobalObject, timeZone: *const ZigString) bool;
|
||||
extern fn JSGlobalObject__tryTakeException(*JSGlobalObject) JSValue;
|
||||
extern fn JSGlobalObject__throwTerminationException(this: *JSGlobalObject) void;
|
||||
};
|
||||
103
src/bun.js/bindings/JSInternalPromise.zig
Normal file
103
src/bun.js/bindings/JSInternalPromise.zig
Normal file
@@ -0,0 +1,103 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const JSPromise = @import("./JSPromise.zig").JSPromise;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const JSInternalPromise = opaque {
|
||||
extern fn JSC__JSInternalPromise__create(arg0: *JSGlobalObject) *JSInternalPromise;
|
||||
extern fn JSC__JSInternalPromise__isHandled(arg0: *const JSInternalPromise, arg1: *VM) bool;
|
||||
extern fn JSC__JSInternalPromise__reject(arg0: *JSInternalPromise, arg1: *JSGlobalObject, JSValue2: JSValue) void;
|
||||
extern fn JSC__JSInternalPromise__rejectAsHandled(arg0: *JSInternalPromise, arg1: *JSGlobalObject, JSValue2: JSValue) void;
|
||||
extern fn JSC__JSInternalPromise__rejectAsHandledException(arg0: *JSInternalPromise, arg1: *JSGlobalObject, arg2: *JSC.Exception) void;
|
||||
extern fn JSC__JSInternalPromise__rejectedPromise(arg0: *JSGlobalObject, JSValue1: JSValue) *JSInternalPromise;
|
||||
extern fn JSC__JSInternalPromise__resolve(arg0: *JSInternalPromise, arg1: *JSGlobalObject, JSValue2: JSValue) void;
|
||||
extern fn JSC__JSInternalPromise__resolvedPromise(arg0: *JSGlobalObject, JSValue1: JSValue) *JSInternalPromise;
|
||||
extern fn JSC__JSInternalPromise__result(arg0: *const JSInternalPromise, arg1: *VM) JSValue;
|
||||
extern fn JSC__JSInternalPromise__setHandled(arg0: *JSInternalPromise, arg1: *VM) void;
|
||||
extern fn JSC__JSInternalPromise__status(arg0: *const JSInternalPromise, arg1: *VM) JSPromise.Status;
|
||||
|
||||
pub fn status(this: *const JSInternalPromise, vm: *VM) JSPromise.Status {
|
||||
return JSC__JSInternalPromise__status(this, vm);
|
||||
}
|
||||
pub fn result(this: *const JSInternalPromise, vm: *VM) JSValue {
|
||||
return JSC__JSInternalPromise__result(this, vm);
|
||||
}
|
||||
pub fn isHandled(this: *const JSInternalPromise, vm: *VM) bool {
|
||||
return JSC__JSInternalPromise__isHandled(this, vm);
|
||||
}
|
||||
pub fn setHandled(this: *JSInternalPromise, vm: *VM) void {
|
||||
JSC__JSInternalPromise__setHandled(this, vm);
|
||||
}
|
||||
|
||||
pub fn unwrap(promise: *JSInternalPromise, vm: *VM, mode: JSPromise.UnwrapMode) JSPromise.Unwrapped {
|
||||
return switch (promise.status(vm)) {
|
||||
.pending => .pending,
|
||||
.fulfilled => .{ .fulfilled = promise.result(vm) },
|
||||
.rejected => {
|
||||
if (mode == .mark_handled) promise.setHandled(vm);
|
||||
return .{ .rejected = promise.result(vm) };
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn resolvedPromise(globalThis: *JSGlobalObject, value: JSValue) *JSInternalPromise {
|
||||
return JSC__JSInternalPromise__resolvedPromise(globalThis, value);
|
||||
}
|
||||
pub fn rejectedPromise(globalThis: *JSGlobalObject, value: JSValue) *JSInternalPromise {
|
||||
return JSC__JSInternalPromise__rejectedPromise(globalThis, value);
|
||||
}
|
||||
|
||||
pub fn resolve(this: *JSInternalPromise, globalThis: *JSGlobalObject, value: JSValue) void {
|
||||
JSC__JSInternalPromise__resolve(this, globalThis, value);
|
||||
}
|
||||
pub fn reject(this: *JSInternalPromise, globalThis: *JSGlobalObject, value: JSValue) void {
|
||||
JSC__JSInternalPromise__reject(this, globalThis, value);
|
||||
}
|
||||
pub fn rejectAsHandled(this: *JSInternalPromise, globalThis: *JSGlobalObject, value: JSValue) void {
|
||||
JSC__JSInternalPromise__rejectAsHandled(this, globalThis, value);
|
||||
}
|
||||
|
||||
pub fn create(globalThis: *JSGlobalObject) *JSInternalPromise {
|
||||
return JSC__JSInternalPromise__create(globalThis);
|
||||
}
|
||||
|
||||
pub fn asValue(this: *JSInternalPromise) JSValue {
|
||||
return JSValue.fromCell(this);
|
||||
}
|
||||
};
|
||||
83
src/bun.js/bindings/JSMap.zig
Normal file
83
src/bun.js/bindings/JSMap.zig
Normal file
@@ -0,0 +1,83 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
const JSGlobalObject = JSC.JSGlobalObject;
|
||||
const VM = JSC.VM;
|
||||
const ZigString = JSC.ZigString;
|
||||
const CommonStrings = JSC.CommonStrings;
|
||||
const URL = JSC.URL;
|
||||
const WTF = JSC.WTF;
|
||||
const JSString = JSC.JSString;
|
||||
const JSObject = JSC.JSObject;
|
||||
const JSValue = JSC.JSValue;
|
||||
const GetterSetter = JSC.GetterSetter;
|
||||
const CustomGetterSetter = JSC.CustomGetterSetter;
|
||||
|
||||
pub const JSMap = opaque {
|
||||
extern fn JSC__JSMap__create(*JSGlobalObject) JSValue;
|
||||
extern fn JSC__JSMap__get_(?*JSMap, *JSGlobalObject, JSValue) JSValue;
|
||||
extern fn JSC__JSMap__has(arg0: ?*JSMap, arg1: *JSGlobalObject, JSValue2: JSValue) bool;
|
||||
extern fn JSC__JSMap__remove(arg0: ?*JSMap, arg1: *JSGlobalObject, JSValue2: JSValue) bool;
|
||||
extern fn JSC__JSMap__set(arg0: ?*JSMap, arg1: *JSGlobalObject, JSValue2: JSValue, JSValue3: JSValue) void;
|
||||
|
||||
pub fn create(globalObject: *JSGlobalObject) JSValue {
|
||||
return JSC__JSMap__create(globalObject);
|
||||
}
|
||||
|
||||
pub fn set(this: *JSMap, globalObject: *JSGlobalObject, key: JSValue, value: JSValue) void {
|
||||
return JSC__JSMap__set(this, globalObject, key, value);
|
||||
}
|
||||
|
||||
pub fn get_(this: *JSMap, globalObject: *JSGlobalObject, key: JSValue) JSValue {
|
||||
return JSC__JSMap__get_(this, globalObject, key);
|
||||
}
|
||||
|
||||
pub fn get(this: *JSMap, globalObject: *JSGlobalObject, key: JSValue) ?JSValue {
|
||||
const value = get_(this, globalObject, key);
|
||||
if (value.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
pub fn has(this: *JSMap, globalObject: *JSGlobalObject, key: JSValue) bool {
|
||||
return JSC__JSMap__has(this, globalObject, key);
|
||||
}
|
||||
|
||||
pub fn remove(this: *JSMap, globalObject: *JSGlobalObject, key: JSValue) bool {
|
||||
return JSC__JSMap__remove(this, globalObject, key);
|
||||
}
|
||||
|
||||
pub fn fromJS(value: JSValue) ?*JSMap {
|
||||
if (value.jsTypeLoose() == .Map) {
|
||||
return bun.cast(*JSMap, value.asEncoded().asPtr.?);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
94
src/bun.js/bindings/JSModuleLoader.zig
Normal file
94
src/bun.js/bindings/JSModuleLoader.zig
Normal file
@@ -0,0 +1,94 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const JSInternalPromise = @import("./JSInternalPromise.zig").JSInternalPromise;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
pub const JSPromise = @import("./JSPromise.zig").JSPromise;
|
||||
|
||||
pub const JSModuleLoader = extern struct {
|
||||
pub const shim = Shimmer("JSC", "JSModuleLoader", @This());
|
||||
bytes: shim.Bytes,
|
||||
const cppFn = shim.cppFn;
|
||||
pub const include = "JavaScriptCore/JSModuleLoader.h";
|
||||
pub const name = "JSC::JSModuleLoader";
|
||||
pub const namespace = "JSC";
|
||||
|
||||
pub fn evaluate(
|
||||
globalObject: *JSGlobalObject,
|
||||
sourceCodePtr: [*]const u8,
|
||||
sourceCodeLen: usize,
|
||||
originUrlPtr: [*]const u8,
|
||||
originUrlLen: usize,
|
||||
referrerUrlPtr: [*]const u8,
|
||||
referrerUrlLen: usize,
|
||||
thisValue: JSValue,
|
||||
exception: [*]JSValue,
|
||||
) JSValue {
|
||||
return shim.cppFn("evaluate", .{
|
||||
globalObject,
|
||||
sourceCodePtr,
|
||||
sourceCodeLen,
|
||||
originUrlPtr,
|
||||
originUrlLen,
|
||||
referrerUrlPtr,
|
||||
referrerUrlLen,
|
||||
thisValue,
|
||||
exception,
|
||||
});
|
||||
}
|
||||
extern fn JSC__JSModuleLoader__loadAndEvaluateModule(arg0: *JSGlobalObject, arg1: ?*const String) *JSInternalPromise;
|
||||
pub fn loadAndEvaluateModule(globalObject: *JSGlobalObject, module_name: ?*const bun.String) ?*JSInternalPromise {
|
||||
return JSC__JSModuleLoader__loadAndEvaluateModule(globalObject, module_name);
|
||||
}
|
||||
|
||||
extern fn JSModuleLoader__import(*JSGlobalObject, *const bun.String) *JSInternalPromise;
|
||||
pub fn import(globalObject: *JSGlobalObject, module_name: *const bun.String) *JSInternalPromise {
|
||||
return JSModuleLoader__import(globalObject, module_name);
|
||||
}
|
||||
|
||||
// pub fn dependencyKeysIfEvaluated(this: *JSModuleLoader, globalObject: *JSGlobalObject, moduleRecord: *JSModuleRecord) *JSValue {
|
||||
// return shim.cppFn("dependencyKeysIfEvaluated", .{ this, globalObject, moduleRecord });
|
||||
// }
|
||||
|
||||
pub const Extern = [_][]const u8{
|
||||
"evaluate",
|
||||
"loadAndEvaluateModule",
|
||||
"importModule",
|
||||
"checkSyntax",
|
||||
};
|
||||
};
|
||||
182
src/bun.js/bindings/JSObject.zig
Normal file
182
src/bun.js/bindings/JSObject.zig
Normal file
@@ -0,0 +1,182 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const JSObject = extern struct {
|
||||
pub const shim = Shimmer("JSC", "JSObject", @This());
|
||||
const cppFn = shim.cppFn;
|
||||
|
||||
pub fn toJS(obj: *JSObject) JSValue {
|
||||
return JSValue.fromCell(obj);
|
||||
}
|
||||
|
||||
/// Marshall a struct instance into a JSObject, copying its properties.
|
||||
///
|
||||
/// Each field will be encoded with `JSC.toJS`. Fields whose types have a
|
||||
/// `toJS` method will have it called to encode.
|
||||
///
|
||||
/// This method is equivalent to `Object.create(...)` + setting properties,
|
||||
/// and is only intended for creating POJOs.
|
||||
pub fn create(pojo: anytype, global: *JSGlobalObject) *JSObject {
|
||||
return createFromStructWithPrototype(@TypeOf(pojo), pojo, global, false);
|
||||
}
|
||||
/// Marshall a struct into a JSObject, copying its properties. It's
|
||||
/// `__proto__` will be `null`.
|
||||
///
|
||||
/// Each field will be encoded with `JSC.toJS`. Fields whose types have a
|
||||
/// `toJS` method will have it called to encode.
|
||||
///
|
||||
/// This is roughly equivalent to creating an object with
|
||||
/// `Object.create(null)` and adding properties to it.
|
||||
pub fn createNullProto(pojo: anytype, global: *JSGlobalObject) *JSObject {
|
||||
return createFromStructWithPrototype(@TypeOf(pojo), pojo, global, true);
|
||||
}
|
||||
|
||||
/// Marshall a struct instance into a JSObject. `pojo` is borrowed.
|
||||
///
|
||||
/// Each field will be encoded with `JSC.toJS`. Fields whose types have a
|
||||
/// `toJS` method will have it called to encode.
|
||||
///
|
||||
/// This method is equivalent to `Object.create(...)` + setting properties,
|
||||
/// and is only intended for creating POJOs.
|
||||
///
|
||||
/// The object's prototype with either be `null` or `ObjectPrototype`
|
||||
/// depending on whether `null_prototype` is set. Prefer using the object
|
||||
/// prototype (`null_prototype = false`) unless you have a good reason not
|
||||
/// to.
|
||||
fn createFromStructWithPrototype(comptime T: type, pojo: T, global: *JSGlobalObject, comptime null_prototype: bool) *JSObject {
|
||||
const info: std.builtin.Type.Struct = @typeInfo(T).@"struct";
|
||||
|
||||
const obj = obj: {
|
||||
const val = if (comptime null_prototype)
|
||||
JSValue.createEmptyObjectWithNullPrototype(global)
|
||||
else
|
||||
JSValue.createEmptyObject(global, comptime info.fields.len);
|
||||
if (bun.Environment.isDebug)
|
||||
bun.assert(val.isObject());
|
||||
break :obj val.uncheckedPtrCast(JSObject);
|
||||
};
|
||||
|
||||
const cell = toJS(obj);
|
||||
inline for (info.fields) |field| {
|
||||
const property = @field(pojo, field.name);
|
||||
cell.put(
|
||||
global,
|
||||
field.name,
|
||||
JSC.toJS(global, @TypeOf(property), property, .temporary),
|
||||
);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub inline fn put(obj: *JSObject, global: *JSGlobalObject, key: anytype, value: JSValue) !void {
|
||||
obj.toJS().put(global, key, value);
|
||||
}
|
||||
|
||||
pub inline fn putAllFromStruct(obj: *JSObject, global: *JSGlobalObject, properties: anytype) !void {
|
||||
inline for (comptime std.meta.fieldNames(@TypeOf(properties))) |field| {
|
||||
try obj.put(global, field, @field(properties, field));
|
||||
}
|
||||
}
|
||||
|
||||
extern fn JSC__createStructure(*JSC.JSGlobalObject, *JSC.JSCell, u32, names: [*]ExternColumnIdentifier) JSC.JSValue;
|
||||
|
||||
pub const ExternColumnIdentifier = extern struct {
|
||||
tag: u8 = 0,
|
||||
value: extern union {
|
||||
index: u32,
|
||||
name: bun.String,
|
||||
},
|
||||
|
||||
pub fn string(this: *ExternColumnIdentifier) ?*bun.String {
|
||||
return switch (this.tag) {
|
||||
2 => &this.value.name,
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(this: *ExternColumnIdentifier) void {
|
||||
if (this.string()) |str| {
|
||||
str.deref();
|
||||
}
|
||||
}
|
||||
};
|
||||
pub fn createStructure(global: *JSGlobalObject, owner: JSC.JSValue, length: u32, names: [*]ExternColumnIdentifier) JSValue {
|
||||
JSC.markBinding(@src());
|
||||
return JSC__createStructure(global, owner.asCell(), length, names);
|
||||
}
|
||||
|
||||
const InitializeCallback = *const fn (ctx: *anyopaque, obj: *JSObject, global: *JSGlobalObject) callconv(.C) void;
|
||||
extern fn JSC__JSObject__create(global_object: *JSGlobalObject, length: usize, ctx: *anyopaque, initializer: InitializeCallback) JSValue;
|
||||
|
||||
pub fn Initializer(comptime Ctx: type, comptime func: fn (*Ctx, obj: *JSObject, global: *JSGlobalObject) void) type {
|
||||
return struct {
|
||||
pub fn call(this: *anyopaque, obj: *JSObject, global: *JSGlobalObject) callconv(.C) void {
|
||||
@call(bun.callmod_inline, func, .{ @as(*Ctx, @ptrCast(@alignCast(this))), obj, global });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn createWithInitializer(comptime Ctx: type, creator: *Ctx, global: *JSGlobalObject, length: usize) JSValue {
|
||||
const Type = Initializer(Ctx, Ctx.create);
|
||||
return JSC__JSObject__create(global, length, creator, Type.call);
|
||||
}
|
||||
|
||||
pub fn getIndex(this: JSValue, globalThis: *JSGlobalObject, i: u32) JSValue {
|
||||
return cppFn("getIndex", .{
|
||||
this,
|
||||
globalThis,
|
||||
i,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn putRecord(this: *JSObject, global: *JSGlobalObject, key: *ZigString, values: []ZigString) void {
|
||||
return cppFn("putRecord", .{ this, global, key, values.ptr, values.len });
|
||||
}
|
||||
|
||||
extern fn Bun__JSObject__getCodePropertyVMInquiry(*JSGlobalObject, *JSObject) JSValue;
|
||||
|
||||
/// This will not call getters or be observable from JavaScript.
|
||||
pub fn getCodePropertyVMInquiry(obj: *JSObject, global: *JSGlobalObject) ?JSValue {
|
||||
const v = Bun__JSObject__getCodePropertyVMInquiry(global, obj);
|
||||
if (v == .zero) return null;
|
||||
return v;
|
||||
}
|
||||
};
|
||||
336
src/bun.js/bindings/JSPromise.zig
Normal file
336
src/bun.js/bindings/JSPromise.zig
Normal file
@@ -0,0 +1,336 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
const JSGlobalObject = JSC.JSGlobalObject;
|
||||
const VM = JSC.VM;
|
||||
const ZigString = JSC.ZigString;
|
||||
const CommonStrings = JSC.CommonStrings;
|
||||
const URL = JSC.URL;
|
||||
const WTF = JSC.WTF;
|
||||
const JSString = JSC.JSString;
|
||||
const JSObject = JSC.JSObject;
|
||||
const JSValue = JSC.JSValue;
|
||||
const GetterSetter = JSC.GetterSetter;
|
||||
const CustomGetterSetter = JSC.CustomGetterSetter;
|
||||
|
||||
pub const JSPromise = opaque {
|
||||
pub const Status = enum(u32) {
|
||||
pending = 0, // Making this as 0, so that, we can change the status from Pending to others without masking.
|
||||
fulfilled = 1,
|
||||
rejected = 2,
|
||||
};
|
||||
extern fn JSC__JSPromise__asValue(arg0: *JSPromise, arg1: *JSGlobalObject) JSValue;
|
||||
extern fn JSC__JSPromise__create(arg0: *JSGlobalObject) *JSPromise;
|
||||
extern fn JSC__JSPromise__isHandled(arg0: *const JSPromise, arg1: *VM) bool;
|
||||
extern fn JSC__JSPromise__reject(arg0: *JSPromise, arg1: *JSGlobalObject, JSValue2: JSValue) void;
|
||||
extern fn JSC__JSPromise__rejectAsHandled(arg0: *JSPromise, arg1: *JSGlobalObject, JSValue2: JSValue) void;
|
||||
extern fn JSC__JSPromise__rejectAsHandledException(arg0: *JSPromise, arg1: *JSGlobalObject, arg2: ?*JSC.Exception) void;
|
||||
extern fn JSC__JSPromise__rejectedPromise(arg0: *JSGlobalObject, JSValue1: JSValue) *JSPromise;
|
||||
extern fn JSC__JSPromise__rejectedPromiseValue(arg0: *JSGlobalObject, JSValue1: JSValue) JSValue;
|
||||
extern fn JSC__JSPromise__resolve(arg0: *JSPromise, arg1: *JSGlobalObject, JSValue2: JSValue) void;
|
||||
extern fn JSC__JSPromise__resolvedPromise(arg0: *JSGlobalObject, JSValue1: JSValue) *JSPromise;
|
||||
extern fn JSC__JSPromise__resolvedPromiseValue(arg0: *JSGlobalObject, JSValue1: JSValue) JSValue;
|
||||
extern fn JSC__JSPromise__result(arg0: *JSPromise, arg1: *VM) JSValue;
|
||||
extern fn JSC__JSPromise__setHandled(arg0: *JSPromise, arg1: *VM) void;
|
||||
extern fn JSC__JSPromise__status(arg0: *const JSPromise, arg1: *VM) JSPromise.Status;
|
||||
|
||||
pub fn Weak(comptime T: type) type {
|
||||
return struct {
|
||||
weak: JSC.Weak(T) = .{},
|
||||
const WeakType = @This();
|
||||
|
||||
pub fn reject(this: *WeakType, globalThis: *JSC.JSGlobalObject, val: JSC.JSValue) void {
|
||||
this.swap().reject(globalThis, val);
|
||||
}
|
||||
|
||||
/// Like `reject`, except it drains microtasks at the end of the current event loop iteration.
|
||||
pub fn rejectTask(this: *WeakType, globalThis: *JSC.JSGlobalObject, val: JSC.JSValue) void {
|
||||
const loop = JSC.VirtualMachine.get().eventLoop();
|
||||
loop.enter();
|
||||
defer loop.exit();
|
||||
|
||||
this.reject(globalThis, val);
|
||||
}
|
||||
|
||||
pub fn resolve(this: *WeakType, globalThis: *JSC.JSGlobalObject, val: JSC.JSValue) void {
|
||||
this.swap().resolve(globalThis, val);
|
||||
}
|
||||
|
||||
/// Like `resolve`, except it drains microtasks at the end of the current event loop iteration.
|
||||
pub fn resolveTask(this: *WeakType, globalThis: *JSC.JSGlobalObject, val: JSC.JSValue) void {
|
||||
const loop = JSC.VirtualMachine.get().eventLoop();
|
||||
loop.enter();
|
||||
defer loop.exit();
|
||||
this.resolve(globalThis, val);
|
||||
}
|
||||
|
||||
pub fn init(
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
promise: JSValue,
|
||||
ctx: *T,
|
||||
comptime finalizer: *const fn (*T, JSC.JSValue) void,
|
||||
) WeakType {
|
||||
return WeakType{
|
||||
.weak = JSC.Weak(T).create(
|
||||
promise,
|
||||
globalThis,
|
||||
ctx,
|
||||
finalizer,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get(this: *const WeakType) *JSC.JSPromise {
|
||||
return this.weak.get().?.asPromise().?;
|
||||
}
|
||||
|
||||
pub fn getOrNull(this: *const WeakType) ?*JSC.JSPromise {
|
||||
const promise_value = this.weak.get() orelse return null;
|
||||
return promise_value.asPromise();
|
||||
}
|
||||
|
||||
pub fn value(this: *const WeakType) JSValue {
|
||||
return this.weak.get().?;
|
||||
}
|
||||
|
||||
pub fn valueOrEmpty(this: *const WeakType) JSValue {
|
||||
return this.weak.get() orelse .zero;
|
||||
}
|
||||
|
||||
pub fn swap(this: *WeakType) *JSC.JSPromise {
|
||||
const prom = this.weak.swap().asPromise().?;
|
||||
this.weak.deinit();
|
||||
return prom;
|
||||
}
|
||||
pub fn deinit(this: *WeakType) void {
|
||||
this.weak.clear();
|
||||
this.weak.deinit();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub const Strong = struct {
|
||||
strong: JSC.Strong = .{},
|
||||
|
||||
pub fn reject(this: *Strong, globalThis: *JSC.JSGlobalObject, val: JSC.JSValue) void {
|
||||
this.swap().reject(globalThis, val);
|
||||
}
|
||||
|
||||
/// Like `reject`, except it drains microtasks at the end of the current event loop iteration.
|
||||
pub fn rejectTask(this: *Strong, globalThis: *JSC.JSGlobalObject, val: JSC.JSValue) void {
|
||||
const loop = JSC.VirtualMachine.get().eventLoop();
|
||||
loop.enter();
|
||||
defer loop.exit();
|
||||
|
||||
this.reject(globalThis, val);
|
||||
}
|
||||
|
||||
pub const rejectOnNextTick = @compileError("Either use an event loop task, or you're draining microtasks when you shouldn't be.");
|
||||
|
||||
pub fn resolve(this: *Strong, globalThis: *JSC.JSGlobalObject, val: JSC.JSValue) void {
|
||||
this.swap().resolve(globalThis, val);
|
||||
}
|
||||
|
||||
/// Like `resolve`, except it drains microtasks at the end of the current event loop iteration.
|
||||
pub fn resolveTask(this: *Strong, globalThis: *JSC.JSGlobalObject, val: JSC.JSValue) void {
|
||||
const loop = JSC.VirtualMachine.get().eventLoop();
|
||||
loop.enter();
|
||||
defer loop.exit();
|
||||
this.resolve(globalThis, val);
|
||||
}
|
||||
|
||||
pub fn init(globalThis: *JSC.JSGlobalObject) Strong {
|
||||
return Strong{
|
||||
.strong = JSC.Strong.create(
|
||||
JSC.JSPromise.create(globalThis).asValue(globalThis),
|
||||
globalThis,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get(this: *const Strong) *JSC.JSPromise {
|
||||
return this.strong.get().?.asPromise().?;
|
||||
}
|
||||
|
||||
pub fn value(this: *const Strong) JSValue {
|
||||
return this.strong.get().?;
|
||||
}
|
||||
|
||||
pub fn valueOrEmpty(this: *const Strong) JSValue {
|
||||
return this.strong.get() orelse .zero;
|
||||
}
|
||||
|
||||
pub fn hasValue(this: *const Strong) bool {
|
||||
return this.strong.has();
|
||||
}
|
||||
|
||||
pub fn globalObject(this: *const Strong) ?*JSC.JSGlobalObject {
|
||||
return this.strong.globalThis;
|
||||
}
|
||||
|
||||
pub fn swap(this: *Strong) *JSC.JSPromise {
|
||||
const prom = this.strong.swap().asPromise().?;
|
||||
this.strong.deinit();
|
||||
return prom;
|
||||
}
|
||||
pub fn deinit(this: *Strong) void {
|
||||
this.strong.clear();
|
||||
this.strong.deinit();
|
||||
}
|
||||
};
|
||||
|
||||
extern fn JSC__JSPromise__wrap(*JSC.JSGlobalObject, *anyopaque, *const fn (*anyopaque, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue) JSC.JSValue;
|
||||
|
||||
pub fn wrap(
|
||||
globalObject: *JSGlobalObject,
|
||||
comptime Function: anytype,
|
||||
args: std.meta.ArgsTuple(@TypeOf(Function)),
|
||||
) JSValue {
|
||||
const Args = std.meta.ArgsTuple(@TypeOf(Function));
|
||||
const Fn = Function;
|
||||
const Wrapper = struct {
|
||||
args: Args,
|
||||
|
||||
pub fn call(this: *@This(), g: *JSC.JSGlobalObject) callconv(.c) JSC.JSValue {
|
||||
return toJSHostValue(g, @call(.auto, Fn, this.args));
|
||||
}
|
||||
};
|
||||
|
||||
var ctx = Wrapper{ .args = args };
|
||||
return JSC__JSPromise__wrap(globalObject, &ctx, @ptrCast(&Wrapper.call));
|
||||
}
|
||||
|
||||
pub fn wrapValue(globalObject: *JSGlobalObject, value: JSValue) JSValue {
|
||||
if (value == .zero) {
|
||||
return resolvedPromiseValue(globalObject, JSValue.jsUndefined());
|
||||
} else if (value.isEmptyOrUndefinedOrNull() or !value.isCell()) {
|
||||
return resolvedPromiseValue(globalObject, value);
|
||||
}
|
||||
|
||||
if (value.jsType() == .JSPromise) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value.isAnyError()) {
|
||||
return rejectedPromiseValue(globalObject, value);
|
||||
}
|
||||
|
||||
return resolvedPromiseValue(globalObject, value);
|
||||
}
|
||||
pub fn status(this: *const JSPromise, vm: *VM) Status {
|
||||
return JSC__JSPromise__status(this, vm);
|
||||
}
|
||||
|
||||
pub fn result(this: *JSPromise, vm: *VM) JSValue {
|
||||
return JSC__JSPromise__result(this, vm);
|
||||
}
|
||||
|
||||
pub fn isHandled(this: *const JSPromise, vm: *VM) bool {
|
||||
return JSC__JSPromise__isHandled(this, vm);
|
||||
}
|
||||
|
||||
pub fn setHandled(this: *JSPromise, vm: *VM) void {
|
||||
JSC__JSPromise__setHandled(this, vm);
|
||||
}
|
||||
|
||||
pub fn resolvedPromise(globalThis: *JSGlobalObject, value: JSValue) *JSPromise {
|
||||
return JSC__JSPromise__resolvedPromise(globalThis, value);
|
||||
}
|
||||
|
||||
/// Create a new promise with an already fulfilled value
|
||||
/// This is the faster function for doing that.
|
||||
pub fn resolvedPromiseValue(globalThis: *JSGlobalObject, value: JSValue) JSValue {
|
||||
return JSC__JSPromise__resolvedPromiseValue(globalThis, value);
|
||||
}
|
||||
|
||||
pub fn rejectedPromise(globalThis: *JSGlobalObject, value: JSValue) *JSPromise {
|
||||
return JSC__JSPromise__rejectedPromise(globalThis, value);
|
||||
}
|
||||
|
||||
pub fn rejectedPromiseValue(globalThis: *JSGlobalObject, value: JSValue) JSValue {
|
||||
return JSC__JSPromise__rejectedPromiseValue(globalThis, value);
|
||||
}
|
||||
|
||||
/// Fulfill an existing promise with the value
|
||||
/// The value can be another Promise
|
||||
/// If you want to create a new Promise that is already resolved, see JSPromise.resolvedPromiseValue
|
||||
pub fn resolve(this: *JSPromise, globalThis: *JSGlobalObject, value: JSValue) void {
|
||||
if (comptime bun.Environment.isDebug) {
|
||||
const loop = JSC.VirtualMachine.get().eventLoop();
|
||||
loop.debug.js_call_count_outside_tick_queue += @as(usize, @intFromBool(!loop.debug.is_inside_tick_queue));
|
||||
if (loop.debug.track_last_fn_name and !loop.debug.is_inside_tick_queue) {
|
||||
loop.debug.last_fn_name = String.static("resolve");
|
||||
}
|
||||
}
|
||||
|
||||
JSC__JSPromise__resolve(this, globalThis, value);
|
||||
}
|
||||
|
||||
pub fn reject(this: *JSPromise, globalThis: *JSGlobalObject, value: JSValue) void {
|
||||
if (comptime bun.Environment.isDebug) {
|
||||
const loop = JSC.VirtualMachine.get().eventLoop();
|
||||
loop.debug.js_call_count_outside_tick_queue += @as(usize, @intFromBool(!loop.debug.is_inside_tick_queue));
|
||||
if (loop.debug.track_last_fn_name and !loop.debug.is_inside_tick_queue) {
|
||||
loop.debug.last_fn_name = String.static("reject");
|
||||
}
|
||||
}
|
||||
|
||||
JSC__JSPromise__reject(this, globalThis, value);
|
||||
}
|
||||
|
||||
pub fn rejectAsHandled(this: *JSPromise, globalThis: *JSGlobalObject, value: JSValue) void {
|
||||
JSC__JSPromise__rejectAsHandled(this, globalThis, value);
|
||||
}
|
||||
|
||||
pub fn create(globalThis: *JSGlobalObject) *JSPromise {
|
||||
return JSC__JSPromise__create(globalThis);
|
||||
}
|
||||
|
||||
pub fn asValue(this: *JSPromise, globalThis: *JSGlobalObject) JSValue {
|
||||
return JSC__JSPromise__asValue(this, globalThis);
|
||||
}
|
||||
|
||||
pub const Unwrapped = union(enum) {
|
||||
pending,
|
||||
fulfilled: JSValue,
|
||||
rejected: JSValue,
|
||||
};
|
||||
|
||||
pub const UnwrapMode = enum { mark_handled, leave_unhandled };
|
||||
|
||||
pub fn unwrap(promise: *JSPromise, vm: *VM, mode: UnwrapMode) Unwrapped {
|
||||
return switch (promise.status(vm)) {
|
||||
.pending => .pending,
|
||||
.fulfilled => .{ .fulfilled = promise.result(vm) },
|
||||
.rejected => {
|
||||
if (mode == .mark_handled) promise.setHandled(vm);
|
||||
return .{ .rejected = promise.result(vm) };
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
138
src/bun.js/bindings/JSString.zig
Normal file
138
src/bun.js/bindings/JSString.zig
Normal file
@@ -0,0 +1,138 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const JSString = extern struct {
|
||||
pub const shim = Shimmer("JSC", "JSString", @This());
|
||||
bytes: shim.Bytes,
|
||||
const cppFn = shim.cppFn;
|
||||
pub const include = "JavaScriptCore/JSString.h";
|
||||
pub const name = "JSC::JSString";
|
||||
pub const namespace = "JSC";
|
||||
|
||||
pub fn toJS(str: *JSString) JSValue {
|
||||
return JSValue.fromCell(str);
|
||||
}
|
||||
|
||||
pub fn toObject(this: *JSString, global: *JSGlobalObject) ?*JSObject {
|
||||
return shim.cppFn("toObject", .{ this, global });
|
||||
}
|
||||
|
||||
pub fn toZigString(this: *JSString, global: *JSGlobalObject, zig_str: *JSC.ZigString) void {
|
||||
return shim.cppFn("toZigString", .{ this, global, zig_str });
|
||||
}
|
||||
|
||||
pub fn ensureStillAlive(this: *JSString) void {
|
||||
std.mem.doNotOptimizeAway(this);
|
||||
}
|
||||
|
||||
pub fn getZigString(this: *JSString, global: *JSGlobalObject) JSC.ZigString {
|
||||
var out = JSC.ZigString.init("");
|
||||
this.toZigString(global, &out);
|
||||
return out;
|
||||
}
|
||||
|
||||
pub const view = getZigString;
|
||||
|
||||
/// doesn't always allocate
|
||||
pub fn toSlice(
|
||||
this: *JSString,
|
||||
global: *JSGlobalObject,
|
||||
allocator: std.mem.Allocator,
|
||||
) ZigString.Slice {
|
||||
var str = ZigString.init("");
|
||||
this.toZigString(global, &str);
|
||||
return str.toSlice(allocator);
|
||||
}
|
||||
|
||||
pub fn toSliceClone(
|
||||
this: *JSString,
|
||||
global: *JSGlobalObject,
|
||||
allocator: std.mem.Allocator,
|
||||
) JSError!ZigString.Slice {
|
||||
var str = ZigString.init("");
|
||||
this.toZigString(global, &str);
|
||||
return str.toSliceClone(allocator);
|
||||
}
|
||||
|
||||
pub fn toSliceZ(
|
||||
this: *JSString,
|
||||
global: *JSGlobalObject,
|
||||
allocator: std.mem.Allocator,
|
||||
) ZigString.Slice {
|
||||
var str = ZigString.init("");
|
||||
this.toZigString(global, &str);
|
||||
return str.toSliceZ(allocator);
|
||||
}
|
||||
|
||||
pub fn eql(this: *const JSString, global: *JSGlobalObject, other: *JSString) bool {
|
||||
return shim.cppFn("eql", .{ this, global, other });
|
||||
}
|
||||
|
||||
pub fn iterator(this: *JSString, globalObject: *JSGlobalObject, iter: *anyopaque) void {
|
||||
return shim.cppFn("iterator", .{ this, globalObject, iter });
|
||||
}
|
||||
|
||||
pub fn length(this: *const JSString) usize {
|
||||
return shim.cppFn("length", .{
|
||||
this,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn is8Bit(this: *const JSString) bool {
|
||||
return shim.cppFn("is8Bit", .{
|
||||
this,
|
||||
});
|
||||
}
|
||||
|
||||
pub const JStringIteratorAppend8Callback = *const fn (*Iterator, [*]const u8, u32) callconv(.C) void;
|
||||
pub const JStringIteratorAppend16Callback = *const fn (*Iterator, [*]const u16, u32) callconv(.C) void;
|
||||
pub const JStringIteratorWrite8Callback = *const fn (*Iterator, [*]const u8, u32, u32) callconv(.C) void;
|
||||
pub const JStringIteratorWrite16Callback = *const fn (*Iterator, [*]const u16, u32, u32) callconv(.C) void;
|
||||
pub const Iterator = extern struct {
|
||||
data: ?*anyopaque,
|
||||
stop: u8,
|
||||
append8: ?JStringIteratorAppend8Callback,
|
||||
append16: ?JStringIteratorAppend16Callback,
|
||||
write8: ?JStringIteratorWrite8Callback,
|
||||
write16: ?JStringIteratorWrite16Callback,
|
||||
};
|
||||
|
||||
pub const Extern = [_][]const u8{ "toZigString", "iterator", "toObject", "eql", "value", "length", "is8Bit", "createFromOwnedString", "createFromString" };
|
||||
};
|
||||
69
src/bun.js/bindings/JSUint8Array.zig
Normal file
69
src/bun.js/bindings/JSUint8Array.zig
Normal file
@@ -0,0 +1,69 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
const JSGlobalObject = JSC.JSGlobalObject;
|
||||
const VM = JSC.VM;
|
||||
const ZigString = JSC.ZigString;
|
||||
const CommonStrings = JSC.CommonStrings;
|
||||
const URL = JSC.URL;
|
||||
const WTF = JSC.WTF;
|
||||
const JSString = JSC.JSString;
|
||||
const JSObject = JSC.JSObject;
|
||||
const JSValue = JSC.JSValue;
|
||||
const GetterSetter = JSC.GetterSetter;
|
||||
const CustomGetterSetter = JSC.CustomGetterSetter;
|
||||
|
||||
pub const JSUint8Array = opaque {
|
||||
pub const name = "Uint8Array_alias";
|
||||
pub fn ptr(this: *JSUint8Array) [*]u8 {
|
||||
return @as(*[*]u8, @ptrFromInt(@intFromPtr(this) + Sizes.Bun_FFI_PointerOffsetToTypedArrayVector)).*;
|
||||
}
|
||||
|
||||
pub fn len(this: *JSUint8Array) usize {
|
||||
return @as(*usize, @ptrFromInt(@intFromPtr(this) + Sizes.Bun_FFI_PointerOffsetToTypedArrayLength)).*;
|
||||
}
|
||||
|
||||
pub fn slice(this: *JSUint8Array) []u8 {
|
||||
return this.ptr()[0..this.len()];
|
||||
}
|
||||
|
||||
extern fn JSUint8Array__fromDefaultAllocator(*JSC.JSGlobalObject, ptr: [*]u8, len: usize) JSC.JSValue;
|
||||
/// *bytes* must come from bun.default_allocator
|
||||
pub fn fromBytes(globalThis: *JSGlobalObject, bytes: []u8) JSC.JSValue {
|
||||
return JSUint8Array__fromDefaultAllocator(globalThis, bytes.ptr, bytes.len);
|
||||
}
|
||||
|
||||
extern fn Bun__createUint8ArrayForCopy(*JSC.JSGlobalObject, ptr: ?*const anyopaque, len: usize, buffer: bool) JSValue;
|
||||
pub fn fromBytesCopy(globalThis: *JSGlobalObject, bytes: []const u8) JSValue {
|
||||
return Bun__createUint8ArrayForCopy(globalThis, bytes.ptr, bytes.len, false);
|
||||
}
|
||||
|
||||
pub fn createEmpty(globalThis: *JSGlobalObject) JSValue {
|
||||
return Bun__createUint8ArrayForCopy(globalThis, null, 0, false);
|
||||
}
|
||||
};
|
||||
2686
src/bun.js/bindings/JSValue.zig
Normal file
2686
src/bun.js/bindings/JSValue.zig
Normal file
File diff suppressed because it is too large
Load Diff
156
src/bun.js/bindings/SystemError.zig
Normal file
156
src/bun.js/bindings/SystemError.zig
Normal file
@@ -0,0 +1,156 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
const JSGlobalObject = JSC.JSGlobalObject;
|
||||
const VM = JSC.VM;
|
||||
const ZigString = JSC.ZigString;
|
||||
const CommonStrings = JSC.CommonStrings;
|
||||
const URL = JSC.URL;
|
||||
const WTF = JSC.WTF;
|
||||
const JSString = JSC.JSString;
|
||||
const JSObject = JSC.JSObject;
|
||||
const JSValue = JSC.JSValue;
|
||||
const GetterSetter = JSC.GetterSetter;
|
||||
const CustomGetterSetter = JSC.CustomGetterSetter;
|
||||
|
||||
pub const SystemError = extern struct {
|
||||
errno: c_int = 0,
|
||||
/// label for errno
|
||||
code: String = String.empty,
|
||||
message: String = String.empty,
|
||||
path: String = String.empty,
|
||||
syscall: String = String.empty,
|
||||
hostname: String = String.empty,
|
||||
fd: bun.FileDescriptor = bun.toFD(-1),
|
||||
dest: String = String.empty,
|
||||
|
||||
pub fn Maybe(comptime Result: type) type {
|
||||
return union(enum) {
|
||||
err: SystemError,
|
||||
result: Result,
|
||||
};
|
||||
}
|
||||
|
||||
pub const shim = Shimmer("", "SystemError", @This());
|
||||
|
||||
pub const name = "SystemError";
|
||||
pub const namespace = "";
|
||||
|
||||
pub fn getErrno(this: *const SystemError) bun.C.E {
|
||||
// The inverse in bun.sys.Error.toSystemError()
|
||||
return @enumFromInt(this.errno * -1);
|
||||
}
|
||||
|
||||
pub fn deref(this: *const SystemError) void {
|
||||
this.path.deref();
|
||||
this.code.deref();
|
||||
this.message.deref();
|
||||
this.syscall.deref();
|
||||
this.hostname.deref();
|
||||
this.dest.deref();
|
||||
}
|
||||
|
||||
pub fn ref(this: *SystemError) void {
|
||||
this.path.ref();
|
||||
this.code.ref();
|
||||
this.message.ref();
|
||||
this.syscall.ref();
|
||||
this.hostname.ref();
|
||||
this.dest.ref();
|
||||
}
|
||||
|
||||
pub fn toErrorInstance(this: *const SystemError, global: *JSGlobalObject) JSValue {
|
||||
defer this.deref();
|
||||
|
||||
return shim.cppFn("toErrorInstance", .{ this, global });
|
||||
}
|
||||
|
||||
/// This constructs the ERR_SYSTEM_ERROR error object, which has an `info`
|
||||
/// property containing the details of the system error:
|
||||
///
|
||||
/// SystemError [ERR_SYSTEM_ERROR]: A system error occurred: {syscall} returned {errno} ({message})
|
||||
/// {
|
||||
/// name: "ERR_SYSTEM_ERROR",
|
||||
/// info: {
|
||||
/// errno: -{errno},
|
||||
/// code: {code}, // string
|
||||
/// message: {message}, // string
|
||||
/// syscall: {syscall}, // string
|
||||
/// },
|
||||
/// errno: -{errno},
|
||||
/// syscall: {syscall},
|
||||
/// }
|
||||
///
|
||||
/// Before using this function, consider if the Node.js API it is
|
||||
/// implementing follows this convention. It is exclusively used
|
||||
/// to match the error code that `node:os` throws.
|
||||
pub fn toErrorInstanceWithInfoObject(this: *const SystemError, global: *JSGlobalObject) JSValue {
|
||||
defer this.deref();
|
||||
|
||||
return SystemError__toErrorInstanceWithInfoObject(this, global);
|
||||
}
|
||||
extern fn SystemError__toErrorInstanceWithInfoObject(*const SystemError, *JSC.JSGlobalObject) JSValue;
|
||||
|
||||
pub fn format(self: SystemError, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
if (!self.path.isEmpty()) {
|
||||
// TODO: remove this hardcoding
|
||||
switch (bun.Output.enable_ansi_colors_stderr) {
|
||||
inline else => |enable_colors| try writer.print(
|
||||
comptime bun.Output.prettyFmt(
|
||||
"<r><red>{}<r><d>:<r> <b>{s}<r>: {} <d>({}())<r>",
|
||||
enable_colors,
|
||||
),
|
||||
.{
|
||||
self.code,
|
||||
self.path,
|
||||
self.message,
|
||||
self.syscall,
|
||||
},
|
||||
),
|
||||
}
|
||||
} else
|
||||
// TODO: remove this hardcoding
|
||||
switch (bun.Output.enable_ansi_colors_stderr) {
|
||||
inline else => |enable_colors| try writer.print(
|
||||
comptime bun.Output.prettyFmt(
|
||||
"<r><red>{}<r><d>:<r> {} <d>({}())<r>",
|
||||
enable_colors,
|
||||
),
|
||||
.{
|
||||
self.code,
|
||||
self.message,
|
||||
self.syscall,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub const Extern = [_][]const u8{
|
||||
"toErrorInstance",
|
||||
};
|
||||
};
|
||||
29
src/bun.js/bindings/Thenables.zig
Normal file
29
src/bun.js/bindings/Thenables.zig
Normal file
@@ -0,0 +1,29 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const Thenables = opaque {};
|
||||
150
src/bun.js/bindings/URL.zig
Normal file
150
src/bun.js/bindings/URL.zig
Normal file
@@ -0,0 +1,150 @@
|
||||
pub const URL = opaque {
|
||||
extern fn URL__fromJS(JSValue, *JSC.JSGlobalObject) ?*URL;
|
||||
extern fn URL__fromString(*bun.String) ?*URL;
|
||||
extern fn URL__protocol(*URL) String;
|
||||
extern fn URL__href(*URL) String;
|
||||
extern fn URL__username(*URL) String;
|
||||
extern fn URL__password(*URL) String;
|
||||
extern fn URL__search(*URL) String;
|
||||
extern fn URL__host(*URL) String;
|
||||
extern fn URL__hostname(*URL) String;
|
||||
extern fn URL__port(*URL) u32;
|
||||
extern fn URL__deinit(*URL) void;
|
||||
extern fn URL__pathname(*URL) String;
|
||||
extern fn URL__getHrefFromJS(JSValue, *JSC.JSGlobalObject) String;
|
||||
extern fn URL__getHref(*String) String;
|
||||
extern fn URL__getFileURLString(*String) String;
|
||||
extern fn URL__getHrefJoin(*String, *String) String;
|
||||
extern fn URL__pathFromFileURL(*String) String;
|
||||
|
||||
pub fn hrefFromString(str: bun.String) String {
|
||||
JSC.markBinding(@src());
|
||||
var input = str;
|
||||
return URL__getHref(&input);
|
||||
}
|
||||
|
||||
pub fn join(base: bun.String, relative: bun.String) String {
|
||||
JSC.markBinding(@src());
|
||||
var base_str = base;
|
||||
var relative_str = relative;
|
||||
return URL__getHrefJoin(&base_str, &relative_str);
|
||||
}
|
||||
|
||||
pub fn fileURLFromString(str: bun.String) String {
|
||||
JSC.markBinding(@src());
|
||||
var input = str;
|
||||
return URL__getFileURLString(&input);
|
||||
}
|
||||
|
||||
pub fn pathFromFileURL(str: bun.String) String {
|
||||
JSC.markBinding(@src());
|
||||
var input = str;
|
||||
return URL__pathFromFileURL(&input);
|
||||
}
|
||||
|
||||
/// This percent-encodes the URL, punycode-encodes the hostname, and returns the result
|
||||
/// If it fails, the tag is marked Dead
|
||||
pub fn hrefFromJS(value: JSValue, globalObject: *JSC.JSGlobalObject) bun.JSError!String {
|
||||
JSC.markBinding(@src());
|
||||
const result = URL__getHrefFromJS(value, globalObject);
|
||||
if (globalObject.hasException()) return error.JSError;
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn fromJS(value: JSValue, globalObject: *JSC.JSGlobalObject) bun.JSError!?*URL {
|
||||
JSC.markBinding(@src());
|
||||
const result = URL__fromJS(value, globalObject);
|
||||
if (globalObject.hasException()) return error.JSError;
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn fromUTF8(input: []const u8) ?*URL {
|
||||
return fromString(String.fromUTF8(input));
|
||||
}
|
||||
pub fn fromString(str: bun.String) ?*URL {
|
||||
JSC.markBinding(@src());
|
||||
var input = str;
|
||||
return URL__fromString(&input);
|
||||
}
|
||||
pub fn protocol(url: *URL) String {
|
||||
JSC.markBinding(@src());
|
||||
return URL__protocol(url);
|
||||
}
|
||||
pub fn href(url: *URL) String {
|
||||
JSC.markBinding(@src());
|
||||
return URL__href(url);
|
||||
}
|
||||
pub fn username(url: *URL) String {
|
||||
JSC.markBinding(@src());
|
||||
return URL__username(url);
|
||||
}
|
||||
pub fn password(url: *URL) String {
|
||||
JSC.markBinding(@src());
|
||||
return URL__password(url);
|
||||
}
|
||||
pub fn search(url: *URL) String {
|
||||
JSC.markBinding(@src());
|
||||
return URL__search(url);
|
||||
}
|
||||
pub fn host(url: *URL) String {
|
||||
JSC.markBinding(@src());
|
||||
return URL__host(url);
|
||||
}
|
||||
pub fn hostname(url: *URL) String {
|
||||
JSC.markBinding(@src());
|
||||
return URL__hostname(url);
|
||||
}
|
||||
/// Returns `std.math.maxInt(u32)` if the port is not set. Otherwise, `port`
|
||||
/// is guaranteed to be within the `u16` range.
|
||||
pub fn port(url: *URL) u32 {
|
||||
JSC.markBinding(@src());
|
||||
return URL__port(url);
|
||||
}
|
||||
pub fn deinit(url: *URL) void {
|
||||
JSC.markBinding(@src());
|
||||
return URL__deinit(url);
|
||||
}
|
||||
pub fn pathname(url: *URL) String {
|
||||
JSC.markBinding(@src());
|
||||
return URL__pathname(url);
|
||||
}
|
||||
};
|
||||
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
const VM = @import("./VM.zig").VM;
|
||||
const ZigString = @import("./ZigString.zig").ZigString;
|
||||
const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
const JSString = @import("./JSString.zig").JSString;
|
||||
const JSObject = @import("./JSObject.zig").JSObject;
|
||||
const JSCell = @import("./JSCell.zig").JSCell;
|
||||
const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
const JSValue = JSC.JSValue;
|
||||
79
src/bun.js/bindings/URLSearchParams.zig
Normal file
79
src/bun.js/bindings/URLSearchParams.zig
Normal file
@@ -0,0 +1,79 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const URLSearchParams = opaque {
|
||||
extern fn URLSearchParams__create(globalObject: *JSGlobalObject, *const ZigString) JSValue;
|
||||
pub fn create(globalObject: *JSGlobalObject, init: ZigString) JSValue {
|
||||
JSC.markBinding(@src());
|
||||
return URLSearchParams__create(globalObject, &init);
|
||||
}
|
||||
|
||||
extern fn URLSearchParams__fromJS(JSValue) ?*URLSearchParams;
|
||||
pub fn fromJS(value: JSValue) ?*URLSearchParams {
|
||||
JSC.markBinding(@src());
|
||||
return URLSearchParams__fromJS(value);
|
||||
}
|
||||
|
||||
extern fn URLSearchParams__toString(
|
||||
self: *URLSearchParams,
|
||||
ctx: *anyopaque,
|
||||
callback: *const fn (ctx: *anyopaque, str: *const ZigString) callconv(.C) void,
|
||||
) void;
|
||||
|
||||
pub fn toString(
|
||||
self: *URLSearchParams,
|
||||
comptime Ctx: type,
|
||||
ctx: *Ctx,
|
||||
comptime callback: *const fn (ctx: *Ctx, str: ZigString) void,
|
||||
) void {
|
||||
JSC.markBinding(@src());
|
||||
const Wrap = struct {
|
||||
const cb_ = callback;
|
||||
pub fn cb(c: *anyopaque, str: *const ZigString) callconv(.C) void {
|
||||
cb_(
|
||||
bun.cast(*Ctx, c),
|
||||
str.*,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
URLSearchParams__toString(self, ctx, Wrap.cb);
|
||||
}
|
||||
};
|
||||
250
src/bun.js/bindings/VM.zig
Normal file
250
src/bun.js/bindings/VM.zig
Normal file
@@ -0,0 +1,250 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
const JSGlobalObject = JSC.JSGlobalObject;
|
||||
const VM = JSC.VM;
|
||||
const ZigString = JSC.ZigString;
|
||||
const CommonStrings = JSC.CommonStrings;
|
||||
const URL = JSC.URL;
|
||||
const WTF = JSC.WTF;
|
||||
const JSString = JSC.JSString;
|
||||
const JSObject = JSC.JSObject;
|
||||
const JSValue = JSC.JSValue;
|
||||
const GetterSetter = JSC.GetterSetter;
|
||||
const CustomGetterSetter = JSC.CustomGetterSetter;
|
||||
|
||||
pub const VM = extern struct {
|
||||
pub const shim = Shimmer("JSC", "VM", @This());
|
||||
bytes: shim.Bytes,
|
||||
|
||||
const cppFn = shim.cppFn;
|
||||
|
||||
pub const include = "JavaScriptCore/VM.h";
|
||||
pub const name = "JSC::VM";
|
||||
pub const namespace = "JSC";
|
||||
|
||||
pub const HeapType = enum(u8) {
|
||||
SmallHeap = 0,
|
||||
LargeHeap = 1,
|
||||
};
|
||||
|
||||
pub fn create(heap_type: HeapType) *VM {
|
||||
return cppFn("create", .{@intFromEnum(heap_type)});
|
||||
}
|
||||
|
||||
pub fn deinit(vm: *VM, global_object: *JSGlobalObject) void {
|
||||
return cppFn("deinit", .{ vm, global_object });
|
||||
}
|
||||
|
||||
pub fn setControlFlowProfiler(vm: *VM, enabled: bool) void {
|
||||
return cppFn("setControlFlowProfiler", .{ vm, enabled });
|
||||
}
|
||||
|
||||
pub fn isJITEnabled() bool {
|
||||
return cppFn("isJITEnabled", .{});
|
||||
}
|
||||
|
||||
/// deprecated in favor of getAPILock to avoid an annoying callback wrapper
|
||||
pub fn holdAPILock(this: *VM, ctx: ?*anyopaque, callback: *const fn (ctx: ?*anyopaque) callconv(.C) void) void {
|
||||
cppFn("holdAPILock", .{ this, ctx, callback });
|
||||
}
|
||||
|
||||
extern fn JSC__VM__getAPILock(vm: *VM) void;
|
||||
extern fn JSC__VM__releaseAPILock(vm: *VM) void;
|
||||
|
||||
/// See `JSLock.h` in WebKit for more detail on how the API lock prevents races.
|
||||
pub fn getAPILock(vm: *VM) Lock {
|
||||
JSC__VM__getAPILock(vm);
|
||||
return .{ .vm = vm };
|
||||
}
|
||||
|
||||
pub const Lock = struct {
|
||||
vm: *VM,
|
||||
pub fn release(lock: Lock) void {
|
||||
JSC__VM__releaseAPILock(lock.vm);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn deferGC(this: *VM, ctx: ?*anyopaque, callback: *const fn (ctx: ?*anyopaque) callconv(.C) void) void {
|
||||
cppFn("deferGC", .{ this, ctx, callback });
|
||||
}
|
||||
extern fn JSC__VM__reportExtraMemory(*VM, usize) void;
|
||||
pub fn reportExtraMemory(this: *VM, size: usize) void {
|
||||
JSC.markBinding(@src());
|
||||
JSC__VM__reportExtraMemory(this, size);
|
||||
}
|
||||
|
||||
pub fn deleteAllCode(
|
||||
vm: *VM,
|
||||
global_object: *JSGlobalObject,
|
||||
) void {
|
||||
return cppFn("deleteAllCode", .{ vm, global_object });
|
||||
}
|
||||
|
||||
pub fn whenIdle(
|
||||
vm: *VM,
|
||||
callback: *const fn (...) callconv(.C) void,
|
||||
) void {
|
||||
return cppFn("whenIdle", .{ vm, callback });
|
||||
}
|
||||
|
||||
pub fn shrinkFootprint(
|
||||
vm: *VM,
|
||||
) void {
|
||||
return cppFn("shrinkFootprint", .{
|
||||
vm,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn runGC(vm: *VM, sync: bool) usize {
|
||||
return cppFn("runGC", .{
|
||||
vm,
|
||||
sync,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn heapSize(vm: *VM) usize {
|
||||
return cppFn("heapSize", .{
|
||||
vm,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn collectAsync(vm: *VM) void {
|
||||
return cppFn("collectAsync", .{
|
||||
vm,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn setExecutionForbidden(vm: *VM, forbidden: bool) void {
|
||||
cppFn("setExecutionForbidden", .{ vm, forbidden });
|
||||
}
|
||||
|
||||
pub fn setExecutionTimeLimit(vm: *VM, timeout: f64) void {
|
||||
return cppFn("setExecutionTimeLimit", .{ vm, timeout });
|
||||
}
|
||||
|
||||
pub fn clearExecutionTimeLimit(vm: *VM) void {
|
||||
return cppFn("clearExecutionTimeLimit", .{vm});
|
||||
}
|
||||
|
||||
pub fn executionForbidden(vm: *VM) bool {
|
||||
return cppFn("executionForbidden", .{
|
||||
vm,
|
||||
});
|
||||
}
|
||||
|
||||
// These four functions fire VM traps. To understand what that means, see VMTraps.h for a giant explainer.
|
||||
// These may be called concurrently from another thread.
|
||||
|
||||
/// Fires NeedTermination Trap. Thread safe. See JSC's "VMTraps.h" for explaination on traps.
|
||||
pub fn notifyNeedTermination(vm: *VM) void {
|
||||
cppFn("notifyNeedTermination", .{vm});
|
||||
}
|
||||
/// Fires NeedWatchdogCheck Trap. Thread safe. See JSC's "VMTraps.h" for explaination on traps.
|
||||
pub fn notifyNeedWatchdogCheck(vm: *VM) void {
|
||||
cppFn("notifyNeedWatchdogCheck", .{vm});
|
||||
}
|
||||
/// Fires NeedDebuggerBreak Trap. Thread safe. See JSC's "VMTraps.h" for explaination on traps.
|
||||
pub fn notifyNeedDebuggerBreak(vm: *VM) void {
|
||||
cppFn("notifyNeedDebuggerBreak", .{vm});
|
||||
}
|
||||
/// Fires NeedShellTimeoutCheck Trap. Thread safe. See JSC's "VMTraps.h" for explaination on traps.
|
||||
pub fn notifyNeedShellTimeoutCheck(vm: *VM) void {
|
||||
cppFn("notifyNeedShellTimeoutCheck", .{vm});
|
||||
}
|
||||
|
||||
pub fn isEntered(vm: *VM) bool {
|
||||
return cppFn("isEntered", .{
|
||||
vm,
|
||||
});
|
||||
}
|
||||
|
||||
// manual extern to workaround shimmer limitation
|
||||
// shimmer doesnt let you change the return type or make it non-pub
|
||||
extern fn JSC__VM__throwError(*VM, *JSGlobalObject, JSValue) void;
|
||||
fn throwError(vm: *VM, global_object: *JSGlobalObject, value: JSValue) void {
|
||||
JSC__VM__throwError(vm, global_object, value);
|
||||
}
|
||||
|
||||
pub fn releaseWeakRefs(vm: *VM) void {
|
||||
return cppFn("releaseWeakRefs", .{vm});
|
||||
}
|
||||
|
||||
pub fn drainMicrotasks(
|
||||
vm: *VM,
|
||||
) void {
|
||||
return cppFn("drainMicrotasks", .{
|
||||
vm,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn externalMemorySize(vm: *VM) usize {
|
||||
return cppFn("externalMemorySize", .{vm});
|
||||
}
|
||||
|
||||
/// `RESOURCE_USAGE` build option in JavaScriptCore is required for this function
|
||||
/// This is faster than checking the heap size
|
||||
pub fn blockBytesAllocated(vm: *VM) usize {
|
||||
return cppFn("blockBytesAllocated", .{vm});
|
||||
}
|
||||
|
||||
pub fn performOpportunisticallyScheduledTasks(vm: *VM, until: f64) void {
|
||||
cppFn("performOpportunisticallyScheduledTasks", .{ vm, until });
|
||||
}
|
||||
|
||||
pub const Extern = [_][]const u8{
|
||||
"setControlFlowProfiler",
|
||||
"collectAsync",
|
||||
"externalMemorySize",
|
||||
"blockBytesAllocated",
|
||||
"heapSize",
|
||||
"releaseWeakRefs",
|
||||
"throwError",
|
||||
"deferGC",
|
||||
"holdAPILock",
|
||||
"runGC",
|
||||
"generateHeapSnapshot",
|
||||
"isJITEnabled",
|
||||
"deleteAllCode",
|
||||
"create",
|
||||
"deinit",
|
||||
"setExecutionForbidden",
|
||||
"executionForbidden",
|
||||
"isEntered",
|
||||
"throwError",
|
||||
"drainMicrotasks",
|
||||
"whenIdle",
|
||||
"shrinkFootprint",
|
||||
"setExecutionTimeLimit",
|
||||
"clearExecutionTimeLimit",
|
||||
"notifyNeedTermination",
|
||||
"notifyNeedWatchdogCheck",
|
||||
"notifyNeedDebuggerBreak",
|
||||
"notifyNeedShellTimeoutCheck",
|
||||
};
|
||||
};
|
||||
45
src/bun.js/bindings/WTF.zig
Normal file
45
src/bun.js/bindings/WTF.zig
Normal file
@@ -0,0 +1,45 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const WTF = struct {
|
||||
extern fn WTF__parseDouble(bytes: [*]const u8, length: usize, counted: *usize) f64;
|
||||
|
||||
pub fn parseDouble(buf: []const u8) !f64 {
|
||||
JSC.markBinding(@src());
|
||||
|
||||
if (buf.len == 0)
|
||||
return error.InvalidCharacter;
|
||||
|
||||
var count: usize = 0;
|
||||
const res = WTF__parseDouble(buf.ptr, buf.len, &count);
|
||||
|
||||
if (count == 0)
|
||||
return error.InvalidCharacter;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
892
src/bun.js/bindings/ZigString.zig
Normal file
892
src/bun.js/bindings/ZigString.zig
Normal file
@@ -0,0 +1,892 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub const JSGlobalObject = @import("./JSGlobalObject.zig").JSGlobalObject;
|
||||
pub const URL = @import("./URL.zig").URL;
|
||||
pub const VM = @import("./VM.zig").VM;
|
||||
pub const WTF = @import("./WTF.zig").WTF;
|
||||
pub const JSString = @import("./JSString.zig").JSString;
|
||||
pub const ZigString = @import("./ZigString.zig").ZigString;
|
||||
pub const CommonStrings = @import("./CommonStrings.zig").CommonStrings;
|
||||
pub const JSObject = @import("./JSObject.zig").JSObject;
|
||||
pub const JSCell = @import("./JSCell.zig").JSCell;
|
||||
pub const GetterSetter = @import("./GetterSetter.zig").GetterSetter;
|
||||
pub const CustomGetterSetter = @import("./CustomGetterSetter.zig").CustomGetterSetter;
|
||||
|
||||
pub const ZigString = extern struct {
|
||||
/// This can be a UTF-16, Latin1, or UTF-8 string.
|
||||
/// The pointer itself is tagged, so it cannot be used without untagging it first
|
||||
/// Accessing it directly is unsafe.
|
||||
_unsafe_ptr_do_not_use: [*]const u8,
|
||||
len: usize,
|
||||
|
||||
pub const ByteString = union(enum) {
|
||||
latin1: []const u8,
|
||||
utf16: []const u16,
|
||||
};
|
||||
|
||||
pub fn fromBytes(slice_: []const u8) ZigString {
|
||||
if (!strings.isAllASCII(slice_)) {
|
||||
return initUTF8(slice_);
|
||||
}
|
||||
|
||||
return init(slice_);
|
||||
}
|
||||
|
||||
pub inline fn as(this: ZigString) ByteString {
|
||||
return if (this.is16Bit()) .{ .utf16 = this.utf16SliceAligned() } else .{ .latin1 = this.slice() };
|
||||
}
|
||||
|
||||
pub fn encode(this: ZigString, encoding: JSC.Node.Encoding) []u8 {
|
||||
return this.encodeWithAllocator(bun.default_allocator, encoding);
|
||||
}
|
||||
|
||||
pub fn encodeWithAllocator(this: ZigString, allocator: std.mem.Allocator, encoding: JSC.Node.Encoding) []u8 {
|
||||
return switch (this.as()) {
|
||||
inline else => |repr| switch (encoding) {
|
||||
inline else => |enc| JSC.WebCore.Encoder.constructFrom(std.meta.Child(@TypeOf(repr)), repr, allocator, enc),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn dupeForJS(utf8: []const u8, allocator: std.mem.Allocator) !ZigString {
|
||||
if (try strings.toUTF16Alloc(allocator, utf8, false, false)) |utf16| {
|
||||
var out = ZigString.initUTF16(utf16);
|
||||
out.mark();
|
||||
out.markUTF16();
|
||||
return out;
|
||||
} else {
|
||||
var out = ZigString.init(try allocator.dupe(u8, utf8));
|
||||
out.mark();
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
extern fn ZigString__toValueGC(arg0: *const ZigString, arg1: *JSGlobalObject) JSC.JSValue;
|
||||
pub fn toJS(this: *const ZigString, ctx: *JSC.JSGlobalObject) JSValue {
|
||||
if (this.isGloballyAllocated()) {
|
||||
return this.toExternalValue(ctx);
|
||||
}
|
||||
|
||||
return ZigString__toValueGC(this, ctx);
|
||||
}
|
||||
|
||||
/// This function is not optimized!
|
||||
pub fn eqlCaseInsensitive(this: ZigString, other: ZigString) bool {
|
||||
var fallback = std.heap.stackFallback(1024, bun.default_allocator);
|
||||
const fallback_allocator = fallback.get();
|
||||
|
||||
var utf16_slice = this.toSliceLowercase(fallback_allocator);
|
||||
var latin1_slice = other.toSliceLowercase(fallback_allocator);
|
||||
defer utf16_slice.deinit();
|
||||
defer latin1_slice.deinit();
|
||||
return strings.eqlLong(utf16_slice.slice(), latin1_slice.slice(), true);
|
||||
}
|
||||
|
||||
pub fn toSliceLowercase(this: ZigString, allocator: std.mem.Allocator) Slice {
|
||||
if (this.len == 0)
|
||||
return Slice.empty;
|
||||
var fallback = std.heap.stackFallback(512, allocator);
|
||||
const fallback_allocator = fallback.get();
|
||||
|
||||
const uppercase_buffer = this.toOwnedSlice(fallback_allocator) catch unreachable;
|
||||
const buffer = allocator.alloc(u8, uppercase_buffer.len) catch unreachable;
|
||||
const out = strings.copyLowercase(uppercase_buffer, buffer);
|
||||
|
||||
return Slice{
|
||||
.allocator = NullableAllocator.init(allocator),
|
||||
.ptr = out.ptr,
|
||||
.len = @as(u32, @truncate(out.len)),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn indexOfAny(this: ZigString, comptime chars: []const u8) ?strings.OptionalUsize {
|
||||
if (this.is16Bit()) {
|
||||
return strings.indexOfAny16(this.utf16SliceAligned(), chars);
|
||||
} else {
|
||||
return strings.indexOfAny(this.slice(), chars);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn charAt(this: ZigString, offset: usize) u8 {
|
||||
if (this.is16Bit()) {
|
||||
return @as(u8, @truncate(this.utf16SliceAligned()[offset]));
|
||||
} else {
|
||||
return @as(u8, @truncate(this.slice()[offset]));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eql(this: ZigString, other: ZigString) bool {
|
||||
if (this.len == 0 or other.len == 0)
|
||||
return this.len == other.len;
|
||||
|
||||
const left_utf16 = this.is16Bit();
|
||||
const right_utf16 = other.is16Bit();
|
||||
|
||||
if (left_utf16 == right_utf16 and left_utf16) {
|
||||
return strings.eqlLong(std.mem.sliceAsBytes(this.utf16SliceAligned()), std.mem.sliceAsBytes(other.utf16SliceAligned()), true);
|
||||
} else if (left_utf16 == right_utf16) {
|
||||
return strings.eqlLong(this.slice(), other.slice(), true);
|
||||
}
|
||||
|
||||
const utf16: ZigString = if (left_utf16) this else other;
|
||||
const latin1: ZigString = if (left_utf16) other else this;
|
||||
|
||||
if (latin1.isAllASCII()) {
|
||||
return strings.utf16EqlString(utf16.utf16SliceAligned(), latin1.slice());
|
||||
}
|
||||
|
||||
// slow path
|
||||
var utf16_slice = utf16.toSlice(bun.default_allocator);
|
||||
var latin1_slice = latin1.toSlice(bun.default_allocator);
|
||||
defer utf16_slice.deinit();
|
||||
defer latin1_slice.deinit();
|
||||
return strings.eqlLong(utf16_slice.slice(), latin1_slice.slice(), true);
|
||||
}
|
||||
|
||||
pub fn isAllASCII(this: ZigString) bool {
|
||||
if (this.is16Bit()) {
|
||||
return strings.firstNonASCII16([]const u16, this.utf16SliceAligned()) == null;
|
||||
}
|
||||
|
||||
return strings.isAllASCII(this.slice());
|
||||
}
|
||||
|
||||
pub fn clone(this: ZigString, allocator: std.mem.Allocator) !ZigString {
|
||||
var sliced = this.toSlice(allocator);
|
||||
if (!sliced.isAllocated()) {
|
||||
var str = ZigString.init(try allocator.dupe(u8, sliced.slice()));
|
||||
str.mark();
|
||||
str.markUTF8();
|
||||
return str;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
extern fn ZigString__toJSONObject(this: *const ZigString, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue;
|
||||
|
||||
pub fn toJSONObject(this: ZigString, globalThis: *JSC.JSGlobalObject) JSValue {
|
||||
JSC.markBinding(@src());
|
||||
return ZigString__toJSONObject(&this, globalThis);
|
||||
}
|
||||
|
||||
extern fn BunString__toURL(this: *const ZigString, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue;
|
||||
|
||||
pub fn toURL(this: ZigString, globalThis: *JSC.JSGlobalObject) JSValue {
|
||||
JSC.markBinding(@src());
|
||||
return BunString__toURL(&this, globalThis);
|
||||
}
|
||||
|
||||
pub fn hasPrefixChar(this: ZigString, char: u8) bool {
|
||||
if (this.len == 0)
|
||||
return false;
|
||||
|
||||
if (this.is16Bit()) {
|
||||
return this.utf16SliceAligned()[0] == char;
|
||||
}
|
||||
|
||||
return this.slice()[0] == char;
|
||||
}
|
||||
|
||||
pub fn substringWithLen(this: ZigString, start_index: usize, end_index: usize) ZigString {
|
||||
if (this.is16Bit()) {
|
||||
return ZigString.from16SliceMaybeGlobal(this.utf16SliceAligned()[start_index..end_index], this.isGloballyAllocated());
|
||||
}
|
||||
|
||||
var out = ZigString.init(this.slice()[start_index..end_index]);
|
||||
if (this.isUTF8()) {
|
||||
out.markUTF8();
|
||||
}
|
||||
|
||||
if (this.isGloballyAllocated()) {
|
||||
out.mark();
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
pub fn substring(this: ZigString, start_index: usize) ZigString {
|
||||
return this.substringWithLen(@min(this.len, start_index), this.len);
|
||||
}
|
||||
|
||||
pub fn maxUTF8ByteLength(this: ZigString) usize {
|
||||
if (this.isUTF8())
|
||||
return this.len;
|
||||
|
||||
if (this.is16Bit()) {
|
||||
return this.utf16SliceAligned().len * 3;
|
||||
}
|
||||
|
||||
// latin1
|
||||
return this.len * 2;
|
||||
}
|
||||
|
||||
pub fn utf16ByteLength(this: ZigString) usize {
|
||||
if (this.isUTF8()) {
|
||||
return bun.simdutf.length.utf16.from.utf8(this.slice());
|
||||
}
|
||||
|
||||
if (this.is16Bit()) {
|
||||
return this.len * 2;
|
||||
}
|
||||
|
||||
return JSC.WebCore.Encoder.byteLengthU8(this.slice().ptr, this.slice().len, .utf16le);
|
||||
}
|
||||
|
||||
pub fn latin1ByteLength(this: ZigString) usize {
|
||||
if (this.isUTF8()) {
|
||||
@panic("TODO");
|
||||
}
|
||||
|
||||
return this.len;
|
||||
}
|
||||
|
||||
/// Count the number of bytes in the UTF-8 version of the string.
|
||||
/// This function is slow. Use maxUITF8ByteLength() to get a quick estimate
|
||||
pub fn utf8ByteLength(this: ZigString) usize {
|
||||
if (this.isUTF8()) {
|
||||
return this.len;
|
||||
}
|
||||
|
||||
if (this.is16Bit()) {
|
||||
return JSC.WebCore.Encoder.byteLengthU16(this.utf16SliceAligned().ptr, this.utf16Slice().len, .utf8);
|
||||
}
|
||||
|
||||
return JSC.WebCore.Encoder.byteLengthU8(this.slice().ptr, this.slice().len, .utf8);
|
||||
}
|
||||
|
||||
pub fn toOwnedSlice(this: ZigString, allocator: std.mem.Allocator) ![]u8 {
|
||||
if (this.isUTF8())
|
||||
return try allocator.dupeZ(u8, this.slice());
|
||||
|
||||
var list = std.ArrayList(u8).init(allocator);
|
||||
list = if (this.is16Bit())
|
||||
try strings.toUTF8ListWithType(list, []const u16, this.utf16SliceAligned())
|
||||
else
|
||||
try strings.allocateLatin1IntoUTF8WithList(list, 0, []const u8, this.slice());
|
||||
|
||||
if (list.capacity > list.items.len) {
|
||||
list.items.ptr[list.items.len] = 0;
|
||||
}
|
||||
|
||||
return list.items;
|
||||
}
|
||||
|
||||
pub fn toOwnedSliceZ(this: ZigString, allocator: std.mem.Allocator) ![:0]u8 {
|
||||
if (this.isUTF8())
|
||||
return allocator.dupeZ(u8, this.slice());
|
||||
|
||||
var list = std.ArrayList(u8).init(allocator);
|
||||
list = if (this.is16Bit())
|
||||
try strings.toUTF8ListWithType(list, []const u16, this.utf16SliceAligned())
|
||||
else
|
||||
try strings.allocateLatin1IntoUTF8WithList(list, 0, []const u8, this.slice());
|
||||
|
||||
try list.append(0);
|
||||
return list.items[0 .. list.items.len - 1 :0];
|
||||
}
|
||||
|
||||
pub fn trunc(this: ZigString, len: usize) ZigString {
|
||||
return .{ ._unsafe_ptr_do_not_use = this._unsafe_ptr_do_not_use, .len = @min(len, this.len) };
|
||||
}
|
||||
|
||||
pub fn eqlComptime(this: ZigString, comptime other: []const u8) bool {
|
||||
if (this.is16Bit()) {
|
||||
return strings.eqlComptimeUTF16(this.utf16SliceAligned(), other);
|
||||
}
|
||||
|
||||
if (comptime strings.isAllASCII(other)) {
|
||||
if (this.len != other.len)
|
||||
return false;
|
||||
|
||||
return strings.eqlComptimeIgnoreLen(this.slice(), other);
|
||||
}
|
||||
|
||||
@compileError("Not implemented yet for latin1");
|
||||
}
|
||||
|
||||
pub const shim = Shimmer("", "ZigString", @This());
|
||||
|
||||
pub inline fn length(this: ZigString) usize {
|
||||
return this.len;
|
||||
}
|
||||
|
||||
pub fn byteSlice(this: ZigString) []const u8 {
|
||||
if (this.is16Bit()) {
|
||||
return std.mem.sliceAsBytes(this.utf16SliceAligned());
|
||||
}
|
||||
|
||||
return this.slice();
|
||||
}
|
||||
|
||||
pub fn markStatic(this: *ZigString) void {
|
||||
this.ptr = @as([*]const u8, @ptrFromInt(@intFromPtr(this.ptr) | (1 << 60)));
|
||||
}
|
||||
|
||||
pub fn isStatic(this: *const ZigString) bool {
|
||||
return @intFromPtr(this.ptr) & (1 << 60) != 0;
|
||||
}
|
||||
|
||||
pub const Slice = struct {
|
||||
allocator: NullableAllocator = .{},
|
||||
ptr: [*]const u8 = undefined,
|
||||
len: u32 = 0,
|
||||
|
||||
pub fn reportExtraMemory(this: *const Slice, vm: *JSC.VM) void {
|
||||
if (this.allocator.get()) |allocator| {
|
||||
// Don't report it if the memory is actually owned by JSC.
|
||||
if (!bun.String.isWTFAllocator(allocator)) {
|
||||
vm.reportExtraMemory(this.len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn isWTFAllocated(this: *const Slice) bool {
|
||||
return bun.String.isWTFAllocator(this.allocator.get() orelse return false);
|
||||
}
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, input: []const u8) Slice {
|
||||
return .{
|
||||
.ptr = input.ptr,
|
||||
.len = @as(u32, @truncate(input.len)),
|
||||
.allocator = NullableAllocator.init(allocator),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toZigString(this: Slice) ZigString {
|
||||
if (this.isAllocated())
|
||||
return ZigString.initUTF8(this.ptr[0..this.len]);
|
||||
return ZigString.init(this.slice());
|
||||
}
|
||||
|
||||
pub inline fn length(this: Slice) usize {
|
||||
return this.len;
|
||||
}
|
||||
|
||||
pub const byteSlice = Slice.slice;
|
||||
|
||||
pub fn fromUTF8NeverFree(input: []const u8) Slice {
|
||||
return .{
|
||||
.ptr = input.ptr,
|
||||
.len = @as(u32, @truncate(input.len)),
|
||||
.allocator = .{},
|
||||
};
|
||||
}
|
||||
|
||||
pub const empty = Slice{ .ptr = "", .len = 0 };
|
||||
|
||||
pub inline fn isAllocated(this: Slice) bool {
|
||||
return !this.allocator.isNull();
|
||||
}
|
||||
|
||||
pub fn toOwned(this: Slice, allocator: std.mem.Allocator) OOM!Slice {
|
||||
const duped = try allocator.dupe(u8, this.ptr[0..this.len]);
|
||||
return .{ .allocator = .init(allocator), .ptr = duped.ptr, .len = this.len };
|
||||
}
|
||||
|
||||
// TODO: this is identical to `cloneIfNeeded`
|
||||
pub fn clone(this: Slice, allocator: std.mem.Allocator) OOM!Slice {
|
||||
if (this.isAllocated()) {
|
||||
return Slice{ .allocator = this.allocator, .ptr = this.ptr, .len = this.len };
|
||||
}
|
||||
|
||||
const duped = try allocator.dupe(u8, this.ptr[0..this.len]);
|
||||
return Slice{ .allocator = NullableAllocator.init(allocator), .ptr = duped.ptr, .len = this.len };
|
||||
}
|
||||
|
||||
pub fn cloneIfNeeded(this: Slice, allocator: std.mem.Allocator) !Slice {
|
||||
if (this.isAllocated()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const duped = try allocator.dupe(u8, this.ptr[0..this.len]);
|
||||
return Slice{ .allocator = NullableAllocator.init(allocator), .ptr = duped.ptr, .len = this.len };
|
||||
}
|
||||
|
||||
pub fn cloneWithTrailingSlash(this: Slice, allocator: std.mem.Allocator) !Slice {
|
||||
const buf = try strings.cloneNormalizingSeparators(allocator, this.slice());
|
||||
return Slice{ .allocator = NullableAllocator.init(allocator), .ptr = buf.ptr, .len = @as(u32, @truncate(buf.len)) };
|
||||
}
|
||||
|
||||
pub fn cloneZ(this: Slice, allocator: std.mem.Allocator) !Slice {
|
||||
if (this.isAllocated() or this.len == 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const duped = try allocator.dupeZ(u8, this.ptr[0..this.len]);
|
||||
return Slice{ .allocator = NullableAllocator.init(allocator), .ptr = duped.ptr, .len = this.len };
|
||||
}
|
||||
|
||||
pub fn slice(this: Slice) []const u8 {
|
||||
return this.ptr[0..this.len];
|
||||
}
|
||||
|
||||
pub fn sliceZ(this: Slice) [:0]const u8 {
|
||||
return this.ptr[0..this.len :0];
|
||||
}
|
||||
|
||||
pub fn toSliceZ(this: Slice, buf: []u8) [:0]const u8 {
|
||||
if (this.len == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (this.ptr[this.len] == 0) {
|
||||
return this.sliceZ();
|
||||
}
|
||||
|
||||
if (this.len >= buf.len) {
|
||||
return "";
|
||||
}
|
||||
|
||||
bun.copy(u8, buf, this.slice());
|
||||
buf[this.len] = 0;
|
||||
return buf[0..this.len :0];
|
||||
}
|
||||
|
||||
pub fn mut(this: Slice) []u8 {
|
||||
return @as([*]u8, @ptrFromInt(@intFromPtr(this.ptr)))[0..this.len];
|
||||
}
|
||||
|
||||
/// Does nothing if the slice is not allocated
|
||||
pub fn deinit(this: *const Slice) void {
|
||||
this.allocator.free(this.slice());
|
||||
}
|
||||
};
|
||||
|
||||
pub const name = "ZigString";
|
||||
pub const namespace = "";
|
||||
|
||||
pub inline fn is16Bit(this: *const ZigString) bool {
|
||||
return (@intFromPtr(this._unsafe_ptr_do_not_use) & (1 << 63)) != 0;
|
||||
}
|
||||
|
||||
pub inline fn utf16Slice(this: *const ZigString) []align(1) const u16 {
|
||||
if (comptime bun.Environment.allow_assert) {
|
||||
if (this.len > 0 and !this.is16Bit()) {
|
||||
@panic("ZigString.utf16Slice() called on a latin1 string.\nPlease use .toSlice() instead or carefully check that .is16Bit() is false first.");
|
||||
}
|
||||
}
|
||||
|
||||
return @as([*]align(1) const u16, @ptrCast(untagged(this._unsafe_ptr_do_not_use)))[0..this.len];
|
||||
}
|
||||
|
||||
pub inline fn utf16SliceAligned(this: *const ZigString) []const u16 {
|
||||
if (comptime bun.Environment.allow_assert) {
|
||||
if (this.len > 0 and !this.is16Bit()) {
|
||||
@panic("ZigString.utf16SliceAligned() called on a latin1 string.\nPlease use .toSlice() instead or carefully check that .is16Bit() is false first.");
|
||||
}
|
||||
}
|
||||
|
||||
return @as([*]const u16, @ptrCast(@alignCast(untagged(this._unsafe_ptr_do_not_use))))[0..this.len];
|
||||
}
|
||||
|
||||
pub inline fn isEmpty(this: *const ZigString) bool {
|
||||
return this.len == 0;
|
||||
}
|
||||
|
||||
pub fn fromStringPointer(ptr: StringPointer, buf: string, to: *ZigString) void {
|
||||
to.* = ZigString{
|
||||
.len = ptr.length,
|
||||
._unsafe_ptr_do_not_use = buf[ptr.offset..][0..ptr.length].ptr,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn sortDesc(slice_: []ZigString) void {
|
||||
std.sort.block(ZigString, slice_, {}, cmpDesc);
|
||||
}
|
||||
|
||||
pub fn cmpDesc(_: void, a: ZigString, b: ZigString) bool {
|
||||
return strings.cmpStringsDesc({}, a.slice(), b.slice());
|
||||
}
|
||||
|
||||
pub fn sortAsc(slice_: []ZigString) void {
|
||||
std.sort.block(ZigString, slice_, {}, cmpAsc);
|
||||
}
|
||||
|
||||
pub fn cmpAsc(_: void, a: ZigString, b: ZigString) bool {
|
||||
return strings.cmpStringsAsc({}, a.slice(), b.slice());
|
||||
}
|
||||
|
||||
pub inline fn init(slice_: []const u8) ZigString {
|
||||
return ZigString{ ._unsafe_ptr_do_not_use = slice_.ptr, .len = slice_.len };
|
||||
}
|
||||
|
||||
pub fn initUTF8(slice_: []const u8) ZigString {
|
||||
var out = init(slice_);
|
||||
out.markUTF8();
|
||||
return out;
|
||||
}
|
||||
|
||||
pub fn fromUTF8(slice_: []const u8) ZigString {
|
||||
var out = init(slice_);
|
||||
if (!strings.isAllASCII(slice_))
|
||||
out.markUTF8();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
pub fn static(comptime slice_: [:0]const u8) *const ZigString {
|
||||
const Holder = struct {
|
||||
const null_terminated_ascii_literal = slice_;
|
||||
pub const value = &ZigString{ ._unsafe_ptr_do_not_use = null_terminated_ascii_literal.ptr, .len = null_terminated_ascii_literal.len };
|
||||
};
|
||||
|
||||
return Holder.value;
|
||||
}
|
||||
|
||||
pub const GithubActionFormatter = struct {
|
||||
text: ZigString,
|
||||
|
||||
pub fn format(this: GithubActionFormatter, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
var bytes = this.text.toSlice(bun.default_allocator);
|
||||
defer bytes.deinit();
|
||||
try bun.fmt.githubActionWriter(writer, bytes.slice());
|
||||
}
|
||||
};
|
||||
|
||||
pub fn githubAction(this: ZigString) GithubActionFormatter {
|
||||
return GithubActionFormatter{ .text = this };
|
||||
}
|
||||
|
||||
pub fn toAtomicValue(this: *const ZigString, globalThis: *JSC.JSGlobalObject) JSValue {
|
||||
return shim.cppFn("toAtomicValue", .{ this, globalThis });
|
||||
}
|
||||
|
||||
pub fn initUTF16(items: []const u16) ZigString {
|
||||
var out = ZigString{ ._unsafe_ptr_do_not_use = @ptrCast(items), .len = items.len };
|
||||
out.markUTF16();
|
||||
return out;
|
||||
}
|
||||
|
||||
pub fn from16Slice(slice_: []const u16) ZigString {
|
||||
return from16(slice_.ptr, slice_.len);
|
||||
}
|
||||
|
||||
fn from16SliceMaybeGlobal(slice_: []const u16, global: bool) ZigString {
|
||||
var str = init(@as([*]const u8, @alignCast(@ptrCast(slice_.ptr)))[0..slice_.len]);
|
||||
str.markUTF16();
|
||||
if (global) {
|
||||
str.mark();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/// Globally-allocated memory only
|
||||
pub fn from16(slice_: [*]const u16, len: usize) ZigString {
|
||||
var str = init(@as([*]const u8, @ptrCast(slice_))[0..len]);
|
||||
str.markUTF16();
|
||||
str.mark();
|
||||
str.assertGlobal();
|
||||
return str;
|
||||
}
|
||||
|
||||
pub fn toBase64DataURL(this: ZigString, allocator: std.mem.Allocator) ![]const u8 {
|
||||
const slice_ = this.slice();
|
||||
const size = std.base64.standard.Encoder.calcSize(slice_.len);
|
||||
var buf = try allocator.alloc(u8, size + "data:;base64,".len);
|
||||
const encoded = std.base64.url_safe.Encoder.encode(buf["data:;base64,".len..], slice_);
|
||||
buf[0.."data:;base64,".len].* = "data:;base64,".*;
|
||||
return buf[0 .. "data:;base64,".len + encoded.len];
|
||||
}
|
||||
|
||||
pub fn detectEncoding(this: *ZigString) void {
|
||||
if (!strings.isAllASCII(this.slice())) {
|
||||
this.markUTF16();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toExternalU16(ptr: [*]const u16, len: usize, global: *JSGlobalObject) JSValue {
|
||||
if (len > String.max_length()) {
|
||||
bun.default_allocator.free(ptr[0..len]);
|
||||
global.ERR_STRING_TOO_LONG("Cannot create a string longer than 2^32-1 characters", .{}).throw() catch {}; // TODO: propagate?
|
||||
return .zero;
|
||||
}
|
||||
return shim.cppFn("toExternalU16", .{ ptr, len, global });
|
||||
}
|
||||
|
||||
pub fn isUTF8(this: ZigString) bool {
|
||||
return (@intFromPtr(this._unsafe_ptr_do_not_use) & (1 << 61)) != 0;
|
||||
}
|
||||
|
||||
pub fn markUTF8(this: *ZigString) void {
|
||||
this._unsafe_ptr_do_not_use = @as([*]const u8, @ptrFromInt(@intFromPtr(this._unsafe_ptr_do_not_use) | (1 << 61)));
|
||||
}
|
||||
|
||||
pub fn markUTF16(this: *ZigString) void {
|
||||
this._unsafe_ptr_do_not_use = @as([*]const u8, @ptrFromInt(@intFromPtr(this._unsafe_ptr_do_not_use) | (1 << 63)));
|
||||
}
|
||||
|
||||
pub fn setOutputEncoding(this: *ZigString) void {
|
||||
if (!this.is16Bit()) this.detectEncoding();
|
||||
if (this.is16Bit()) this.markUTF8();
|
||||
}
|
||||
|
||||
pub inline fn isGloballyAllocated(this: ZigString) bool {
|
||||
return (@intFromPtr(this._unsafe_ptr_do_not_use) & (1 << 62)) != 0;
|
||||
}
|
||||
|
||||
pub inline fn deinitGlobal(this: ZigString) void {
|
||||
bun.default_allocator.free(this.slice());
|
||||
}
|
||||
|
||||
pub const mark = markGlobal;
|
||||
|
||||
pub inline fn markGlobal(this: *ZigString) void {
|
||||
this._unsafe_ptr_do_not_use = @as([*]const u8, @ptrFromInt(@intFromPtr(this._unsafe_ptr_do_not_use) | (1 << 62)));
|
||||
}
|
||||
|
||||
pub fn format(self: ZigString, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
if (self.isUTF8()) {
|
||||
try writer.writeAll(self.slice());
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.is16Bit()) {
|
||||
try bun.fmt.formatUTF16Type(@TypeOf(self.utf16Slice()), self.utf16Slice(), writer);
|
||||
return;
|
||||
}
|
||||
|
||||
try bun.fmt.formatLatin1(self.slice(), writer);
|
||||
}
|
||||
|
||||
pub inline fn toRef(slice_: []const u8, global: *JSGlobalObject) C_API.JSValueRef {
|
||||
return init(slice_).toJS(global).asRef();
|
||||
}
|
||||
|
||||
pub const Empty = ZigString{ ._unsafe_ptr_do_not_use = "", .len = 0 };
|
||||
|
||||
pub inline fn untagged(ptr: [*]const u8) [*]const u8 {
|
||||
// this can be null ptr, so long as it's also a 0 length string
|
||||
@setRuntimeSafety(false);
|
||||
return @as([*]const u8, @ptrFromInt(@as(u53, @truncate(@intFromPtr(ptr)))));
|
||||
}
|
||||
|
||||
pub fn slice(this: *const ZigString) []const u8 {
|
||||
if (comptime bun.Environment.allow_assert) {
|
||||
if (this.len > 0 and this.is16Bit()) {
|
||||
@panic("ZigString.slice() called on a UTF-16 string.\nPlease use .toSlice() instead or carefully check that .is16Bit() is false first.");
|
||||
}
|
||||
}
|
||||
|
||||
return untagged(this._unsafe_ptr_do_not_use)[0..@min(this.len, std.math.maxInt(u32))];
|
||||
}
|
||||
|
||||
pub fn dupe(this: ZigString, allocator: std.mem.Allocator) ![]const u8 {
|
||||
return try allocator.dupe(u8, this.slice());
|
||||
}
|
||||
|
||||
pub fn toSliceFast(this: ZigString, allocator: std.mem.Allocator) Slice {
|
||||
if (this.len == 0)
|
||||
return Slice.empty;
|
||||
if (is16Bit(&this)) {
|
||||
const buffer = this.toOwnedSlice(allocator) catch unreachable;
|
||||
return Slice{
|
||||
.allocator = NullableAllocator.init(allocator),
|
||||
.ptr = buffer.ptr,
|
||||
.len = @as(u32, @truncate(buffer.len)),
|
||||
};
|
||||
}
|
||||
|
||||
return Slice{
|
||||
.ptr = untagged(this._unsafe_ptr_do_not_use),
|
||||
.len = @as(u32, @truncate(this.len)),
|
||||
};
|
||||
}
|
||||
|
||||
/// This function checks if the input is latin1 non-ascii
|
||||
/// It is slow but safer when the input is from JavaScript
|
||||
pub fn toSlice(this: ZigString, allocator: std.mem.Allocator) Slice {
|
||||
if (this.len == 0)
|
||||
return Slice.empty;
|
||||
if (is16Bit(&this)) {
|
||||
const buffer = this.toOwnedSlice(allocator) catch unreachable;
|
||||
return Slice{
|
||||
.allocator = NullableAllocator.init(allocator),
|
||||
.ptr = buffer.ptr,
|
||||
.len = @as(u32, @truncate(buffer.len)),
|
||||
};
|
||||
}
|
||||
|
||||
if (!this.isUTF8() and !strings.isAllASCII(untagged(this._unsafe_ptr_do_not_use)[0..this.len])) {
|
||||
const buffer = this.toOwnedSlice(allocator) catch unreachable;
|
||||
return Slice{
|
||||
.allocator = NullableAllocator.init(allocator),
|
||||
.ptr = buffer.ptr,
|
||||
.len = @as(u32, @truncate(buffer.len)),
|
||||
};
|
||||
}
|
||||
|
||||
return Slice{
|
||||
.ptr = untagged(this._unsafe_ptr_do_not_use),
|
||||
.len = @as(u32, @truncate(this.len)),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toSliceClone(this: ZigString, allocator: std.mem.Allocator) OOM!Slice {
|
||||
if (this.len == 0)
|
||||
return Slice.empty;
|
||||
const buffer = try this.toOwnedSlice(allocator);
|
||||
return Slice{
|
||||
.allocator = NullableAllocator.init(allocator),
|
||||
.ptr = buffer.ptr,
|
||||
.len = @as(u32, @truncate(buffer.len)),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn toSliceZ(this: ZigString, allocator: std.mem.Allocator) Slice {
|
||||
if (this.len == 0)
|
||||
return Slice.empty;
|
||||
|
||||
if (is16Bit(&this)) {
|
||||
const buffer = this.toOwnedSliceZ(allocator) catch unreachable;
|
||||
return Slice{
|
||||
.ptr = buffer.ptr,
|
||||
.len = @as(u32, @truncate(buffer.len)),
|
||||
.allocator = NullableAllocator.init(allocator),
|
||||
};
|
||||
}
|
||||
|
||||
return Slice{
|
||||
.ptr = untagged(this._unsafe_ptr_do_not_use),
|
||||
.len = @as(u32, @truncate(this.len)),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn sliceZBuf(this: ZigString, buf: *bun.PathBuffer) ![:0]const u8 {
|
||||
return try std.fmt.bufPrintZ(buf, "{}", .{this});
|
||||
}
|
||||
|
||||
pub inline fn full(this: *const ZigString) []const u8 {
|
||||
return untagged(this._unsafe_ptr_do_not_use)[0..this.len];
|
||||
}
|
||||
|
||||
pub fn trimmedSlice(this: *const ZigString) []const u8 {
|
||||
return strings.trim(this.full(), " \r\n");
|
||||
}
|
||||
|
||||
inline fn assertGlobalIfNeeded(this: *const ZigString) void {
|
||||
if (comptime bun.Environment.allow_assert) {
|
||||
if (this.isGloballyAllocated()) {
|
||||
this.assertGlobal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fn assertGlobal(this: *const ZigString) void {
|
||||
if (comptime bun.Environment.allow_assert) {
|
||||
bun.assert(this.len == 0 or
|
||||
bun.Mimalloc.mi_is_in_heap_region(untagged(this._unsafe_ptr_do_not_use)) or
|
||||
bun.Mimalloc.mi_check_owned(untagged(this._unsafe_ptr_do_not_use)));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toExternalValue(this: *const ZigString, global: *JSGlobalObject) JSValue {
|
||||
this.assertGlobal();
|
||||
if (this.len > String.max_length()) {
|
||||
bun.default_allocator.free(@constCast(this.byteSlice()));
|
||||
global.ERR_STRING_TOO_LONG("Cannot create a string longer than 2^32-1 characters", .{}).throw() catch {}; // TODO: propagate?
|
||||
return .zero;
|
||||
}
|
||||
return shim.cppFn("toExternalValue", .{ this, global });
|
||||
}
|
||||
|
||||
pub fn toExternalValueWithCallback(
|
||||
this: *const ZigString,
|
||||
global: *JSGlobalObject,
|
||||
callback: *const fn (ctx: ?*anyopaque, ptr: ?*anyopaque, len: usize) callconv(.C) void,
|
||||
) JSValue {
|
||||
return shim.cppFn("toExternalValueWithCallback", .{ this, global, callback });
|
||||
}
|
||||
|
||||
pub fn external(
|
||||
this: *const ZigString,
|
||||
global: *JSGlobalObject,
|
||||
ctx: ?*anyopaque,
|
||||
callback: *const fn (ctx: ?*anyopaque, ptr: ?*anyopaque, len: usize) callconv(.C) void,
|
||||
) JSValue {
|
||||
if (this.len > String.max_length()) {
|
||||
callback(ctx, @constCast(@ptrCast(this.byteSlice().ptr)), this.len);
|
||||
global.ERR_STRING_TOO_LONG("Cannot create a string longer than 2^32-1 characters", .{}).throw() catch {}; // TODO: propagate?
|
||||
return .zero;
|
||||
}
|
||||
|
||||
return shim.cppFn("external", .{ this, global, ctx, callback });
|
||||
}
|
||||
|
||||
pub fn to16BitValue(this: *const ZigString, global: *JSGlobalObject) JSValue {
|
||||
this.assertGlobal();
|
||||
return shim.cppFn("to16BitValue", .{ this, global });
|
||||
}
|
||||
|
||||
pub fn withEncoding(this: *const ZigString) ZigString {
|
||||
var out = this.*;
|
||||
out.setOutputEncoding();
|
||||
return out;
|
||||
}
|
||||
|
||||
pub fn toJSStringRef(this: *const ZigString) C_API.JSStringRef {
|
||||
if (comptime @hasDecl(@import("root").bun, "bindgen")) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return if (this.is16Bit())
|
||||
C_API.JSStringCreateWithCharactersNoCopy(@as([*]const u16, @ptrCast(@alignCast(untagged(this._unsafe_ptr_do_not_use)))), this.len)
|
||||
else
|
||||
C_API.JSStringCreateStatic(untagged(this._unsafe_ptr_do_not_use), this.len);
|
||||
}
|
||||
|
||||
pub fn toErrorInstance(this: *const ZigString, global: *JSGlobalObject) JSValue {
|
||||
return shim.cppFn("toErrorInstance", .{ this, global });
|
||||
}
|
||||
|
||||
pub fn toTypeErrorInstance(this: *const ZigString, global: *JSGlobalObject) JSValue {
|
||||
return shim.cppFn("toTypeErrorInstance", .{ this, global });
|
||||
}
|
||||
|
||||
pub fn toSyntaxErrorInstance(this: *const ZigString, global: *JSGlobalObject) JSValue {
|
||||
return shim.cppFn("toSyntaxErrorInstance", .{ this, global });
|
||||
}
|
||||
|
||||
pub fn toRangeErrorInstance(this: *const ZigString, global: *JSGlobalObject) JSValue {
|
||||
return shim.cppFn("toRangeErrorInstance", .{ this, global });
|
||||
}
|
||||
|
||||
pub const Extern = [_][]const u8{
|
||||
"toAtomicValue",
|
||||
"toExternalValue",
|
||||
"to16BitValue",
|
||||
"toErrorInstance",
|
||||
"toExternalU16",
|
||||
"toExternalValueWithCallback",
|
||||
"external",
|
||||
"toTypeErrorInstance",
|
||||
"toSyntaxErrorInstance",
|
||||
"toRangeErrorInstance",
|
||||
};
|
||||
};
|
||||
@@ -6227,9 +6227,6 @@ pub const JSValue = enum(i64) {
|
||||
}
|
||||
};
|
||||
|
||||
extern "c" fn AsyncContextFrame__withAsyncContextIfNeeded(global: *JSGlobalObject, callback: JSValue) JSValue;
|
||||
extern "c" fn Bun__JSValue__isAsyncContextFrame(value: JSValue) bool;
|
||||
|
||||
pub const VM = extern struct {
|
||||
pub const shim = Shimmer("JSC", "VM", @This());
|
||||
bytes: shim.Bytes,
|
||||
|
||||
341
src/bun.js/bindings/helpers.zig
Normal file
341
src/bun.js/bindings/helpers.zig
Normal file
@@ -0,0 +1,341 @@
|
||||
const std = @import("std");
|
||||
const bun = @import("root").bun;
|
||||
const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const C_API = bun.JSC.C;
|
||||
const StringPointer = @import("../../api/schema.zig").Api.StringPointer;
|
||||
const Exports = @import("./exports.zig");
|
||||
const strings = bun.strings;
|
||||
const ErrorableZigString = Exports.ErrorableZigString;
|
||||
const ErrorableResolvedSource = Exports.ErrorableResolvedSource;
|
||||
const ZigException = Exports.ZigException;
|
||||
const ZigStackTrace = Exports.ZigStackTrace;
|
||||
const ArrayBuffer = @import("../base.zig").ArrayBuffer;
|
||||
const JSC = bun.JSC;
|
||||
const Shimmer = JSC.Shimmer;
|
||||
const FFI = @import("./FFI.zig");
|
||||
const NullableAllocator = bun.NullableAllocator;
|
||||
const MutableString = bun.MutableString;
|
||||
const JestPrettyFormat = @import("../test/pretty_format.zig").JestPrettyFormat;
|
||||
const String = bun.String;
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const JSError = bun.JSError;
|
||||
const OOM = bun.OOM;
|
||||
|
||||
const Api = @import("../../api/schema.zig").Api;
|
||||
const JSGlobalObject = JSC.JSGlobalObject;
|
||||
const JSValue = JSC.JSValue;
|
||||
const JSPromise = JSC.JSPromise;
|
||||
const JSPromiseRejectionOperation = JSC.JSPromiseRejectionOperation;
|
||||
const CallFrame = JSC.CallFrame;
|
||||
const ZigString = JSC.ZigString;
|
||||
const JSHostFunctionPtr = JSC.JSHostFunctionPtr;
|
||||
const JSHostZigFunction = JSC.JSHostZigFunction;
|
||||
const Bun = JSC.API.Bun;
|
||||
|
||||
pub fn NewGlobalObject(comptime Type: type) type {
|
||||
return struct {
|
||||
const importNotImpl = "Import not implemented";
|
||||
const resolveNotImpl = "resolve not implemented";
|
||||
const moduleNotImpl = "Module fetch not implemented";
|
||||
pub fn import(global: *JSGlobalObject, specifier: *String, source: *String) callconv(.C) ErrorableString {
|
||||
if (comptime @hasDecl(Type, "import")) {
|
||||
return @call(bun.callmod_inline, Type.import, .{ global, specifier.*, source.* });
|
||||
}
|
||||
return ErrorableString.err(error.ImportFailed, String.init(importNotImpl).toErrorInstance(global).asVoid());
|
||||
}
|
||||
pub fn resolve(
|
||||
res: *ErrorableString,
|
||||
global: *JSGlobalObject,
|
||||
specifier: *String,
|
||||
source: *String,
|
||||
query_string: *ZigString,
|
||||
) callconv(.C) void {
|
||||
if (comptime @hasDecl(Type, "resolve")) {
|
||||
@call(bun.callmod_inline, Type.resolve, .{ res, global, specifier.*, source.*, query_string, true });
|
||||
return;
|
||||
}
|
||||
res.* = ErrorableString.err(error.ResolveFailed, String.init(resolveNotImpl).toErrorInstance(global).asVoid());
|
||||
}
|
||||
pub fn fetch(ret: *ErrorableResolvedSource, global: *JSGlobalObject, specifier: *String, source: *String) callconv(.C) void {
|
||||
if (comptime @hasDecl(Type, "fetch")) {
|
||||
@call(bun.callmod_inline, Type.fetch, .{ ret, global, specifier.*, source.* });
|
||||
return;
|
||||
}
|
||||
ret.* = ErrorableResolvedSource.err(error.FetchFailed, String.init(moduleNotImpl).toErrorInstance(global).asVoid());
|
||||
}
|
||||
pub fn promiseRejectionTracker(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue {
|
||||
if (comptime @hasDecl(Type, "promiseRejectionTracker")) {
|
||||
return @call(bun.callmod_inline, Type.promiseRejectionTracker, .{ global, promise, rejection });
|
||||
}
|
||||
return JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn reportUncaughtException(global: *JSGlobalObject, exception: *JSC.Exception) callconv(.C) JSValue {
|
||||
if (comptime @hasDecl(Type, "reportUncaughtException")) {
|
||||
return @call(bun.callmod_inline, Type.reportUncaughtException, .{ global, exception });
|
||||
}
|
||||
return JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn onCrash() callconv(.C) void {
|
||||
if (comptime @hasDecl(Type, "onCrash")) {
|
||||
return @call(bun.callmod_inline, Type.onCrash, .{});
|
||||
}
|
||||
|
||||
Output.flush();
|
||||
|
||||
@panic("A C++ exception occurred");
|
||||
}
|
||||
};
|
||||
}
|
||||
pub fn PromiseCallback(comptime Type: type, comptime CallbackFunction: fn (*Type, *JSGlobalObject, []const JSValue) anyerror!JSValue) type {
|
||||
return struct {
|
||||
pub fn callback(
|
||||
ctx: ?*anyopaque,
|
||||
globalThis: *JSGlobalObject,
|
||||
arguments: [*]const JSValue,
|
||||
arguments_len: usize,
|
||||
) callconv(.C) JSValue {
|
||||
return CallbackFunction(@as(*Type, @ptrCast(@alignCast(ctx.?))), globalThis, arguments[0..arguments_len]) catch |err| brk: {
|
||||
break :brk ZigString.init(bun.asByteSlice(@errorName(err))).toErrorInstance(globalThis);
|
||||
};
|
||||
}
|
||||
}.callback;
|
||||
}
|
||||
pub fn JSHostZigFunctionWithContext(comptime ContextType: type) type {
|
||||
return fn (*ContextType, *JSGlobalObject, *CallFrame) bun.JSError!JSValue;
|
||||
}
|
||||
pub fn JSHostFunctionTypeWithContext(comptime ContextType: type) type {
|
||||
return fn (*ContextType, *JSC.JSGlobalObject, *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue;
|
||||
}
|
||||
pub fn toJSHostFunction(comptime Function: JSHostZigFunction) JSC.JSHostFunctionType {
|
||||
return struct {
|
||||
pub fn function(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue {
|
||||
if (bun.Environment.allow_assert and bun.Environment.is_canary) {
|
||||
const value = Function(globalThis, callframe) catch |err| switch (err) {
|
||||
error.JSError => .zero,
|
||||
error.OutOfMemory => globalThis.throwOutOfMemoryValue(),
|
||||
};
|
||||
if (comptime bun.Environment.isDebug) {
|
||||
if (value != .zero) {
|
||||
if (globalThis.hasException()) {
|
||||
var formatter = JSC.ConsoleObject.Formatter{ .globalThis = globalThis };
|
||||
defer formatter.deinit();
|
||||
bun.Output.err("Assertion failed",
|
||||
\\Native function returned a non-zero JSValue while an exception is pending
|
||||
\\
|
||||
\\ fn: {s}
|
||||
\\ value: {}
|
||||
\\
|
||||
, .{
|
||||
&Function, // use `(lldb) image lookup --address 0x1ec4` to discover what function failed
|
||||
value.toFmt(&formatter),
|
||||
});
|
||||
Output.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
bun.assert((value == .zero) == globalThis.hasException());
|
||||
return value;
|
||||
}
|
||||
return @call(.always_inline, Function, .{ globalThis, callframe }) catch |err| switch (err) {
|
||||
error.JSError => .zero,
|
||||
error.OutOfMemory => globalThis.throwOutOfMemoryValue(),
|
||||
};
|
||||
}
|
||||
}.function;
|
||||
}
|
||||
pub fn toJSHostFunctionWithContext(comptime ContextType: type, comptime Function: JSHostZigFunctionWithContext(ContextType)) JSHostFunctionTypeWithContext(ContextType) {
|
||||
return struct {
|
||||
pub fn function(ctx: *ContextType, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue {
|
||||
if (bun.Environment.allow_assert and bun.Environment.is_canary) {
|
||||
const value = Function(ctx, globalThis, callframe) catch |err| switch (err) {
|
||||
error.JSError => .zero,
|
||||
error.OutOfMemory => globalThis.throwOutOfMemoryValue(),
|
||||
};
|
||||
if (comptime bun.Environment.isDebug) {
|
||||
if (value != .zero) {
|
||||
if (globalThis.hasException()) {
|
||||
var formatter = JSC.ConsoleObject.Formatter{ .globalThis = globalThis };
|
||||
defer formatter.deinit();
|
||||
bun.Output.err("Assertion failed",
|
||||
\\Native function returned a non-zero JSValue while an exception is pending
|
||||
\\
|
||||
\\ fn: {s}
|
||||
\\ value: {}
|
||||
\\
|
||||
, .{
|
||||
&Function, // use `(lldb) image lookup --address 0x1ec4` to discover what function failed
|
||||
value.toFmt(&formatter),
|
||||
});
|
||||
Output.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
bun.assert((value == .zero) == globalThis.hasException());
|
||||
return value;
|
||||
}
|
||||
return @call(.always_inline, Function, .{ ctx, globalThis, callframe }) catch |err| switch (err) {
|
||||
error.JSError => .zero,
|
||||
error.OutOfMemory => globalThis.throwOutOfMemoryValue(),
|
||||
};
|
||||
}
|
||||
}.function;
|
||||
}
|
||||
pub fn toJSHostValue(globalThis: *JSGlobalObject, value: error{ OutOfMemory, JSError }!JSValue) JSValue {
|
||||
if (bun.Environment.allow_assert and bun.Environment.is_canary) {
|
||||
const normal = value catch |err| switch (err) {
|
||||
error.JSError => .zero,
|
||||
error.OutOfMemory => globalThis.throwOutOfMemoryValue(),
|
||||
};
|
||||
bun.assert((normal == .zero) == globalThis.hasException());
|
||||
return normal;
|
||||
}
|
||||
return value catch |err| switch (err) {
|
||||
error.JSError => .zero,
|
||||
error.OutOfMemory => globalThis.throwOutOfMemoryValue(),
|
||||
};
|
||||
}
|
||||
extern "c" fn JSCInitialize(env: [*]const [*:0]u8, count: usize, cb: *const fn ([*]const u8, len: usize) callconv(.C) void, eval_mode: bool) void;
|
||||
|
||||
pub fn initialize(eval_mode: bool) void {
|
||||
JSC.markBinding(@src());
|
||||
bun.analytics.Features.jsc += 1;
|
||||
JSCInitialize(
|
||||
std.os.environ.ptr,
|
||||
std.os.environ.len,
|
||||
struct {
|
||||
pub fn callback(name: [*]const u8, len: usize) callconv(.C) void {
|
||||
Output.prettyErrorln(
|
||||
\\<r><red>error<r><d>:<r> invalid JSC environment variable
|
||||
\\
|
||||
\\ <b>{s}<r>
|
||||
\\
|
||||
\\For a list of options, see this file:
|
||||
\\
|
||||
\\ https://github.com/oven-sh/webkit/blob/main/Source/JavaScriptCore/runtime/OptionsList.h
|
||||
\\
|
||||
\\Environment variables must be prefixed with "BUN_JSC_". This code runs before .env files are loaded, so those won't work here.
|
||||
\\
|
||||
\\Warning: options change between releases of Bun and WebKit without notice. This is not a stable API, you should not rely on it beyond debugging something, and it may be removed entirely in a future version of Bun.
|
||||
,
|
||||
.{name[0..len]},
|
||||
);
|
||||
bun.Global.exit(1);
|
||||
}
|
||||
}.callback,
|
||||
eval_mode,
|
||||
);
|
||||
}
|
||||
|
||||
const private = struct {
|
||||
pub extern fn Bun__CreateFFIFunctionWithDataValue(
|
||||
*JSGlobalObject,
|
||||
?*const ZigString,
|
||||
argCount: u32,
|
||||
function: JSHostFunctionPtr,
|
||||
strong: bool,
|
||||
data: *anyopaque,
|
||||
) JSValue;
|
||||
pub extern fn Bun__CreateFFIFunction(
|
||||
globalObject: *JSGlobalObject,
|
||||
symbolName: ?*const ZigString,
|
||||
argCount: u32,
|
||||
functionPointer: JSHostFunctionPtr,
|
||||
strong: bool,
|
||||
) *anyopaque;
|
||||
|
||||
pub extern fn Bun__CreateFFIFunctionValue(
|
||||
globalObject: *JSGlobalObject,
|
||||
symbolName: ?*const ZigString,
|
||||
argCount: u32,
|
||||
functionPointer: JSHostFunctionPtr,
|
||||
strong: bool,
|
||||
add_ptr_field: bool,
|
||||
inputFunctionPtr: ?*anyopaque,
|
||||
) JSValue;
|
||||
|
||||
pub extern fn Bun__untrackFFIFunction(
|
||||
globalObject: *JSGlobalObject,
|
||||
function: JSValue,
|
||||
) bool;
|
||||
|
||||
pub extern fn Bun__FFIFunction_getDataPtr(JSValue) ?*anyopaque;
|
||||
pub extern fn Bun__FFIFunction_setDataPtr(JSValue, ?*anyopaque) void;
|
||||
};
|
||||
|
||||
pub fn NewFunction(
|
||||
globalObject: *JSGlobalObject,
|
||||
symbolName: ?*const ZigString,
|
||||
argCount: u32,
|
||||
comptime functionPointer: anytype,
|
||||
strong: bool,
|
||||
) JSValue {
|
||||
if (@TypeOf(functionPointer) == JSC.JSHostFunctionType) {
|
||||
return NewRuntimeFunction(globalObject, symbolName, argCount, functionPointer, strong, false, null);
|
||||
}
|
||||
return NewRuntimeFunction(globalObject, symbolName, argCount, toJSHostFunction(functionPointer), strong, false, null);
|
||||
}
|
||||
|
||||
pub fn createCallback(
|
||||
globalObject: *JSGlobalObject,
|
||||
symbolName: ?*const ZigString,
|
||||
argCount: u32,
|
||||
comptime functionPointer: anytype,
|
||||
) JSValue {
|
||||
if (@TypeOf(functionPointer) == JSC.JSHostFunctionType) {
|
||||
return NewRuntimeFunction(globalObject, symbolName, argCount, functionPointer, false, false);
|
||||
}
|
||||
return NewRuntimeFunction(globalObject, symbolName, argCount, toJSHostFunction(functionPointer), false, false, null);
|
||||
}
|
||||
|
||||
pub fn NewRuntimeFunction(
|
||||
globalObject: *JSGlobalObject,
|
||||
symbolName: ?*const ZigString,
|
||||
argCount: u32,
|
||||
functionPointer: JSHostFunctionPtr,
|
||||
strong: bool,
|
||||
add_ptr_property: bool,
|
||||
inputFunctionPtr: ?*anyopaque,
|
||||
) JSValue {
|
||||
JSC.markBinding(@src());
|
||||
return private.Bun__CreateFFIFunctionValue(globalObject, symbolName, argCount, functionPointer, strong, add_ptr_property, inputFunctionPtr);
|
||||
}
|
||||
|
||||
pub fn getFunctionData(function: JSValue) ?*anyopaque {
|
||||
JSC.markBinding(@src());
|
||||
return private.Bun__FFIFunction_getDataPtr(function);
|
||||
}
|
||||
|
||||
pub fn setFunctionData(function: JSValue, value: ?*anyopaque) void {
|
||||
JSC.markBinding(@src());
|
||||
return private.Bun__FFIFunction_setDataPtr(function, value);
|
||||
}
|
||||
|
||||
pub fn NewFunctionWithData(
|
||||
globalObject: *JSGlobalObject,
|
||||
symbolName: ?*const ZigString,
|
||||
argCount: u32,
|
||||
comptime functionPointer: JSC.JSHostZigFunction,
|
||||
strong: bool,
|
||||
data: *anyopaque,
|
||||
) JSValue {
|
||||
JSC.markBinding(@src());
|
||||
return private.Bun__CreateFFIFunctionWithDataValue(
|
||||
globalObject,
|
||||
symbolName,
|
||||
argCount,
|
||||
toJSHostFunction(functionPointer),
|
||||
strong,
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn untrackFunction(
|
||||
globalObject: *JSGlobalObject,
|
||||
value: JSValue,
|
||||
) bool {
|
||||
JSC.markBinding(@src());
|
||||
return private.Bun__untrackFFIFunction(globalObject, value);
|
||||
}
|
||||
Reference in New Issue
Block a user