aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/feature_flags.zig3
-rw-r--r--src/global.zig4
-rw-r--r--src/http.zig3
-rw-r--r--src/javascript/jsc/JavascriptCore.zig269
m---------src/javascript/jsc/WebKit0
-rw-r--r--src/javascript/jsc/api/router.zig105
-rw-r--r--src/javascript/jsc/base.zig194
-rw-r--r--src/javascript/jsc/bindings/DefaultGlobal.cpp162
-rw-r--r--src/javascript/jsc/bindings/DefaultGlobal.h65
-rw-r--r--src/javascript/jsc/bindings/DefaultGlobal.zig272
-rw-r--r--src/javascript/jsc/bindings/JSCInlines.h57
-rw-r--r--src/javascript/jsc/bindings/JSValue.zig0
-rw-r--r--src/javascript/jsc/bindings/bindings-generator.zig32
-rw-r--r--src/javascript/jsc/bindings/bindings.cpp10
-rw-r--r--src/javascript/jsc/bindings/bindings.zig2
-rw-r--r--src/javascript/jsc/bindings/header-gen.zig368
-rw-r--r--src/javascript/jsc/bindings/headers.h42
-rw-r--r--src/javascript/jsc/bindings/imports.zig1
-rw-r--r--src/javascript/jsc/bindings/inlines.cpp0
-rw-r--r--src/javascript/jsc/bindings/root.h71
-rw-r--r--src/javascript/jsc/javascript.zig157
-rw-r--r--src/javascript/jsc/typescript.zig59
-rw-r--r--src/js_printer.zig1
-rw-r--r--src/router.zig58
-rw-r--r--src/test/fixtures/console.log.js4
25 files changed, 1697 insertions, 242 deletions
diff --git a/src/feature_flags.zig b/src/feature_flags.zig
index 16adec042..828bae1fd 100644
--- a/src/feature_flags.zig
+++ b/src/feature_flags.zig
@@ -38,3 +38,6 @@ pub const CSSModulePolyfill = enum {
// Just return whatever the property key they referenced was
facade,
};
+
+// having issues compiling WebKit with this enabled
+pub const remote_inspector = false;
diff --git a/src/global.zig b/src/global.zig
index 5a1428049..16a515086 100644
--- a/src/global.zig
+++ b/src/global.zig
@@ -7,7 +7,7 @@ pub usingnamespace @import("env.zig");
pub const FeatureFlags = @import("feature_flags.zig");
pub const Output = struct {
- threadlocal var source: *Source = undefined;
+ threadlocal var source: Source = undefined;
pub const Source = struct {
const StreamType = {
if (isWasm) {
@@ -41,7 +41,7 @@ pub const Output = struct {
}
pub fn set(_source: *Source) void {
- source = _source;
+ source = _source.*;
}
};
pub var enable_ansi_colors = isNative;
diff --git a/src/http.zig b/src/http.zig
index f9d1acf0e..0514e88aa 100644
--- a/src/http.zig
+++ b/src/http.zig
@@ -44,7 +44,7 @@ threadlocal var res_headers_buf: [100]picohttp.Header = undefined;
const sync = @import("./sync.zig");
const JavaScript = @import("./javascript/jsc/JavaScript.zig");
const js = @import("javascript/jsc/javascript.zig");
-
+const Router = @import("./router.zig");
pub const Watcher = watcher.NewWatcher(*Server);
const ENABLE_LOGGER = false;
@@ -193,6 +193,7 @@ pub const RequestContext = struct {
controlled: bool = false,
watcher: *Watcher,
timer: std.time.Timer,
+ matched_route: ?Router.Match = null,
full_url: [:0]const u8 = "",
res_headers_count: usize = 0,
diff --git a/src/javascript/jsc/JavascriptCore.zig b/src/javascript/jsc/JavascriptCore.zig
index 0f1a624ce..d1a3a9f22 100644
--- a/src/javascript/jsc/JavascriptCore.zig
+++ b/src/javascript/jsc/JavascriptCore.zig
@@ -240,6 +240,15 @@ pub const OpaqueJSPropertyNameArray = struct_OpaqueJSPropertyNameArray;
pub const OpaqueJSPropertyNameAccumulator = struct_OpaqueJSPropertyNameAccumulator;
pub const OpaqueJSValue = struct_OpaqueJSValue;
+// const JSProcessID = ;
+pub extern fn JSRemoteInspectorDisableAutoStart() void;
+pub extern fn JSRemoteInspectorStart() void;
+// JS_EXPORT void JSRemoteInspectorSetParentProcessInformation(JSProcessID, const uint8_t* auditData, size_t auditLength) JSC_API_AVAILABLE(macos(10.11), ios(9.0));
+
+pub extern fn JSRemoteInspectorSetLogToSystemConsole(enabled: bool) void;
+pub extern fn JSRemoteInspectorGetInspectionEnabledByDefault(void) bool;
+pub extern fn JSRemoteInspectorSetInspectionEnabledByDefault(enabled: bool) void;
+
// -- Manual --
// StringImpl::createWithoutCopying
@@ -266,6 +275,262 @@ pub fn isObjectOfClassAndResolveIfNeeded(ctx: JSContextRef, obj: JSObjectRef, cl
if (prop == null) {
return null;
}
-
-
}
+
+pub const UTF8Ptr = [*c]const u8;
+pub const UTF16Ptr = [*c]const u16;
+
+// --- Custom Methods! ----
+pub const Encoding = enum(u8) {
+ empty = 0,
+ char8 = 8,
+ char16 = 16,
+};
+pub const JSCellValue = u64;
+pub const CellType = enum(u8) {
+ CellType = 0,
+ StringType = 1,
+ HeapBigIntType = 2,
+ LastMaybeFalsyCellPrimitive = 2,
+ SymbolType = 3,
+ GetterSetterType = 4,
+ CustomGetterSetterType = 5,
+ APIValueWrapperType = 6,
+ NativeExecutableType = 7,
+ ProgramExecutableType = 8,
+ ModuleProgramExecutableType = 9,
+ EvalExecutableType = 10,
+ FunctionExecutableType = 11,
+ UnlinkedFunctionExecutableType = 12,
+ UnlinkedProgramCodeBlockType = 13,
+ UnlinkedModuleProgramCodeBlockType = 14,
+ UnlinkedEvalCodeBlockType = 15,
+ UnlinkedFunctionCodeBlockType = 16,
+ CodeBlockType = 17,
+ JSImmutableButterflyType = 18,
+ JSSourceCodeType = 19,
+ JSScriptFetcherType = 20,
+ JSScriptFetchParametersType = 21,
+ ObjectType = 22,
+ FinalObjectType = 23,
+ JSCalleeType = 24,
+ JSFunctionType = 25,
+ InternalFunctionType = 26,
+ NullSetterFunctionType = 27,
+ BooleanObjectType = 28,
+ NumberObjectType = 29,
+ ErrorInstanceType = 30,
+ PureForwardingProxyType = 31,
+ DirectArgumentsType = 32,
+ ScopedArgumentsType = 33,
+ ClonedArgumentsType = 34,
+ ArrayType = 35,
+ DerivedArrayType = 36,
+ ArrayBufferType = 37,
+ Int8ArrayType = 38,
+ Uint8ArrayType = 39,
+ Uint8ClampedArrayType = 40,
+ Int16ArrayType = 41,
+ Uint16ArrayType = 42,
+ Int32ArrayType = 43,
+ Uint32ArrayType = 44,
+ Float32ArrayType = 45,
+ Float64ArrayType = 46,
+ BigInt64ArrayType = 47,
+ BigUint64ArrayType = 48,
+ DataViewType = 49,
+ GlobalObjectType = 50,
+ GlobalLexicalEnvironmentType = 51,
+ LexicalEnvironmentType = 52,
+ ModuleEnvironmentType = 53,
+ StrictEvalActivationType = 54,
+ WithScopeType = 55,
+ ModuleNamespaceObjectType = 56,
+ RegExpObjectType = 57,
+ JSDateType = 58,
+ ProxyObjectType = 59,
+ JSGeneratorType = 60,
+ JSAsyncGeneratorType = 61,
+ JSArrayIteratorType = 62,
+ JSMapIteratorType = 63,
+ JSSetIteratorType = 64,
+ JSStringIteratorType = 65,
+ JSPromiseType = 66,
+ JSMapType = 67,
+ JSSetType = 68,
+ JSWeakMapType = 69,
+ JSWeakSetType = 70,
+ WebAssemblyModuleType = 71,
+ StringObjectType = 72,
+ DerivedStringObjectType = 73,
+ LastJSCObjectType = 73,
+ MaxJSType = 255,
+ _,
+
+ pub fn isString(this: CellType) bool {
+ return switch (this) {
+ .StringType => true,
+ else => false,
+ };
+ }
+};
+pub const ExternalStringFinalizer = fn (finalize_ptr: ?*c_void, ref: JSStringRef, buffer: *c_void, byteLength: usize) callconv(.C) void;
+pub extern fn JSStringCreate(string: UTF8Ptr, length: usize) JSStringRef;
+pub extern fn JSStringCreateStatic(string: UTF8Ptr, length: usize) JSStringRef;
+pub extern fn JSStringCreateExternal(string: UTF8Ptr, length: usize, finalize_ptr: ?*c_void, finalizer: ExternalStringFinalizer) JSStringRef;
+pub extern fn JSStringIsEqualToString(a: JSStringRef, string: UTF8Ptr, length: usize) bool;
+pub extern fn JSStringEncoding(string: JSStringRef) Encoding;
+pub extern fn JSStringGetCharacters8Ptr(string: JSStringRef) UTF8Ptr;
+extern fn JSStringIterate(string: JSCellValue, iter: *JSStringIterator_) void;
+pub extern fn JSCellType(cell: JSCellValue) CellType;
+pub extern fn JSStringIsStatic(ref: JSStringRef) bool;
+pub extern fn JSStringIsExternal(ref: JSStringRef) bool;
+
+pub const JStringIteratorAppendCallback = fn (ctx: *JSStringIterator_, ptr: *c_void, length: u32) callconv(.C) c_void;
+pub const JStringIteratorWriteCallback = fn (ctx: *JSStringIterator_, ptr: *c_void, length: u32, offset: u32) callconv(.C) c_void;
+const JSStringIterator_ = extern struct {
+ ctx: *c_void,
+ stop: u8,
+
+ append8: JStringIteratorAppendCallback,
+ append16: JStringIteratorAppendCallback,
+ write8: JStringIteratorWriteCallback,
+ write16: JStringIteratorWriteCallback,
+};
+
+pub const JSString = struct {
+ pub const Callback = fn (finalize_ptr_: ?*c_void, ref: JSStringRef, buffer: *c_void, byteLength: usize) callconv(.C) void;
+ _ref: JSStringRef = null,
+ backing: Backing = .{ .gc = 0 },
+
+ pub const Backing = union(Ownership) {
+ external: ExternalString,
+ static: []const u8,
+ gc: u0,
+ };
+
+ pub fn deref(this: *JSString) void {
+ if (this._ref == null) return;
+
+ JSStringRetain(this._ref);
+ }
+
+ const ExternalString = struct {
+ callback: Callback,
+ external_callback: *c_void,
+ external_ptr: ?*c_void = null,
+ slice: []const u8,
+ };
+
+ pub fn External(comptime ExternalType: type, external_type: *ExternalType, str: []const u8, callback: fn (this: *ExternalType, buffer: []const u8) void) JSString {
+ const CallbackFunctionType = @TypeOf(callback);
+
+ const ExternalWrapper = struct {
+ pub fn finalizer_callback(finalize_ptr_: ?*c_void, buffer: *c_void, byteLength: usize) callconv(.C) void {
+ var finalize_ptr = finalize_ptr_ orelse return;
+
+ var jsstring = @ptrCast(
+ *JSString,
+ @alignCast(
+ @alignOf(
+ *JSString,
+ ),
+ finalize_ptr,
+ ),
+ );
+
+ var cb = @as(CallbackFunctionType, jsstring.external_callback orelse return);
+ var raw_external_ptr = jsstring.external_ptr orelse return;
+
+ var external_ptr = @ptrCast(
+ *ExternalType,
+ @alignCast(
+ @alignOf(
+ *ExternalType,
+ ),
+ raw_external_ptr,
+ ),
+ );
+
+ cb(external_ptr, @ptrCast([*]u8, buffer)[0..byteLength]);
+ }
+ };
+
+ return JSString{
+ .backing = .{
+ .external = .{
+ .slice = str,
+ .external_callback = callback,
+ .external_ptr = external_type,
+ .callback = ExternalWrapper.finalizer_callback,
+ },
+ },
+ };
+ }
+
+ // pub fn Iterator(comptime WriterType: type) type {
+ // return struct {
+
+ // };
+ // }
+
+ pub const Ownership = enum { external, static, gc };
+
+ pub fn Static(str: []const u8) JSString {
+ return JSString{ ._ref = null, .backing = .{ .static = str } };
+ }
+
+ pub fn ref(this: *JSString) JSStringRef {
+ if (this._ref == null) {
+ switch (this.backing) {
+ .External => |external| {
+ this._ref = JSStringCreateExternal(external.slice, external.slice.len, this, this.external_callback.?);
+ },
+ .Static => |slice| {
+ this._ref = JSStringCreateStatic(slice.ptr, slice.len);
+ },
+ .gc => {
+ return null;
+ },
+ }
+ }
+
+ JSStringRetain(this._ref);
+
+ return this._ref;
+ }
+
+ pub fn fromStringRef(string_ref: JSStringRef) JSString {}
+
+ pub fn init(str: []const u8) JSString {}
+
+ pub fn static(str: []const u8) JSString {}
+
+ pub fn finalize(this: *JSString) void {
+ this.loaded = false;
+ }
+
+ pub fn value(this: *JSString, ctx: JSContextRef) JSValueRef {
+ return JSValueMakeString(ctx, this.ref());
+ }
+
+ pub fn len(this: *const JSString) usize {
+ return JSStringGetLength(this.ref);
+ }
+
+ pub fn encoding(this: *const JSString) Encoding {
+ return JSStringEncoding(this.ref);
+ }
+
+ // pub fn eql(this: *const JSString, str: string) {
+
+ // }
+
+ pub fn eqlJS(this: *const JSString, ctx: JSContextRef, comptime Type: type, that: Type) bool {
+ switch (comptime Type) {
+ JSValueRef => {},
+ JSStringRef => {},
+ JSString => {},
+ }
+ }
+};
diff --git a/src/javascript/jsc/WebKit b/src/javascript/jsc/WebKit
-Subproject 26db06f4db00380b673808316cb959e2c0d0160
+Subproject 7d494581249d31ff34d65436f077e76ea2516b9
diff --git a/src/javascript/jsc/api/router.zig b/src/javascript/jsc/api/router.zig
index b37cdf55e..84dad71ef 100644
--- a/src/javascript/jsc/api/router.zig
+++ b/src/javascript/jsc/api/router.zig
@@ -2,40 +2,57 @@ usingnamespace @import("../base.zig");
const std = @import("std");
const Api = @import("../../../api/schema.zig").Api;
const FilesystemRouter = @import("../../../router.zig");
+const http = @import("../../../http.zig");
const JavaScript = @import("../javascript.zig");
usingnamespace @import("../webcore/response.zig");
const Router = @This();
-match: FilesystemRouter.RouteMap.MatchedRoute,
+route: *const FilesystemRouter.Match,
file_path_str: js.JSStringRef = null,
pathname_str: js.JSStringRef = null,
-pub fn constructor(
+pub fn importRoute(
+ this: *Router,
ctx: js.JSContextRef,
function: js.JSObjectRef,
+ thisObject: js.JSObjectRef,
arguments: []const js.JSValueRef,
exception: js.ExceptionRef,
) js.JSObjectRef {
- return null;
+ return JavaScript.VirtualMachine.instance.require(
+ ctx,
+ std.fs.path.dirname(this.route.file_path).?,
+ this.route.file_path,
+ exception,
+ );
}
pub fn match(
obj: *c_void,
ctx: js.JSContextRef,
function: js.JSObjectRef,
+ thisObject: js.JSObjectRef,
arguments: []const js.JSValueRef,
exception: js.ExceptionRef,
) js.JSObjectRef {
- return null;
-}
+ if (arguments.len == 0) {
+ JSError(getAllocator(ctx), "Expected string, FetchEvent, or Request but there were no arguments", .{}, ctx, exception);
+ return null;
+ }
+
+ if (js.JSValueIsObjectOfClass(ctx, arguments[0], FetchEvent.Class.get().*)) {
+ return matchFetchEvent(ctx, To.Zig.ptr(FetchEvent, arguments[0]), exception);
+ }
+
+ if (js.JSValueIsString(ctx, arguments[0])) {
+ return matchPathName(ctx, arguments[0], exception);
+ }
+
+ if (js.JSValueIsObjectOfClass(ctx, arguments[0], Request.Class.get().*)) {
+ return matchRequest(ctx, To.Zig.ptr(Request, arguments[0]), exception);
+ }
-fn matcher(
- obj: *c_void,
- ctx: js.JSContextRef,
- arg: js.JSValueRef,
- exception: js.ExceptionRef,
-) js.JSObjectRef {
return null;
}
@@ -44,13 +61,19 @@ fn matchRequest(
request: *const Request,
exception: js.ExceptionRef,
) js.JSObjectRef {
- return null;
+ return createRouteObject(ctx, request.request_context, exception);
}
-fn matchPathName(
+fn matchPathNameString(
ctx: js.JSContextRef,
pathname: string,
exception: js.ExceptionRef,
+) js.JSObjectRef {}
+
+fn matchPathName(
+ ctx: js.JSContextRef,
+ pathname: js.JSStringRef,
+ exception: js.ExceptionRef,
) js.JSObjectRef {
return null;
}
@@ -60,36 +83,49 @@ fn matchFetchEvent(
fetch_event: *const FetchEvent,
exception: js.ExceptionRef,
) js.JSObjectRef {
- return null;
+ return createRouteObject(ctx, fetch_event.request_context, exception);
+}
+
+fn createRouteObject(ctx: js.JSContextRef, req: *const http.RequestContext, exception: js.ExceptionRef) js.JSValueRef {
+ const route = &(req.matched_route orelse {
+ return js.JSValueMakeNull(ctx);
+ });
+
+ var router = getAllocator(ctx).create(Router) catch unreachable;
+ router.* = Router{
+ .route = route,
+ };
+
+ return Class.new(ctx, router);
}
const match_type_definition = &[_]d.ts{
.{
- .tsdoc = "Match a {@link https://developer.mozilla.org/en-US/docs/Web/API/Request Request} to a Route from the local filesystem.",
+ .tsdoc = "Match a {@link https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent FetchEvent} to a `Route` from the local filesystem. Returns `null` if there is no match.",
.args = &[_]d.ts.arg{
.{
- .name = "request",
- .@"return" = "Request",
+ .name = "event",
+ .@"return" = "FetchEvent",
},
},
.@"return" = "Route | null",
},
.{
- .tsdoc = "Match a {@link https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent FetchEvent} to a Route from the local filesystem.",
+ .tsdoc = "Match a `pathname` to a `Route` from the local filesystem. Returns `null` if there is no match.",
.args = &[_]d.ts.arg{
.{
- .name = "event",
- .@"return" = "FetchEvent",
+ .name = "pathname",
+ .@"return" = "string",
},
},
.@"return" = "Route | null",
},
.{
- .tsdoc = "Match a `pathname` to a Route from the local filesystem.",
+ .tsdoc = "Match a {@link https://developer.mozilla.org/en-US/docs/Web/API/Request Request} to a `Route` from the local filesystem. Returns `null` if there is no match.",
.args = &[_]d.ts.arg{
.{
- .name = "pathname",
- .@"return" = "string",
+ .name = "request",
+ .@"return" = "Request",
},
},
.@"return" = "Route | null",
@@ -110,7 +146,7 @@ pub const Class = NewClass(
},
.{
.match = .{
- .get = match,
+ .rfn = match,
.ts = match_type_definition,
},
},
@@ -136,9 +172,14 @@ pub const Instance = NewClass(
.finalize = .{
.rfn = finalize,
},
- .constructor = .{
- .rfn = constructor,
- .ts = match_type_definition,
+ .import = .{
+ .rfn = importRoute,
+ .ts = d.ts{
+ .@"return" = "Object",
+ .tsdoc =
+ \\Synchronously load & evaluate the file corresponding to the route. Returns the exports of the route. This is similar to `await import(route.filepath)`, except it's synchronous. It is recommended to use this function instead of `import`.
+ ,
+ },
},
},
.{
@@ -156,11 +197,7 @@ pub const Instance = NewClass(
.ts = d.ts{
.@"return" = "string",
.tsdoc =
- \\Project-relative filesystem path to the route file. Useful for importing.
- \\
- \\@example ```tsx
- \\await import(route.filepath);
- \\```
+ \\Project-relative filesystem path to the route file.
,
},
},
@@ -213,7 +250,7 @@ pub fn getFilePath(
exception: js.ExceptionRef,
) js.JSValueRef {
if (this.file_path_str == null) {
- this.file_path_str = js.JSStringCreateWithUTF8CString(this.match.file_path.ptr);
+ this.file_path_str = js.JSStringCreateWithUTF8CString(this.route.file_path.ptr);
}
return js.JSValueMakeString(ctx, this.file_path_str);
@@ -234,7 +271,7 @@ pub fn getPathname(
exception: js.ExceptionRef,
) js.JSValueRef {
if (this.pathname_str == null) {
- this.pathname_str = js.JSStringCreateWithUTF8CString(this.match.pathname.ptr);
+ this.pathname_str = js.JSStringCreateWithUTF8CString(this.route.pathname.ptr);
}
return js.JSValueMakeString(ctx, this.pathname_str);
diff --git a/src/javascript/jsc/base.zig b/src/javascript/jsc/base.zig
index f0c5dc4b6..36567000a 100644
--- a/src/javascript/jsc/base.zig
+++ b/src/javascript/jsc/base.zig
@@ -163,6 +163,17 @@ pub const To = 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 @ptrCast(
+ *StructType,
+ @alignCast(
+ @alignOf(
+ *StructType,
+ ),
+ js.JSObjectGetPrivate(obj).?,
+ ),
+ );
+ }
};
};
@@ -194,23 +205,23 @@ pub const RuntimeImports = struct {
pub const Properties = struct {
pub const UTF8 = struct {
- pub const module = "module";
- pub const globalThis = "globalThis";
- pub const exports = "exports";
- pub const log = "log";
- pub const debug = "debug";
- pub const name = "name";
- pub const info = "info";
- pub const error_ = "error";
- pub const warn = "warn";
- pub const console = "console";
- pub const require = "require";
- pub const description = "description";
- pub const initialize_bundled_module = "$$m";
- pub const load_module_function = "$lOaDuRcOdE$";
- pub const window = "window";
- pub const default = "default";
- pub const include = "include";
+ 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 GET = "GET";
pub const PUT = "PUT";
@@ -287,16 +298,14 @@ pub const Properties = struct {
pub fn init() void {
inline for (std.meta.fieldNames(UTF8)) |name| {
- @field(Refs, name) = js.JSStringRetain(
- js.JSStringCreateWithCharactersNoCopy(
- @field(StringStore.UTF16, name).ptr,
- @field(StringStore.UTF16, name).len - 1,
- ),
+ @field(Refs, name) = js.JSStringCreateStatic(
+ @field(UTF8, name).ptr,
+ @field(UTF8, name).len,
);
if (isDebug) {
std.debug.assert(
- js.JSStringIsEqualToUTF8CString(@field(Refs, name), @field(UTF8, name)[0.. :0]),
+ js.JSStringIsEqualToString(@field(Refs, name), @field(UTF8, name).ptr, @field(UTF8, name).len),
);
}
}
@@ -315,22 +324,22 @@ fn hasTypeScript(comptime Type: type) bool {
return true;
}
- return @hasDecl(d.ts, "ts");
+ return @hasDecl(Type, "ts");
}
fn getTypeScript(comptime Type: type, value: Type) d.ts.or_decl {
if (comptime hasTypeScriptField(Type)) {
- if (comptime Type.ts == d.ts.decl) {
+ if (@TypeOf(Type.ts) == d.ts.decl) {
return d.ts.or_decl{ .decl = value };
} else {
- return d.ts.or_decl{ .ts = value };
+ return d.ts.or_decl{ .ts = value.ts };
}
}
- if (comptime Type.ts == d.ts.decl) {
- return d.ts.or_decl{ .decl = value };
+ if (@TypeOf(Type.ts) == d.ts.decl) {
+ return d.ts.or_decl{ .decl = Type.ts };
} else {
- return d.ts.or_decl{ .ts = value };
+ return d.ts.or_decl{ .ts = value.ts };
}
}
@@ -723,30 +732,7 @@ pub fn NewClass(
const name = options.name;
const ClassDefinitionCreator = @This();
const function_names = std.meta.fieldNames(@TypeOf(staticFunctions));
- const names_buf = brk: {
- var total_len: usize = 0;
- for (function_names) |field, i| {
- total_len += std.unicode.utf8ToUtf16LeStringLiteral(field).len;
- }
- var offset: usize = 0;
- var names_buf_ = std.mem.zeroes([total_len]u16);
- for (function_names) |field, i| {
- var name_ = std.unicode.utf8ToUtf16LeStringLiteral(field);
- std.mem.copy(u16, names_buf_[offset .. name_.len + offset], name_[0..]);
- offset += name_.len;
- }
- break :brk names_buf_;
- };
- const function_name_literals: [function_names.len][]const js.JSChar = brk: {
- var names = std.mem.zeroes([function_names.len][]const js.JSChar);
- var len: usize = 0;
- for (function_names) |field, i| {
- const end = len + std.unicode.utf8ToUtf16LeStringLiteral(field).len;
- names[i] = names_buf[len..end];
- len = end;
- }
- break :brk names;
- };
+ const function_name_literals = function_names;
var function_name_refs: [function_names.len]js.JSStringRef = undefined;
var class_name_str = name[0.. :0].ptr;
@@ -755,13 +741,7 @@ pub fn NewClass(
var instance_functions: [function_names.len]js.JSObjectRef = undefined;
const property_names = std.meta.fieldNames(@TypeOf(properties));
var property_name_refs: [property_names.len]js.JSStringRef = undefined;
- const property_name_literals: [property_names.len][]const js.JSChar = brk: {
- var list = std.mem.zeroes([property_names.len][]const js.JSChar);
- for (property_names) |prop_name, i| {
- list[i] = std.unicode.utf8ToUtf16LeStringLiteral(prop_name);
- }
- break :brk list;
- };
+ const property_name_literals = property_names;
var static_properties: [property_names.len]js.JSStaticValue = undefined;
pub var ref: js.JSClassRef = null;
@@ -784,15 +764,19 @@ pub fn NewClass(
pub const static_value_count = static_properties.len;
- /// only use with singletons
- pub fn make(ctx: js.JSContextRef) js.JSObjectRef {}
+ pub fn new(ctx: js.JSContextRef, ptr: ?*ZigType) js.JSObjectRef {
+ return js.JSObjectMake(ctx, get().*, ptr);
+ }
pub fn get() callconv(.C) [*c]js.JSClassRef {
if (!loaded) {
loaded = true;
definition = define();
- ref = js.JSClassRetain(js.JSClassCreate(&definition));
+ ref = js.JSClassCreate(&definition);
}
+
+ _ = js.JSClassRetain(ref);
+
return &ref;
}
@@ -905,11 +889,11 @@ pub fn NewClass(
);
var exc: js.JSValueRef = null;
-
- switch (comptime @typeInfo(@TypeOf(@field(
+ const Field = @TypeOf(@field(
properties,
property_names[id],
- )))) {
+ ));
+ switch (comptime @typeInfo(Field)) {
.Fn => {
return @field(
properties,
@@ -922,19 +906,46 @@ pub fn NewClass(
);
},
.Struct => {
- return @field(
+ const func = @field(
@field(
properties,
property_names[id],
),
"get",
- )(
- this,
- ctx,
- obj,
- prop,
- exception,
);
+
+ const Func = @typeInfo(@TypeOf(func));
+ const WithPropFn = fn (
+ *ZigType,
+ js.JSContextRef,
+ js.JSObjectRef,
+ js.JSStringRef,
+ js.ExceptionRef,
+ ) js.JSValueRef;
+
+ const WithoutPropFn = fn (
+ *ZigType,
+ js.JSContextRef,
+ js.JSObjectRef,
+ 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,
}
@@ -1026,12 +1037,14 @@ pub fn NewClass(
switch (@typeInfo(Func)) {
.Struct => {
if (hasTypeScript(Func)) {
- var ts_functions: if (std.meta.trait.isIndexable(@TypeOf(func.ts))) @TypeOf(func.ts) else [1]@TypeOf(func.ts) = undefined;
+ var ts_functions: []const d.ts = &[_]d.ts{};
if (std.meta.trait.isIndexable(@TypeOf(func.ts))) {
- ts_functions = func.ts;
+ ts_functions = std.mem.span(func.ts);
} else {
- ts_functions = .{func.ts};
+ var funcs1 = std.mem.zeroes([1]d.ts);
+ funcs1[0] = func.ts;
+ ts_functions = std.mem.span(&funcs1);
}
for (ts_functions) |ts_function_| {
@@ -1193,11 +1206,14 @@ pub fn NewClass(
switch (@typeInfo(Func)) {
.Struct => {
if (hasTypeScript(Func)) {
- var ts_functions = std.mem.zeroes([count]d.ts);
+ var ts_functions: []const d.ts = &[_]d.ts{};
+
if (std.meta.trait.isIndexable(@TypeOf(func.ts))) {
- ts_functions = func.ts;
+ ts_functions = std.mem.span(func.ts);
} else {
- ts_functions[0] = func.ts;
+ var funcs1 = std.mem.zeroes([1]d.ts);
+ funcs1[0] = func.ts;
+ ts_functions = std.mem.span(&funcs1);
}
for (ts_functions) |ts_function_| {
@@ -1206,6 +1222,10 @@ pub fn NewClass(
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;
}
@@ -1277,10 +1297,16 @@ pub fn NewClass(
} else if (comptime strings.eqlComptime(function_names[i], "finalize")) {
def.finalize = To.JS.Finalize(ZigType, staticFunctions.finalize.rfn).rfn;
} else {
- var callback = To.JS.Callback(
- ZigType,
- @field(staticFunctions, function_names[i]).rfn,
+ const ctxfn = @field(staticFunctions, function_names[i]).rfn;
+ const Func: std.builtin.TypeInfo.Fn = @typeInfo(@TypeOf(ctxfn)).Fn;
+
+ const PointerType = std.meta.Child(Func.args[0].arg_type.?);
+
+ var callback = if (Func.calling_convention == .C) ctxfn else To.JS.Callback(
+ PointerType,
+ ctxfn,
).rfn;
+
static_functions[count] = js.JSStaticFunction{
.name = (function_names[i][0.. :0]).ptr,
.callAsFunction = callback,
@@ -1323,7 +1349,7 @@ pub fn NewClass(
if (property_names.len > 0) {
inline for (comptime property_name_literals) |prop_name, i| {
- property_name_refs[i] = js.JSStringCreateWithCharactersNoCopy(
+ property_name_refs[i] = js.JSStringCreateStatic(
prop_name.ptr,
prop_name.len,
);
@@ -1335,7 +1361,7 @@ pub fn NewClass(
if (comptime hasSetter(@TypeOf(field))) {
static_properties[i].setProperty = StaticProperty(i).setter;
}
- static_properties[i].name = property_names[i][0.. :0];
+ static_properties[i].name = property_names[i][0.. :0].ptr;
}
def.staticValues = (&static_properties);
diff --git a/src/javascript/jsc/bindings/DefaultGlobal.cpp b/src/javascript/jsc/bindings/DefaultGlobal.cpp
new file mode 100644
index 000000000..2c83c0e3c
--- /dev/null
+++ b/src/javascript/jsc/bindings/DefaultGlobal.cpp
@@ -0,0 +1,162 @@
+
+#include "root.h"
+#include "DefaultGlobal.h"
+
+#include <wtf/text/AtomStringImpl.h>
+
+#include <JavaScriptCore/APICast.h>
+#include <JavaScriptCore/CallFrameInlines.h>
+#include <JavaScriptCore/CatchScope.h>
+#include <JavaScriptCore/Completion.h>
+#include <JavaScriptCore/Error.h>
+#include <JavaScriptCore/Exception.h>
+#include <JavaScriptCore/JSContextInternal.h>
+#include <JavaScriptCore/JSInternalPromise.h>
+#include <JavaScriptCore/JSModuleLoader.h>
+#include <JavaScriptCore/JSNativeStdFunction.h>
+#include <JavaScriptCore/JSPromise.h>
+#include <JavaScriptCore/JSSourceCode.h>
+#include <JavaScriptCore/JSValueInternal.h>
+#include <JavaScriptCore/JSVirtualMachineInternal.h>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <JavaScriptCore/ObjectConstructor.h>
+#include <JavaScriptCore/SourceOrigin.h>
+#include <wtf/URL.h>
+
+#include "JSCInlines.h"
+
+
+
+class Script;
+namespace JSC {
+ class Identifier;
+ class JSObject;
+ class JSString;
+
+}
+
+
+
+
+
+namespace Wundle {
+
+
+
+const ClassInfo DefaultGlobal::s_info = { "GlobalObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DefaultGlobal) };
+const GlobalObjectMethodTable DefaultGlobal::s_globalObjectMethodTable = {
+ &supportsRichSourceInfo,
+ &shouldInterruptScript,
+ &javaScriptRuntimeFlags,
+ nullptr, // queueTaskToEventLoop
+ &shouldInterruptScriptBeforeTimeout,
+ &moduleLoaderImportModule, // moduleLoaderImportModule
+ &moduleLoaderResolve, // moduleLoaderResolve
+ &moduleLoaderFetch, // moduleLoaderFetch
+ &moduleLoaderCreateImportMetaProperties, // moduleLoaderCreateImportMetaProperties
+ &moduleLoaderEvaluate, // moduleLoaderEvaluate
+ nullptr, // promiseRejectionTracker
+ &reportUncaughtExceptionAtEventLoop,
+ &currentScriptExecutionOwner,
+ &scriptExecutionStatus,
+ nullptr, // defaultLanguage
+ nullptr, // compileStreaming
+ nullptr, // instantiateStreaming
+};
+
+
+void DefaultGlobal::reportUncaughtExceptionAtEventLoop(JSGlobalObject* globalObject, Exception* exception) {}
+JSC::Identifier DefaultGlobal::moduleLoaderResolve(JSGlobalObject* globalObject, JSModuleLoader* loader, JSValue key, JSValue referrer, JSValue val) {
+ String string = key.toWTFString(globalObject);
+ return JSC::Identifier::fromString(globalObject->vm(), string );
+}
+JSInternalPromise* DefaultGlobal::moduleLoaderImportModule(JSGlobalObject* globalObject, JSModuleLoader*, JSString* specifierValue, JSValue, const SourceOrigin& sourceOrigin) {
+ return nullptr;
+}
+JSInternalPromise* DefaultGlobal::moduleLoaderFetch(JSGlobalObject* globalObject, JSModuleLoader*, JSValue key, JSValue, JSValue) {
+ return nullptr;
+}
+JSC::JSObject* DefaultGlobal::moduleLoaderCreateImportMetaProperties(JSGlobalObject* globalObject, JSModuleLoader*loader, JSValue key, JSModuleRecord* record, JSValue value) {
+ return nullptr;
+}
+JSValue DefaultGlobal::moduleLoaderEvaluate(JSGlobalObject* globalObject, JSModuleLoader* moduleLoader, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher, JSValue sentValue, JSValue resumeMode) {
+ return jsNull();
+}
+
+using namespace JSC;
+
+
+JSC::ObjectPrototype* DefaultGlobal__objectPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->objectPrototype();
+}
+JSC::FunctionPrototype* DefaultGlobal__functionPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->functionPrototype();
+}
+JSC::ArrayPrototype* DefaultGlobal__arrayPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->arrayPrototype();
+}
+JSC::JSObject* DefaultGlobal__booleanPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->booleanPrototype();
+}
+JSC::StringPrototype* DefaultGlobal__stringPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->stringPrototype();
+}
+JSC::JSObject* DefaultGlobal__numberPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->numberPrototype();
+}
+JSC::BigIntPrototype* DefaultGlobal__bigIntPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->bigIntPrototype();
+}
+JSC::JSObject* DefaultGlobal__datePrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->datePrototype();
+}
+JSC::JSObject* DefaultGlobal__symbolPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->symbolPrototype();
+}
+JSC::RegExpPrototype* DefaultGlobal__regExpPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->regExpPrototype();
+}
+JSC::JSObject* DefaultGlobal__errorPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->errorPrototype();
+}
+JSC::IteratorPrototype* DefaultGlobal__iteratorPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->iteratorPrototype();
+}
+JSC::AsyncIteratorPrototype* DefaultGlobal__asyncIteratorPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->asyncIteratorPrototype();
+}
+JSC::GeneratorFunctionPrototype* DefaultGlobal__generatorFunctionPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->generatorFunctionPrototype();
+}
+JSC::GeneratorPrototype* DefaultGlobal__generatorPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->generatorPrototype();
+}
+JSC::AsyncFunctionPrototype* DefaultGlobal__asyncFunctionPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->asyncFunctionPrototype();
+}
+JSC::ArrayIteratorPrototype* DefaultGlobal__arrayIteratorPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->arrayIteratorPrototype();
+}
+JSC::MapIteratorPrototype* DefaultGlobal__mapIteratorPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->mapIteratorPrototype();
+}
+JSC::SetIteratorPrototype* DefaultGlobal__setIteratorPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->setIteratorPrototype();
+}
+JSC::JSObject* DefaultGlobal__mapPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->mapPrototype();
+}
+JSC::JSObject* DefaultGlobal__jsSetPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->jsSetPrototype();
+}
+JSC::JSPromisePrototype* DefaultGlobal__promisePrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->promisePrototype();
+}
+JSC::AsyncGeneratorPrototype* DefaultGlobal__asyncGeneratorPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->asyncGeneratorPrototype();
+}
+JSC::AsyncGeneratorFunctionPrototype* DefaultGlobal__asyncGeneratorFunctionPrototype(Wundle::DefaultGlobal* arg0) {
+ return arg0->asyncGeneratorFunctionPrototype();
+}
+
+}
diff --git a/src/javascript/jsc/bindings/DefaultGlobal.h b/src/javascript/jsc/bindings/DefaultGlobal.h
new file mode 100644
index 000000000..6bc5eb0c9
--- /dev/null
+++ b/src/javascript/jsc/bindings/DefaultGlobal.h
@@ -0,0 +1,65 @@
+#pragma once
+
+namespace JSC {
+ class Structure;
+ class Identifier;
+
+}
+
+#include "root.h"
+#include <JavaScriptCore/JSGlobalObject.h>
+#include "JSCInlines.h"
+
+using namespace JSC;
+
+
+namespace Wundle {
+
+class Script;
+
+class DefaultGlobal final : public JSC::JSGlobalObject {
+public:
+ using Base = JSC::JSGlobalObject;
+
+ DECLARE_EXPORT_INFO;
+ static const JSC::GlobalObjectMethodTable s_globalObjectMethodTable;
+
+ static constexpr bool needsDestruction = true;
+ template<typename CellType, SubspaceAccess mode>
+ static JSC::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ return vm.apiGlobalObjectSpace<mode>();
+ }
+
+ static DefaultGlobal* create(JSC::VM& vm, JSC::Structure* structure)
+ {
+ auto* object = new (NotNull, allocateCell<DefaultGlobal>(vm.heap)) DefaultGlobal(vm, structure);
+ object->finishCreation(vm);
+ return object;
+ }
+
+ static Structure* createStructure(JSC::VM& vm, JSC::JSValue prototype)
+ {
+ auto* result = Structure::create(vm, nullptr, prototype, TypeInfo(GlobalObjectType, StructureFlags), info());
+ result->setTransitionWatchpointIsLikelyToBeFired(true);
+ return result;
+ }
+
+ static void reportUncaughtExceptionAtEventLoop(JSGlobalObject*, Exception*);
+
+ static JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, JSModuleLoader*, JSC::JSString* moduleNameValue, JSValue parameters, const SourceOrigin&);
+ static JSC::Identifier moduleLoaderResolve(JSGlobalObject*, JSModuleLoader*, JSValue keyValue, JSValue referrerValue, JSValue);
+ static JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, JSModuleLoader*, JSValue, JSValue, JSValue);
+ static JSC::JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*, JSModuleLoader*, JSValue, JSModuleRecord*, JSValue);
+ static JSValue moduleLoaderEvaluate(JSGlobalObject*, JSModuleLoader*, JSValue, JSValue, JSValue, JSValue, JSValue);
+
+
+private:
+ DefaultGlobal(JSC::VM& vm, JSC::Structure* structure)
+ : Base(vm, structure, &s_globalObjectMethodTable)
+ { }
+};
+
+
+}
+
diff --git a/src/javascript/jsc/bindings/DefaultGlobal.zig b/src/javascript/jsc/bindings/DefaultGlobal.zig
new file mode 100644
index 000000000..dfc931efb
--- /dev/null
+++ b/src/javascript/jsc/bindings/DefaultGlobal.zig
@@ -0,0 +1,272 @@
+usingnamespace @import("./imports.zig");
+
+const std = @import("std");
+const main = @import("root");
+const is_bindgen = std.meta.trait.hasDecls(main, .{"bindgen"});
+
+fn Shimmer(comptime name: []const u8, comptime Parent: type) type {
+ return struct {
+ pub inline fn cppFn(comptime typeName: []const u8, args: anytype) (@typeInfo(@TypeOf(@field(Parent.C, typeName))).Fn.return_type orelse void) {
+ if (comptime is_bindgen) {
+ return .{};
+ } else {
+ const func = @field(Parent, typeName);
+ const Func = @TypeOf(func);
+ // const Func: std.builtin.TypeInfo = brk: {
+ // var FuncType: std.builtin.TypeInfo = @typeInfo(@TypeOf(func));
+ // var decl = std.meta.declarationInfo(Parent, name);
+ // var argument_field_list: [function_info.args.len]std.builtin.TypeInfo.StructField = undefined;
+ // inline for (function_info.args) |arg, i| {
+ // const T = arg.arg_type.?;
+ // @setEvalBranchQuota(10_000);
+ // var num_buf: [128]u8 = undefined;
+ // argument_field_list[i] = std.builtin.TypeInfo.StructField{
+ // .name = std.fmt.bufPrint(&num_buf, "{d}", .{i}) catch unreachable,
+ // .field_type = T,
+ // .default_value = @as(?T, null),
+ // .is_comptime = false,
+ // .alignment = if (@sizeOf(T) > 0) @alignOf(T) else 0,
+ // };
+ // }
+
+ // std.builtin.TypeInfo{
+ // .Struct = std.builtin.TypeInfo.Struct{
+ // .is_tuple = true,
+ // .layout = .Auto,
+ // .decls = &[_]std.builtin.TypeInfo.Declaration{},
+ // .fields = &argument_field_list,
+ // },
+ // });
+ // };
+
+ const identifier = comptime std.fmt.comptimePrint("{s}__{s}", .{ name, typeName });
+ const Outgoing = comptime @extern(Func, std.builtin.ExternOptions{ .name = identifier });
+ const Decl: std.builtin.TypeInfo.Fn = @typeInfo(Func).Fn;
+ if (comptime Decl.return_type) |ReturnType| {
+ if (comptime @typeInfo(ReturnType) == .Pointer) {
+ const Ptr: std.builtin.TypeInfo.Pointer = comptime @typeInfo(ReturnType).Pointer;
+ const ChildType: type = brk: {
+ if (@typeInfo(ChildType) == .Struct) {
+ const Struct: std.builtin.TypeInfo.Struct = ChildType.Struct;
+ for (Struct.fields) |field| {
+ if (std.mem.eql(u8, field.name, "ref")) {
+ break :brk field.field_type;
+ }
+ }
+ }
+ break :brk Ptr.child;
+ };
+
+ if (comptime Ptr.is_const) {
+ const return_type = @call(.{}, comptime Outgoing, args);
+ return @ptrCast(*const ChildType, @alignCast(alignment, return_type));
+ } else {
+ var return_type = @call(.{}, comptime Outgoing, args);
+ return @ptrCast(*ChildType, @alignCast(alignment, return_type));
+ }
+ }
+
+ return @as(ReturnType, @call(.{}, comptime Outgoing, args));
+ } else {
+ @call(.{}, comptime Outgoing, args);
+ }
+ }
+ }
+ };
+}
+
+pub const JSCell = packed struct {
+ ref: Type,
+ pub const shim = Shimmer("JSCell", @This());
+ const cppFn = shim.cppFn;
+ pub const include = "\"GenericBindings.h\"";
+ pub const name = "JSC::JSCell";
+
+ pub const Type = *c_void;
+
+ pub fn getObject(this: *const JSCell) ?JSObject {
+ return shim.cppFn("getObject", .{this.ref});
+ }
+
+ pub fn getString(this: *const JSCell, globalObject: *DefaultGlobal) ?String {
+ return shim.cppFn("getString", .{ this.ref, globalObject.ref });
+ }
+
+ pub fn getType(this: *const JSCell) u8 {
+ return @intCast(CellType, shim.cppFn("getType", .{
+ this.ref,
+ }));
+ }
+};
+
+pub const JSString = packed struct {
+ ref: Type,
+ pub const shim = Shimmer("JSString", @This());
+ const cppFn = shim.cppFn;
+ pub const include = "\"GenericBindings.h\"";
+ pub const name = "JSC::JSString";
+
+ pub const Type = *c_void;
+
+ pub fn getObject(this: *const JSCell) ?JSObject {
+
+ return shim.cppFn("getObject", .{this.ref});
+ }
+
+ pub fn getString(this: *const JSCell, globalObject: *DefaultGlobal) ?String {
+ return shim.cppFn("getString", .{ this.ref, globalObject.ref });
+ }
+
+
+};
+
+pub const DefaultGlobal = struct {
+ pub const shim = Shimmer("DefaultGlobal", @This());
+
+ ref: Type,
+ pub const Type = *c_void;
+
+ pub const include = "\"DefaultGlobal.h\"";
+ pub const name = "Wundle::DefaultGlobal";
+
+ const cppFn = shim.cppFn;
+
+ pub fn objectPrototype(instance: *DefaultGlobal) ObjectPrototype {
+ return cppFn("objectPrototype", .{instance.ref});
+ }
+ pub fn functionPrototype(instance: *DefaultGlobal) FunctionPrototype {
+ return cppFn("functionPrototype", .{instance.ref});
+ }
+ pub fn arrayPrototype(instance: *DefaultGlobal) ArrayPrototype {
+ return cppFn("arrayPrototype", .{instance.ref});
+ }
+ pub fn booleanPrototype(instance: *DefaultGlobal) JSObject {
+ return cppFn("booleanPrototype", .{instance.ref});
+ }
+ pub fn stringPrototype(instance: *DefaultGlobal) StringPrototype {
+ return cppFn("stringPrototype", .{instance.ref});
+ }
+ pub fn numberPrototype(instance: *DefaultGlobal) JSObject {
+ return cppFn("numberPrototype", .{instance.ref});
+ }
+ pub fn bigIntPrototype(instance: *DefaultGlobal) BigIntPrototype {
+ return cppFn("bigIntPrototype", .{instance.ref});
+ }
+ pub fn datePrototype(instance: *DefaultGlobal) JSObject {
+ return cppFn("datePrototype", .{instance.ref});
+ }
+ pub fn symbolPrototype(instance: *DefaultGlobal) JSObject {
+ return cppFn("symbolPrototype", .{instance.ref});
+ }
+ pub fn regExpPrototype(instance: *DefaultGlobal) RegExpPrototype {
+ return cppFn("regExpPrototype", .{instance.ref});
+ }
+ pub fn errorPrototype(instance: *DefaultGlobal) JSObject {
+ return cppFn("errorPrototype", .{instance.ref});
+ }
+ pub fn iteratorPrototype(instance: *DefaultGlobal) IteratorPrototype {
+ return cppFn("iteratorPrototype", .{instance.ref});
+ }
+ pub fn asyncIteratorPrototype(instance: *DefaultGlobal) AsyncIteratorPrototype {
+ return cppFn("asyncIteratorPrototype", .{instance.ref});
+ }
+ pub fn generatorFunctionPrototype(instance: *DefaultGlobal) GeneratorFunctionPrototype {
+ return cppFn("generatorFunctionPrototype", .{instance.ref});
+ }
+ pub fn generatorPrototype(instance: *DefaultGlobal) GeneratorPrototype {
+ return cppFn("generatorPrototype", .{instance.ref});
+ }
+ pub fn asyncFunctionPrototype(instance: *DefaultGlobal) AsyncFunctionPrototype {
+ return cppFn("asyncFunctionPrototype", .{instance.ref});
+ }
+ pub fn arrayIteratorPrototype(instance: *DefaultGlobal) ArrayIteratorPrototype {
+ return cppFn("arrayIteratorPrototype", .{instance.ref});
+ }
+ pub fn mapIteratorPrototype(instance: *DefaultGlobal) MapIteratorPrototype {
+ return cppFn("mapIteratorPrototype", .{instance.ref});
+ }
+ pub fn setIteratorPrototype(instance: *DefaultGlobal) SetIteratorPrototype {
+ return cppFn("setIteratorPrototype", .{instance.ref});
+ }
+ pub fn mapPrototype(instance: *DefaultGlobal) JSObject {
+ return cppFn("mapPrototype", .{instance.ref});
+ }
+ pub fn jsSetPrototype(instance: *DefaultGlobal) JSObject {
+ return cppFn("jsSetPrototype", .{instance.ref});
+ }
+ pub fn promisePrototype(instance: *DefaultGlobal) JSPromisePrototype {
+ return cppFn("promisePrototype", .{instance.ref});
+ }
+ pub fn asyncGeneratorPrototype(instance: *DefaultGlobal) AsyncGeneratorPrototype {
+ return cppFn("asyncGeneratorPrototype", .{instance.ref});
+ }
+ pub fn asyncGeneratorFunctionPrototype(instance: *DefaultGlobal) AsyncGeneratorFunctionPrototype {
+ return cppFn("asyncGeneratorFunctionPrototype", .{instance.ref});
+ }
+};
+
+fn _JSCellStub(comptime str: []const u8) type {
+ if (is_bindgen) {
+ return struct {
+ pub const C = struct {
+ pub const name = "JSC::" ++ str ++ "*";
+ ref: ?*c_void = null,
+ };
+ };
+ } else {
+ return struct {
+ pub const C = *c_void;
+ };
+ }
+}
+
+fn _Wundle(comptime str: []const u8) type {
+ if (is_bindgen) {
+ return struct {
+ pub const C = struct {
+ pub const name = "Wundle::" ++ str ++ "*";
+ ref: ?*c_void = null,
+ };
+ };
+ } else {
+ return struct {
+ pub const C = *c_void;
+ };
+ }
+}
+
+fn _WTF(comptime str: []const u8) type {
+ if (is_bindgen) {
+ return struct {
+ pub const C = struct {
+ pub const name = "WTF::" ++ str ++ "*";
+ ref: ?*c_void = null,
+ };
+ };
+ } else {
+ return struct {
+ pub const C = *c_void;
+ };
+ }
+}
+
+const _DefaultGlobal = _Wundle("DefaultGlobal");
+const ObjectPrototype = _JSCellStub("ObjectPrototype");
+const FunctionPrototype = _JSCellStub("FunctionPrototype");
+const ArrayPrototype = _JSCellStub("ArrayPrototype");
+const JSObject = _JSCellStub("JSObject");
+const StringPrototype = _JSCellStub("StringPrototype");
+const BigIntPrototype = _JSCellStub("BigIntPrototype");
+const RegExpPrototype = _JSCellStub("RegExpPrototype");
+const IteratorPrototype = _JSCellStub("IteratorPrototype");
+const AsyncIteratorPrototype = _JSCellStub("AsyncIteratorPrototype");
+const GeneratorFunctionPrototype = _JSCellStub("GeneratorFunctionPrototype");
+const GeneratorPrototype = _JSCellStub("GeneratorPrototype");
+const AsyncFunctionPrototype = _JSCellStub("AsyncFunctionPrototype");
+const ArrayIteratorPrototype = _JSCellStub("ArrayIteratorPrototype");
+const MapIteratorPrototype = _JSCellStub("MapIteratorPrototype");
+const SetIteratorPrototype = _JSCellStub("SetIteratorPrototype");
+const JSPromisePrototype = _JSCellStub("JSPromisePrototype");
+const AsyncGeneratorPrototype = _JSCellStub("AsyncGeneratorPrototype");
+const AsyncGeneratorFunctionPrototype = _JSCellStub("AsyncGeneratorFunctionPrototype");
+const String = _WTF("String");
diff --git a/src/javascript/jsc/bindings/JSCInlines.h b/src/javascript/jsc/bindings/JSCInlines.h
new file mode 100644
index 000000000..f45088ecc
--- /dev/null
+++ b/src/javascript/jsc/bindings/JSCInlines.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+// This file's only purpose is to collect commonly used *Inlines.h files, so that you don't
+// have to include all of them in every .cpp file. Instead you just include this. It's good
+// style to make sure that every .cpp file includes JSCInlines.h.
+//
+// JSC should never include this file, or any *Inline.h file, from interface headers, since
+// this could lead to a circular dependency.
+//
+// WebCore, or any other downstream client of JSC, is allowed to include this file in headers.
+// In fact, it can make a lot of sense: outside of JSC, this file becomes a kind of umbrella
+// header that pulls in most (all?) of the interesting things in JSC.
+
+#include <JavaScriptCore/ExceptionHelpers.h>
+#include <JavaScriptCore/GCIncomingRefCountedInlines.h>
+#include <JavaScriptCore/HeapInlines.h>
+#include <JavaScriptCore/IdentifierInlines.h>
+#include <JavaScriptCore/JSArrayBufferViewInlines.h>
+#include <JavaScriptCore/JSCJSValueInlines.h>
+#include <JavaScriptCore/JSCellInlines.h>
+#include <JavaScriptCore/JSFunctionInlines.h>
+#include <JavaScriptCore/JSGlobalObjectInlines.h>
+#include <JavaScriptCore/JSObjectInlines.h>
+#include <JavaScriptCore/JSProxy.h>
+#include <JavaScriptCore/JSString.h>
+#include <JavaScriptCore/Operations.h>
+#include <JavaScriptCore/SlotVisitorInlines.h>
+#include <JavaScriptCore/StrongInlines.h>
+#include <JavaScriptCore/StructureInlines.h>
+#include <JavaScriptCore/ThrowScope.h>
+#include <JavaScriptCore/WeakGCMapInlines.h>
+#include <JavaScriptCore/WeakGCSetInlines.h>
diff --git a/src/javascript/jsc/bindings/JSValue.zig b/src/javascript/jsc/bindings/JSValue.zig
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/javascript/jsc/bindings/JSValue.zig
diff --git a/src/javascript/jsc/bindings/bindings-generator.zig b/src/javascript/jsc/bindings/bindings-generator.zig
new file mode 100644
index 000000000..ac6fbe738
--- /dev/null
+++ b/src/javascript/jsc/bindings/bindings-generator.zig
@@ -0,0 +1,32 @@
+const Bindings = @import("bindings.zig");
+const HeaderGen = @import("./header-gen.zig").HeaderGen;
+
+const std = @import("std");
+const builtin = std.builtin;
+const io = std.io;
+const fs = std.fs;
+const process = std.process;
+const ChildProcess = std.ChildProcess;
+const Progress = std.Progress;
+const print = std.debug.print;
+const mem = std.mem;
+const testing = std.testing;
+const Allocator = std.mem.Allocator;
+
+pub const bindgen = true;
+
+pub fn main() anyerror!void {
+ var allocator = std.heap.c_allocator;
+ var stdout = std.io.getStdOut();
+ var writer = stdout.writer();
+ const src: std.builtin.SourceLocation = @src();
+ const paths = [_][]const u8{ std.fs.path.dirname(src.file) orelse return error.BadPath, "headers.h" };
+ const file = try std.fs.createFileAbsolute(try std.fs.path.join(allocator, &paths), .{});
+
+ const HeaderGenerator = HeaderGen(
+ Bindings,
+ "src/javascript/jsc/bindings/bindings.zig",
+ );
+
+ HeaderGenerator.exec(HeaderGenerator{}, file);
+}
diff --git a/src/javascript/jsc/bindings/bindings.cpp b/src/javascript/jsc/bindings/bindings.cpp
new file mode 100644
index 000000000..ad35863e2
--- /dev/null
+++ b/src/javascript/jsc/bindings/bindings.cpp
@@ -0,0 +1,10 @@
+#include "root.h"
+
+
+// namespace Bundler {
+// class CustomGlobalObject : public JSC::JSGlobalObject {
+
+// };
+
+// }
+
diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig
new file mode 100644
index 000000000..016de2ab9
--- /dev/null
+++ b/src/javascript/jsc/bindings/bindings.zig
@@ -0,0 +1,2 @@
+pub usingnamespace @import("./JSValue.zig");
+pub usingnamespace @import("./DefaultGlobal.zig");
diff --git a/src/javascript/jsc/bindings/header-gen.zig b/src/javascript/jsc/bindings/header-gen.zig
new file mode 100644
index 000000000..e0ea96a21
--- /dev/null
+++ b/src/javascript/jsc/bindings/header-gen.zig
@@ -0,0 +1,368 @@
+const std = @import("std");
+const Dir = std.fs.Dir;
+const FnMeta = std.builtin.TypeInfo.Fn;
+const FnDecl = std.builtin.TypeInfo.Declaration.Data.FnDecl;
+const StructMeta = std.builtin.TypeInfo.Struct;
+const EnumMeta = std.builtin.TypeInfo.Enum;
+const UnionMeta = std.builtin.TypeInfo.Union;
+const warn = std.debug.warn;
+
+pub const C_Generator = struct {
+ file: std.fs.File,
+ filebase: []const u8,
+ const Self = @This();
+
+ pub fn init(comptime src_file: []const u8, file: std.fs.File) Self {
+ var res = Self{ .file = file, .filebase = src_file };
+
+ file.writeAll("\n/**** " ++ src_file ++ " /*****/\n\n") catch unreachable;
+ return res;
+ }
+
+ pub fn deinit(self: *Self) void {
+ self.file.writeAll("\n/***** ") catch unreachable;
+ self.file.writeAll(self.filebase) catch unreachable;
+ self.file.writeAll(" *****/") catch unreachable;
+ }
+
+ pub fn gen_func(self: *Self, comptime name: []const u8, comptime func: FnDecl, comptime meta: FnMeta, comptime arg_names: []const []const u8) void {
+ switch (meta.calling_convention) {
+ .Naked => self.write("__attribute__((naked)) "),
+ .Stdcall => self.write("__attribute__((stdcall)) "),
+ .Fastcall => self.write("__attribute__((fastcall)) "),
+ .Thiscall => self.write("__attribute__((thiscall)) "),
+ else => {},
+ }
+
+ self.write("extern \"C\" ");
+ self.writeType(func.return_type);
+ self.write(" " ++ name ++ "(");
+
+ inline for (meta.args) |arg, i| {
+ self.writeType(arg.arg_type.?);
+ if (func.arg_names.len > i) {
+ self.write(comptime arg_names[i]);
+ } else {
+ self.write(comptime std.fmt.comptimePrint(" arg{d}", .{i}));
+ }
+
+ //TODO: Figure out how to get arg names; for now just do arg0..argN
+ if (i != meta.args.len - 1)
+ self.write(", ");
+ }
+
+ self.write(");\n");
+ }
+
+ pub fn gen_struct(self: *Self, comptime name: []const u8, comptime meta: StructMeta) void {
+ self.write("typedef struct ");
+
+ if (meta.layout == .Packed)
+ self.write("__attribute__((__packed__)) ");
+
+ self.write(name ++ " {\n");
+
+ inline for (meta.fields) |field| {
+ self.write(" ");
+
+ const info = @typeInfo(field.field_type);
+
+ if (info == .Array) {
+ self.writeType(info.Array.child);
+ } else {
+ self.writeType(field.field_type);
+ }
+
+ self.write(" " ++ field.name);
+
+ if (info == .Array) {
+ _ = self.file.writer().print("[{}]", .{info.Array.len}) catch unreachable;
+ }
+
+ self.write(";\n");
+ }
+ self.write("} " ++ name ++ "_t;\n\n");
+ }
+
+ pub fn gen_enum(self: *Self, comptime name: []const u8, comptime meta: EnumMeta) void {
+ self.write("enum " ++ name ++ " {\n");
+
+ comptime var last = 0;
+ inline for (meta.fields) |field, i| {
+ self.write(" " ++ field.name);
+
+ // if field value is unexpected/custom, manually define it
+ if ((i == 0 and field.value != 0) or (i > 0 and field.value > last + 1)) {
+ _ = self.file.writer().print(" = {}", .{field.value}) catch unreachable;
+ }
+
+ self.write(",\n");
+
+ last = field.value;
+ }
+
+ self.write("};\n\n");
+ }
+
+ pub fn gen_union(self: *Self, comptime name: []const u8, comptime meta: UnionMeta) void {
+ self.write("typedef union ");
+
+ self.write(name ++ " {\n");
+
+ inline for (meta.fields) |field| {
+ self.write(" ");
+ self.writeType(field.field_type);
+ self.write(" " ++ field.name ++ ";\n");
+ }
+ self.write("} " ++ name ++ "_t;\n\n");
+ }
+
+ fn writeType(self: *Self, comptime T: type) void {
+ const TT = if (@typeInfo(T) == .Pointer) @typeInfo(T).Pointer.child else T;
+
+ if (comptime std.meta.trait.hasDecls(TT, .{"C"}) and std.meta.trait.hasDecls(TT.C, .{"name"})) {
+ writeType(self, TT.C);
+ if (std.meta.trait.isSingleItemPtr(T)) {
+ write(self, "*");
+ }
+ return;
+ }
+
+ if (comptime std.meta.trait.hasDecls(TT, .{"name"})) {
+ self.write(comptime T.name);
+ if (std.meta.trait.isSingleItemPtr(T)) {
+ write(self, "*");
+ }
+ return;
+ }
+
+ switch (T) {
+ void => self.write("void"),
+ bool => self.write("bool"),
+ usize => self.write("size_t"),
+ isize => self.write("int"),
+ u8 => self.write("uint8_t"),
+ u16 => self.write("uint16_t"),
+ u32 => self.write("uint32_t"),
+ u64 => self.write("uint64_t"),
+ i8 => self.write("int8_t"),
+ i16 => self.write("int16_t"),
+ i24 => self.write("int24_t"),
+ i32 => self.write("int32_t"),
+ i64 => self.write("int64_t"),
+ [*]bool => self.write("bool*"),
+ [*]usize => self.write("size_t*"),
+ [*]isize => self.write("int*"),
+ [*]u8 => self.write("uint8_t*"),
+ [*]u16 => self.write("uint16_t*"),
+ [*]u32 => self.write("uint32_t*"),
+ [*]u64 => self.write("uint64_t*"),
+ [*]i8 => self.write("int8_t*"),
+ [*]i16 => self.write("int16_t*"),
+ [*]i32 => self.write("int32_t*"),
+ [*]i64 => self.write("int64_t*"),
+ else => {
+ const meta = @typeInfo(T);
+ switch (meta) {
+ .Pointer => {
+ const child = meta.Pointer.child;
+ const childmeta = @typeInfo(child);
+ // if (childmeta == .Struct and childmeta.Struct.layout != .Extern) {
+ // self.write("void");
+ // } else {
+ self.writeType(child);
+ // }
+ self.write("*");
+ },
+ .Optional => self.writeType(meta.Optional.child),
+ .Array => @compileError("Handle goofy looking C Arrays in the calling function"),
+ else => self.write(@typeName(T) ++ "_t"),
+ }
+ },
+ }
+ }
+
+ fn write(self: *Self, comptime str: []const u8) void {
+ _ = self.file.writeAll(str) catch {};
+ }
+};
+
+const builtin = std.builtin;
+const TypeInfo = builtin.TypeInfo;
+const Declaration = TypeInfo.Declaration;
+
+const GeneratorInterface = struct {
+ fn init() void {}
+ fn deinit() void {}
+ fn gen_func() void {}
+ fn gen_struct() void {}
+ fn gen_enum() void {}
+ fn gen_union() void {}
+};
+
+fn validateGenerator(comptime Generator: type) void {
+ comptime {
+ const interface = @typeInfo(GeneratorInterface).Struct.decls;
+
+ for (interface) |decl| {
+ if (@hasDecl(Generator, decl.name) == false) {
+ @compileError("Generator: '" ++
+ @typeName(Generator) ++
+ "' is missing function: " ++
+ decl.name);
+ }
+ }
+ }
+}
+
+const NamedStruct = struct {
+ name: []const u8,
+ Type: type,
+};
+
+pub fn getCStruct(comptime T: type) ?NamedStruct {
+ if (!std.meta.trait.isContainer(T) or (std.meta.trait.isSingleItemPtr(T) and !std.meta.trait.isContainer(std.meta.Child(T)))) {
+ return null;
+ }
+
+ inline for (std.meta.declarations(T)) |decl| {
+ if (std.mem.eql(u8, decl.name, "C")) {
+ switch (decl.data) {
+ .Type => |TT| {
+ return NamedStruct{ .Type = TT, .name = @typeName(T) };
+ },
+ else => {},
+ }
+ }
+ }
+
+ return null;
+}
+
+pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
+ const all_decls = std.meta.declarations(import);
+
+ return struct {
+ source_file: []const u8 = fname,
+
+ const Self = @This();
+
+ pub fn init() Self {
+ return Self{};
+ }
+
+ pub fn processDecls(
+ comptime self: Self,
+ file: std.fs.File,
+ comptime Parent: type,
+ comptime Type: type,
+ comptime prefix: []const u8,
+ ) void {
+ const decls = std.meta.declarations(Type);
+ var gen = C_Generator.init(prefix, file);
+ defer gen.deinit();
+
+ if (comptime std.meta.trait.hasDecls(Type, .{"include"})) {
+ comptime var new_name = std.mem.zeroes([Type.include.len]u8);
+
+ comptime {
+ _ = std.mem.replace(u8, Type.include, "/", "_", std.mem.span(&new_name));
+ _ = std.mem.replace(u8, &new_name, ".", "_", std.mem.span(&new_name));
+ }
+ const inner_name = comptime std.mem.trim(u8, &new_name, "<>\"");
+ file.writeAll("#ifndef BINDINGS__decls__" ++ inner_name ++ "\n") catch {};
+ file.writeAll("#define BINDINGS__decls__" ++ inner_name ++ "\n") catch {};
+ file.writeAll("#include " ++ Type.include ++ "\n") catch {};
+ file.writeAll("namespace Wundle {\n class " ++ prefix ++ ";\n}\n") catch {};
+ file.writeAll("#endif\n\n") catch {};
+ }
+
+ // iterate exported enums
+ // do this first in case target lang needs enums defined before use
+ inline for (decls) |decl| {
+ if (decl.is_pub and decl.data == .Type and comptime std.ascii.isUpper(decl.name[0])) {
+ const T = decl.data.Type;
+ const info = @typeInfo(T);
+ if (info == .Enum and decl.is_pub) {
+ const layout = info.Enum.layout;
+ gen.gen_enum(prefix ++ "__" ++ decl.name, info.Enum);
+ }
+ }
+ }
+
+ // iterate exported structs
+ inline for (decls) |decl| {
+ if (decl.is_pub and decl.data == .Type and decl.is_pub and comptime std.ascii.isUpper(decl.name[0])) {
+ const T = decl.data.Type;
+ const info = @typeInfo(T);
+ if (info == .Struct and decl.is_pub) {
+ gen.gen_struct(decl.name, @typeInfo(T).Struct);
+ }
+ }
+ }
+
+ inline for (decls) |decl| {
+ if (decl.is_pub and decl.data == .Type and decl.is_pub) {
+ const T = decl.data.Type;
+ const info = @typeInfo(T);
+ if (info == .Union and comptime std.ascii.isUpper(decl.name[0])) {
+ const layout = info.Union.layout;
+ gen.gen_union(prefix ++ "__" ++ decl.name, info.Union);
+ }
+ }
+ }
+
+ // iterate exported fns
+ inline for (decls) |decl, decl_i| {
+ if (decl.is_pub and decl.data == .Fn and decl.is_pub) {
+ const func = decl.data.Fn;
+ // if (func.) {
+ const fn_meta = @typeInfo(func.fn_type).Fn;
+ const info = @typeInfo(Type);
+ const struct_decl = info.Struct.decls[decl_i];
+ // blocked by https://github.com/ziglang/zig/issues/8259
+ gen.gen_func(
+ prefix ++ "__" ++ decl.name,
+ func,
+ fn_meta,
+ struct_decl.data.Fn.arg_names,
+ );
+ // }
+ }
+ }
+ }
+
+ pub fn exec(comptime self: Self, file: std.fs.File) void {
+ const Generator = C_Generator;
+ validateGenerator(Generator);
+
+ file.writeAll("#pragma once\n#include <stddef.h>\n#include <stdint.h>\n#include <stdbool.h>\n\n") catch {};
+
+ inline for (all_decls) |_decls| {
+ if (comptime _decls.is_pub) {
+ switch (_decls.data) {
+ .Type => |Type| {
+ if (getCStruct(Type)) |CStruct| {
+ processDecls(
+ self,
+ file,
+ Type,
+ CStruct.Type,
+ CStruct.name,
+ );
+ }
+ },
+ else => {},
+ }
+ }
+ }
+
+ // processDecls(
+ // self,
+ // file,
+ // import,
+ // "Bindings",
+ // );
+ }
+ };
+}
diff --git a/src/javascript/jsc/bindings/headers.h b/src/javascript/jsc/bindings/headers.h
new file mode 100644
index 000000000..231c6697e
--- /dev/null
+++ b/src/javascript/jsc/bindings/headers.h
@@ -0,0 +1,42 @@
+#pragma once
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+
+/**** DefaultGlobal /*****/
+
+#ifndef BINDINGS__decls__DefaultGlobal_h
+#define BINDINGS__decls__DefaultGlobal_h
+#include "DefaultGlobal.h"
+namespace Wundle {
+ class DefaultGlobal;
+}
+#endif
+
+extern "C" JSC::ObjectPrototype* DefaultGlobal__objectPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::FunctionPrototype* DefaultGlobal__functionPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::ArrayPrototype* DefaultGlobal__arrayPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::JSObject* DefaultGlobal__booleanPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::StringPrototype* DefaultGlobal__stringPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::JSObject* DefaultGlobal__numberPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::BigIntPrototype* DefaultGlobal__bigIntPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::JSObject* DefaultGlobal__datePrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::JSObject* DefaultGlobal__symbolPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::RegExpPrototype* DefaultGlobal__regExpPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::JSObject* DefaultGlobal__errorPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::IteratorPrototype* DefaultGlobal__iteratorPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::AsyncIteratorPrototype* DefaultGlobal__asyncIteratorPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::GeneratorFunctionPrototype* DefaultGlobal__generatorFunctionPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::GeneratorPrototype* DefaultGlobal__generatorPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::AsyncFunctionPrototype* DefaultGlobal__asyncFunctionPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::ArrayIteratorPrototype* DefaultGlobal__arrayIteratorPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::MapIteratorPrototype* DefaultGlobal__mapIteratorPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::SetIteratorPrototype* DefaultGlobal__setIteratorPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::JSObject* DefaultGlobal__mapPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::JSObject* DefaultGlobal__jsSetPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::JSPromisePrototype* DefaultGlobal__promisePrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::AsyncGeneratorPrototype* DefaultGlobal__asyncGeneratorPrototype(Wundle::DefaultGlobal* arg0);
+extern "C" JSC::AsyncGeneratorFunctionPrototype* DefaultGlobal__asyncGeneratorFunctionPrototype(Wundle::DefaultGlobal* arg0);
+
+/***** DefaultGlobal *****/ \ No newline at end of file
diff --git a/src/javascript/jsc/bindings/imports.zig b/src/javascript/jsc/bindings/imports.zig
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/src/javascript/jsc/bindings/imports.zig
@@ -0,0 +1 @@
+
diff --git a/src/javascript/jsc/bindings/inlines.cpp b/src/javascript/jsc/bindings/inlines.cpp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/javascript/jsc/bindings/inlines.cpp
diff --git a/src/javascript/jsc/bindings/root.h b/src/javascript/jsc/bindings/root.h
new file mode 100644
index 000000000..2ac4c15bc
--- /dev/null
+++ b/src/javascript/jsc/bindings/root.h
@@ -0,0 +1,71 @@
+#pragma once
+
+/*
+ * Copyright (C) 2006-2021 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#define HAVE_CONFIG_H 1
+#define BUILDING_WITH_CMAKE 1
+
+#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H && defined(BUILDING_WITH_CMAKE)
+#include "cmakeconfig.h"
+#endif
+
+#define JSC_API_AVAILABLE(...)
+#define JSC_CLASS_AVAILABLE(...) JS_EXPORT
+#define JSC_API_DEPRECATED(...)
+// Use zero since it will be less than any possible version number.
+#define JSC_MAC_VERSION_TBA 0
+#define JSC_IOS_VERSION_TBA 0
+
+#include <wtf/ExportMacros.h>
+
+#if !defined(JS_EXPORT_PRIVATE)
+
+#if defined(BUILDING_JavaScriptCore) || defined(STATICALLY_LINKED_WITH_JavaScriptCore)
+#define JS_EXPORT_PRIVATE WTF_EXPORT_DECLARATION
+#else
+#define JS_EXPORT_PRIVATE WTF_IMPORT_DECLARATION
+#endif
+
+#endif
+
+
+#ifdef __cplusplus
+#undef new
+#undef delete
+#include <wtf/FastMalloc.h>
+#endif
+
+#include <wtf/DisallowCType.h>
+
+/* Disabling warning C4206: nonstandard extension used: translation unit is empty.
+ By design, we rely on #define flags to make some translation units empty.
+ Make sure this warning does not turn into an error.
+*/
+#if COMPILER(MSVC)
+#pragma warning(disable:4206)
+#endif
+
+#ifdef USE_FOUNDATION
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+
+#include <JavaScriptCore/Heap.h> \ No newline at end of file
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index 416897ccf..e984ccbb1 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -163,6 +163,10 @@ 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.* = .{
@@ -188,10 +192,9 @@ pub const VirtualMachine = struct {
global.* = GlobalObject{ .vm = vm };
try vm.global.boot();
vm.ctx = vm.global.ctx;
-
+ Properties.init();
Module.boot(vm);
- Properties.init();
if (vm.bundler.options.node_modules_bundle) |bundle| {
vm.node_modules = bundle;
vm.node_module_list = try allocator.create(Module.NodeModuleList);
@@ -201,6 +204,47 @@ pub const VirtualMachine = struct {
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 {
@@ -517,7 +561,8 @@ pub const Module = struct {
);
if (this.console == null) {
- this.console = js.JSObjectMake(js.JSContextGetGlobalContext(ctx), this.vm.global.console_class, this.vm.global);
+ this.console = js.JSObjectMake(js.JSContextGetGlobalContext(ctx), GlobalObject.ConsoleClass.get().*, this.vm.global);
+ js.JSValueProtect(ctx, this.console);
}
return this.console;
@@ -611,8 +656,7 @@ pub const Module = struct {
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.staticFunctions = GlobalObject.GlobalClass.definition.staticFunctions;
- // node_module_global_class_def.parentClass = vm.global.global_class;
+ 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);
@@ -637,7 +681,6 @@ pub const Module = struct {
// .callAsFunction = To.JS.Callback(NodeModuleList, initializeNodeModule),
// };
// node_module_global_class_def.staticFunctions = &node_module_list.static_functions;
- node_module_list.node_module_global_class_def = node_module_global_class_def;
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);
@@ -708,45 +751,7 @@ pub const Module = struct {
return ref;
}
- 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| {
- Output.prettyErrorln(
- "<r><red>RequireError<r>: Failed to load module <b>\"{s}\"<r> at \"{s}\": <red>{s}<r>",
- .{ import_path, module.path.name.dirWithTrailingSlash(), @errorName(err) },
- );
- Output.flush();
- JSError(
- getAllocator(ctx),
- "{s}: failed to load module \"{s}\" from \"{s}\"",
- .{
- @errorName(err),
- import_path,
- module.path.name.dirWithTrailingSlash(),
- },
- ctx,
- exception,
- );
- return null;
- }
+ return this.vm.require(ctx, module.path.name.dirWithTrailingSlash(), import_path, exception);
}
pub fn requireFirst(
@@ -853,9 +858,9 @@ pub const Module = struct {
return null;
}
- const ModuleClass = NewClass(
+ pub const ModuleClass = NewClass(
Module,
- .{ .name = "Module" },
+ .{ .name = Properties.UTF8.module },
.{
.@"require" = require,
.@"requireFirst" = requireFirst,
@@ -888,6 +893,7 @@ pub const Module = struct {
// ExportsClass.callAsConstructor = To.JS.Callback(Module, callExportsAsConstructor);
exports_class_ref = js.JSClassRetain(js.JSClassCreate(&ExportsClass));
+ _ = Module.ModuleClass.get().*;
}
pub const LoadResult = union(Tag) {
@@ -907,13 +913,26 @@ pub const Module = struct {
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: [:0]u8, 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.JSStringCreateWithUTF8CString(source.ptr);
- defer js.JSStringRelease(source_code_ref);
- var source_url = try allocator.dupeZ(u8, path.text);
- defer allocator.free(source_url);
- var source_url_ref = js.JSStringCreateWithUTF8CString(source_url.ptr);
- defer js.JSStringRelease(source_url_ref);
+ 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 });
@@ -926,16 +945,16 @@ pub const Module = struct {
.ref = undefined,
.vm = vm,
};
- module.ref = js.JSObjectMake(global_ctx, Module.ModuleClass.get(), module);
+ 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.JSStringRetain(js.JSStringCreateWithUTF8CString(Properties.UTF8.module[0.. :0]));
- module_wrapper_params[1] = js.JSStringRetain(js.JSStringCreateWithUTF8CString(Properties.UTF8.exports[0.. :0]));
- // module_wrapper_loaded = true;
+ 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;
@@ -951,7 +970,7 @@ pub const Module = struct {
@truncate(c_uint, module_wrapper_params.len),
&module_wrapper_params,
source_code_ref,
- null,
+ source_url,
1,
&except,
);
@@ -1140,7 +1159,7 @@ pub const Module = struct {
vm,
vm.allocator,
vm.log,
- source_code_printer.ctx.sentinel,
+ source_code_printer.ctx.written,
path,
js.JSContextGetGlobalContext(ctx),
ctx,
@@ -1154,7 +1173,7 @@ pub const Module = struct {
vm,
vm.allocator,
vm.log,
- source_code_printer.ctx.sentinel,
+ source_code_printer.ctx.written,
path,
js.JSContextGetGlobalContext(ctx),
ctx,
@@ -1245,7 +1264,7 @@ pub const Module = struct {
exception: js.ExceptionRef,
) callconv(.C) js.JSValueRef {
if (this.id == null) {
- this.id = js.JSStringCreateWithUTF8CString(this.path.text.ptr);
+ this.id = js.JSStringCreateStatic(this.path.text.ptr, this.path.text.len);
}
return this.id;
@@ -1475,9 +1494,7 @@ pub const GlobalObject = struct {
ref: js.JSObjectRef = undefined,
vm: *VirtualMachine,
ctx: js.JSGlobalContextRef = undefined,
- console_class: js.JSClassRef = undefined,
- console: js.JSObjectRef = undefined,
- console_definition: js.JSClassDefinition = undefined,
+ console: js.JSObjectRef = null,
global_class_def: js.JSClassDefinition = undefined,
global_class: js.JSClassRef = undefined,
@@ -1530,12 +1547,12 @@ pub const GlobalObject = struct {
obj: js.JSObjectRef,
exception: js.ExceptionRef,
) js.JSValueRef {
- // if (global.console == null) {
- // global.console = js.JSObjectMake(js.JSContextGetGlobalContext(ctx), global.console_class, global);
- // js.JSValueProtect(js.JSContextGetGlobalContext(ctx), global.console);
- // }
+ if (global.console == null) {
+ global.console = js.JSObjectMake(js.JSContextGetGlobalContext(ctx), ConsoleClass.get().*, global);
+ js.JSValueProtect(ctx, global.console);
+ }
- return js.JSObjectMake(js.JSContextGetGlobalContext(ctx), ConsoleClass.get().*, global);
+ return global.console;
}
pub fn boot(global: *GlobalObject) !void {
diff --git a/src/javascript/jsc/typescript.zig b/src/javascript/jsc/typescript.zig
index da22fc88c..e10df2b2f 100644
--- a/src/javascript/jsc/typescript.zig
+++ b/src/javascript/jsc/typescript.zig
@@ -27,43 +27,66 @@ const hidden_globals = [_]d.ts.decl{
const global = JavaScript.GlobalObject.GlobalClass.typescriptDeclaration();
pub fn main() anyerror!void {
+ var allocator = std.heap.c_allocator;
var argv = std.mem.span(std.os.argv);
- var dest = [_]string{ argv[argv.len - 2], argv[argv.len - 1] };
-
- var dir_path = resolve_path.joinAbs(std.process.getCwdAlloc(allocator), .auto, &dest);
+ var dest = [_]string{ std.mem.span(argv[argv.len - 2]), std.mem.span(argv[argv.len - 1]) };
+ var stdout = std.io.getStdOut();
+ var writer = stdout.writer();
+ try writer.print("{s}/{s}\n", .{ dest[0], dest[1] });
+ var dir_path = resolve_path.joinAbsString(try std.process.getCwdAlloc(allocator), &dest, .auto);
std.debug.assert(dir_path.len > 0 and strings.eqlComptime(std.fs.path.basename(dir_path), "types"));
- try std.fs.deleteTreeAbsolute(dir_path);
+ std.fs.deleteTreeAbsolute(dir_path) catch {};
try std.fs.makeDirAbsolute(dir_path);
var dir = try std.fs.openDirAbsolute(dir_path, std.fs.Dir.OpenDirOptions{});
+ var index_file = try dir.createFile("index.d.ts", .{});
+ try index_file.writeAll(
+ \\/// <reference no-default-lib="true" />
+ \\/// <reference lib="esnext" />
+ \\/// <reference types="speedy.js/types/globals" />
+ \\/// <reference types="speedy.js/types/modules" />
+ \\
+ );
+
+ var global_file = try dir.createFile("globals.d.ts", .{});
+ try global_file.writeAll(
+ \\// Speedy.js v
+ \\
+ \\
+ );
+ try global_file.writeAll(comptime d.ts.class.Printer.printDecl(global, 0));
- var index_file = dir.openFile("index.d.ts", .{ .write = true });
- try index_file.writeAll(comptime d.ts.class.Printer.printDecl(global, 0));
+ var module_file = try dir.createFile("modules.d.ts", .{});
+ try module_file.writeAll(
+ \\// Speedy.js v
+ \\
+ \\
+ );
- try index_file.writeAll("\n");
+ try global_file.writeAll("\n");
- try index_file.writeAll("declare global {\n");
+ try global_file.writeAll("declare global {\n");
inline for (hidden_globals) |module, i| {
if (i > 0) {
- try index_file.writeAll("\n");
+ try global_file.writeAll("\n");
}
- try index_file.writeAll(comptime d.ts.class.Printer.printDecl(module, 2));
+ try global_file.writeAll(comptime d.ts.class.Printer.printDecl(module, 2));
}
- try index_file.writeAll("}\n");
- var stdout = std.io.getStdOut();
- try stdout.writeAll("✔️ index.d.ts");
+ try global_file.writeAll("}\n\n");
+ try stdout.writeAll(" ✔️ index.d.ts\n");
inline for (modules) |decl| {
- var module: d.ts.module = comptime decl.module;
+ comptime var module: d.ts.module = decl.module;
const basepath = comptime module.path["speedy.js/".len..];
if (std.fs.path.dirname(basepath)) |dirname| {
- dir.makePath(dirname);
+ try dir.makePath(dirname);
}
- var file = try dir.openFile(comptime basepath ++ ".d.ts", .{ .write = true });
- try file.writeAll(comptime d.ts.class.Printer.printDecl(module, 0));
- try stdout.writeAll(comptime "✔️ " ++ basepath);
+ try module_file.writeAll(comptime d.ts.class.Printer.printDecl(decl, 0));
+ try stdout.writeAll(comptime " ✔️ " ++ basepath ++ " - modules.d.ts\n");
}
+
+ try global_file.writeAll("export {};\n");
}
diff --git a/src/js_printer.zig b/src/js_printer.zig
index 6cbd1a931..fbdff279a 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -3790,6 +3790,7 @@ pub const BufferWriter = struct {
) anyerror!void {
if (ctx.append_null_byte) {
ctx.sentinel = ctx.buffer.toOwnedSentinelLeaky();
+ ctx.written = ctx.buffer.toOwnedSliceLeaky();
} else {
ctx.written = ctx.buffer.toOwnedSliceLeaky();
}
diff --git a/src/router.zig b/src/router.zig
index 67a203d09..40deb4349 100644
--- a/src/router.zig
+++ b/src/router.zig
@@ -180,6 +180,7 @@ const TinyPtr = packed struct {
const Param = struct {
key: string,
+ kind: RoutePart.Tag,
value: string,
pub const List = std.MultiArrayList(Param);
@@ -302,25 +303,6 @@ pub const RouteMap = struct {
return written;
}
- pub const MatchedRoute = struct {
- /// normalized url path from the request
- path: string,
- /// raw url path from the request
- pathname: string,
- /// absolute filesystem path to the entry point
- file_path: string,
- /// route name, like `"posts/[id]"`
- name: string,
-
- /// basename of the route in the file system, including file extension
- basename: string,
-
- hash: u32,
- params: *Param.List,
- redirect_path: ?string = null,
- query_string: string = "",
- };
-
const MatchContext = struct {
params: *Param.List,
segments: []string,
@@ -339,7 +321,7 @@ pub const RouteMap = struct {
this: *MatchContext,
head_i: u16,
segment_i: u16,
- ) ?MatchedRoute {
+ ) ?Match {
var match = this._matchDynamicRoute(head_i, segment_i) orelse return null;
this.matched_route_name.append("/");
this.matched_route_name.append(match.name);
@@ -350,7 +332,7 @@ pub const RouteMap = struct {
this: *MatchContext,
head_i: u16,
segment_i: u16,
- ) ?MatchedRoute {
+ ) ?Match {
const start_len = this.params.len;
var head = this.map.routes.get(head_i);
const segment = this.segments[segment_i];
@@ -369,7 +351,7 @@ pub const RouteMap = struct {
else => {},
}
- var match_result: MatchedRoute = undefined;
+ var match_result: Match = undefined;
if (head.children.len > 0 and remaining.len > 0) {
var child_i = head.children.offset;
const last = child_i + head.children.len;
@@ -391,7 +373,7 @@ pub const RouteMap = struct {
this.params.shrinkRetainingCapacity(start_len);
return null;
} else {
- match_result = MatchedRoute{
+ match_result = Match{
.path = head.path,
.name = head.name,
.params = this.params,
@@ -412,9 +394,10 @@ pub const RouteMap = struct {
.param => {
this.params.append(
this.allocator,
- .{
+ Param{
.key = head.part.str(head.name),
.value = segment,
+ .kind = head.part.tag,
},
) catch unreachable;
},
@@ -427,7 +410,7 @@ pub const RouteMap = struct {
// This makes many passes over the list of routes
// However, most of those passes are basically array.indexOf(number) and then smallerArray.indexOf(number)
- pub fn matchPage(this: *RouteMap, url_path: URLPath, params: *Param.List) ?MatchedRoute {
+ pub fn matchPage(this: *RouteMap, url_path: URLPath, params: *Param.List) ?Match {
// Trim trailing slash
var path = url_path.path;
var redirect = false;
@@ -454,7 +437,7 @@ pub const RouteMap = struct {
if (path.len == 0) {
if (this.index) |index| {
- return MatchedRoute{
+ return Match{
.params = params,
.name = "index",
.path = this.routes.items(.path)[index],
@@ -479,7 +462,7 @@ pub const RouteMap = struct {
const children = this.routes.items(.hash)[route.children.offset .. route.children.offset + route.children.len];
for (children) |child_hash, i| {
if (child_hash == index_route_hash) {
- return MatchedRoute{
+ return Match{
.params = params,
.name = this.routes.items(.name)[i],
.path = this.routes.items(.path)[i],
@@ -492,7 +475,7 @@ pub const RouteMap = struct {
// It's an exact route, there are no params
// /foo/bar => /foo/bar.js
} else {
- return MatchedRoute{
+ return Match{
.params = params,
.name = route.name,
.path = route.path,
@@ -642,3 +625,22 @@ pub fn match(app: *Router, comptime RequestContextType: type, ctx: *RequestConte
try ctx.handleRequest();
}
+
+pub const Match = struct {
+ /// normalized url path from the request
+ path: string,
+ /// raw url path from the request
+ pathname: string,
+ /// absolute filesystem path to the entry point
+ file_path: string,
+ /// route name, like `"posts/[id]"`
+ name: string,
+
+ /// basename of the route in the file system, including file extension
+ basename: string,
+
+ hash: u32,
+ params: *Param.List,
+ redirect_path: ?string = null,
+ query_string: string = "",
+};
diff --git a/src/test/fixtures/console.log.js b/src/test/fixtures/console.log.js
index cb95413ed..3088f90d5 100644
--- a/src/test/fixtures/console.log.js
+++ b/src/test/fixtures/console.log.js
@@ -1,3 +1 @@
-import React from "react";
-
-console.log("Is this JavaScriptCore?", JSON.stringify(<div>hello</div>));
+console.log("Waiting for debugger.");