aboutsummaryrefslogtreecommitdiff
path: root/src/javascript/jsc/base.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/javascript/jsc/base.zig')
-rw-r--r--src/javascript/jsc/base.zig3029
1 files changed, 0 insertions, 3029 deletions
diff --git a/src/javascript/jsc/base.zig b/src/javascript/jsc/base.zig
deleted file mode 100644
index eaf15beba..000000000
--- a/src/javascript/jsc/base.zig
+++ /dev/null
@@ -1,3029 +0,0 @@
-pub const js = @import("../../jsc.zig").C;
-const std = @import("std");
-const bun = @import("../../global.zig");
-const string = bun.string;
-const Output = bun.Output;
-const Global = bun.Global;
-const Environment = bun.Environment;
-const strings = bun.strings;
-const MutableString = bun.MutableString;
-const stringZ = bun.stringZ;
-const default_allocator = bun.default_allocator;
-const C = bun.C;
-const JavaScript = @import("./javascript.zig");
-const ResolveError = JavaScript.ResolveError;
-const BuildError = JavaScript.BuildError;
-const JSC = @import("../../jsc.zig");
-const WebCore = @import("./webcore.zig");
-const Test = @import("./test/jest.zig");
-const Fetch = WebCore.Fetch;
-const Response = WebCore.Response;
-const Request = WebCore.Request;
-const Router = @import("./api/router.zig");
-const FetchEvent = WebCore.FetchEvent;
-const IdentityContext = @import("../../identity_context.zig").IdentityContext;
-
-const Body = WebCore.Body;
-const TaggedPointerTypes = @import("../../tagged_pointer.zig");
-const TaggedPointerUnion = TaggedPointerTypes.TaggedPointerUnion;
-
-pub const ExceptionValueRef = [*c]js.JSValueRef;
-pub const JSValueRef = js.JSValueRef;
-
-fn ObjectPtrType(comptime Type: type) type {
- if (Type == void) return Type;
- return *Type;
-}
-
-pub const To = struct {
- pub const JS = struct {
- pub inline fn str(_: anytype, val: anytype) js.JSStringRef {
- return js.JSStringCreateWithUTF8CString(val[0.. :0]);
- }
-
- pub fn functionWithCallback(
- comptime ZigContextType: type,
- zig: ObjectPtrType(ZigContextType),
- name: js.JSStringRef,
- ctx: js.JSContextRef,
- comptime callback: fn (
- obj: ObjectPtrType(ZigContextType),
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- thisObject: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef,
- ) js.JSObjectRef {
- var function = js.JSObjectMakeFunctionWithCallback(ctx, name, Callback(ZigContextType, callback).rfn);
- std.debug.assert(js.JSObjectSetPrivate(
- function,
- JSPrivateDataPtr.init(zig).ptr(),
- ));
- return function;
- }
-
- pub fn Finalize(
- comptime ZigContextType: type,
- comptime ctxfn: fn (
- this: ObjectPtrType(ZigContextType),
- ) void,
- ) type {
- return struct {
- pub fn rfn(
- object: js.JSObjectRef,
- ) callconv(.C) void {
- return ctxfn(
- GetJSPrivateData(ZigContextType, object) orelse return,
- );
- }
- };
- }
-
- pub fn Constructor(
- comptime ctxfn: fn (
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef,
- ) type {
- return struct {
- pub fn rfn(
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- argumentCount: usize,
- arguments: [*c]const js.JSValueRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- return ctxfn(
- ctx,
- function,
- if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
- exception,
- );
- }
- };
- }
- pub fn ConstructorCallback(
- comptime ctxfn: fn (
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef,
- ) type {
- return struct {
- pub fn rfn(
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- argumentCount: usize,
- arguments: [*c]const js.JSValueRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- return ctxfn(
- ctx,
- function,
- if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
- exception,
- );
- }
- };
- }
-
- pub fn withType(comptime Type: type, value: Type, context: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.C.JSValueRef {
- return withTypeClone(Type, value, context, exception, false);
- }
-
- pub fn withTypeClone(comptime Type: type, value: Type, context: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef, clone: bool) JSC.C.JSValueRef {
- if (comptime std.meta.trait.isNumber(Type)) {
- return JSC.JSValue.jsNumberWithType(Type, value).asRef();
- }
-
- var zig_str: JSC.ZigString = undefined;
-
- return switch (comptime Type) {
- void => JSC.C.JSValueMakeUndefined(context),
- bool => JSC.C.JSValueMakeBoolean(context, value),
- []const u8, [:0]const u8, [*:0]const u8, []u8, [:0]u8, [*:0]u8 => brk: {
- zig_str = ZigString.init(value);
- const val = zig_str.toValueAuto(context.ptr());
-
- break :brk val.asObjectRef();
- },
- []const PathString, []const []const u8, []const []u8, [][]const u8, [][:0]const u8, [][:0]u8 => {
- if (value.len == 0)
- return JSC.C.JSObjectMakeArray(context, 0, null, exception);
-
- var stack_fallback = std.heap.stackFallback(512, bun.default_allocator);
- var allocator = stack_fallback.get();
-
- var zig_strings = allocator.alloc(ZigString, value.len) catch unreachable;
- defer if (stack_fallback.fixed_buffer_allocator.end_index >= 511) allocator.free(zig_strings);
-
- for (value) |path_string, i| {
- if (comptime Type == []const PathString) {
- zig_strings[i] = ZigString.init(path_string.slice());
- } else {
- zig_strings[i] = ZigString.init(path_string);
- }
- }
- // there is a possible C ABI bug or something here when the ptr is null
- // it should not be segfaulting but it is
- // that's why we check at the top of this function
- var array = JSC.JSValue.createStringArray(context.ptr(), zig_strings.ptr, zig_strings.len, clone).asObjectRef();
-
- if (clone and value.len > 0) {
- for (value) |path_string| {
- if (comptime Type == []const PathString) {
- bun.default_allocator.free(path_string.slice());
- } else {
- bun.default_allocator.free(path_string);
- }
- }
- bun.default_allocator.free(value);
- }
-
- return array;
- },
-
- JSC.C.JSValueRef => value,
-
- else => {
- const Info: std.builtin.TypeInfo = comptime @typeInfo(Type);
- if (comptime Info == .Enum) {
- const Enum: std.builtin.TypeInfo.Enum = Info.Enum;
- if (comptime !std.meta.trait.isNumber(Enum.tag_type)) {
- zig_str = JSC.ZigString.init(@tagName(value));
- return zig_str.toValue(context.ptr()).asObjectRef();
- }
- }
-
- // Recursion can stack overflow here
- if (comptime std.meta.trait.isSlice(Type)) {
- const Child = std.meta.Child(Type);
-
- const prefill = 32;
- if (value.len <= prefill) {
- var array: [prefill]JSC.C.JSValueRef = undefined;
- var i: u8 = 0;
- const len = @minimum(@intCast(u8, value.len), prefill);
- while (i < len and exception.* == null) : (i += 1) {
- array[i] = if (comptime Child == JSC.C.JSValueRef)
- value[i]
- else
- To.JS.withType(Child, value[i], context, exception);
- }
-
- if (exception.* != null) {
- return null;
- }
-
- // TODO: this function copies to a MarkedArgumentsBuffer
- // That copy is unnecessary.
- const obj = JSC.C.JSObjectMakeArray(context, len, &array, exception);
-
- if (exception.* != null) {
- return null;
- }
- return obj;
- }
-
- {
- var array = bun.default_allocator.alloc(JSC.C.JSValueRef, value.len) catch unreachable;
- defer bun.default_allocator.free(array);
- var i: usize = 0;
- while (i < value.len and exception.* == null) : (i += 1) {
- array[i] = if (comptime Child == JSC.C.JSValueRef)
- value[i]
- else
- To.JS.withType(Child, value[i], context, exception);
- }
-
- if (exception.* != null) {
- return null;
- }
-
- // TODO: this function copies to a MarkedArgumentsBuffer
- // That copy is unnecessary.
- const obj = JSC.C.JSObjectMakeArray(context, value.len, array.ptr, exception);
- if (exception.* != null) {
- return null;
- }
-
- return obj;
- }
- }
-
- if (comptime std.meta.trait.isZigString(Type)) {
- zig_str = JSC.ZigString.init(value);
- return zig_str.toValue(context.ptr()).asObjectRef();
- }
-
- if (comptime Info == .Pointer) {
- const Child = comptime std.meta.Child(Type);
- if (comptime std.meta.trait.isContainer(Child) and @hasDecl(Child, "Class") and @hasDecl(Child.Class, "isJavaScriptCoreClass")) {
- return Child.Class.make(context, value);
- }
- }
-
- if (comptime Info == .Struct) {
- if (comptime @hasDecl(Type, "Class") and @hasDecl(Type.Class, "isJavaScriptCoreClass")) {
- if (comptime !@hasDecl(Type, "finalize")) {
- @compileError(comptime std.fmt.comptimePrint("JSC class {s} must implement finalize to prevent memory leaks", .{Type.Class.name}));
- }
-
- if (comptime !@hasDecl(Type, "toJS")) {
- var val = bun.default_allocator.create(Type) catch unreachable;
- val.* = value;
- return Type.Class.make(context, val);
- }
- }
- }
-
- const res = value.toJS(context, exception);
-
- if (@TypeOf(res) == JSC.C.JSValueRef) {
- return res;
- } else if (@TypeOf(res) == JSC.JSValue) {
- return res.asObjectRef();
- }
- },
- };
- }
-
- pub fn PropertyGetter(
- comptime Type: type,
- ) type {
- return comptime fn (
- this: ObjectPtrType(Type),
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef;
- }
-
- pub fn Getter(comptime Type: type, comptime field: std.meta.FieldEnum(Type)) PropertyGetter(Type) {
- return struct {
- pub fn rfn(
- this: ObjectPtrType(Type),
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- return withType(std.meta.fieldInfo(Type, field).field_type, @field(this, @tagName(field)), ctx, exception);
- }
- }.rfn;
- }
-
- pub fn Callback(
- comptime ZigContextType: type,
- comptime ctxfn: fn (
- obj: ObjectPtrType(ZigContextType),
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- thisObject: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef,
- ) type {
- return struct {
- pub fn rfn(
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- thisObject: js.JSObjectRef,
- argumentCount: usize,
- arguments: [*c]const js.JSValueRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- if (comptime ZigContextType == anyopaque) {
- return ctxfn(
- js.JSObjectGetPrivate(function) orelse js.JSObjectGetPrivate(thisObject) orelse undefined,
- ctx,
- function,
- thisObject,
- if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
- exception,
- );
- } else if (comptime ZigContextType == void) {
- return ctxfn(
- void{},
- ctx,
- function,
- thisObject,
- if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
- exception,
- );
- } else {
- return ctxfn(
- GetJSPrivateData(ZigContextType, function) orelse GetJSPrivateData(ZigContextType, thisObject) orelse return js.JSValueMakeUndefined(ctx),
- ctx,
- function,
- thisObject,
- if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
- exception,
- );
- }
- }
- };
- }
- };
-
- pub const Ref = struct {
- pub inline fn str(ref: anytype) js.JSStringRef {
- return @as(js.JSStringRef, ref);
- }
- };
-
- pub const Zig = struct {
- pub inline fn str(ref: anytype, buf: anytype) string {
- return buf[0..js.JSStringGetUTF8CString(Ref.str(ref), buf.ptr, buf.len)];
- }
- pub inline fn ptr(comptime StructType: type, obj: js.JSObjectRef) *StructType {
- return GetJSPrivateData(StructType, obj).?;
- }
- };
-};
-
-pub const Properties = struct {
- pub const UTF8 = struct {
- pub var filepath: string = "filepath";
-
- pub const module: string = "module";
- pub const globalThis: string = "globalThis";
- pub const exports: string = "exports";
- pub const log: string = "log";
- pub const debug: string = "debug";
- pub const name: string = "name";
- pub const info: string = "info";
- pub const error_: string = "error";
- pub const warn: string = "warn";
- pub const console: string = "console";
- pub const require: string = "require";
- pub const description: string = "description";
- pub const initialize_bundled_module: string = "$$m";
- pub const load_module_function: string = "$lOaDuRcOdE$";
- pub const window: string = "window";
- pub const default: string = "default";
- pub const include: string = "include";
-
- pub const env: string = "env";
-
- pub const GET = "GET";
- pub const PUT = "PUT";
- pub const POST = "POST";
- pub const PATCH = "PATCH";
- pub const HEAD = "HEAD";
- pub const OPTIONS = "OPTIONS";
-
- pub const navigate = "navigate";
- pub const follow = "follow";
- };
-
- pub const Refs = struct {
- pub var empty_string_ptr = [_]u8{0};
- pub var empty_string: js.JSStringRef = undefined;
- };
-
- pub fn init() void {
- Refs.empty_string = js.JSStringCreateWithUTF8CString(&Refs.empty_string_ptr);
- }
-};
-
-const hasSetter = std.meta.trait.hasField("set");
-const hasReadOnly = std.meta.trait.hasField("ro");
-const hasFinalize = std.meta.trait.hasField("finalize");
-const hasEnumerable = std.meta.trait.hasField("enumerable");
-
-const hasTypeScriptField = std.meta.trait.hasField("ts");
-fn hasTypeScript(comptime Type: type) bool {
- if (hasTypeScriptField(Type)) {
- return true;
- }
-
- return @hasDecl(Type, "ts");
-}
-
-fn getTypeScript(comptime Type: type, value: Type) d.ts.or_decl {
- if (comptime !@hasDecl(Type, "ts") and !@hasField(Type, "ts")) {
- return d.ts.or_decl{
- .ts = .{ .name = @typeName(Type) },
- };
- }
-
- if (comptime hasTypeScriptField(Type)) {
- if (@TypeOf(value.ts) == d.ts.decl) {
- return d.ts.or_decl{ .decl = value };
- } else {
- return d.ts.or_decl{ .ts = value.ts };
- }
- }
-
- if (@TypeOf(Type.ts) == d.ts.decl) {
- return d.ts.or_decl{ .decl = Type.ts };
- } else {
- return d.ts.or_decl{ .ts = value.ts };
- }
-}
-
-pub const d = struct {
- pub const ts = struct {
- @"return": string = "unknown",
- tsdoc: string = "",
- name: string = "",
- read_only: ?bool = null,
- args: []const arg = &[_]arg{},
- splat_args: bool = false,
-
- pub const or_decl = union(Tag) {
- ts: ts,
- decl: decl,
- pub const Tag = enum { ts, decl };
- };
-
- pub const decl = union(Tag) {
- module: module,
- class: class,
- empty: u0,
- pub const Tag = enum { module, class, empty };
- };
-
- pub const module = struct {
- tsdoc: string = "",
- read_only: ?bool = null,
- path: string = "",
- global: bool = false,
-
- properties: []ts = &[_]ts{},
- functions: []ts = &[_]ts{},
- classes: []class = &[_]class{},
- };
-
- pub const class = struct {
- name: string = "",
- tsdoc: string = "",
- @"return": string = "",
- read_only: ?bool = null,
- interface: bool = true,
- default_export: bool = false,
-
- properties: []ts = &[_]ts{},
- functions: []ts = &[_]ts{},
-
- pub const Printer = struct {
- const indent_level = 2;
- pub fn printIndented(comptime fmt: string, args: anytype, comptime indent: usize) string {
- comptime var buf: string = "";
- comptime buf = buf ++ " " ** indent;
-
- return comptime buf ++ std.fmt.comptimePrint(fmt, args);
- }
-
- pub fn printVar(comptime property: d.ts, comptime indent: usize) string {
- comptime var buf: string = "";
- comptime buf = buf ++ " " ** indent;
-
- comptime {
- if (property.read_only orelse false) {
- buf = buf ++ "readonly ";
- }
-
- buf = buf ++ "var ";
- buf = buf ++ property.name;
- buf = buf ++ ": ";
-
- if (property.@"return".len > 0) {
- buf = buf ++ property.@"return";
- } else {
- buf = buf ++ "any";
- }
-
- buf = buf ++ ";\n";
- }
-
- comptime {
- if (property.tsdoc.len > 0) {
- buf = printTSDoc(property.tsdoc, indent) ++ buf;
- }
- }
-
- return buf;
- }
-
- pub fn printProperty(comptime property: d.ts, comptime indent: usize) string {
- comptime var buf: string = "";
- comptime buf = buf ++ " " ** indent;
-
- comptime {
- if (property.read_only orelse false) {
- buf = buf ++ "readonly ";
- }
-
- buf = buf ++ property.name;
- buf = buf ++ ": ";
-
- if (property.@"return".len > 0) {
- buf = buf ++ property.@"return";
- } else {
- buf = buf ++ "any";
- }
-
- buf = buf ++ ";\n";
- }
-
- comptime {
- if (property.tsdoc.len > 0) {
- buf = printTSDoc(property.tsdoc, indent) ++ buf;
- }
- }
-
- return buf;
- }
- pub fn printInstanceFunction(comptime func: d.ts, comptime _indent: usize, comptime no_type: bool) string {
- comptime var indent = _indent;
- comptime var buf: string = "";
-
- comptime {
- var args: string = "";
- for (func.args) |a, i| {
- if (i > 0) {
- args = args ++ ", ";
- }
- args = args ++ printArg(a);
- }
-
- if (no_type) {
- buf = buf ++ printIndented("{s}({s});\n", .{
- func.name,
- args,
- }, indent);
- } else {
- buf = buf ++ printIndented("{s}({s}): {s};\n", .{
- func.name,
- args,
- func.@"return",
- }, indent);
- }
- }
-
- comptime {
- if (func.tsdoc.len > 0) {
- buf = printTSDoc(func.tsdoc, indent) ++ buf;
- }
- }
-
- return buf;
- }
- pub fn printFunction(comptime func: d.ts, comptime _indent: usize, comptime no_type: bool) string {
- comptime var indent = _indent;
- comptime var buf: string = "";
-
- comptime {
- var args: string = "";
- for (func.args) |a, i| {
- if (i > 0) {
- args = args ++ ", ";
- }
- args = args ++ printArg(a);
- }
-
- if (no_type) {
- buf = buf ++ printIndented("function {s}({s});\n", .{
- func.name,
- args,
- }, indent);
- } else {
- buf = buf ++ printIndented("function {s}({s}): {s};\n", .{
- func.name,
- args,
- func.@"return",
- }, indent);
- }
- }
-
- comptime {
- if (func.tsdoc.len > 0) {
- buf = printTSDoc(func.tsdoc, indent) ++ buf;
- }
- }
-
- return buf;
- }
- pub fn printArg(
- comptime _arg: d.ts.arg,
- ) string {
- comptime var buf: string = "";
- comptime {
- buf = buf ++ _arg.name;
- buf = buf ++ ": ";
-
- if (_arg.@"return".len == 0) {
- buf = buf ++ "any";
- } else {
- buf = buf ++ _arg.@"return";
- }
- }
-
- return buf;
- }
-
- pub fn printDecl(comptime klass: d.ts.decl, comptime _indent: usize) string {
- return comptime switch (klass) {
- .module => |mod| printModule(mod, _indent),
- .class => |cla| printClass(cla, _indent),
- .empty => "",
- };
- }
-
- pub fn printModule(comptime klass: d.ts.module, comptime _indent: usize) string {
- comptime var indent = _indent;
- comptime var buf: string = "";
- comptime brk: {
- if (klass.tsdoc.len > 0) {
- buf = buf ++ printTSDoc(klass.tsdoc, indent);
- }
-
- if (klass.global) {
- buf = buf ++ printIndented("declare global {{\n", .{}, indent);
- } else {
- buf = buf ++ printIndented("declare module \"{s}\" {{\n", .{klass.path}, indent);
- }
-
- indent += indent_level;
-
- for (klass.properties) |property, i| {
- if (i > 0) {
- buf = buf ++ "\n";
- }
-
- buf = buf ++ printVar(property, indent);
- }
-
- buf = buf ++ "\n";
-
- for (klass.functions) |func, i| {
- if (i > 0) {
- buf = buf ++ "\n";
- }
-
- buf = buf ++ printFunction(
- func,
- indent,
- false,
- );
- }
-
- for (klass.classes) |func, i| {
- if (i > 0) {
- buf = buf ++ "\n";
- }
-
- buf = buf ++ printClass(
- func,
- indent,
- );
- }
-
- indent -= indent_level;
-
- buf = buf ++ printIndented("}}\n", .{}, indent);
-
- break :brk;
- }
- return comptime buf;
- }
-
- pub fn printClass(comptime klass: d.ts.class, comptime _indent: usize) string {
- comptime var indent = _indent;
- comptime var buf: string = "";
- comptime brk: {
- if (klass.tsdoc.len > 0) {
- buf = buf ++ printTSDoc(klass.tsdoc, indent);
- }
-
- const qualifier = if (!klass.default_export) "export " else "";
-
- if (klass.interface) {
- buf = buf ++ printIndented("export interface {s} {{\n", .{klass.name}, indent);
- } else {
- buf = buf ++ printIndented("{s}class {s} {{\n", .{ qualifier, klass.name }, indent);
- }
-
- indent += indent_level;
-
- var did_print_constructor = false;
- for (klass.functions) |func| {
- if (!strings.eqlComptime(func.name, "constructor")) continue;
- did_print_constructor = true;
- buf = buf ++ printInstanceFunction(
- func,
- indent,
- !klass.interface,
- );
- }
-
- for (klass.properties) |property, i| {
- if (i > 0 or did_print_constructor) {
- buf = buf ++ "\n";
- }
-
- buf = buf ++ printProperty(property, indent);
- }
-
- buf = buf ++ "\n";
-
- for (klass.functions) |func, i| {
- if (i > 0) {
- buf = buf ++ "\n";
- }
-
- if (strings.eqlComptime(func.name, "constructor")) continue;
-
- buf = buf ++ printInstanceFunction(
- func,
- indent,
- false,
- );
- }
-
- indent -= indent_level;
-
- buf = buf ++ printIndented("}}\n", .{}, indent);
-
- if (klass.default_export) {
- buf = buf ++ printIndented("export = {s};\n", .{klass.name}, indent);
- }
-
- break :brk;
- }
- return comptime buf;
- }
-
- pub fn printTSDoc(comptime str: string, comptime indent: usize) string {
- comptime var buf: string = "";
-
- comptime brk: {
- var splitter = std.mem.split(u8, str, "\n");
-
- const first = splitter.next() orelse break :brk;
- const second = splitter.next() orelse {
- buf = buf ++ printIndented("/** {s} */\n", .{std.mem.trim(u8, first, " ")}, indent);
- break :brk;
- };
- buf = buf ++ printIndented("/**\n", .{}, indent);
- buf = buf ++ printIndented(" * {s}\n", .{std.mem.trim(u8, first, " ")}, indent);
- buf = buf ++ printIndented(" * {s}\n", .{std.mem.trim(u8, second, " ")}, indent);
- while (splitter.next()) |line| {
- buf = buf ++ printIndented(" * {s}\n", .{std.mem.trim(u8, line, " ")}, indent);
- }
- buf = buf ++ printIndented("*/\n", .{}, indent);
- }
-
- return buf;
- }
- };
- };
-
- pub const arg = struct {
- name: string = "",
- @"return": string = "any",
- optional: bool = false,
- };
- };
-};
-
-// This should only exist at compile-time.
-pub const ClassOptions = struct {
- name: stringZ,
-
- read_only: bool = false,
- hidden: []const string = &[_]string{},
- no_inheritance: bool = false,
- singleton: bool = false,
- ts: d.ts.decl = d.ts.decl{ .empty = 0 },
-};
-
-pub fn NewConstructor(
- comptime InstanceType: type,
- comptime staticFunctions: anytype,
- comptime properties: anytype,
-) type {
- return struct {
- pub usingnamespace NewClassWithInstanceType(void, InstanceType.Class.class_options, staticFunctions, properties, InstanceType);
- const name_string = &ZigString.init(InstanceType.Class.class_options.name);
- pub fn constructor(ctx: js.JSContextRef) callconv(.C) js.JSObjectRef {
- return JSValue.makeWithNameAndPrototype(
- ctx.ptr(),
- @This().get().*,
- InstanceType.Class.get().*,
- name_string,
- ).asObjectRef();
- }
- };
-}
-
-const _to_json: stringZ = "toJSON";
-
-pub fn NewClass(
- comptime ZigType: type,
- comptime options: ClassOptions,
- comptime staticFunctions: anytype,
- comptime properties: anytype,
-) type {
- return NewClassWithInstanceType(ZigType, options, staticFunctions, properties, void);
-}
-
-pub fn NewClassWithInstanceType(
- comptime ZigType: type,
- comptime options: ClassOptions,
- comptime staticFunctions: anytype,
- comptime properties: anytype,
- comptime InstanceType: type,
-) type {
- return struct {
- const read_only = options.read_only;
- const singleton = options.singleton;
- pub const name = options.name;
- pub const class_options = options;
- pub const isJavaScriptCoreClass = true;
- pub const Zig = ZigType;
- const ClassDefinitionCreator = @This();
- const function_names = std.meta.fieldNames(@TypeOf(staticFunctions));
- const function_name_literals = function_names;
- var function_name_refs: [function_names.len]js.JSStringRef = undefined;
- var function_name_refs_set = false;
-
- const property_names = std.meta.fieldNames(@TypeOf(properties));
- var property_name_refs: [property_names.len]js.JSStringRef = undefined;
- var property_name_refs_set: bool = false;
- const property_name_literals = property_names;
-
- const LazyClassRef = struct {
- ref: js.JSClassRef = null,
- loaded: bool = false,
- };
-
- threadlocal var lazy_ref: LazyClassRef = LazyClassRef{};
-
- pub inline fn isLoaded() bool {
- return lazy_ref.loaded;
- }
-
- const ConstructorWrapper = struct {
- pub fn rfn(
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- _: js.JSObjectRef,
- argumentCount: usize,
- arguments: [*c]const js.JSValueRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- return &complete_definition.callAsConstructor.?(ctx, function, argumentCount, arguments, exception);
- }
- };
-
- pub fn throwInvalidConstructorError(ctx: js.JSContextRef, _: js.JSObjectRef, _: usize, _: [*c]const js.JSValueRef, exception: js.ExceptionRef) callconv(.C) js.JSObjectRef {
- JSError(getAllocator(ctx), "" ++ name ++ " is not a constructor", .{}, ctx, exception);
- return null;
- }
-
- pub fn throwInvalidFunctionError(
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSObjectRef,
- _: usize,
- _: [*c]const js.JSValueRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- JSError(getAllocator(ctx), "" ++ name ++ " is not a function", .{}, ctx, exception);
- return null;
- }
-
- pub const Constructor = ConstructorWrapper.rfn;
- const class_definition_ptr = &complete_definition;
-
- pub fn get() callconv(.C) [*c]js.JSClassRef {
- var lazy = lazy_ref;
-
- if (!lazy.loaded) {
- lazy = .{
- .ref = js.JSClassCreate(class_definition_ptr),
- .loaded = true,
- };
- lazy_ref = lazy;
- }
-
- _ = js.JSClassRetain(lazy.ref);
-
- return &lazy.ref;
- }
-
- pub fn customHasInstance(ctx: js.JSContextRef, _: js.JSObjectRef, value: js.JSValueRef, _: js.ExceptionRef) callconv(.C) bool {
- if (InstanceType != void) {
- var current = value;
- while (current != null) {
- if (js.JSValueIsObjectOfClass(ctx, current, InstanceType.Class.get().*)) {
- return true;
- }
- current = js.JSObjectGetPrototype(ctx, current);
- }
- return false;
- }
-
- return js.JSValueIsObjectOfClass(ctx, value, get().*);
- }
-
- pub fn make(ctx: js.JSContextRef, ptr: *ZigType) js.JSObjectRef {
- var real_ptr = JSPrivateDataPtr.init(ptr).ptr();
- if (comptime Environment.allow_assert) {
- std.debug.assert(JSPrivateDataPtr.isValidPtr(real_ptr));
- std.debug.assert(JSPrivateDataPtr.from(real_ptr).get(ZigType).? == ptr);
- }
-
- var result = js.JSObjectMake(
- ctx,
- get().*,
- real_ptr,
- );
-
- if (comptime Environment.allow_assert) {
- std.debug.assert(JSPrivateDataPtr.from(js.JSObjectGetPrivate(result)).ptr() == real_ptr);
- }
-
- return result;
- }
- pub fn GetClass(comptime ReceiverType: type) type {
- const ClassGetter = struct {
- get: fn (
- *ReceiverType,
- js.JSContextRef,
- js.JSObjectRef,
- js.ExceptionRef,
- ) js.JSValueRef = rfn,
-
- pub const ts = typescriptDeclaration();
-
- pub fn rfn(
- _: *ReceiverType,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.ExceptionRef,
- ) js.JSValueRef {
- return js.JSObjectMake(ctx, get().*, null);
- }
- };
-
- return ClassGetter;
- }
-
- fn StaticProperty(comptime id: usize) type {
- return struct {
- pub fn getter(
- ctx: js.JSContextRef,
- obj: js.JSObjectRef,
- prop: js.JSStringRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- var this: ObjectPtrType(ZigType) = if (comptime ZigType == void) void{} else GetJSPrivateData(ZigType, obj) orelse return js.JSValueMakeUndefined(ctx);
-
- const Field = @TypeOf(@field(
- properties,
- property_names[id],
- ));
- switch (comptime @typeInfo(Field)) {
- .Fn => {
- return @field(
- properties,
- property_names[id],
- )(
- this,
- ctx,
- obj,
- exception,
- );
- },
- .Struct => {
- comptime {
- if (!@hasField(@TypeOf(@field(properties, property_names[id])), "get")) {
- @compileError(
- "Cannot get static property " ++ property_names[id] ++ " of " ++ name ++ " because it is a struct without a getter",
- );
- }
- }
- const func = @field(
- @field(
- properties,
- property_names[id],
- ),
- "get",
- );
-
- const Func = @typeInfo(@TypeOf(func));
- const WithPropFn = fn (
- ObjectPtrType(ZigType),
- js.JSContextRef,
- js.JSObjectRef,
- js.JSStringRef,
- js.ExceptionRef,
- ) js.JSValueRef;
-
- if (Func.Fn.args.len == @typeInfo(WithPropFn).Fn.args.len) {
- return func(
- this,
- ctx,
- obj,
- prop,
- exception,
- );
- } else {
- return func(
- this,
- ctx,
- obj,
- exception,
- );
- }
- },
- else => unreachable,
- }
- }
-
- pub fn setter(
- ctx: js.JSContextRef,
- obj: js.JSObjectRef,
- prop: js.JSStringRef,
- value: js.JSValueRef,
- exception: js.ExceptionRef,
- ) callconv(.C) bool {
- var this = GetJSPrivateData(ZigType, obj) orelse return false;
-
- switch (comptime @typeInfo(@TypeOf(@field(
- properties,
- property_names[id],
- )))) {
- .Struct => {
- return @field(
- @field(
- properties,
- property_names[id],
- ),
- "set",
- )(
- this,
- ctx,
- obj,
- prop,
- value,
- exception,
- );
- },
- else => unreachable,
- }
- }
- };
- }
-
- pub inline fn getDefinition() js.JSClassDefinition {
- var definition = complete_definition;
- definition.className = options.name;
- return definition;
- }
-
- const GetterNameFormatter = struct {
- index: usize = 0,
-
- pub fn format(this: @This(), comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
- try writer.writeAll(std.mem.span(class_name_str));
- try writer.writeAll("_get_");
- const property_name = property_names[this.index];
- try writer.writeAll(std.mem.span(property_name));
- }
- };
-
- const SetterNameFormatter = struct {
- index: usize = 0,
-
- pub fn format(this: @This(), comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
- try writer.writeAll(std.mem.span(class_name_str));
- try writer.writeAll("_set_");
- const property_name = property_names[this.index];
- try writer.writeAll(std.mem.span(property_name));
- }
- };
-
- const FunctionNameFormatter = struct {
- index: usize = 0,
-
- pub fn format(this: @This(), comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
- try writer.writeAll(std.mem.span(class_name_str));
- try writer.writeAll("_fn_");
- const property_name = function_names[this.index];
- try writer.writeAll(std.mem.span(property_name));
- }
- };
-
- const PropertyDeclaration = struct {
- index: usize = 0,
- pub fn format(this: @This(), comptime fmt: []const u8, opts: std.fmt.FormatOptions, writer: anytype) !void {
- const definition = getDefinition();
- const property = definition.staticValues[this.index];
-
- if (property.getProperty != null) {
- try writer.writeAll("static JSC_DECLARE_CUSTOM_GETTER(");
- const getter_name = GetterNameFormatter{ .index = this.index };
- try getter_name.format(fmt, opts, writer);
- try writer.writeAll(");\n");
- }
-
- if (property.setProperty != null) {
- try writer.writeAll("static JSC_DECLARE_CUSTOM_SETTER(");
- const getter_name = SetterNameFormatter{ .index = this.index };
- try getter_name.format(fmt, opts, writer);
- try writer.writeAll(");\n");
- }
- }
- };
-
- const FunctionDeclaration = struct {
- index: usize = 0,
- pub fn format(this: @This(), comptime fmt: []const u8, opts: std.fmt.FormatOptions, writer: anytype) !void {
- const definition = getDefinition();
- const function = definition.staticFunctions[this.index];
-
- if (function.callAsFunction != null) {
- try writer.writeAll("static JSC_DECLARE_HOST_FUNCTION(");
- const getter_name = FunctionNameFormatter{ .index = this.index };
- try getter_name.format(fmt, opts, writer);
- try writer.writeAll(");\n");
- }
- }
- };
-
- const PropertyDefinition = struct {
- index: usize = 0,
- pub fn format(this: @This(), comptime fmt: []const u8, opts: std.fmt.FormatOptions, writer: anytype) !void {
- const definition = getDefinition();
- const property = definition.staticValues[this.index];
-
- if (property.getProperty != null) {
- try writer.writeAll("static JSC_DEFINE_CUSTOM_GETTER(");
- const getter_name = GetterNameFormatter{ .index = this.index };
- try getter_name.format(fmt, opts, writer);
- try writer.writeAll(", (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) {\n");
- try std.fmt.format(
- writer,
- \\ JSC::VM& vm = globalObject->vm();
- \\ Bun::{[name]s}* thisObject = JSC::jsDynamicCast<Bun::{[name]s}*>( JSValue::decode(thisValue));
- \\ if (UNLIKELY(!thisObject)) {{
- \\ return JSValue::encode(JSC::jsUndefined());
- \\ }}
- \\
- \\ auto clientData = Bun::clientData(vm);
- \\ auto scope = DECLARE_THROW_SCOPE(vm);
- \\
- ,
- .{ .name = std.mem.span(class_name_str) },
- );
- if (ZigType == void) {
- try std.fmt.format(
- writer,
- \\ JSC::EncodedJSValue result = Zig__{[getter]any}(globalObject);
- ,
- .{ .getter = getter_name },
- );
- } else {
- try std.fmt.format(
- writer,
- \\ JSC::EncodedJSValue result = Zig__{[getter]any}(globalObject, thisObject->m_ptr);
- ,
- .{ .getter = getter_name },
- );
- }
-
- try writer.writeAll(
- \\ JSC::JSObject *obj = JSC::JSValue::decode(result).getObject();
- \\
- \\ if (UNLIKELY(obj != nullptr && obj->isErrorInstance())) {
- \\ scope.throwException(globalObject, obj);
- \\ return JSValue::encode(JSC::jsUndefined());
- \\ }
- \\
- \\ scope.release();
- \\
- \\ return result;
- );
-
- try writer.writeAll("}\n");
- }
-
- if (property.setProperty != null) {
- try writer.writeAll("JSC_DEFINE_CUSTOM_SETTER(");
- const getter_name = SetterNameFormatter{ .index = this.index };
- try getter_name.format(fmt, opts, writer);
- try writer.writeAll(", (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::EncodedJSValue value, JSC::PropertyName)) {\n");
- try std.fmt.format(writer,
- \\ JSC::VM& vm = globalObject->vm();
- \\ Bun::{[name]s}* thisObject = JSC::jsDynamicCast<Bun::{[name]s}*>( JSValue::decode(thisValue));
- \\ if (UNLIKELY(!thisObject)) {{
- \\ return false;
- \\ }}
- \\
- \\ auto clientData = Bun::clientData(vm);
- \\ auto scope = DECLARE_THROW_SCOPE(vm);
- \\
- \\
- , .{ .name = getter_name });
- try writer.writeAll("};\n");
- }
- }
- };
-
- const PropertyDeclarationsFormatter = struct {
- pub fn format(_: @This(), comptime fmt: []const u8, opts: std.fmt.FormatOptions, writer: anytype) !void {
- const definition = getDefinition();
- for (definition.staticValues[0 .. static_values_ptr.len - 1]) |_, i| {
- const property = PropertyDeclaration{ .index = i };
- try property.format(fmt, opts, writer);
- }
- }
- };
-
- const PropertyDefinitionsFormatter = struct {
- pub fn format(_: @This(), comptime fmt: []const u8, opts: std.fmt.FormatOptions, writer: anytype) !void {
- const definition = getDefinition();
- if (static_values_ptr.len > 1) {
- for (definition.staticValues[0 .. static_values_ptr.len - 1]) |_, i| {
- const property = PropertyDefinition{ .index = i };
- try property.format(fmt, opts, writer);
- }
- }
- }
- };
-
- const FunctionDefinitionsFormatter = struct {
- pub fn format(_: @This(), comptime fmt: []const u8, opts: std.fmt.FormatOptions, writer: anytype) !void {
- _ = fmt;
- _ = writer;
- _ = opts;
- // for (static_properties[0 .. static_properties.len - 1]) |_, i| {
- // const property = FunctionDefinition{ .index = i };
- // try property.format(fmt, opts, writer);
- // }
- }
- };
-
- const FunctionDeclarationsFormatter = struct {
- pub fn format(_: @This(), comptime fmt: []const u8, opts: std.fmt.FormatOptions, writer: anytype) !void {
- _ = fmt;
- _ = writer;
- const definition = getDefinition();
- if (static_functions__.len > 1) {
- for (definition.staticFunctions[0 .. static_functions__.len - 1]) |_, i| {
- const function = FunctionDeclaration{ .index = i };
- try function.format(fmt, opts, writer);
- }
- }
- }
- };
-
- pub fn @"generateC++Header"(writer: anytype) !void {
- const header_file =
- \\// AUTO-GENERATED FILE
- \\#pragma once
- \\
- \\#include "BunBuiltinNames.h"
- \\#include "BunClientData.h"
- \\#include "root.h"
- \\
- \\
- \\namespace Bun {{
- \\
- \\using namespace JSC;
- \\using namespace Zig;
- \\
- \\class {[name]s} : public JSNonFinalObject {{
- \\ using Base = JSNonFinalObject;
- \\
- \\public:
- \\ {[name]s}(JSC::VM& vm, Structure* structure) : Base(vm, structure) {{}}
- \\
- \\
- \\ DECLARE_INFO;
- \\
- \\ static constexpr unsigned StructureFlags = Base::StructureFlags;
- \\ template<typename CellType, SubspaceAccess> static GCClient::IsoSubspace* subspaceFor(VM& vm)
- \\ {{
- \\ return &vm.cellSpace();
- \\ }}
- \\ static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject,
- \\ JSC::JSValue prototype)
- \\ {{
- \\ return JSC::Structure::create(vm, globalObject, prototype,
- \\ JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
- \\ }}
- \\
- \\ static {[name]s}* create(JSC::VM& vm, JSC::Structure* structure)
- \\ {{
- \\ {[name]s}* accessor = new (NotNull, JSC::allocateCell<{[name]s}>(vm)) {[name]s}(vm, structure);
- \\ accessor->finishCreation(vm);
- \\ return accessor;
- \\ }}
- \\
- \\ void finishCreation(JSC::VM& vm);
- \\
- \\}};
- \\
- \\}} // namespace Bun
- \\
- ;
- _ = writer;
- _ = header_file;
- const Opts = struct { name: string };
- try writer.print(header_file, Opts{
- .name = std.mem.span(name),
- });
- }
-
- const LookupTableFormatter = struct {
- // example:
- //
- // /* Source for IntlLocalePrototype.lut.h
- // @begin localePrototypeTable
- // maximize intlLocalePrototypeFuncMaximize DontEnum|Function 0
- // minimize intlLocalePrototypeFuncMinimize DontEnum|Function 0
- // toString intlLocalePrototypeFuncToString DontEnum|Function 0
- // baseName intlLocalePrototypeGetterBaseName DontEnum|ReadOnly|CustomAccessor
- // calendar intlLocalePrototypeGetterCalendar DontEnum|ReadOnly|CustomAccessor
- // calendars intlLocalePrototypeGetterCalendars DontEnum|ReadOnly|CustomAccessor
- // caseFirst intlLocalePrototypeGetterCaseFirst DontEnum|ReadOnly|CustomAccessor
- // collation intlLocalePrototypeGetterCollation DontEnum|ReadOnly|CustomAccessor
- // collations intlLocalePrototypeGetterCollations DontEnum|ReadOnly|CustomAccessor
- // hourCycle intlLocalePrototypeGetterHourCycle DontEnum|ReadOnly|CustomAccessor
- // hourCycles intlLocalePrototypeGetterHourCycles DontEnum|ReadOnly|CustomAccessor
- // numeric intlLocalePrototypeGetterNumeric DontEnum|ReadOnly|CustomAccessor
- // numberingSystem intlLocalePrototypeGetterNumberingSystem DontEnum|ReadOnly|CustomAccessor
- // numberingSystems intlLocalePrototypeGetterNumberingSystems DontEnum|ReadOnly|CustomAccessor
- // language intlLocalePrototypeGetterLanguage DontEnum|ReadOnly|CustomAccessor
- // script intlLocalePrototypeGetterScript DontEnum|ReadOnly|CustomAccessor
- // region intlLocalePrototypeGetterRegion DontEnum|ReadOnly|CustomAccessor
- // timeZones intlLocalePrototypeGetterTimeZones DontEnum|ReadOnly|CustomAccessor
- // textInfo intlLocalePrototypeGetterTextInfo DontEnum|ReadOnly|CustomAccessor
- // weekInfo intlLocalePrototypeGetterWeekInfo DontEnum|ReadOnly|CustomAccessor
- // @end
- // */
- pub fn format(_: @This(), comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
- const definition = getDefinition();
- try writer.writeAll("/* Source for ");
- try writer.writeAll(std.mem.span(definition.className));
- try writer.writeAll(".lut.h\n");
- try writer.writeAll("@begin ");
- try writer.writeAll(std.mem.span(definition.className));
- try writer.writeAll("HashTableValues \n");
- var middle_padding: usize = 0;
- if (property_names.len > 0) {
- for (property_names) |prop| {
- middle_padding = @maximum(prop.len, middle_padding);
- }
- }
- if (function_names.len > 0) {
- for (function_names[0..function_names.len]) |_name| {
- middle_padding = @maximum(std.mem.span(_name).len, middle_padding);
- }
- }
-
- if (property_names.len > 0) {
- comptime var i: usize = 0;
- inline while (i < property_names.len) : (i += 1) {
- try writer.writeAll(" ");
- const name_ = property_names[i];
- try writer.writeAll(name_);
- try writer.writeAll(" ");
- var k: usize = 0;
- while (k < middle_padding - name_.len) : (k += 1) {
- try writer.writeAll(" ");
- }
-
- try writer.print("{any} ", .{GetterNameFormatter{ .index = i }});
-
- k = 0;
-
- while (k < middle_padding - name_.len) : (k += 1) {
- try writer.writeAll(" ");
- }
-
- try writer.writeAll("CustomAccessor");
- if (options.read_only or @hasField(@TypeOf(@field(properties, property_names[i])), "ro")) {
- try writer.writeAll("|ReadOnly");
- }
-
- if (@hasField(@TypeOf(@field(properties, property_names[i])), "enumerable") and !@field(properties, property_names[i])) {
- try writer.writeAll("|DontEnum");
- }
-
- try writer.writeAll("\n");
- }
- }
- if (function_names.len > 0) {
- comptime var i: usize = 0;
- inline while (i < function_names.len) : (i += 1) {
- try writer.writeAll(" ");
- const name_ = function_names[i];
- try writer.writeAll(name_);
- try writer.writeAll(" ");
- var k: usize = 0;
- while (k < middle_padding - name_.len) : (k += 1) {
- try writer.writeAll(" ");
- }
-
- try writer.print("{any} ", .{FunctionNameFormatter{ .index = i }});
- k = 0;
-
- while (k < middle_padding - name_.len) : (k += 1) {
- try writer.writeAll(" ");
- }
- var read_only_ = false;
- if (options.read_only or @hasField(@TypeOf(comptime @field(staticFunctions, function_names[i])), "ro")) {
- read_only_ = true;
- try writer.writeAll("ReadOnly");
- }
-
- if (comptime std.meta.trait.isContainer(
- @TypeOf(comptime @field(staticFunctions, function_names[i])),
- ) and
- @hasField(@TypeOf(comptime @field(
- staticFunctions,
- function_names[i],
- )), "enumerable") and !@field(staticFunctions, function_names[i]).enumerable) {
- if (read_only_) {
- try writer.writeAll("|");
- }
- try writer.writeAll("DontEnum");
- }
-
- try writer.writeAll("Function 1");
-
- try writer.writeAll("\n");
- }
- }
-
- try writer.writeAll("@end\n*/\n");
- }
- };
-
- pub fn @"generateC++Class"(writer: anytype) !void {
- const implementation_file =
- \\// AUTO-GENERATED FILE
- \\
- \\#include "{[name]s}.generated.h"
- \\#include "{[name]s}.lut.h"
- \\
- \\namespace Bun {{
- \\
- \\{[lut]any}
- \\
- \\using JSGlobalObject = JSC::JSGlobalObject;
- \\using Exception = JSC::Exception;
- \\using JSValue = JSC::JSValue;
- \\using JSString = JSC::JSString;
- \\using JSModuleLoader = JSC::JSModuleLoader;
- \\using JSModuleRecord = JSC::JSModuleRecord;
- \\using Identifier = JSC::Identifier;
- \\using SourceOrigin = JSC::SourceOrigin;
- \\using JSObject = JSC::JSObject;
- \\using JSNonFinalObject = JSC::JSNonFinalObject;
- \\namespace JSCastingHelpers = JSC::JSCastingHelpers;
- \\
- \\#pragma mark - Function Declarations
- \\
- \\{[function_declarations]any}
- \\
- \\#pragma mark - Property Declarations
- \\
- \\{[property_declarations]any}
- \\
- \\#pragma mark - Function Definitions
- \\
- \\{[function_definitions]any}
- \\
- \\#pragma mark - Property Definitions
- \\
- \\{[property_definitions]any}
- \\
- \\const JSC::ClassInfo {[name]s}::s_info = {{ "{[name]s}"_s, &Base::s_info, &{[name]s}HashTableValues, nullptr, CREATE_METHOD_TABLE([name]s) }};
- \\
- \\ void {[name]s}::finishCreation(JSC::VM& vm) {{
- \\ Base::finishCreation(vm);
- \\ auto clientData = Bun::clientData(vm);
- \\ JSC::JSGlobalObject *globalThis = globalObject();
- \\
- \\
- \\#pragma mark - Property Initializers
- \\
- \\{[property_initializers]any}
- \\
- \\#pragma mark - Function Initializers
- \\
- \\{[function_initializers]any}
- \\
- \\ }}
- \\
- \\}} // namespace Bun
- \\
- ;
-
- try writer.print(implementation_file, .{
- .name = std.mem.span(class_name_str),
- .function_initializers = @as(string, ""),
- .property_initializers = @as(string, ""),
- .function_declarations = FunctionDeclarationsFormatter{},
- .property_declarations = FunctionDeclarationsFormatter{},
- .function_definitions = FunctionDefinitionsFormatter{},
- .property_definitions = PropertyDefinitionsFormatter{},
- .lut = LookupTableFormatter{},
- });
- }
-
- // This should only be run at comptime
- pub fn typescriptModuleDeclaration() d.ts.module {
- comptime var class = options.ts.module;
- comptime {
- if (class.read_only == null) {
- class.read_only = options.read_only;
- }
-
- if (function_name_literals.len > 0) {
- var count: usize = 0;
- inline for (function_name_literals) |_, i| {
- const func = @field(staticFunctions, function_names[i]);
- const Func = @TypeOf(func);
-
- switch (@typeInfo(Func)) {
- .Struct => {
- var total: usize = 1;
- if (hasTypeScript(Func)) {
- if (std.meta.trait.isIndexable(@TypeOf(func.ts))) {
- total = func.ts.len;
- }
- }
-
- count += total;
- },
- else => continue,
- }
- }
-
- var funcs = std.mem.zeroes([count]d.ts);
- class.functions = std.mem.span(&funcs);
- var func_i: usize = 0;
- @setEvalBranchQuota(99999);
- inline for (function_name_literals) |_, i| {
- const func = @field(staticFunctions, function_names[i]);
- const Func = @TypeOf(func);
-
- switch (@typeInfo(Func)) {
- .Struct => {
- var ts_functions: []const d.ts = &[_]d.ts{};
-
- if (hasTypeScript(Func)) {
- if (std.meta.trait.isIndexable(@TypeOf(func.ts))) {
- ts_functions = std.mem.span(func.ts);
- }
- }
-
- if (ts_functions.len == 0 and hasTypeScript(Func)) {
- var funcs1 = std.mem.zeroes([1]d.ts);
- funcs1[0] = func.ts;
- ts_functions = std.mem.span(&funcs1);
- } else {
- var funcs1 = std.mem.zeroes([1]d.ts);
- funcs1[0] = .{ .name = function_names[i] };
- ts_functions = std.mem.span(&funcs1);
- }
-
- for (ts_functions) |ts_function_| {
- var ts_function = ts_function_;
- if (ts_function.name.len == 0) {
- ts_function.name = function_names[i];
- }
-
- if (ts_function.read_only == null) {
- ts_function.read_only = class.read_only;
- }
-
- class.functions[func_i] = ts_function;
-
- func_i += 1;
- }
- },
- else => continue,
- }
- }
- }
-
- if (property_names.len > 0) {
- var count: usize = 0;
- var class_count: usize = 0;
-
- inline for (property_names) |_, i| {
- const field = @field(properties, property_names[i]);
- const Field = @TypeOf(field);
-
- if (hasTypeScript(Field)) {
- switch (getTypeScript(Field, field)) {
- .decl => |dec| {
- switch (dec) {
- .class => {
- class_count += 1;
- },
- else => {},
- }
- },
- .ts => {
- count += 1;
- },
- }
- }
- }
-
- var props = std.mem.zeroes([count]d.ts);
- class.properties = std.mem.span(&props);
- var property_i: usize = 0;
-
- var classes = std.mem.zeroes([class_count + class.classes.len]d.ts.class);
- if (class.classes.len > 0) {
- std.mem.copy(d.ts.class, classes, class.classes);
- }
-
- var class_i: usize = class.classes.len;
- class.classes = std.mem.span(&classes);
-
- inline for (property_names) |property_name, i| {
- const field = @field(properties, property_names[i]);
- const Field = @TypeOf(field);
-
- if (hasTypeScript(Field)) {
- switch (getTypeScript(Field, field)) {
- .decl => |dec| {
- switch (dec) {
- .class => |ts_class| {
- class.classes[class_i] = ts_class;
- class_i += 1;
- },
- else => {},
- }
- },
- .ts => |ts_field_| {
- var ts_field: d.ts = ts_field_;
- if (ts_field.name.len == 0) {
- ts_field.name = property_name;
- }
-
- if (ts_field.read_only == null) {
- if (hasReadOnly(Field)) {
- ts_field.read_only = field.ro;
- } else {
- ts_field.read_only = class.read_only;
- }
- }
-
- class.properties[property_i] = ts_field;
-
- property_i += 1;
- },
- }
- }
- }
- }
- }
-
- return class;
- }
-
- pub fn typescriptDeclaration() d.ts.decl {
- comptime var decl = options.ts;
- comptime switch (decl) {
- .module => {
- decl.module = typescriptModuleDeclaration();
- },
- .class => {
- decl.class = typescriptClassDeclaration(decl.class);
- },
- .empty => {
- decl = d.ts.decl{
- .class = typescriptClassDeclaration(
- d.ts.class{
- .name = options.name,
- },
- ),
- };
- },
- };
-
- return decl;
- }
-
- pub fn getPropertyNames(
- _: js.JSContextRef,
- _: js.JSObjectRef,
- props: js.JSPropertyNameAccumulatorRef,
- ) callconv(.C) void {
- if (comptime property_name_refs.len > 0) {
- comptime var i: usize = 0;
- if (!property_name_refs_set) {
- property_name_refs_set = true;
- inline while (i < property_name_refs.len) : (i += 1) {
- property_name_refs[i] = js.JSStringCreateStatic(property_names[i].ptr, property_names[i].len);
- }
- comptime i = 0;
- }
- inline while (i < property_name_refs.len) : (i += 1) {
- js.JSPropertyNameAccumulatorAddName(props, property_name_refs[i]);
- }
- }
-
- if (comptime function_name_refs.len > 0) {
- comptime var j: usize = 0;
- if (!function_name_refs_set) {
- function_name_refs_set = true;
- inline while (j < function_name_refs.len) : (j += 1) {
- function_name_refs[j] = js.JSStringCreateStatic(function_names[j].ptr, function_names[j].len);
- }
- comptime j = 0;
- }
-
- inline while (j < function_name_refs.len) : (j += 1) {
- js.JSPropertyNameAccumulatorAddName(props, function_name_refs[j]);
- }
- }
- }
-
- // This should only be run at comptime
- pub fn typescriptClassDeclaration(comptime original: d.ts.class) d.ts.class {
- comptime var class = original;
-
- comptime {
- if (class.name.len == 0) {
- class.name = options.name;
- }
-
- if (class.read_only == null) {
- class.read_only = options.read_only;
- }
-
- if (function_name_literals.len > 0) {
- var count: usize = 0;
- inline for (function_name_literals) |_, i| {
- const func = @field(staticFunctions, function_names[i]);
- const Func = @TypeOf(func);
-
- switch (@typeInfo(Func)) {
- .Struct => {
- var total: usize = 1;
- if (hasTypeScript(Func)) {
- if (std.meta.trait.isIndexable(@TypeOf(func.ts))) {
- total = func.ts.len;
- }
- }
-
- count += total;
- },
- else => continue,
- }
- }
-
- var funcs = std.mem.zeroes([count]d.ts);
- class.functions = std.mem.span(&funcs);
- var func_i: usize = 0;
-
- inline for (function_name_literals) |_, i| {
- const func = @field(staticFunctions, function_names[i]);
- const Func = @TypeOf(func);
-
- switch (@typeInfo(Func)) {
- .Struct => {
- var ts_functions: []const d.ts = &[_]d.ts{};
-
- if (hasTypeScript(Func)) {
- if (std.meta.trait.isIndexable(@TypeOf(func.ts))) {
- ts_functions = std.mem.span(func.ts);
- }
- }
-
- if (ts_functions.len == 0 and hasTypeScript(Func)) {
- var funcs1 = std.mem.zeroes([1]d.ts);
- funcs1[0] = func.ts;
- ts_functions = std.mem.span(&funcs1);
- } else {
- var funcs1 = std.mem.zeroes([1]d.ts);
- funcs1[0] = .{ .name = function_names[i] };
- ts_functions = std.mem.span(&funcs1);
- }
-
- for (ts_functions) |ts_function_| {
- var ts_function = ts_function_;
- if (ts_function.name.len == 0) {
- ts_function.name = function_names[i];
- }
-
- if (class.interface and strings.eqlComptime(ts_function.name, "constructor")) {
- ts_function.name = "new";
- }
-
- if (ts_function.read_only == null) {
- ts_function.read_only = class.read_only;
- }
-
- class.functions[func_i] = ts_function;
-
- func_i += 1;
- }
- },
- else => continue,
- }
- }
- }
-
- if (property_names.len > 0) {
- var count: usize = property_names.len;
-
- var props = std.mem.zeroes([count]d.ts);
- class.properties = std.mem.span(&props);
- var property_i: usize = 0;
-
- inline for (property_names) |property_name, i| {
- const field = @field(properties, property_names[i]);
-
- var ts_field: d.ts = .{};
-
- if (hasTypeScript(@TypeOf(field))) {
- ts_field = field.ts;
- }
-
- if (ts_field.name.len == 0) {
- ts_field.name = property_name;
- }
-
- if (ts_field.read_only == null) {
- if (hasReadOnly(@TypeOf(field))) {
- ts_field.read_only = field.ro;
- } else {
- ts_field.read_only = class.read_only;
- }
- }
-
- class.properties[property_i] = ts_field;
- property_i += 1;
- }
- }
- }
-
- return comptime class;
- }
-
- const static_properties: [property_names.len + 1]js.JSStaticValue = brk: {
- var props: [property_names.len + 1]js.JSStaticValue = undefined;
- std.mem.set(
- js.JSStaticValue,
- &props,
- js.JSStaticValue{
- .name = @intToPtr([*c]const u8, 0),
- .getProperty = null,
- .setProperty = null,
- .attributes = js.JSPropertyAttributes.kJSPropertyAttributeNone,
- },
- );
- for (property_name_literals) |_, i| {
- props[i] = brk2: {
- var static_prop = JSC.C.JSStaticValue{
- .name = property_names[i][0.. :0].ptr,
- .getProperty = null,
- .setProperty = null,
- .attributes = @intToEnum(js.JSPropertyAttributes, 0),
- };
- static_prop.getProperty = StaticProperty(i).getter;
-
- const field = @field(properties, property_names[i]);
-
- if (hasSetter(@TypeOf(field))) {
- static_prop.setProperty = StaticProperty(i).setter;
- }
- break :brk2 static_prop;
- };
- }
- break :brk props;
- };
-
- // this madness is a workaround for stage1 compiler bugs
- fn generateDef(comptime ReturnType: type) ReturnType {
- var count = 0;
- var def: js.JSClassDefinition = js.JSClassDefinition{
- .version = 0,
- .attributes = js.JSClassAttributes.kJSClassAttributeNone,
- .className = "",
- .parentClass = null,
- .staticValues = null,
- .staticFunctions = null,
- .initialize = null,
- .finalize = null,
- .hasProperty = null,
- .getProperty = null,
- .setProperty = null,
- .deleteProperty = null,
- .getPropertyNames = null,
- .callAsFunction = null,
- .callAsConstructor = null,
- .hasInstance = null,
- .convertToType = null,
- };
-
- var __static_functions: [function_name_literals.len + 1]js.JSStaticFunction = undefined;
- for (__static_functions) |_, i| {
- __static_functions[i] = js.JSStaticFunction{
- .name = @intToPtr([*c]const u8, 0),
- .callAsFunction = null,
- .attributes = js.JSPropertyAttributes.kJSPropertyAttributeNone,
- };
- }
-
- for (function_name_literals) |function_name_literal, i| {
- const is_read_only = options.read_only;
-
- _ = i;
- switch (@typeInfo(@TypeOf(@field(staticFunctions, function_name_literal)))) {
- .Struct => {
- if (strings.eqlComptime(function_name_literal, "constructor")) {
- def.callAsConstructor = To.JS.Constructor(staticFunctions.constructor.rfn).rfn;
- } else if (strings.eqlComptime(function_name_literal, "finalize")) {
- def.finalize = To.JS.Finalize(ZigType, staticFunctions.finalize.rfn).rfn;
- } else if (strings.eqlComptime(function_name_literal, "call")) {
- def.callAsFunction = To.JS.Callback(ZigType, staticFunctions.call.rfn).rfn;
- } else if (strings.eqlComptime(function_name_literal, "callAsFunction")) {
- const ctxfn = @field(staticFunctions, function_name_literal).rfn;
- const Func: std.builtin.TypeInfo.Fn = @typeInfo(@TypeOf(ctxfn)).Fn;
-
- const PointerType = std.meta.Child(Func.args[0].arg_type.?);
-
- def.callAsFunction = if (Func.calling_convention == .C) ctxfn else To.JS.Callback(
- PointerType,
- ctxfn,
- ).rfn;
- } else if (strings.eqlComptime(function_name_literal, "hasProperty")) {
- def.hasProperty = @field(staticFunctions, "hasProperty").rfn;
- } else if (strings.eqlComptime(function_name_literal, "getProperty")) {
- def.getProperty = @field(staticFunctions, "getProperty").rfn;
- } else if (strings.eqlComptime(function_name_literal, "setProperty")) {
- def.setProperty = @field(staticFunctions, "setProperty").rfn;
- } else if (strings.eqlComptime(function_name_literal, "deleteProperty")) {
- def.deleteProperty = @field(staticFunctions, "deleteProperty").rfn;
- } else if (strings.eqlComptime(function_name_literal, "getPropertyNames")) {
- def.getPropertyNames = @field(staticFunctions, "getPropertyNames").rfn;
- } else if (strings.eqlComptime(function_name_literal, "convertToType")) {
- def.convertToType = @field(staticFunctions, "convertToType").rfn;
- } else {
- const CtxField = @field(staticFunctions, function_name_literals[i]);
- if (!@hasField(@TypeOf(CtxField), "rfn")) {
- @compileError("Expected " ++ options.name ++ "." ++ function_name_literal ++ " to have .rfn");
- }
- const ctxfn = CtxField.rfn;
- const Func: std.builtin.TypeInfo.Fn = @typeInfo(@TypeOf(ctxfn)).Fn;
-
- var attributes: c_uint = @enumToInt(js.JSPropertyAttributes.kJSPropertyAttributeNone);
-
- if (is_read_only or hasReadOnly(@TypeOf(CtxField))) {
- attributes |= @enumToInt(js.JSPropertyAttributes.kJSPropertyAttributeReadOnly);
- }
-
- if (hasEnumerable(@TypeOf(CtxField)) and !CtxField.enumerable) {
- attributes |= @enumToInt(js.JSPropertyAttributes.kJSPropertyAttributeDontEnum);
- }
-
- var PointerType = void;
-
- if (Func.args[0].arg_type.? != void) {
- PointerType = std.meta.Child(Func.args[0].arg_type.?);
- }
-
- __static_functions[count] = js.JSStaticFunction{
- .name = @ptrCast([*c]const u8, function_names[i].ptr),
- .callAsFunction = if (Func.calling_convention == .C) ctxfn else To.JS.Callback(
- PointerType,
- ctxfn,
- ).rfn,
- .attributes = @intToEnum(js.JSPropertyAttributes, attributes),
- };
-
- count += 1;
- }
- },
- .Fn => {
- if (strings.eqlComptime(function_name_literal, "constructor")) {
- def.callAsConstructor = To.JS.Constructor(staticFunctions.constructor).rfn;
- } else if (strings.eqlComptime(function_name_literal, "finalize")) {
- def.finalize = To.JS.Finalize(ZigType, staticFunctions.finalize).rfn;
- } else if (strings.eqlComptime(function_name_literal, "call")) {
- def.callAsFunction = To.JS.Callback(ZigType, staticFunctions.call).rfn;
- } else if (strings.eqlComptime(function_name_literal, "getPropertyNames")) {
- def.getPropertyNames = To.JS.Callback(ZigType, staticFunctions.getPropertyNames).rfn;
- } else if (strings.eqlComptime(function_name_literal, "hasInstance")) {
- def.hasInstance = staticFunctions.hasInstance;
- } else {
- const attributes: js.JSPropertyAttributes = brk: {
- var base = @enumToInt(js.JSPropertyAttributes.kJSPropertyAttributeNone);
-
- if (is_read_only)
- base |= @enumToInt(js.JSPropertyAttributes.kJSPropertyAttributeReadOnly);
-
- break :brk @intToEnum(js.JSPropertyAttributes, base);
- };
-
- __static_functions[count] = js.JSStaticFunction{
- .name = @ptrCast([*c]const u8, function_names[i].ptr),
- .callAsFunction = To.JS.Callback(
- ZigType,
- @field(staticFunctions, function_name_literal),
- ).rfn,
- .attributes = attributes,
- };
-
- count += 1;
- }
- },
- else => {},
- }
- }
-
- if (ReturnType == JSC.C.JSClassDefinition) {
- return def;
- } else {
- return __static_functions;
- }
- }
-
- const base_def_ = generateDef(JSC.C.JSClassDefinition);
- const static_functions__: [function_name_literals.len + 1]js.JSStaticFunction = generateDef([function_name_literals.len + 1]js.JSStaticFunction);
- const static_functions_ptr = &static_functions__;
- const static_values_ptr = &static_properties;
- const class_name_str: stringZ = options.name;
-
- const complete_definition = brk: {
- var def = base_def_;
- def.staticFunctions = static_functions_ptr;
- if (options.no_inheritance) {
- def.attributes = JSC.C.JSClassAttributes.kJSClassAttributeNoAutomaticPrototype;
- }
- if (property_names.len > 0) {
- def.staticValues = static_values_ptr;
- }
-
- def.className = class_name_str;
- // def.getProperty = getPropertyCallback;
-
- if (def.callAsConstructor == null) {
- def.callAsConstructor = throwInvalidConstructorError;
- }
-
- if (def.callAsFunction == null) {
- def.callAsFunction = throwInvalidFunctionError;
- }
-
- if (def.getPropertyNames == null) {
- def.getPropertyNames = getPropertyNames;
- }
-
- if (!singleton and def.hasInstance == null)
- def.hasInstance = customHasInstance;
- break :brk def;
- };
- };
-}
-
-const JSValue = JSC.JSValue;
-const ZigString = JSC.ZigString;
-
-pub const PathString = bun.PathString;
-
-pub fn JSError(
- _: std.mem.Allocator,
- comptime fmt: string,
- args: anytype,
- ctx: js.JSContextRef,
- exception: ExceptionValueRef,
-) void {
- @setCold(true);
-
- if (comptime std.meta.fields(@TypeOf(args)).len == 0) {
- var zig_str = JSC.ZigString.init(fmt);
- if (comptime !strings.isAllASCII(fmt)) {
- zig_str.markUTF16();
- }
-
- exception.* = zig_str.toErrorInstance(ctx).asObjectRef();
- } else {
- var fallback = std.heap.stackFallback(256, default_allocator);
- var allocator = fallback.get();
-
- var buf = std.fmt.allocPrint(allocator, fmt, args) catch unreachable;
- var zig_str = JSC.ZigString.init(buf);
- zig_str.detectEncoding();
- zig_str.mark();
- // it alwayas clones
- exception.* = zig_str.toErrorInstance(ctx).asObjectRef();
- allocator.free(buf);
- }
-}
-
-pub fn throwTypeError(
- code: JSC.Node.ErrorCode,
- comptime fmt: string,
- args: anytype,
- ctx: js.JSContextRef,
- exception: ExceptionValueRef,
-) void {
- exception.* = toTypeError(code, fmt, args, ctx).asObjectRef();
-}
-
-pub fn toTypeError(
- code: JSC.Node.ErrorCode,
- comptime fmt: string,
- args: anytype,
- ctx: js.JSContextRef,
-) JSC.JSValue {
- @setCold(true);
- var zig_str: JSC.ZigString = undefined;
- if (comptime std.meta.fields(@TypeOf(args)).len == 0) {
- zig_str = JSC.ZigString.init(fmt);
- zig_str.detectEncoding();
- } else {
- var buf = std.fmt.allocPrint(default_allocator, fmt, args) catch unreachable;
- zig_str = JSC.ZigString.init(buf);
- zig_str.detectEncoding();
- zig_str.mark();
- }
- const code_str = ZigString.init(@tagName(code));
- return JSC.JSValue.createTypeError(&zig_str, &code_str, ctx.ptr());
-}
-
-pub fn throwInvalidArguments(
- comptime fmt: string,
- args: anytype,
- ctx: js.JSContextRef,
- exception: ExceptionValueRef,
-) void {
- @setCold(true);
- return throwTypeError(JSC.Node.ErrorCode.ERR_INVALID_ARG_TYPE, fmt, args, ctx, exception);
-}
-
-pub fn toInvalidArguments(
- comptime fmt: string,
- args: anytype,
- ctx: js.JSContextRef,
-) JSC.JSValue {
- @setCold(true);
- return toTypeError(JSC.Node.ErrorCode.ERR_INVALID_ARG_TYPE, fmt, args, ctx);
-}
-
-pub fn getAllocator(_: js.JSContextRef) std.mem.Allocator {
- return default_allocator;
-}
-
-pub const JSStringList = std.ArrayList(js.JSStringRef);
-
-pub const ArrayBuffer = extern struct {
- ptr: [*]u8 = undefined,
- offset: u32,
- len: u32,
- byte_len: u32,
- typed_array_type: JSC.JSValue.JSType,
- value: JSC.JSValue = JSC.JSValue.zero,
-
- pub const name = "Bun__ArrayBuffer";
- pub const Stream = std.io.FixedBufferStream([]u8);
-
- pub inline fn stream(this: ArrayBuffer) Stream {
- return Stream{ .pos = 0, .buf = this.slice() };
- }
-
- pub fn create(globalThis: *JSC.JSGlobalObject, bytes: []const u8, comptime kind: JSC.JSValue.JSType) JSValue {
- JSC.markBinding();
- return switch (comptime kind) {
- .Uint8Array => Bun__createUint8ArrayForCopy(globalThis, bytes.ptr, bytes.len),
- .ArrayBuffer => Bun__createArrayBufferForCopy(globalThis, bytes.ptr, bytes.len),
- else => @compileError("Not implemented yet"),
- };
- }
-
- extern "C" fn Bun__createUint8ArrayForCopy(*JSC.JSGlobalObject, ptr: *const anyopaque, len: usize) JSValue;
- extern "C" fn Bun__createArrayBufferForCopy(*JSC.JSGlobalObject, ptr: *const anyopaque, len: usize) JSValue;
-
- pub fn fromTypedArray(ctx: JSC.C.JSContextRef, value: JSC.JSValue, _: JSC.C.ExceptionRef) ArrayBuffer {
- var out = std.mem.zeroes(ArrayBuffer);
- std.debug.assert(value.asArrayBuffer_(ctx.ptr(), &out));
- out.value = value;
- return out;
- }
-
- pub fn fromBytes(bytes: []u8, typed_array_type: JSC.JSValue.JSType) ArrayBuffer {
- return ArrayBuffer{ .offset = 0, .len = @intCast(u32, bytes.len), .byte_len = @intCast(u32, bytes.len), .typed_array_type = typed_array_type, .ptr = bytes.ptr };
- }
-
- pub fn toJSUnchecked(this: ArrayBuffer, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.JSValue {
- if (this.typed_array_type == .ArrayBuffer) {
- return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy(
- ctx,
- this.ptr,
- this.byte_len,
- MarkedArrayBuffer_deallocator,
- @intToPtr(*anyopaque, @ptrToInt(&bun.default_allocator)),
- exception,
- ));
- }
-
- return JSC.JSValue.fromRef(JSC.C.JSObjectMakeTypedArrayWithBytesNoCopy(
- ctx,
- this.typed_array_type.toC(),
- this.ptr,
- this.byte_len,
- MarkedArrayBuffer_deallocator,
- @intToPtr(*anyopaque, @ptrToInt(&bun.default_allocator)),
- exception,
- ));
- }
-
- pub fn toJS(this: ArrayBuffer, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.JSValue {
- if (!this.value.isEmpty()) {
- return this.value;
- }
-
- // If it's not a mimalloc heap buffer, we're not going to call a deallocator
- if (!bun.Global.Mimalloc.mi_is_in_heap_region(this.ptr)) {
- if (this.typed_array_type == .ArrayBuffer) {
- return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy(
- ctx,
- this.ptr,
- this.byte_len,
- null,
- null,
- exception,
- ));
- }
-
- return JSC.JSValue.fromRef(JSC.C.JSObjectMakeTypedArrayWithBytesNoCopy(
- ctx,
- this.typed_array_type.toC(),
- this.ptr,
- this.byte_len,
- null,
- null,
- exception,
- ));
- }
-
- return this.toJSUnchecked(ctx, exception);
- }
-
- pub fn toJSWithContext(
- this: ArrayBuffer,
- ctx: JSC.C.JSContextRef,
- deallocator: ?*anyopaque,
- callback: JSC.C.JSTypedArrayBytesDeallocator,
- exception: JSC.C.ExceptionRef,
- ) JSC.JSValue {
- if (!this.value.isEmpty()) {
- return this.value;
- }
-
- if (this.typed_array_type == .ArrayBuffer) {
- return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy(
- ctx,
- this.ptr,
- this.byte_len,
- callback,
- deallocator,
- exception,
- ));
- }
-
- return JSC.JSValue.fromRef(JSC.C.JSObjectMakeTypedArrayWithBytesNoCopy(
- ctx,
- this.typed_array_type.toC(),
- this.ptr,
- this.byte_len,
- callback,
- deallocator,
- exception,
- ));
- }
-
- pub const fromArrayBuffer = fromTypedArray;
-
- pub inline fn slice(this: *const @This()) []u8 {
- return this.ptr[this.offset .. this.offset + this.len];
- }
-
- pub inline fn byteSlice(this: *const @This()) []u8 {
- return this.ptr[this.offset .. this.offset + this.byte_len];
- }
-
- pub inline fn asU16(this: *const @This()) []u16 {
- return std.mem.bytesAsSlice(u16, @alignCast(@alignOf([*]u16), this.ptr[this.offset..this.byte_len]));
- }
-
- pub inline fn asU16Unaligned(this: *const @This()) []align(1) u16 {
- return std.mem.bytesAsSlice(u16, @alignCast(@alignOf([*]align(1) u16), this.ptr[this.offset..this.byte_len]));
- }
-
- pub inline fn asU32(this: *const @This()) []u32 {
- return std.mem.bytesAsSlice(u32, @alignCast(@alignOf([*]u32), this.ptr)[this.offset..this.byte_len]);
- }
-};
-
-pub const MarkedArrayBuffer = struct {
- buffer: ArrayBuffer,
- allocator: ?std.mem.Allocator = null,
-
- pub const Stream = ArrayBuffer.Stream;
-
- pub inline fn stream(this: *MarkedArrayBuffer) Stream {
- return this.buffer.stream();
- }
-
- pub fn fromTypedArray(ctx: JSC.C.JSContextRef, value: JSC.JSValue, exception: JSC.C.ExceptionRef) MarkedArrayBuffer {
- return MarkedArrayBuffer{
- .allocator = null,
- .buffer = ArrayBuffer.fromTypedArray(ctx, value, exception),
- };
- }
- pub fn fromArrayBuffer(ctx: JSC.C.JSContextRef, value: JSC.JSValue, exception: JSC.C.ExceptionRef) MarkedArrayBuffer {
- return MarkedArrayBuffer{
- .allocator = null,
- .buffer = ArrayBuffer.fromArrayBuffer(ctx, value, exception),
- };
- }
-
- pub fn fromString(str: []const u8, allocator: std.mem.Allocator) !MarkedArrayBuffer {
- var buf = try allocator.dupe(u8, str);
- return MarkedArrayBuffer.fromBytes(buf, allocator, JSC.JSValue.JSType.Uint8Array);
- }
-
- pub fn fromJS(global: *JSC.JSGlobalObject, value: JSC.JSValue, _: JSC.C.ExceptionRef) ?MarkedArrayBuffer {
- const array_buffer = value.asArrayBuffer(global) orelse return null;
- return MarkedArrayBuffer{ .buffer = array_buffer, .allocator = null };
- }
-
- pub fn fromBytes(bytes: []u8, allocator: std.mem.Allocator, typed_array_type: JSC.JSValue.JSType) MarkedArrayBuffer {
- return MarkedArrayBuffer{
- .buffer = ArrayBuffer.fromBytes(bytes, typed_array_type),
- .allocator = allocator,
- };
- }
-
- pub inline fn slice(this: *const @This()) []u8 {
- return this.buffer.slice();
- }
-
- pub fn destroy(this: *MarkedArrayBuffer) void {
- const content = this.*;
- if (this.allocator) |allocator| {
- this.allocator = null;
- allocator.free(content.buffer.slice());
- allocator.destroy(this);
- }
- }
-
- pub fn init(allocator: std.mem.Allocator, size: u32, typed_array_type: js.JSTypedArrayType) !*MarkedArrayBuffer {
- const bytes = try allocator.alloc(u8, size);
- var container = try allocator.create(MarkedArrayBuffer);
- container.* = MarkedArrayBuffer.fromBytes(bytes, allocator, typed_array_type);
- return container;
- }
-
- pub fn toJSObjectRef(this: MarkedArrayBuffer, ctx: js.JSContextRef, exception: js.ExceptionRef) js.JSObjectRef {
- return js.JSObjectMakeTypedArrayWithBytesNoCopy(
- ctx,
- this.buffer.typed_array_type.toC(),
- this.buffer.ptr,
-
- this.buffer.byte_len,
- MarkedArrayBuffer_deallocator,
- this.buffer.ptr,
- exception,
- );
- }
-
- pub const toJS = toJSObjectRef;
-};
-
-// expensive heap reference-counted string type
-// only use this for big strings
-// like source code
-// not little ones
-pub const RefString = struct {
- ptr: [*]const u8 = undefined,
- len: usize = 0,
- hash: Hash = 0,
-
- count: u32 = 0,
- allocator: std.mem.Allocator,
-
- ctx: ?*anyopaque = null,
- onBeforeDeinit: ?Callback = null,
-
- pub const Hash = u32;
- pub const Map = std.HashMap(Hash, *JSC.RefString, IdentityContext(Hash), 80);
-
- pub fn toJS(this: *RefString, global: *JSC.JSGlobalObject) JSValue {
- return JSC.ZigString.init(this.slice()).external(global, this, RefString__external);
- }
-
- pub const Callback = fn (ctx: *anyopaque, str: *RefString) void;
-
- pub fn computeHash(input: []const u8) u32 {
- return @truncate(u32, std.hash.Wyhash.hash(0, input));
- }
-
- pub fn ref(this: *RefString) void {
- this.count += 1;
- }
-
- pub fn slice(this: *RefString) []const u8 {
- this.ref();
-
- return this.leak();
- }
-
- pub fn leak(this: RefString) []const u8 {
- @setRuntimeSafety(false);
- return this.ptr[0..this.len];
- }
-
- pub fn deref(this: *RefString) void {
- this.count -|= 1;
-
- if (this.count == 0) {
- this.deinit();
- }
- }
-
- pub export fn RefString__free(this: *RefString, _: [*]const u8, _: usize) void {
- this.deref();
- }
-
- pub export fn RefString__external(this: ?*anyopaque, _: ?*anyopaque, _: usize) void {
- bun.cast(*RefString, this.?).deref();
- }
-
- pub fn deinit(this: *RefString) void {
- if (this.onBeforeDeinit) |onBeforeDeinit| {
- onBeforeDeinit(this.ctx.?, this);
- }
-
- this.allocator.free(this.leak());
- this.allocator.destroy(this);
- }
-};
-
-comptime {
- std.testing.refAllDecls(RefString);
-}
-
-// TODO: remove this abstraction and make it work directly with
-pub const ExternalBuffer = struct {
- global: *JSC.JSGlobalObject,
- ctx: ?*anyopaque = null,
- function: JSC.napi.napi_finalize = null,
- allocator: std.mem.Allocator,
- buf: []u8 = &[_]u8{},
-
- pub fn create(ctx: ?*anyopaque, buf: []u8, global: *JSC.JSGlobalObject, function: JSC.napi.napi_finalize, allocator: std.mem.Allocator) !*ExternalBuffer {
- var container = try allocator.create(ExternalBuffer);
- container.* = .{
- .ctx = ctx,
- .global = global,
- .allocator = allocator,
- .function = function,
- .buf = buf,
- };
- return container;
- }
-
- pub fn toJS(this: *ExternalBuffer, ctx: *JSC.JSGlobalObject) JSC.JSValue {
- return JSC.JSValue.createBufferWithCtx(ctx, this.buf, this.ctx, ExternalBuffer_deallocator);
- }
-
- pub fn toArrayBuffer(this: *ExternalBuffer, ctx: *JSC.JSGlobalObject) JSC.JSValue {
- return JSValue.c(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy(ctx.ref(), this.buf.ptr, this.buf.len, ExternalBuffer_deallocator, this, null));
- }
-};
-pub export fn ExternalBuffer_deallocator(bytes_: *anyopaque, ctx: *anyopaque) callconv(.C) void {
- var external: *ExternalBuffer = bun.cast(*ExternalBuffer, ctx);
- external.function.?(external.global, external.ctx, bytes_);
- const allocator = external.allocator;
- allocator.destroy(external);
-}
-
-pub export fn MarkedArrayBuffer_deallocator(bytes_: *anyopaque, _: *anyopaque) void {
- const mimalloc = @import("../../allocators/mimalloc.zig");
- // zig's memory allocator interface won't work here
- // mimalloc knows the size of things
- // but we don't
- mimalloc.mi_free(bytes_);
-}
-
-pub export fn BlobArrayBuffer_deallocator(_: *anyopaque, blob: *anyopaque) void {
- // zig's memory allocator interface won't work here
- // mimalloc knows the size of things
- // but we don't
- var store = bun.cast(*JSC.WebCore.Blob.Store, blob);
- store.deref();
-}
-
-pub fn castObj(obj: js.JSObjectRef, comptime Type: type) *Type {
- return JSPrivateDataPtr.from(js.JSObjectGetPrivate(obj)).as(Type);
-}
-
-const JSNode = @import("../../js_ast.zig").Macro.JSNode;
-const LazyPropertiesObject = @import("../../js_ast.zig").Macro.LazyPropertiesObject;
-const ModuleNamespace = @import("../../js_ast.zig").Macro.ModuleNamespace;
-const FetchTaskletContext = Fetch.FetchTasklet.FetchTaskletContext;
-const Expect = Test.Expect;
-const DescribeScope = Test.DescribeScope;
-const TestScope = Test.TestScope;
-const ExpectPrototype = Test.ExpectPrototype;
-const NodeFS = JSC.Node.NodeFS;
-const DirEnt = JSC.Node.DirEnt;
-const Stats = JSC.Node.Stats;
-const BigIntStats = JSC.Node.BigIntStats;
-const Transpiler = @import("./api/transpiler.zig");
-const TextEncoder = WebCore.TextEncoder;
-const TextDecoder = WebCore.TextDecoder;
-const TimeoutTask = JSC.BunTimer.Timeout.TimeoutTask;
-const HTMLRewriter = JSC.Cloudflare.HTMLRewriter;
-const Element = JSC.Cloudflare.Element;
-const Comment = JSC.Cloudflare.Comment;
-const TextChunk = JSC.Cloudflare.TextChunk;
-const DocType = JSC.Cloudflare.DocType;
-const EndTag = JSC.Cloudflare.EndTag;
-const DocEnd = JSC.Cloudflare.DocEnd;
-const AttributeIterator = JSC.Cloudflare.AttributeIterator;
-const Blob = JSC.WebCore.Blob;
-const Server = JSC.API.Server;
-const SSLServer = JSC.API.SSLServer;
-const DebugServer = JSC.API.DebugServer;
-const DebugSSLServer = JSC.API.DebugSSLServer;
-const SHA1 = JSC.API.Bun.Crypto.SHA1;
-const MD5 = JSC.API.Bun.Crypto.MD5;
-const MD4 = JSC.API.Bun.Crypto.MD4;
-const SHA224 = JSC.API.Bun.Crypto.SHA224;
-const SHA512 = JSC.API.Bun.Crypto.SHA512;
-const SHA384 = JSC.API.Bun.Crypto.SHA384;
-const SHA256 = JSC.API.Bun.Crypto.SHA256;
-const SHA512_256 = JSC.API.Bun.Crypto.SHA512_256;
-const MD5_SHA1 = JSC.API.Bun.Crypto.MD5_SHA1;
-const FFI = JSC.FFI;
-pub const JSPrivateDataPtr = TaggedPointerUnion(.{
- AttributeIterator,
- BigIntStats,
- Blob,
- Body,
- BuildError,
- Comment,
- DebugServer,
- DebugSSLServer,
- DescribeScope,
- DirEnt,
- DocEnd,
- DocType,
- Element,
- EndTag,
- Expect,
- ExpectPrototype,
- FetchEvent,
- FetchTaskletContext,
- HTMLRewriter,
- JSNode,
- LazyPropertiesObject,
- MD4,
- MD5_SHA1,
- MD5,
- ModuleNamespace,
- NodeFS,
- Request,
- ResolveError,
- Response,
- Router,
- Server,
- SHA1,
- SHA224,
- SHA256,
- SHA384,
- SHA512_256,
- SHA512,
- SSLServer,
- Stats,
- TextChunk,
- TextDecoder,
- TimeoutTask,
- Transpiler,
- FFI,
-});
-
-pub inline fn GetJSPrivateData(comptime Type: type, ref: js.JSObjectRef) ?*Type {
- return JSPrivateDataPtr.from(js.JSObjectGetPrivate(ref)).get(Type);
-}
-
-pub const JSPropertyNameIterator = struct {
- array: js.JSPropertyNameArrayRef,
- count: u32,
- i: u32 = 0,
-
- pub fn next(this: *JSPropertyNameIterator) ?js.JSStringRef {
- if (this.i >= this.count) return null;
- const i = this.i;
- this.i += 1;
-
- return js.JSPropertyNameArrayGetNameAtIndex(this.array, i);
- }
-};
-
-pub fn getterWrap(comptime Container: type, comptime name: string) GetterType(Container) {
- return struct {
- const FunctionType = @TypeOf(@field(Container, name));
- const FunctionTypeInfo: std.builtin.TypeInfo.Fn = @typeInfo(FunctionType).Fn;
- const ArgsTuple = std.meta.ArgsTuple(FunctionType);
-
- pub fn callback(
- this: *Container,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSStringRef,
- exception: js.ExceptionRef,
- ) js.JSObjectRef {
- const result: JSValue = if (comptime std.meta.fields(ArgsTuple).len == 1)
- @call(.{}, @field(Container, name), .{
- this,
- })
- else
- @call(.{}, @field(Container, name), .{ this, ctx.ptr() });
- if (!result.isUndefinedOrNull() and result.isError()) {
- exception.* = result.asObjectRef();
- return null;
- }
-
- return result.asObjectRef();
- }
- }.callback;
-}
-
-pub fn setterWrap(comptime Container: type, comptime name: string) SetterType(Container) {
- return struct {
- const FunctionType = @TypeOf(@field(Container, name));
- const FunctionTypeInfo: std.builtin.TypeInfo.Fn = @typeInfo(FunctionType).Fn;
-
- pub fn callback(
- this: *Container,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSStringRef,
- value: js.JSValueRef,
- exception: js.ExceptionRef,
- ) bool {
- @call(.{}, @field(Container, name), .{ this, JSC.JSValue.fromRef(value), exception, ctx.ptr() });
- return exception.* == null;
- }
- }.callback;
-}
-
-fn GetterType(comptime Container: type) type {
- return fn (
- this: *Container,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- _: js.JSStringRef,
- exception: js.ExceptionRef,
- ) js.JSObjectRef;
-}
-
-fn SetterType(comptime Container: type) type {
- return fn (
- this: *Container,
- ctx: js.JSContextRef,
- obj: js.JSObjectRef,
- prop: js.JSStringRef,
- value: js.JSValueRef,
- exception: js.ExceptionRef,
- ) bool;
-}
-
-fn MethodType(comptime Container: type, comptime has_container: bool) type {
- return fn (
- this: if (has_container) *Container else void,
- ctx: js.JSContextRef,
- thisObject: js.JSObjectRef,
- target: js.JSObjectRef,
- args: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSObjectRef;
-}
-
-pub fn wrapSync(
- comptime Container: type,
- comptime name: string,
-) MethodType(Container, true) {
- return wrap(Container, name, false);
-}
-
-pub fn wrapAsync(
- comptime Container: type,
- comptime name: string,
-) MethodType(Container, true) {
- return wrap(Container, name, true);
-}
-
-pub fn wrap(
- comptime Container: type,
- comptime name: string,
- comptime maybe_async: bool,
-) MethodType(Container, true) {
- return wrapWithHasContainer(Container, name, maybe_async, true, true);
-}
-
-pub fn wrapWithHasContainer(
- comptime Container: type,
- comptime name: string,
- comptime maybe_async: bool,
- comptime has_container: bool,
- comptime auto_protect: bool,
-) MethodType(Container, has_container) {
- return struct {
- const FunctionType = @TypeOf(@field(Container, name));
- const FunctionTypeInfo: std.builtin.TypeInfo.Fn = @typeInfo(FunctionType).Fn;
- const Args = std.meta.ArgsTuple(FunctionType);
- const eater = if (auto_protect) JSC.Node.ArgumentsSlice.protectEatNext else JSC.Node.ArgumentsSlice.nextEat;
-
- pub fn callback(
- this: if (has_container) *Container else void,
- ctx: js.JSContextRef,
- _: js.JSObjectRef,
- thisObject: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSObjectRef {
- var iter = JSC.Node.ArgumentsSlice.from(ctx.bunVM(), arguments);
- var args: Args = undefined;
-
- comptime var i: usize = 0;
- inline while (i < FunctionTypeInfo.args.len) : (i += 1) {
- const ArgType = comptime FunctionTypeInfo.args[i].arg_type.?;
-
- switch (comptime ArgType) {
- *Container => {
- args[i] = this;
- },
- *JSC.JSGlobalObject => {
- args[i] = ctx.ptr();
- },
- JSC.Node.StringOrBuffer => {
- const arg = iter.nextEat() orelse {
- exception.* = JSC.toInvalidArguments("expected string or buffer", .{}, ctx).asObjectRef();
- iter.deinit();
- return null;
- };
- args[i] = JSC.Node.StringOrBuffer.fromJS(ctx.ptr(), iter.arena.allocator(), arg, exception) orelse {
- exception.* = JSC.toInvalidArguments("expected string or buffer", .{}, ctx).asObjectRef();
- iter.deinit();
- return null;
- };
- },
- ?JSC.Node.StringOrBuffer => {
- if (iter.nextEat()) |arg| {
- args[i] = JSC.Node.StringOrBuffer.fromJS(ctx.ptr(), iter.arena.allocator(), arg, exception) orelse {
- exception.* = JSC.toInvalidArguments("expected string or buffer", .{}, ctx).asObjectRef();
- iter.deinit();
- return null;
- };
- } else {
- args[i] = null;
- }
- },
- JSC.ArrayBuffer => {
- if (iter.nextEat()) |arg| {
- args[i] = arg.asArrayBuffer(ctx.ptr()) orelse {
- exception.* = JSC.toInvalidArguments("expected TypedArray", .{}, ctx).asObjectRef();
- iter.deinit();
- return null;
- };
- } else {
- exception.* = JSC.toInvalidArguments("expected TypedArray", .{}, ctx).asObjectRef();
- iter.deinit();
- return null;
- }
- },
- ?JSC.ArrayBuffer => {
- if (iter.nextEat()) |arg| {
- args[i] = arg.asArrayBuffer(ctx.ptr()) orelse {
- exception.* = JSC.toInvalidArguments("expected TypedArray", .{}, ctx).asObjectRef();
- iter.deinit();
- return null;
- };
- } else {
- args[i] = null;
- }
- },
- ZigString => {
- var string_value = eater(&iter) orelse {
- JSC.throwInvalidArguments("Missing argument", .{}, ctx, exception);
- iter.deinit();
- return null;
- };
-
- if (string_value.isUndefinedOrNull()) {
- JSC.throwInvalidArguments("Expected string", .{}, ctx, exception);
- iter.deinit();
- return null;
- }
-
- args[i] = string_value.getZigString(ctx.ptr());
- },
- ?JSC.Cloudflare.ContentOptions => {
- if (iter.nextEat()) |content_arg| {
- if (content_arg.get(ctx.ptr(), "html")) |html_val| {
- args[i] = .{ .html = html_val.toBoolean() };
- }
- } else {
- args[i] = null;
- }
- },
- *Response => {
- args[i] = (eater(&iter) orelse {
- JSC.throwInvalidArguments("Missing Response object", .{}, ctx, exception);
- iter.deinit();
- return null;
- }).as(Response) orelse {
- JSC.throwInvalidArguments("Expected Response object", .{}, ctx, exception);
- iter.deinit();
- return null;
- };
- },
- *Request => {
- args[i] = (eater(&iter) orelse {
- JSC.throwInvalidArguments("Missing Request object", .{}, ctx, exception);
- iter.deinit();
- return null;
- }).as(Request) orelse {
- JSC.throwInvalidArguments("Expected Request object", .{}, ctx, exception);
- iter.deinit();
- return null;
- };
- },
- js.JSObjectRef => {
- args[i] = thisObject;
- if (!JSValue.fromRef(thisObject).isCell() or !JSValue.fromRef(thisObject).isObject()) {
- JSC.throwInvalidArguments("Expected object", .{}, ctx, exception);
- iter.deinit();
- return null;
- }
- },
- js.ExceptionRef => {
- args[i] = exception;
- },
- JSValue => {
- const val = eater(&iter) orelse {
- JSC.throwInvalidArguments("Missing argument", .{}, ctx, exception);
- iter.deinit();
- return null;
- };
- args[i] = val;
- },
- ?JSValue => {
- args[i] = eater(&iter);
- },
- else => @compileError("Unexpected Type " ++ @typeName(ArgType)),
- }
- }
-
- var result: JSValue = @call(.{}, @field(Container, name), args);
- if (!result.isEmptyOrUndefinedOrNull() and result.isError()) {
- exception.* = result.asObjectRef();
- iter.deinit();
- return null;
- }
-
- if (comptime maybe_async) {
- var vm = ctx.ptr().bunVM();
- vm.tick();
-
- var promise = JSC.JSInternalPromise.resolvedPromise(ctx.ptr(), result);
-
- switch (promise.status(ctx.ptr().vm())) {
- JSC.JSPromise.Status.Pending => {
- while (promise.status(ctx.ptr().vm()) == .Pending) {
- vm.tick();
- }
- result = promise.result(ctx.ptr().vm());
- },
- JSC.JSPromise.Status.Rejected => {
- result = promise.result(ctx.ptr().vm());
- exception.* = result.asObjectRef();
- },
- JSC.JSPromise.Status.Fulfilled => {
- result = promise.result(ctx.ptr().vm());
- },
- }
- }
-
- iter.deinit();
-
- return result.asObjectRef();
- }
- }.callback;
-}
-
-pub fn cachedBoundFunction(comptime name: [:0]const u8, comptime callback: anytype) (fn (
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
-) js.JSValueRef) {
- return struct {
- const name_ = name;
- pub fn call(
- arg2: js.JSContextRef,
- arg3: js.JSObjectRef,
- arg4: js.JSObjectRef,
- arg5: usize,
- arg6: [*c]const js.JSValueRef,
- arg7: js.ExceptionRef,
- ) callconv(.C) js.JSObjectRef {
- return callback(
- {},
- arg2,
- arg3,
- arg4,
- arg6[0..arg5],
- arg7,
- );
- }
-
- pub fn getter(
- _: void,
- ctx: js.JSContextRef,
- _: js.JSValueRef,
- _: js.JSStringRef,
- _: js.ExceptionRef,
- ) js.JSValueRef {
- const name_slice = std.mem.span(name_);
- var existing = ctx.ptr().getCachedObject(&ZigString.init(name_slice));
- if (existing.isEmpty()) {
- return ctx.ptr().putCachedObject(
- &ZigString.init(name_slice),
- JSValue.fromRef(JSC.C.JSObjectMakeFunctionWithCallback(ctx, JSC.C.JSStringCreateStatic(name_slice.ptr, name_slice.len), call)),
- ).asObjectRef();
- }
-
- return existing.asObjectRef();
- }
- }.getter;
-}