aboutsummaryrefslogtreecommitdiff
path: root/src/javascript/jsc/javascript.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/javascript/jsc/javascript.zig')
-rw-r--r--src/javascript/jsc/javascript.zig1411
1 files changed, 31 insertions, 1380 deletions
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index c8ce409af..51a287b27 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -16,33 +16,33 @@ usingnamespace @import("./node_env_buf_map.zig");
usingnamespace @import("./base.zig");
usingnamespace @import("./webcore/response.zig");
usingnamespace @import("./config.zig");
+usingnamespace @import("./bindings/exports.zig");
+usingnamespace @import("./bindings/bindings.zig");
+
+pub const GlobalClasses = [_]type{
+ Request.Class,
+ Response.Class,
+ Headers.Class,
+};
+
+pub const Module = struct {
+ reload_pending: bool = false,
+};
// If you read JavascriptCore/API/JSVirtualMachine.mm - https://github.com/WebKit/WebKit/blob/acff93fb303baa670c055cb24c2bad08691a01a0/Source/JavaScriptCore/API/JSVirtualMachine.mm#L101
// We can see that it's sort of like std.mem.Allocator but for JSGlobalContextRef, to support Automatic Reference Counting
// Its unavailable on Linux
pub const VirtualMachine = struct {
const RequireCacheType = std.AutoHashMap(u32, *Module);
- // root: js.JSGlobalContextRef,
- ctx: js.JSGlobalContextRef = undefined,
- group: js.JSContextGroupRef,
+ global: *JSGlobalObject,
allocator: *std.mem.Allocator,
- require_cache: RequireCacheType,
- node_module_list: ?*Module.NodeModuleList,
node_modules: ?*NodeModuleBundle = null,
- node_modules_ref: js.JSObjectRef = null,
- global: *GlobalObject,
bundler: Bundler,
- log: *logger.Log,
watcher: ?*http.Watcher = null,
-
- event_listeners: EventListenerMixin.Map,
-
- pub threadlocal var instance: *VirtualMachine = undefined;
-
- pub fn deinit(vm: *VirtualMachine) void {
- js.JSGlobalContextRelease(vm.ctx);
- js.JSContextGroupRelease(vm.group);
- }
+ console: ZigConsoleClient,
+ require_cache: RequireCacheType,
+ log: *logger.Log,
+ pub threadlocal var vm: *VirtualMachine = undefined;
pub fn init(
allocator: *std.mem.Allocator,
@@ -50,8 +50,6 @@ pub const VirtualMachine = struct {
existing_bundle: ?*NodeModuleBundle,
_log: ?*logger.Log,
) !*VirtualMachine {
- var group = js.JSContextGroupRetain(js.JSContextGroupCreate());
-
var log: *logger.Log = undefined;
if (_log) |__log| {
log = __log;
@@ -59,107 +57,40 @@ pub const VirtualMachine = struct {
log = try allocator.create(logger.Log);
}
- if (FeatureFlags.remote_inspector) {
- js.JSRemoteInspectorSetInspectionEnabledByDefault(true);
- }
-
- var vm = try allocator.create(VirtualMachine);
- var global = try allocator.create(GlobalObject);
- vm.* = .{
+ vm = try allocator.create(VirtualMachine);
+ vm.* = VirtualMachine{
+ .global = undefined,
.allocator = allocator,
+ .require_cache = RequireCacheType.init(allocator),
.bundler = try Bundler.init(
allocator,
log,
try configureTransformOptionsForSpeedy(allocator, _args),
existing_bundle,
),
- .node_module_list = null,
+ .console = ZigConsoleClient.init(Output.errorWriter(), Output.writer()),
+ .node_modules = existing_bundle,
.log = log,
- .group = group,
-
- .event_listeners = EventListenerMixin.Map.init(allocator),
-
- .require_cache = RequireCacheType.init(allocator),
- .global = global,
};
- vm.bundler.configureLinker();
-
- global.* = GlobalObject{ .vm = vm };
- try vm.global.boot();
- vm.ctx = vm.global.ctx;
- Properties.init();
- Module.boot(vm);
-
- if (vm.bundler.options.node_modules_bundle) |bundle| {
- vm.node_modules = bundle;
- vm.node_module_list = try allocator.create(Module.NodeModuleList);
- try Module.NodeModuleList.create(vm, bundle, vm.node_module_list.?);
- vm.global.ctx = vm.node_module_list.?.bundle_ctx;
+ var global_classes: [GlobalClasses.len]js.JSClassRef = undefined;
+ inline for (GlobalClasses) |Class, i| {
+ global_classes[i] = Class.get().*;
}
+ vm.global = ZigGlobalObject.create(
+ &global_classes,
+ @intCast(i32, global_classes.len),
+ &vm.console,
+ );
return vm;
}
-
- pub fn require(
- vm: *VirtualMachine,
- ctx: js.JSContextRef,
- source_dir: string,
- import_path: string,
- exception: js.ExceptionRef,
- ) js.JSObjectRef {
- if (vm.bundler.linker.resolver.resolve(source_dir, import_path, .require)) |resolved| {
- var load_result = Module.loadFromResolveResult(vm, ctx, resolved, exception) catch |err| {
- return null;
- };
-
- switch (load_result) {
- .Module => |new_module| {
- return new_module.internalGetExports(js.JSContextGetGlobalContext(ctx));
- },
- .Path => |path| {
- return js.JSValueMakeString(ctx, js.JSStringCreateWithUTF8CString(path.text.ptr));
- },
- }
- } else |err| {
- Output.prettyErrorln(
- "<r><red>RequireError<r>: Failed to load module <b>\"{s}\"<r> at \"{s}\": <red>{s}<r>",
- .{ import_path, source_dir, @errorName(err) },
- );
- Output.flush();
- JSError(
- getAllocator(ctx),
- "{s}: failed to load module \"{s}\" from \"{s}\"",
- .{
- @errorName(err),
- import_path,
- source_dir,
- },
- ctx,
- exception,
- );
- return null;
- }
- }
};
pub const Object = struct {
ref: js.jsObjectRef,
};
-pub const String = struct {
- ref: js.JSStringRef,
- len: usize,
-
- pub fn chars(this: *const String) []const js.JSChar {
- return js.JSStringGetCharactersPtr(this.ref)[0..js.JSStringGetLength(this.ref)];
- }
-
- pub fn eql(this: *const String, str: [*c]const u8) bool {
- return str.len == this.len and js.JSStringIsEqualToUTF8CString(this, str);
- }
-};
-
const GetterFn = fn (
this: anytype,
ctx: js.JSContextRef,
@@ -182,1071 +113,6 @@ const JSProp = struct {
ro: bool = false,
};
-pub const Module = struct {
- path: Fs.Path,
-
- ref: js.JSObjectRef,
-
- id: js.JSValueRef = null,
- exports: js.JSValueRef = null,
-
- vm: *VirtualMachine,
- require_func: js.JSObjectRef = null,
- loaded: bool = false,
- exports_function: js.JSValueRef = null,
-
- // When the Watcher detects the source file changed, we bust the require cache
- // However, we want to lazily bust the require cache.
- // We don't want to actually reload the references until the code is next executed
- // reload_pending should not be applied to bundled modules
- reload_pending: bool = false,
-
- pub const NodeModuleList = struct {
- tempbuf: []u8,
- property_names: [*]u8,
- module_property_map: []u64,
- static_functions: [1]js.JSStaticFunction,
- property_getters: []js.JSObjectRef,
-
- node_module_global_class: js.JSClassRef,
- node_module_global_class_def: js.JSClassDefinition,
- vm: *VirtualMachine,
-
- // This is probably a mistake.
- bundle_ctx: js.JSGlobalContextRef,
-
- require_cache: []?*Module,
-
- exports_function_call: js.JSObjectRef = null,
- console: js.JSObjectRef = null,
-
- const RequireBundleClassName = "requireFromBundle";
- var require_bundle_class_def: js.JSClassDefinition = undefined;
- var require_bundle_class_ref: js.JSClassRef = undefined;
- var require_bundle_class_loaded = false;
-
- pub fn loadBundledModuleById(node_module_list: *NodeModuleList, id: u32, call_ctx: js.JSContextRef) !*Module {
- if (node_module_list.require_cache[id]) |mod| {
- return mod;
- }
-
- var module = try node_module_list.vm.allocator.create(Module);
- node_module_list.require_cache[id] = module;
- errdefer node_module_list.vm.allocator.destroy(module);
-
- try Module.NodeModuleList.Instance.evalBundledModule(
- module,
- node_module_list.vm.allocator,
- node_module_list.vm,
- node_module_list,
- id,
- call_ctx,
- );
-
- return module;
- }
-
- pub const Instance = struct {
- module: Module,
- node_module_list: *NodeModuleList,
-
- threadlocal var source_code_buffer: MutableString = undefined;
- threadlocal var source_code_buffer_loaded = false;
-
- pub fn evalBundledModule(
- module: *Module,
- allocator: *std.mem.Allocator,
- vm: *VirtualMachine,
- node_module_list: *NodeModuleList,
- id: u32,
- call_ctx: js.JSContextRef,
- ) !void {
- const bundled_module = &vm.node_modules.?.bundle.modules[id];
- const total_length = bundled_module.code.length + 1;
- if (!source_code_buffer_loaded) {
- source_code_buffer = try MutableString.init(allocator, total_length);
- source_code_buffer_loaded = true;
- } else {
- source_code_buffer.reset();
- source_code_buffer.growIfNeeded(total_length) catch {};
- }
-
- source_code_buffer.list.resize(allocator, total_length) catch unreachable;
-
- var node_module_file = std.fs.File{ .handle = vm.node_modules.?.fd };
- const read = try node_module_file.pread(source_code_buffer.list.items, bundled_module.code.offset);
- var buf = source_code_buffer.list.items[0..read];
-
- const bundled_package = &vm.node_modules.?.bundle.packages[bundled_module.package_id];
- // We want linear because we expect it to virtually always be at 0
- // However, out of caution we check.
-
- var start_at: usize = std.mem.indexOfPosLinear(u8, buf, 0, "export var $") orelse return error.FailedCorruptNodeModuleMissingExport;
- start_at += "export var $".len;
- // export var $fooo = $$m("packageName", "id", (module, exports) => {
- // ^
- start_at = std.mem.indexOfPosLinear(
- u8,
- buf,
- start_at,
- "\",",
- ) orelse return error.FailedCorruptNodeModuleMissingModuleWrapper;
- start_at += 1;
-
- // export var $fooo = $$m("packageName", "id", (module, exports) => {
- // ^
- start_at = std.mem.indexOfPosLinear(
- u8,
- buf,
- start_at,
- "\",",
- ) orelse return error.FailedCorruptNodeModuleMissingModuleWrapper;
- start_at += 1;
- start_at = std.mem.indexOfPosLinear(
- u8,
- buf,
- start_at,
- "=>",
- ) orelse return error.FailedCorruptNodeModuleMissingModuleWrapper;
- start_at += 2;
- // (module, exports) => {
- // ^
- start_at = std.mem.indexOfPosLinear(
- u8,
- buf,
- start_at,
- "{",
- ) orelse return error.FailedCorruptNodeModuleMissingModuleWrapper;
- start_at += 1;
- // (module, exports) => {
- //
- // ^
- var curr_buf = buf[start_at..];
- curr_buf = curr_buf[0 .. std.mem.lastIndexOfScalar(u8, curr_buf, ';') orelse return error.FailedCorruptNodeModuleMissingModuleWrapper];
- curr_buf = curr_buf[0 .. std.mem.lastIndexOfScalar(u8, curr_buf, ')') orelse return error.FailedCorruptNodeModuleMissingModuleWrapper];
- curr_buf = curr_buf[0 .. std.mem.lastIndexOfScalar(u8, curr_buf, '}') orelse return error.FailedCorruptNodeModuleMissingModuleWrapper];
- curr_buf.ptr[curr_buf.len] = 0;
- var source_buf = curr_buf.ptr[0..curr_buf.len :0];
- var source_url_buf = try std.fmt.allocPrint(
- allocator,
- "{s}/{s}",
- .{
- vm.node_modules.?.str(bundled_package.name),
- vm.node_modules.?.str(bundled_module.path),
- },
- );
- errdefer allocator.free(source_url_buf);
-
- var exception: js.JSValueRef = null;
- try Module.load(
- module,
- vm,
- allocator,
- vm.log,
- source_buf,
- Fs.Path.initWithPretty(source_url_buf, source_url_buf),
- node_module_list.bundle_ctx,
- call_ctx,
- call_ctx,
- &exception,
- false,
- );
- }
- };
-
- pub const RequireBundledModule = struct {
- id: u32,
- list: *NodeModuleList,
- };
-
- // key: hash of module.path
- // value: index of module
- const ModuleIDMap = hash_map.AutoHashMap(u64, u32);
-
- pub fn initializeGlobal(ctx: JSContextRef, obj: JSObjectRef) callconv(.C) void {}
-
- pub fn getRequireFromBundleProperty(
- ctx: js.JSContextRef,
- thisObject: js.JSObjectRef,
- prop: js.JSStringRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- var thisPtr = js.JSObjectGetPrivate(thisObject);
- if (thisPtr == null) return null;
-
- var this = @ptrCast(
- *NodeModuleList,
- @alignCast(
- @alignOf(
- *NodeModuleList,
- ),
- thisPtr.?,
- ),
- );
-
- std.mem.set(u8, this.tempbuf, 0);
- const size = js.JSStringGetUTF8CString(prop, this.tempbuf.ptr, this.tempbuf.len);
- const key = std.hash.Wyhash.hash(0, this.tempbuf);
- const id = @intCast(u32, std.mem.indexOfScalar(u64, this.module_property_map, key) orelse return null);
-
- if (this.property_getters[id] == null) {
- if (!require_bundle_class_loaded) {
- require_bundle_class_def = js.kJSClassDefinitionEmpty;
- require_bundle_class_def.className = RequireBundleClassName[0.. :0];
- require_bundle_class_def.callAsFunction = To.JS.Callback(RequireBundledModule, requireBundledModule).rfn;
- require_bundle_class_ref = js.JSClassRetain(js.JSClassCreate(&require_bundle_class_def));
- require_bundle_class_loaded = true;
- }
-
- // TODO: remove this allocation by ptr casting
- var require_from_bundle = this.vm.allocator.create(RequireBundledModule) catch unreachable;
- require_from_bundle.* = RequireBundledModule{
- .list = this,
- .id = id,
- };
- this.property_getters[id] = js.JSObjectMake(this.bundle_ctx, require_bundle_class_ref, require_from_bundle);
- js.JSValueProtect(this.bundle_ctx, this.property_getters[id]);
- }
-
- return this.property_getters[id];
- }
-
- // this is what $aosdi123() inside a node_modules.jsb calls
- pub fn requireBundledModule(
- obj: *RequireBundledModule,
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- thisObject: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- const bundle = &obj.list.vm.node_modules.?.bundle;
- const bundled_module = &bundle.modules[obj.id];
- const bundled_pkg = &bundle.packages[bundled_module.package_id];
- var module = loadBundledModuleById(obj.list, obj.id, obj.list.bundle_ctx) catch |err| {
- Output.prettyErrorln("<r><red>RequireError<r>: <b>{s}<r> in \"<cyan>{s}/{s}<r>\"", .{
- @errorName(err),
- obj.list.vm.node_modules.?.str(bundled_pkg.name),
- obj.list.vm.node_modules.?.str(bundled_module.path),
- });
- var message = std.fmt.allocPrintZ(obj.list.vm.allocator, "RequireError: {s} in \"{s}/{s}\"", .{
- @errorName(err),
- obj.list.vm.node_modules.?.str(bundled_pkg.name),
- obj.list.vm.node_modules.?.str(bundled_module.path),
- }) catch unreachable;
- defer Output.flush();
- defer obj.list.vm.allocator.free(message);
- var args = obj.list.vm.allocator.alloc(js.JSStringRef, 1) catch unreachable;
- args[0] = js.JSStringCreateWithUTF8CString(message.ptr);
- exception.* = js.JSObjectMakeError(ctx, 1, args.ptr, null);
- return js.JSValueMakeUndefined(ctx);
- };
-
- return module.internalGetExports(js.JSContextGetGlobalContext(ctx));
- }
-
- pub fn getConsole(
- ctx: js.JSContextRef,
- thisObject: js.JSObjectRef,
- prop: js.JSStringRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- var this = @ptrCast(
- *NodeModuleList,
- @alignCast(@alignOf(*NodeModuleList), js.JSObjectGetPrivate(thisObject) orelse return null),
- );
-
- if (this.console == null) {
- this.console = js.JSObjectMake(js.JSContextGetGlobalContext(ctx), GlobalObject.ConsoleClass.get().*, this.vm.global);
- js.JSValueProtect(ctx, this.console);
- }
-
- return this.console;
- }
-
- pub fn create(vm: *VirtualMachine, bundle: *const NodeModuleBundle, node_module_list: *NodeModuleList) !void {
- var size: usize = 0;
- var longest_size: usize = 0;
- for (bundle.bundle.modules) |module, i| {
- // Add one for null-terminated string offset
- const this_size = std.fmt.count(
- "${x}" ++ "\\x0",
- .{
- module.id,
- },
- );
- size += this_size;
- longest_size = std.math.max(this_size, longest_size);
- }
- var static_properties = try vm.allocator.alloc(js.JSStaticValue, bundle.bundle.modules.len + 1 + GlobalObject.GlobalClass.static_value_count);
- var copied_static_values = static_properties[bundle.bundle.modules.len..];
- copied_static_values = copied_static_values[0 .. copied_static_values.len - 1];
-
- copied_static_values[0] = js.JSStaticValue{
- .name = Properties.UTF8.console[0.. :0],
- .getProperty = getConsole,
- .setProperty = null,
- .attributes = .kJSPropertyAttributeNone,
- };
-
- copied_static_values[1] = js.JSStaticValue{
- .name = Response.Class.definition.className,
- .getProperty = Response.Class.RawGetter(NodeModuleList).getter,
- .setProperty = null,
- .attributes = .kJSPropertyAttributeNone,
- };
-
- copied_static_values[2] = js.JSStaticValue{
- .name = Headers.Class.definition.className,
- .getProperty = Headers.Class.RawGetter(NodeModuleList).getter,
- .setProperty = null,
- .attributes = .kJSPropertyAttributeNone,
- };
-
- copied_static_values[3] = js.JSStaticValue{
- .name = Request.Class.definition.className,
- .getProperty = Request.Class.RawGetter(NodeModuleList).getter,
- .setProperty = null,
- .attributes = .kJSPropertyAttributeNone,
- };
-
- // copied_static_values must match GlobalObject.GlobalClass.static_value_count
- std.debug.assert(copied_static_values.len == 4);
-
- static_properties[static_properties.len - 1] = std.mem.zeroes(js.JSStaticValue);
- var utf8 = try vm.allocator.alloc(u8, size + std.math.max(longest_size, 32));
- std.mem.set(u8, utf8, 0);
- var tempbuf = utf8[size..];
-
- var names_buf = utf8[0..size];
- var module_property_map = try vm.allocator.alloc(u64, bundle.bundle.modules.len);
-
- for (bundle.bundle.modules) |module, i| {
- var hasher = std.hash.Wyhash.init(0);
-
- const hash = @truncate(
- u32,
- module.id,
- );
-
- // The variable name is the hash of the module path
- var name = std.fmt.bufPrint(names_buf, "${x}", .{hash}) catch unreachable;
- std.mem.set(u8, tempbuf, 0);
- std.mem.copy(u8, tempbuf, name);
- name.ptr[name.len] = 0;
-
- // But we don't store that for the hash map. Instead, we store the hash of name.
- // This lets us avoid storing pointers to the name in the hash table, so if we free it later
- // or something it won't cause issues.
-
- module_property_map[i] = std.hash.Wyhash.hash(0, tempbuf);
- static_properties[i] = js.JSStaticValue{
- .name = name.ptr,
- .getProperty = getRequireFromBundleProperty,
- .setProperty = null,
- .attributes = .kJSPropertyAttributeReadOnly,
- };
- names_buf = names_buf[name.len + 1 ..];
- }
-
- var node_module_global_class_def = js.kJSClassDefinitionEmpty;
- node_module_global_class_def.staticValues = static_properties.ptr;
- node_module_global_class_def.className = node_module_global_class_name[0.. :0];
- node_module_global_class_def.parentClass = GlobalObject.GlobalClass.get().*;
-
- var property_getters = try vm.allocator.alloc(js.JSObjectRef, bundle.bundle.modules.len);
- std.mem.set(js.JSObjectRef, property_getters, null);
-
- node_module_list.* = NodeModuleList{
- .module_property_map = module_property_map,
- .node_module_global_class_def = node_module_global_class_def,
- .vm = vm,
- .tempbuf = tempbuf,
- .property_names = utf8.ptr,
- .bundle_ctx = undefined,
- .property_getters = property_getters,
- .node_module_global_class = undefined,
- .static_functions = undefined,
- .require_cache = try vm.allocator.alloc(?*Module, bundle.bundle.modules.len),
- };
-
- std.mem.set(?*Module, node_module_list.require_cache, null);
-
- // node_module_list.staticFunctions[0] = js.JSStaticFunction{
- // .name = Properties.UTF8.initialize_bundled_module[0.. :0],
- // .callAsFunction = To.JS.Callback(NodeModuleList, initializeNodeModule),
- // };
- // node_module_global_class_def.staticFunctions = &node_module_list.static_functions;
- node_module_list.node_module_global_class = js.JSClassRetain(js.JSClassCreate(&node_module_list.node_module_global_class_def));
- node_module_list.bundle_ctx = js.JSGlobalContextRetain(js.JSGlobalContextCreateInGroup(vm.group, node_module_list.node_module_global_class));
- _ = js.JSObjectSetPrivate(js.JSContextGetGlobalObject(node_module_list.bundle_ctx), node_module_list);
- }
- };
- pub const node_module_global_class_name = "NodeModuleGlobal";
-
- threadlocal var require_buf: MutableString = undefined;
- threadlocal var require_buf_loaded: bool = false;
-
- pub fn callExportsAsFunction(
- this: *Module,
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- thisObject: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- if (js.JSObjectIsFunction(ctx, this.exports_function)) {
- return js.JSObjectCallAsFunction(ctx, this.exports_function, this.ref, arguments.len, arguments.ptr, exception);
- }
-
- return this.exports;
- }
-
- pub fn require(
- this: *Module,
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- thisObject: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- if (arguments.len != 1 or !js.JSValueIsString(ctx, arguments[0]) or js.JSStringGetMaximumUTF8CStringSize(arguments[0]) == 0) {
- defer Output.flush();
- if (arguments.len == 0) {
- Output.prettyErrorln("<r><red>error<r>: <b>require<r> needs a string, e.g. require(\"left-pad\")", .{});
- } else if (arguments.len > 1) {
- Output.prettyErrorln("<r><red>error<r>: <b>require<r> only accepts one argument and it must be a string, e.g. require(\"left-pad\")", .{});
- } else if (!js.JSValueIsString(ctx, arguments[0])) {
- Output.prettyErrorln("<r><red>error<r>: <b>require<r> only supports a string, e.g. require(\"left-pad\")", .{});
- } else {
- Output.prettyErrorln("<r><red>error<r>: <b>require(\"\")<r> string cannot be empty.", .{});
- }
- exception.* = js.JSObjectMakeError(ctx, 0, null, null);
- return null;
- }
-
- const len = js.JSStringGetLength(arguments[0]);
-
- if (!require_buf_loaded) {
- require_buf = MutableString.init(this.vm.allocator, len + 1) catch unreachable;
- require_buf_loaded = true;
- } else {
- require_buf.reset();
- require_buf.growIfNeeded(len + 1) catch {};
- }
-
- require_buf.list.resize(this.vm.allocator, len + 1) catch unreachable;
-
- // var require_buf_ = this.vm.allocator.alloc(u8, len + 1) catch unreachable;
- // var end = js.JSStringGetUTF8CString(arguments[0], require_buf_.ptr, require_buf_.len);
- var end = js.JSStringGetUTF8CString(arguments[0], require_buf.list.items.ptr, require_buf.list.items.len);
- var import_path = require_buf.list.items[0 .. end - 1];
- var module = this;
-
- if (RuntimeImports.resolve(ctx, import_path)) |ref| {
- return ref;
- }
-
- return this.vm.require(ctx, module.path.name.dirWithTrailingSlash(), import_path, exception);
- }
-
- pub fn requireFirst(
- this: *Module,
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- thisObject: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- if (arguments.len == 0 or js.JSStringGetMaximumUTF8CStringSize(arguments[0]) == 0) {
- defer Output.flush();
- if (arguments.len == 0) {
- Output.prettyErrorln("<r><red>error<r>: <b>requireFirst<r> needs a string, e.g. requireFirst(\"left-pad\")", .{});
- } else {
- Output.prettyErrorln("<r><red>error<r>: <b>requireFirst(\"\")<r> string cannot be empty.", .{});
- }
- return null;
- }
-
- var module = this;
-
- var total_len: usize = 0;
- for (arguments) |argument| {
- const len = js.JSStringGetLength(argument);
-
- if (!require_buf_loaded) {
- require_buf = MutableString.init(this.vm.allocator, len + 1) catch unreachable;
- require_buf_loaded = true;
- } else {
- require_buf.reset();
- require_buf.growIfNeeded(len + 1) catch {};
- }
-
- require_buf.list.resize(this.vm.allocator, len + 1) catch unreachable;
-
- const end = js.JSStringGetUTF8CString(argument, require_buf.list.items.ptr, require_buf.list.items.len);
- total_len += end;
- const import_path = require_buf.list.items[0 .. end - 1];
-
- if (this.vm.bundler.linker.resolver.resolve(module.path.name.dirWithTrailingSlash(), import_path, .require)) |resolved| {
- var load_result = Module.loadFromResolveResult(this.vm, ctx, resolved, exception) catch |err| {
- return null;
- };
-
- switch (load_result) {
- .Module => |new_module| {
- // if (isDebug) {
- // Output.prettyln(
- // "Input: {s}\nOutput: {s}",
- // .{ import_path, load_result.Module.path.text },
- // );
- // Output.flush();
- // }
- return new_module.internalGetExports(js.JSContextGetGlobalContext(ctx));
- },
- .Path => |path| {
- return js.JSStringCreateWithUTF8CString(path.text.ptr);
- },
- }
- } else |err| {
- switch (err) {
- error.ModuleNotFound => {},
- else => {
- JSError(
- getAllocator(ctx),
- "{s}: failed to resolve module \"{s}\" from \"{s}\"",
- .{
- @errorName(err),
- import_path,
- module.path.name.dirWithTrailingSlash(),
- },
- ctx,
- exception,
- );
- return null;
- },
- }
- }
- }
-
- require_buf.reset();
- require_buf.growIfNeeded(total_len) catch {};
- var used_len: usize = 0;
- var remainder = require_buf.list.items;
- for (arguments) |argument| {
- const end = js.JSStringGetUTF8CString(argument, remainder.ptr, total_len - used_len);
- used_len += end;
- remainder[end - 1] = ',';
- remainder = remainder[end..];
- }
-
- // If we get this far, it means there were no matches
- JSError(
- getAllocator(ctx),
- "RequireError: failed to resolve modules \"{s}\" from \"{s}\"",
- .{
- require_buf.list.items[0..used_len],
- module.path.name.dirWithTrailingSlash(),
- },
- ctx,
- exception,
- );
- return null;
- }
-
- pub const ModuleClass = NewClass(
- Module,
- .{ .name = Properties.UTF8.module },
- .{
- .@"require" = require,
- .@"requireFirst" = requireFirst,
- },
- .{
- .@"id" = .{
- .get = getId,
- .ro = true,
- },
- .@"loaded" = .{
- .get = getLoaded,
- .ro = true,
- },
- .@"exports" = .{
- .get = getExports,
- .set = setExports,
- .ro = false,
- },
- },
- );
-
- const ExportsClassName = "module.exports";
- var ExportsClass: js.JSClassDefinition = undefined;
- var exports_class_ref: js.JSClassRef = undefined;
-
- pub fn boot(vm: *VirtualMachine) void {
- ExportsClass = std.mem.zeroes(js.JSClassDefinition);
- ExportsClass.className = ExportsClassName[0.. :0];
- ExportsClass.callAsFunction = To.JS.Callback(Module, callExportsAsFunction).rfn;
- // ExportsClass.callAsConstructor = To.JS.Callback(Module, callExportsAsConstructor);
-
- exports_class_ref = js.JSClassRetain(js.JSClassCreate(&ExportsClass));
- _ = Module.ModuleClass.get().*;
- }
-
- pub const LoadResult = union(Tag) {
- Module: *Module,
- Path: Fs.Path,
-
- pub const Tag = enum {
- Module,
- Path,
- };
- };
-
- threadlocal var source_code_printer: js_printer.BufferPrinter = undefined;
- threadlocal var source_code_printer_loaded: bool = false;
- var require_module_params: [3]js.JSStringRef = undefined;
- var require_module_params_loaded: bool = false;
- threadlocal var module_wrapper_params: [2]js.JSStringRef = undefined;
- threadlocal var module_wrapper_loaded = false;
-
- pub fn load(
- module: *Module,
- vm: *VirtualMachine,
- allocator: *std.mem.Allocator,
- log: *logger.Log,
- source: string,
- path: Fs.Path,
- global_ctx: js.JSContextRef,
- call_ctx: js.JSContextRef,
- function_ctx: js.JSContextRef,
- exception: js.ExceptionRef,
- comptime is_reload: bool,
- ) !void {
- var source_code_ref = js.JSStringCreateStatic(source.ptr, source.len - 1);
- var source_url_raw = try std.fmt.allocPrintZ(allocator, "file://{s}", .{path.text});
- var source_url = js.JSStringCreateStatic(source_url_raw.ptr, source_url_raw.len);
-
- if (FeatureFlags.remote_inspector) {
- js.JSGlobalContextSetName(js.JSContextGetGlobalContext(global_ctx), source_url);
- }
-
- if (isDebug) {
- Output.print("// {s}\n{s}", .{ path.pretty, source });
- Output.flush();
- }
-
- if (comptime !is_reload) {
- module.* = Module{
- .path = path,
- .ref = undefined,
- .vm = vm,
- };
- module.ref = js.JSObjectMake(global_ctx, Module.ModuleClass.get().*, module);
- js.JSValueProtect(global_ctx, module.ref);
- } else {
- js.JSValueUnprotect(global_ctx, module.exports.?);
- }
-
- // if (!module_wrapper_loaded) {
- module_wrapper_params[0] = js.JSStringCreateStatic(Properties.UTF8.module.ptr, Properties.UTF8.module.len);
- module_wrapper_params[1] = js.JSStringCreateStatic(Properties.UTF8.exports.ptr, Properties.UTF8.exports.len);
- // module_wrapper_loaded = true;
- // }
-
- var module_wrapper_args: [2]js.JSValueRef = undefined;
- module_wrapper_args[0] = module.ref;
- module_wrapper_args[1] = module.internalGetExports(global_ctx);
- js.JSValueProtect(global_ctx, module_wrapper_args[1]);
-
- var except: js.JSValueRef = null;
- go: {
- var commonjs_wrapper = js.JSObjectMakeFunction(
- global_ctx,
- null,
- @truncate(c_uint, module_wrapper_params.len),
- &module_wrapper_params,
- source_code_ref,
- source_url,
- 1,
- &except,
- );
- js.JSValueProtect(global_ctx, commonjs_wrapper);
- if (except != null) {
- break :go;
- }
-
- // var module = {exports: {}}; ((module, exports) => {
- _ = js.JSObjectCallAsFunction(call_ctx, commonjs_wrapper, null, 2, &module_wrapper_args, &except);
- // module.exports = exports;
- // })(module, module.exports);
-
- // module.exports = module_wrapper_args[1];
-
- js.JSValueUnprotect(global_ctx, commonjs_wrapper);
- }
-
- if (except != null) {
- var message = js.JSValueToStringCopy(function_ctx, except.?, null);
- defer js.JSStringRelease(message);
- var message_str_size = js.JSStringGetMaximumUTF8CStringSize(message);
- var message_str_buf = try allocator.alloc(u8, message_str_size);
- defer allocator.free(message_str_buf);
- var message_str_read = js.JSStringGetUTF8CString(message, message_str_buf.ptr, message_str_size);
- defer Output.flush();
- log.addErrorFmt(null, logger.Loc.Empty, allocator, "Error loading \"{s}\":\n{s}", .{
- path.pretty,
- message_str_buf[0..message_str_read],
- }) catch {};
- Output.prettyErrorln("<r>{s}\n--<r><red>error<r> loading <cyan>\"{s}\"<r>--", .{
- message_str_buf[0..message_str_read],
- path.pretty,
- });
- return error.FailedException;
- }
-
- module.loaded = true;
- }
-
- pub fn loadFromResolveResult(
- vm: *VirtualMachine,
- ctx: js.JSContextRef,
- resolved: resolver.Result,
- exception: js.ExceptionRef,
- ) !LoadResult {
- const hash = http.Watcher.getHash(resolved.path_pair.primary.text);
- var reload_pending = false;
- if (vm.require_cache.get(hash)) |mod| {
- // require_cache should only contain local modules, not bundled ones.
- // so we don't need to check for node_modlues here
- reload_pending = mod.reload_pending;
-
- if (!reload_pending) {
- return LoadResult{ .Module = mod };
- }
- }
-
- const path = resolved.path_pair.primary;
- const loader: options.Loader = brk: {
- if (resolved.is_external) {
- break :brk options.Loader.file;
- }
-
- break :brk vm.bundler.options.loaders.get(path.name.ext) orelse .file;
- };
-
- switch (loader) {
- .js,
- .jsx,
- .ts,
- .tsx,
- .json,
- => {
- if (vm.node_modules) |node_modules| {
- const package_json_ = resolved.package_json orelse brk: {
- // package_json is sometimes null when we're loading as an absolute path
- if (resolved.isLikelyNodeModule()) {
- break :brk vm.bundler.resolver.packageJSONForResolvedNodeModule(&resolved);
- }
- break :brk null;
- };
-
- if (package_json_) |package_json| {
- if (package_json.hash > 0) {
- if (node_modules.getPackageIDByName(package_json.name)) |possible_package_ids| {
- const package_id: ?u32 = brk: {
- for (possible_package_ids) |pid| {
- const pkg = node_modules.bundle.packages[pid];
- if (pkg.hash == package_json.hash) {
- break :brk pid;
- }
- }
-
- break :brk null;
- };
-
- if (package_id) |pid| {
- const package_relative_path = vm.bundler.fs.relative(
- package_json.source.path.name.dirWithTrailingSlash(),
- path.text,
- );
-
- if (node_modules.findModuleIDInPackage(
- &node_modules.bundle.packages[pid],
- package_relative_path,
- )) |id| {
- var list = vm.node_module_list.?;
- return LoadResult{ .Module = try list.loadBundledModuleById(id + node_modules.bundle.packages[pid].modules_offset, ctx) };
- }
- }
- }
- }
- }
- }
-
- vm.bundler.resetStore();
- var fd: ?StoredFileDescriptorType = null;
-
- if (vm.watcher) |watcher| {
- if (watcher.indexOf(hash)) |index| {
- fd = watcher.watchlist.items(.fd)[index];
- }
- }
-
- var parse_result = vm.bundler.parse(
- vm.bundler.allocator,
- path,
- loader,
- resolved.dirname_fd,
- fd,
- hash,
- ) orelse {
- return error.ParseError;
- };
-
- if (!source_code_printer_loaded) {
- var writer = try js_printer.BufferWriter.init(vm.allocator);
- source_code_printer = js_printer.BufferPrinter.init(writer);
- source_code_printer.ctx.append_null_byte = true;
-
- source_code_printer_loaded = true;
- }
-
- source_code_printer.ctx.reset();
-
- // We skip the linker here.
- // var old_linker_allocator = vm.bundler.linker.allocator;
- // defer vm.bundler.linker.allocator = old_linker_allocator;
- // vm.bundler.linker.allocator = vm.allocator;
- // // Always use absolute paths
- // // This makes the resolver faster
- // try vm.bundler.linker.link(
- // Fs.Path.init(path.text),
- // &parse_result,
- // .absolute_path,
- // );
-
- var written = try vm.bundler.print(
- parse_result,
- @TypeOf(&source_code_printer),
- &source_code_printer,
- .speedy,
- );
-
- if (written == 0) {
- return error.PrintingErrorWriteFailed;
- }
- var module: *Module = undefined;
-
- if (reload_pending) {
- module = vm.require_cache.get(hash).?;
- } else {
- module = try vm.allocator.create(Module);
- try vm.require_cache.put(hash, module);
- }
-
- errdefer {
- if (!reload_pending) {
- vm.allocator.destroy(module);
- }
- }
-
- if (reload_pending) {
- try Module.load(
- module,
- vm,
- vm.allocator,
- vm.log,
- source_code_printer.ctx.written,
- path,
- js.JSContextGetGlobalContext(ctx),
- ctx,
- ctx,
- exception,
- true,
- );
- } else {
- try Module.load(
- module,
- vm,
- vm.allocator,
- vm.log,
- source_code_printer.ctx.written,
- path,
- js.JSContextGetGlobalContext(ctx),
- ctx,
- ctx,
- exception,
- false,
- );
- }
-
- return LoadResult{ .Module = module };
- },
-
- // Replace imports to non-executables with paths to those files.
- // In SSR or on web, these become URLs.
- // Otherwise, absolute file paths.
- else => {
- switch (vm.bundler.options.import_path_format) {
- .absolute_path => {
- return LoadResult{ .Path = path };
- },
- .absolute_url => {
- var fs = vm.bundler.fs;
-
- var base = fs.relativeTo(path.text);
- if (strings.lastIndexOfChar(base, '.')) |dot| {
- base = base[0..dot];
- }
-
- var dirname = std.fs.path.dirname(base) orelse "";
-
- var basename = std.fs.path.basename(base);
-
- const needs_slash = dirname.len > 0 and dirname[dirname.len - 1] != '/';
-
- if (needs_slash) {
- const absolute_url = try std.fmt.allocPrintZ(
- vm.allocator,
- "{s}{s}/{s}{s}",
- .{
- vm.bundler.options.public_url,
- dirname,
- basename,
- path.name.ext,
- },
- );
-
- return LoadResult{
- .Path = Fs.Path.initWithPretty(absolute_url, absolute_url),
- };
- } else {
- const absolute_url = try std.fmt.allocPrintZ(
- vm.allocator,
- "{s}{s}{s}{s}",
- .{
- vm.bundler.options.public_url,
- dirname,
- basename,
- path.name.ext,
- },
- );
-
- return LoadResult{
- .Path = Fs.Path.initWithPretty(absolute_url, absolute_url),
- };
- }
- },
- else => unreachable,
- }
- },
- }
- }
-
- pub fn getLoaded(
- this: *Module,
- ctx: js.JSContextRef,
- thisObject: js.JSValueRef,
- prop: js.JSStringRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- return js.JSValueMakeBoolean(ctx, this.loaded);
- }
-
- pub fn getId(
- this: *Module,
- ctx: js.JSContextRef,
- thisObject: js.JSValueRef,
- prop: js.JSStringRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- if (this.id == null) {
- this.id = js.JSStringCreateStatic(this.path.text.ptr, this.path.text.len);
- }
-
- return this.id;
- }
-
- pub fn getExports(
- this: *Module,
- ctx: js.JSContextRef,
- thisObject: js.JSValueRef,
- prop: js.JSStringRef,
- exception: js.ExceptionRef,
- ) callconv(.C) js.JSValueRef {
- return this.exports;
- }
-
- pub fn internalGetExports(this: *Module, globalContext: js.JSContextRef) js.JSValueRef {
- if (this.exports == null) {
- this.exports = js.JSObjectMake(globalContext, exports_class_ref, this);
- }
-
- return this.exports;
- }
-
- pub fn internalGetRequire(this: *Module) js.JSValueRef {
- if (this.require_func == null) {
- this.require_func = To.JS.functionWithCallback(
- Module,
- this,
- Properties.Refs.require,
- this.vm.global.ctx,
- require,
- );
- }
-
- return this.require_func;
- }
-
- pub fn setExports(
- this: *Module,
- ctx: js.JSContextRef,
- thisObject: js.JSValueRef,
- prop: js.JSStringRef,
- value: js.JSValueRef,
- exception: js.ExceptionRef,
- ) bool {
- if (this.exports != null) {
- if (js.JSValueIsString(this.vm.global.ctx, this.exports)) {
- js.JSStringRelease(this.exports);
- }
- }
- switch (js.JSValueGetType(ctx, value)) {
- .kJSTypeObject => {
- if (js.JSValueIsObjectOfClass(ctx, value, exports_class_ref)) {
- var other = @ptrCast(
- *Module,
- @alignCast(
- @alignOf(
- *Module,
- ),
- js.JSObjectGetPrivate(value).?,
- ),
- );
-
- if (other != this) {
- this.exports = other.exports;
- }
-
- return true;
- } else {
- if (js.JSObjectIsFunction(ctx, value)) {
- this.exports_function = value;
- }
- }
- },
- else => {},
- }
-
- this.exports = value;
-
- return true;
- }
-
- pub const RequireObject = struct {};
-};
-
pub const EventListenerMixin = struct {
threadlocal var event_listener_names_buf: [128]u8 = undefined;
pub const List = std.ArrayList(js.JSObjectRef);
@@ -1386,218 +252,3 @@ pub const EventListenerMixin = struct {
return Handler;
}
};
-
-pub const GlobalObject = struct {
- ref: js.JSObjectRef = undefined,
- vm: *VirtualMachine,
- ctx: js.JSGlobalContextRef = undefined,
- console: js.JSObjectRef = null,
- global_class_def: js.JSClassDefinition = undefined,
- global_class: js.JSClassRef = undefined,
-
- pub const ConsoleClass = NewClass(
- GlobalObject,
- .{ .name = "Console", .singleton = true },
- .{
- .@"log" = stdout,
- .@"info" = stdout,
- .@"debug" = stdout,
- .@"verbose" = stdout,
-
- .@"error" = stderr,
- .@"warn" = stderr,
- },
- .{},
- );
-
- pub const GlobalClass = NewClass(
- GlobalObject,
- .{
- .name = "Global",
- .ts = .{ .module = .{ .global = true } },
- },
- .{
- .@"addEventListener" = .{
- .rfn = EventListenerMixin.addEventListener(GlobalObject).addListener,
- .ts = d.ts{
- .args = &[_]d.ts.arg{
- .{ .name = "name", .@"return" = "\"fetch\"" },
- .{ .name = "callback", .@"return" = "(event: FetchEvent) => void" },
- },
- .@"return" = "void",
- },
- },
- },
- .{
- .@"console" = .{
- .get = getConsole,
- },
- .@"Request" = Request.Class.GetClass(GlobalObject){},
- .@"Response" = Response.Class.GetClass(GlobalObject){},
- .@"Headers" = Headers.Class.GetClass(GlobalObject){},
- },
- );
-
- pub fn getConsole(
- global: *GlobalObject,
- ctx: js.JSContextRef,
- obj: js.JSObjectRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- if (global.console == null) {
- global.console = js.JSObjectMake(js.JSContextGetGlobalContext(ctx), ConsoleClass.get().*, global);
- js.JSValueProtect(ctx, global.console);
- }
-
- return global.console;
- }
-
- pub fn boot(global: *GlobalObject) !void {
- global.ctx = js.JSGlobalContextRetain(js.JSGlobalContextCreateInGroup(global.vm.group, GlobalObject.GlobalClass.get().*));
- std.debug.assert(js.JSObjectSetPrivate(js.JSContextGetGlobalObject(global.ctx), global));
-
- if (!printer_buf_loaded) {
- printer_buf_loaded = true;
- printer_buf = try MutableString.init(global.vm.allocator, 4096);
- }
- }
-
- threadlocal var printer_buf: MutableString = undefined;
- threadlocal var printer_buf_loaded: bool = false;
- fn valuePrinter(comptime ValueType: js.JSType, ctx: js.JSContextRef, arg: js.JSValueRef, writer: anytype) !void {
- switch (ValueType) {
- .kJSTypeUndefined => {
- try writer.writeAll("undefined");
- },
- .kJSTypeNull => {
- try writer.writeAll("null");
- },
- .kJSTypeBoolean => {
- if (js.JSValueToBoolean(ctx, arg)) {
- try writer.writeAll("true");
- } else {
- try writer.writeAll("false");
- }
- },
- .kJSTypeNumber => {
- try writer.print(
- "{d}",
- .{js.JSValueToNumber(ctx, arg, null)},
- );
- },
- .kJSTypeString => {
- printer_buf.reset();
- var string_ref = js.JSValueToStringCopy(ctx, arg, null);
- const len = js.JSStringGetMaximumUTF8CStringSize(string_ref) + 1;
-
- printer_buf.growIfNeeded(len) catch {};
- printer_buf.inflate(len) catch {};
- var slice = printer_buf.toOwnedSliceLeaky();
-
- defer js.JSStringRelease(string_ref);
- const used = js.JSStringGetUTF8CString(string_ref, slice.ptr, slice.len);
- try writer.writeAll(slice[0..used]);
- },
- .kJSTypeObject => {
- // TODO:
- try writer.writeAll("[Object object]");
- },
- .kJSTypeSymbol => {
- var description = js.JSObjectGetPropertyForKey(ctx, arg, Properties.Refs.description, null);
- return switch (js.JSValueGetType(ctx, description)) {
- .kJSTypeString => try valuePrinter(.kJSTypeString, ctx, js.JSStringRetain(description), writer),
- else => try valuePrinter(.kJSTypeUndefined, ctx, js.JSStringRetain(description), writer),
- };
- },
- else => {},
- }
- }
-
- fn output(
- writer: anytype,
- ctx: js.JSContextRef,
- arguments: []const js.JSValueRef,
- ) !void {
- defer Output.flush();
- // console.log();
- if (arguments.len == 0) {
- return;
- }
-
- const last = arguments.len - 1;
- defer writer.writeAll("\n") catch {};
-
- for (arguments) |arg, i| {
- switch (js.JSValueGetType(ctx, arg)) {
- .kJSTypeUndefined => {
- try valuePrinter(.kJSTypeUndefined, ctx, arg, writer);
- if (i != last) {
- try writer.writeAll(" ");
- }
- },
- .kJSTypeNull => {
- try valuePrinter(.kJSTypeNull, ctx, arg, writer);
- if (i != last) {
- try writer.writeAll(" ");
- }
- },
- .kJSTypeBoolean => {
- try valuePrinter(.kJSTypeBoolean, ctx, arg, writer);
- if (i != last) {
- try writer.writeAll(" ");
- }
- },
- .kJSTypeNumber => {
- try valuePrinter(.kJSTypeNumber, ctx, arg, writer);
- if (i != last) {
- try writer.writeAll(" ");
- }
- },
- .kJSTypeString => {
- try valuePrinter(.kJSTypeString, ctx, arg, writer);
- if (i != last) {
- try writer.writeAll(" ");
- }
- },
- .kJSTypeObject => {
- try valuePrinter(.kJSTypeObject, ctx, arg, writer);
- if (i != last) {
- try writer.writeAll(" ");
- }
- },
- .kJSTypeSymbol => {
- try valuePrinter(.kJSTypeSymbol, ctx, arg, writer);
- if (i != last) {
- try writer.writeAll(" ");
- }
- },
- else => {},
- }
- }
- }
-
- pub fn stdout(
- obj: *GlobalObject,
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- thisObject: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- output(Output.writer(), ctx, arguments) catch {};
- return js.JSValueMakeUndefined(ctx);
- }
-
- pub fn stderr(
- obj: *GlobalObject,
- ctx: js.JSContextRef,
- function: js.JSObjectRef,
- thisObject: js.JSObjectRef,
- arguments: []const js.JSValueRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- output(Output.errorWriter(), ctx, arguments) catch {};
- return js.JSValueMakeUndefined(ctx);
- // js.JSObjectMakeFunctionWithCallback(ctx: JSContextRef, name: JSStringRef, callAsFunction: JSObjectCallAsFunctionCallback)
- }
-};