WIP bindings

Former-commit-id: 74e75d6925
This commit is contained in:
Jarred Sumner
2021-07-18 02:12:58 -07:00
parent e2b9d4c869
commit 79cd2fbfe0
33 changed files with 1989 additions and 294 deletions

View File

@@ -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 => {},
}
}
};

View File

@@ -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,12 +61,18 @@ fn matchRequest(
request: *const Request,
exception: js.ExceptionRef,
) js.JSObjectRef {
return null;
return createRouteObject(ctx, request.request_context, exception);
}
fn matchPathNameString(
ctx: js.JSContextRef,
pathname: string,
exception: js.ExceptionRef,
) js.JSObjectRef {}
fn matchPathName(
ctx: js.JSContextRef,
pathname: string,
pathname: js.JSStringRef,
exception: js.ExceptionRef,
) js.JSObjectRef {
return null;
@@ -60,22 +83,25 @@ 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.",
.args = &[_]d.ts.arg{
.{
.name = "request",
.@"return" = "Request",
},
},
.@"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 {@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 = "event",
@@ -85,7 +111,7 @@ const match_type_definition = &[_]d.ts{
.@"return" = "Route | null",
},
.{
.tsdoc = "Match a `pathname` 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 = "pathname",
@@ -94,6 +120,16 @@ const match_type_definition = &[_]d.ts{
},
.@"return" = "Route | null",
},
.{
.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 = "request",
.@"return" = "Request",
},
},
.@"return" = "Route | null",
},
};
pub const Class = NewClass(
@@ -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);

View File

@@ -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);

View File

@@ -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();
}
}

View File

@@ -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)
{ }
};
}

View File

@@ -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");

View File

@@ -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>

View File

View File

@@ -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);
}

View File

@@ -0,0 +1,10 @@
#include "root.h"
// namespace Bundler {
// class CustomGlobalObject : public JSC::JSGlobalObject {
// };
// }

View File

@@ -0,0 +1,2 @@
pub usingnamespace @import("./JSValue.zig");
pub usingnamespace @import("./DefaultGlobal.zig");

View File

@@ -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",
// );
}
};
}

View File

@@ -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 *****/

View File

@@ -0,0 +1 @@

View File

View File

@@ -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>

View File

@@ -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 {

View File

@@ -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 index_file = dir.openFile("index.d.ts", .{ .write = true });
try index_file.writeAll(comptime d.ts.class.Printer.printDecl(global, 0));
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));
try index_file.writeAll("\n");
var module_file = try dir.createFile("modules.d.ts", .{});
try module_file.writeAll(
\\// Speedy.js v
\\
\\
);
try index_file.writeAll("declare global {\n");
try global_file.writeAll("\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");
}