Former-commit-id: 60cc85dc0652b34e9c7ec409f32ba635cc4b2e51
This commit is contained in:
Jarred Sumner
2021-07-28 10:56:36 -07:00
parent d18ff76912
commit 68fa7ec2d0
14 changed files with 660 additions and 222 deletions

View File

@@ -123,59 +123,100 @@ JSC::Identifier GlobalObject::moduleLoaderResolve(
) {
auto res = Zig__GlobalObject__resolve(
globalObject,
loader,
JSValue::encode(key),
JSValue::encode(referrer),
nullptr
toZigString(key, globalObject),
toZigString(referrer, globalObject)
);
return toIdentifier(res, globalObject);
if (res.success) {
return toIdentifier(res.result.value, globalObject);
} else {
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
throwException(scope, res.result.err.message, globalObject);
return globalObject->vm().propertyNames->emptyIdentifier;
}
}
JSC::JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* globalObject, JSModuleLoader* loader, JSString* specifierValue, JSValue referrer, const SourceOrigin& sourceOrigin) {
return Zig__GlobalObject__import(
globalObject,
loader,
specifierValue,
JSC::JSValue::encode(referrer),
&sourceOrigin
);
JSC::JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* globalObject, JSModuleLoader*, JSString* moduleNameValue, JSValue parameters, const SourceOrigin& sourceOrigin)
{
JSC::VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
auto* promise = JSC::JSInternalPromise::create(vm, globalObject->internalPromiseStructure());
RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope));
auto sourceURL = sourceOrigin.url();
auto resolved = Zig__GlobalObject__resolve(globalObject, toZigString(moduleNameValue, globalObject), sourceURL.isEmpty() ? ZigStringCwd : toZigString(sourceURL.fileSystemPath()));
if (!resolved.success) {
throwException(scope, resolved.result.err.message, globalObject);
return promise->rejectWithCaughtException(globalObject, scope);
}
auto result = JSC::importModule(globalObject, toIdentifier(resolved.result.value, globalObject), parameters, JSC::jsUndefined());
RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope));
return result;
}
JSC::JSInternalPromise* GlobalObject::moduleLoaderFetch(JSGlobalObject* globalObject, JSModuleLoader* loader, JSValue key, JSValue value1, JSValue value2) {
return Zig__GlobalObject__fetch(
JSC::VM& vm = globalObject->vm();
JSC::JSInternalPromise* promise = JSC::JSInternalPromise::create(vm, globalObject->internalPromiseStructure());
auto scope = DECLARE_THROW_SCOPE(vm);
auto rejectWithError = [&](JSC::JSValue error) {
promise->reject(globalObject, error);
return promise;
};
auto moduleKey = key.toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope));
auto moduleKeyZig = toZigString(moduleKey);
auto res = Zig__GlobalObject__fetch(
globalObject,
loader,
JSValue::encode(key),
JSValue::encode(value1),
JSValue::encode(value2)
moduleKeyZig,
ZigStringEmpty
);
if (!res.success) {
throwException(scope, res.result.err.message, globalObject);
RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope));
}
auto code = Zig::toString(res.result.value);
auto sourceCode = JSC::JSSourceCode::create(
vm,
JSC::makeSource(
code,
JSC::SourceOrigin { WTF::URL::fileURLWithFileSystemPath(moduleKey) },
WTFMove(moduleKey),
TextPosition(),
JSC::SourceProviderSourceType::Module
)
);
scope.release();
promise->resolve(globalObject, sourceCode);
return promise;
}
JSC::JSObject* GlobalObject::moduleLoaderCreateImportMetaProperties(JSGlobalObject* globalObject, JSModuleLoader* loader, JSValue key, JSModuleRecord* record, JSValue val) {
auto res = Zig__GlobalObject__createImportMetaProperties(
globalObject,
loader,
JSValue::encode(key),
record,
JSValue::encode(val)
);
return nullptr;
// auto res = Zig__GlobalObject__createImportMetaProperties(
// globalObject,
// loader,
// JSValue::encode(key),
// record,
// JSValue::encode(val)
// );
return JSValue::decode(res).getObject();
// return JSValue::decode(res).getObject();
}
JSC::JSValue GlobalObject::moduleLoaderEvaluate(JSGlobalObject* globalObject, JSModuleLoader* moduleLoader, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher, JSValue sentValue, JSValue resumeMode) {
auto res = Zig__GlobalObject__eval(
globalObject,
moduleLoader,
JSValue::encode(key),
JSValue::encode(moduleRecordValue),
JSValue::encode(scriptFetcher),
JSValue::encode(sentValue),
JSValue::encode(resumeMode)
);
return JSValue::decode(res);
// VM& vm = globalObject->vm();
return moduleLoader->evaluateNonVirtual(globalObject, key, moduleRecordValue, scriptFetcher, sentValue, resumeMode);
}
}

View File

@@ -38,11 +38,15 @@ pub const ZigString = extern struct {
ptr: [*]const u8,
len: usize,
pub fn init(slice: []const u8) ZigString {
return ZigString{ .ptr = slice.ptr, .len = slice.len };
pub fn init(slice_: []const u8) ZigString {
return ZigString{ .ptr = slice_.ptr, .len = slice_.len };
}
pub const Empty = ZigString{ .ptr = "", .len = 0 };
pub fn slice(this: *const ZigString) []const u8 {
return this.ptr[0..this.len];
}
};
pub const JSCell = extern struct {
@@ -168,29 +172,23 @@ pub const ScriptArguments = extern struct {
pub fn NewGlobalObject(comptime Type: type) type {
return struct {
pub fn import(global: *JSGlobalObject, loader: *JSModuleLoader, specifier: *JSString, referrer: JSValue, origin: *const SourceOrigin) callconv(.C) *JSInternalPromise {
pub fn import(global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) ErrorableZigString {
if (comptime @hasDecl(Type, "import")) {
return @call(.{ .modifier = .always_inline }, Interface.import, .{ global, loader, specifier, referrer, origin });
return @call(.{ .modifier = .always_inline }, Interface.import, .{ global, specifier, source });
}
return JSInternalPromise.rejectedPromise(global, JSValue.jsUndefined());
return ErrorableZigString.err(error.ImportFailed, "Import not implemented");
}
pub fn resolve(global: *JSGlobalObject, loader: *JSModuleLoader, specifier: JSValue, value: JSValue, origin: *const SourceOrigin) callconv(.C) ZigString {
pub fn resolve(global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) ErrorableZigString {
if (comptime @hasDecl(Type, "resolve")) {
return @call(.{ .modifier = .always_inline }, Interface.resolve, .{ global, loader, specifier, value, origin });
return @call(.{ .modifier = .always_inline }, Interface.resolve, .{ global, specifier, source });
}
return ZigString.Empty;
return ErrorableZigString.err(error.ResolveFailed, "resolve not implemented");
}
pub fn fetch(global: *JSGlobalObject, loader: *JSModuleLoader, value1: JSValue, value2: JSValue, value3: JSValue) callconv(.C) *JSInternalPromise {
pub fn fetch(global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) ErrorableZigString {
if (comptime @hasDecl(Type, "fetch")) {
return @call(.{ .modifier = .always_inline }, Interface.fetch, .{ global, loader, value1, value2, value3 });
return @call(.{ .modifier = .always_inline }, Interface.fetch, .{ global, specifier, source });
}
return JSInternalPromise.rejectedPromise(global, JSValue.jsUndefined());
}
pub fn eval(global: *JSGlobalObject, loader: *JSModuleLoader, key: JSValue, moduleRecordValue: JSValue, scriptFetcher: JSValue, awaitedValue: JSValue, resumeMode: JSValue) callconv(.C) JSValue {
if (comptime @hasDecl(Type, "eval")) {
return @call(.{ .modifier = .always_inline }, Interface.eval, .{ global, loader, key, moduleRecordValue, scriptFetcher, awaitedValue, resumeMode });
}
return JSValue.jsUndefined();
return ErrorableZigString.err(error.FetchFailed, "Module fetch not implemented");
}
pub fn promiseRejectionTracker(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue {
if (comptime @hasDecl(Type, "promiseRejectionTracker")) {

View File

@@ -1,5 +1,7 @@
usingnamespace @import("./bindings.zig");
usingnamespace @import("./shared.zig");
usingnamespace @import("../new.zig");
const Fs = @import("../../../fs.zig");
const Handler = struct {
pub export fn global_signal_handler_fn(sig: i32, info: *const std.os.siginfo_t, ctx_ptr: ?*const c_void) callconv(.C) void {
@@ -32,31 +34,26 @@ pub const ZigGlobalObject = extern struct {
return shim.cppFn("create", .{ vm, console });
}
pub fn import(global: *JSGlobalObject, loader: *JSModuleLoader, specifier: *JSString, referrer: JSValue, origin: *const SourceOrigin) callconv(.C) *JSInternalPromise {
// if (comptime is_bindgen) {
// unreachable;
// }
pub fn import(global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) ErrorableZigString {
if (comptime is_bindgen) {
unreachable;
}
return @call(.{ .modifier = .always_inline }, Interface.import, .{ global, loader, specifier, referrer, origin });
return @call(.{ .modifier = .always_inline }, Interface.import, .{ global, specifier, source });
}
pub fn resolve(global: *JSGlobalObject, loader: *JSModuleLoader, specifier: JSValue, value: JSValue, origin: *const SourceOrigin) callconv(.C) ZigString {
pub fn resolve(global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) ErrorableZigString {
if (comptime is_bindgen) {
unreachable;
}
return @call(.{ .modifier = .always_inline }, Interface.resolve, .{ global, loader, specifier, value, origin });
return @call(.{ .modifier = .always_inline }, Interface.resolve, .{ global, specifier, source });
}
pub fn fetch(global: *JSGlobalObject, loader: *JSModuleLoader, value1: JSValue, value2: JSValue, value3: JSValue) callconv(.C) *JSInternalPromise {
pub fn fetch(global: *JSGlobalObject, specifier: ZigString, source: ZigString) callconv(.C) ErrorableZigString {
if (comptime is_bindgen) {
unreachable;
}
return @call(.{ .modifier = .always_inline }, Interface.fetch, .{ global, loader, value1, value2, value3 });
}
pub fn eval(global: *JSGlobalObject, loader: *JSModuleLoader, key: JSValue, moduleRecordValue: JSValue, scriptFetcher: JSValue, awaitedValue: JSValue, resumeMode: JSValue) callconv(.C) JSValue {
if (comptime is_bindgen) {
unreachable;
}
return @call(.{ .modifier = .always_inline }, Interface.eval, .{ global, loader, key, moduleRecordValue, scriptFetcher, awaitedValue, resumeMode });
return @call(.{ .modifier = .always_inline }, Interface.fetch, .{ global, specifier, source });
}
pub fn promiseRejectionTracker(global: *JSGlobalObject, promise: *JSPromise, rejection: JSPromiseRejectionOperation) callconv(.C) JSValue {
if (comptime is_bindgen) {
unreachable;
@@ -89,7 +86,7 @@ pub const ZigGlobalObject = extern struct {
.@"import" = import,
.@"resolve" = resolve,
.@"fetch" = fetch,
.@"eval" = eval,
// .@"eval" = eval,
.@"promiseRejectionTracker" = promiseRejectionTracker,
.@"reportUncaughtException" = reportUncaughtException,
.@"createImportMetaProperties" = createImportMetaProperties,
@@ -102,14 +99,78 @@ pub const ZigGlobalObject = extern struct {
@export(import, .{ .name = Export[0].symbol_name });
@export(resolve, .{ .name = Export[1].symbol_name });
@export(fetch, .{ .name = Export[2].symbol_name });
@export(eval, .{ .name = Export[3].symbol_name });
@export(promiseRejectionTracker, .{ .name = Export[4].symbol_name });
@export(reportUncaughtException, .{ .name = Export[5].symbol_name });
@export(createImportMetaProperties, .{ .name = Export[6].symbol_name });
@export(onCrash, .{ .name = Export[7].symbol_name });
@export(promiseRejectionTracker, .{ .name = Export[3].symbol_name });
@export(reportUncaughtException, .{ .name = Export[4].symbol_name });
@export(createImportMetaProperties, .{ .name = Export[5].symbol_name });
@export(onCrash, .{ .name = Export[6].symbol_name });
}
};
const ErrorCodeInt = std.meta.Int(.unsigned, @sizeOf(anyerror) * 8);
pub const ErrorCode = enum(ErrorCodeInt) {
_,
pub inline fn from(code: anyerror) ErrorCode {
return @intToEnum(ErrorCode, @errorToInt(code));
}
pub const Type = switch (@sizeOf(anyerror)) {
0, 1 => u8,
2 => u16,
3 => u32,
4 => u64,
else => @compileError("anyerror is too big"),
};
};
pub const ZigErrorType = extern struct {
code: ErrorCode,
message: ZigString,
};
pub fn Errorable(comptime Type: type) type {
return extern struct {
result: Result,
success: bool,
pub const name = "Errorable" ++ @typeName(Type);
pub const Result = extern union {
value: Type,
err: ZigErrorType,
};
pub fn value(val: Type) @This() {
return @This(){ .result = .{ .value = val }, .success = true };
}
pub fn ok(val: Type) @This() {
return @This(){ .result = .{ .value = val }, .success = true };
}
threadlocal var err_buf: [4096]u8 = undefined;
pub fn errFmt(code: anyerror, comptime fmt: []const u8, args: anytype) @This() {
const message = std.fmt.bufPrint(&err_buf, fmt, args) catch @errorName(code);
return @call(.{ .modifier = .always_inline }, err, .{ code, message });
}
pub fn err(code: anyerror, msg: []const u8) @This() {
return @This(){
.result = .{
.err = .{
.code = ErrorCode.from(code),
.message = ZigString.init(msg),
},
},
.success = false,
};
}
};
}
pub const ErrorableZigString = Errorable(ZigString);
pub const ErrorableJSValue = Errorable(JSValue);
pub const ZigConsoleClient = struct {
pub const shim = Shimmer("Zig", "ConsoleClient", @This());
pub const Type = *c_void;
@@ -131,13 +192,11 @@ pub const ZigConsoleClient = struct {
error_writer: BufferedWriter,
writer: BufferedWriter,
pub fn init(allocator: *std.mem.Allocator) !*ZigConsoleClient {
var console = try allocator.create(ZigConsoleClient);
console.* = ZigConsoleClient{
.error_writer = BufferedWriter{ .unbuffered_writer = Output.errorWriter() },
.writer = BufferedWriter{ .unbuffered_writer = Output.writer() },
pub fn init(error_writer: Output.WriterType, writer: Output.WriterType) ZigConsoleClient {
return ZigConsoleClient{
.error_writer = BufferedWriter{ .unbuffered_writer = error_writer },
.writer = BufferedWriter{ .unbuffered_writer = writer },
};
return console;
}
pub fn messageWithTypeAndLevel(
@@ -241,3 +300,91 @@ pub const ZigConsoleClient = struct {
});
}
};
// pub const CommonJSModuleConstructor = struct {
// pub const shim = Shimmer("Zig", "CommonJSModuleConstructor", @This());
// pub const name = "Zig::CommonJSModuleConstructor";
// pub const include = "\"CommonJSModule.h\"";
// pub const namespace = shim.namespace;
// pub fn construct(global: *JSGlobalObject, module: *CommonJSModule) callconv(.C) ErrorableJSValue {}
// };
// pub const CommonJSModulePrototype = struct {
// pub const shim = Shimmer("Zig", "CommonJSModulePrototype", @This());
// pub const name = "Zig::CommonJSModulePrototype";
// pub const include = "\"CommonJSModule.h\"";
// pub const namespace = shim.namespace;
// bytes: shim.Bytes,
// };
// pub const CommonJSModule = struct {
// pub const shim = Shimmer("Zig", "CommonJSModule", @This());
// pub const Type = *c_void;
// pub const name = "Zig::CommonJSModule";
// pub const include = "\"CommonJSModule.h\"";
// pub const namespace = shim.namespace;
// path: Fs.Path,
// reload_pending: bool = false,
// exports: JSValue,
// instance: *CommonJSModulePrototype,
// loaded: bool = false,
// pub fn finishLoading(module: *CommonJSModule, global: *JSGlobalObject, exports: JSValue, instance: *CommonJSModulePrototype) callconv(.C) ErrorableJSValue {
// module.loaded = true;
// module.instance = instance;
// module.exports = exports;
// }
// pub fn onCallRequire(module: *CommonJSModule, global: *JSGlobalObject, input: []const u8) callconv(.C) ErrorableJSValue {
// const resolve = ModuleLoader.resolve(global, input, module) catch |err| {
// return ErrorableJSValue.errFmt(
// err,
// "ResolveError: {s} while resolving \"{s}\"\nfrom \"{s}\"",
// .{
// @errorName(err),
// input,
// module.path.pretty,
// },
// );
// };
// const hash = ModuleLoader.hashid(resolve.path_pair.primary.text);
// var reload_pending = false;
// if (ModuleLoader.require_cache.get(hash)) |obj| {
// reload_pending = obj.reload_pending;
// return ErrorableJSValue.ok(obj.exports);
// }
// const result = ModuleLoader.load(global, resolve) catch |err| {
// return ErrorableJSValue.errFmt(
// err,
// "LoadError: {s} while loading \"{s}\"",
// .{
// @errorName(err),
// input,
// module.path.pretty,
// },
// );
// };
// switch (result) {
// .value => |value| {
// return value;
// },
// .module => |mod| {
// return ErrorableJSValue.ok(mod.exports);
// },
// .bundled_module_export => |bundled_module_export| {
// return ErrorableJSValue.ok(bundled_module_export);
// },
// .path => |path| {
// return ErrorableJSValue.ok(ZigString.init(path.text).toJSValue(global));
// },
// }
// }
// };

View File

@@ -218,7 +218,12 @@ pub const C_Generator = struct {
// }
}
pub fn gen_struct(self: *Self, comptime name: []const u8, comptime meta: StructMeta) void {
pub fn gen_struct(
self: *Self,
comptime name: []const u8,
comptime meta: StructMeta,
comptime static_types: anytype,
) void {
self.write("typedef struct ");
if (meta.layout == .Packed)
@@ -232,9 +237,27 @@ pub const C_Generator = struct {
const info = @typeInfo(field.field_type);
if (info == .Array) {
self.writeType(info.Array.child);
const PrintType = comptime brk: {
for (static_types) |static_type| {
if (static_type.Type == info.Array.child) {
break :brk static_type.Type;
}
}
break :brk info.Array.child;
};
self.writeType(PrintType);
} else {
self.writeType(field.field_type);
const PrintType = comptime brk: {
for (static_types) |static_type| {
if (static_type.Type == field.field_type) {
break :brk static_type.Type;
}
}
break :brk field.field_type;
};
self.writeType(PrintType);
}
self.write(" " ++ field.name);
@@ -245,7 +268,7 @@ pub const C_Generator = struct {
self.write(";\n");
}
self.write("} " ++ name ++ "_t;\n\n");
self.write("} " ++ name ++ ";\n\n");
}
pub fn gen_enum(
@@ -276,17 +299,20 @@ pub const C_Generator = struct {
self: *Self,
comptime name: []const u8,
comptime meta: UnionMeta,
comptime static_types: anytype,
) void {
self.write("typedef union ");
self.write(name ++ " {\n");
inline for (meta.fields) |field| {
inline for (meta.fields) |field, i| {
self.write(" ");
self.writeType(field.field_type);
self.writeType(comptime FieldType);
self.write(" " ++ field.name ++ ";\n");
}
self.write("} " ++ name ++ "_t;\n\n");
self.write("} " ++ name ++ ";\n\n");
}
fn writeType(
@@ -515,16 +541,7 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
Enum,
);
},
.Struct => |Struct| {
gen.gen_struct(decl.name, Struct, file);
},
.Union => |Union| {
const layout = Union.layout;
gen.gen_union(
prefix ++ "__" ++ name,
Union,
);
},
.Fn => |func| {
// if (func.) {
// blocked by https://github.com/ziglang/zig/issues/8259
@@ -575,8 +592,11 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
\\#define CPP_DECL AUTO_EXTERN_C
\\#define CPP_SIZE AUTO_EXTERN_C
\\
\\
\\typedef uint16_t ZigErrorCode;
\\typedef struct ZigString { const unsigned char* ptr; size_t len; } ZigString;
\\typedef struct ZigErrorType { ZigErrorCode code; ZigString message; } ZigErrorType;
\\typedef union ErrorableZigStringResult { ZigString value; ZigErrorType err; } ErrorableZigStringResult;
\\typedef struct ErrorableZigString { ErrorableZigStringResult result; bool success; } ErrorableZigString;
\\
) catch {};
@@ -601,13 +621,36 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
var impl_fourth_buffer = std.ArrayList(u8).init(std.heap.c_allocator);
var impl_fourth_writer = impl_fourth_buffer.writer();
// inline for (import.all_static_externs) |static_extern, i| {
// const Type = static_extern.Type;
// var gen = C_Generator.init(static_extern.name, @TypeOf(writer), writer);
// defer gen.deinit();
// switch (@typeInfo(Type)) {
// .Enum => |Enum| {
// gen.gen_enum(
// static_extern.name,
// Enum,
// );
// },
// .Union => |Union| {
// gen.gen_union(static_extern.name, Union, import.all_static_externs);
// },
// .Struct => |Struct| {
// gen.gen_struct(static_extern.name, Struct, import.all_static_externs);
// },
// else => {},
// }
// }
var to_get_sizes: usize = 0;
inline for (all_decls) |_decls| {
if (comptime _decls.is_pub) {
switch (_decls.data) {
.Type => |Type| {
@setEvalBranchQuota(99999);
const is_container_type = switch (@typeInfo(Type)) {
const TypeTypeInfo: std.builtin.TypeInfo = @typeInfo(Type);
const is_container_type = switch (TypeTypeInfo) {
.Opaque, .Struct, .Enum => true,
else => false,
};
@@ -708,6 +751,7 @@ pub fn HeaderGen(comptime import: type, comptime fname: []const u8) type {
}
}
}
impl.writer().print("\nconst size_t sizes[{d}] = {{", .{to_get_sizes}) catch unreachable;
impl.writeAll(impl_third_buffer.items) catch unreachable;
impl.writeAll("};\n") catch unreachable;

View File

@@ -1,4 +1,4 @@
//-- AUTOGENERATED FILE -- 1627423545
//-- AUTOGENERATED FILE -- 1627447221
#pragma once
#include <stddef.h>

View File

@@ -1,4 +1,4 @@
//-- AUTOGENERATED FILE -- 1627423545
//-- AUTOGENERATED FILE -- 1627447221
#pragma once
#include <stddef.h>
@@ -14,8 +14,11 @@
#define CPP_DECL AUTO_EXTERN_C
#define CPP_SIZE AUTO_EXTERN_C
typedef uint16_t ZigErrorCode;
typedef struct ZigString { const unsigned char* ptr; size_t len; } ZigString;
typedef struct ZigErrorType { ZigErrorCode code; ZigString message; } ZigErrorType;
typedef union ErrorableZigStringResult { ZigString value; ZigErrorType err; } ErrorableZigStringResult;
typedef struct ErrorableZigString { ErrorableZigStringResult result; bool success; } ErrorableZigString;
typedef struct bJSC__JSModuleRecord { unsigned char bytes[216]; } bJSC__JSModuleRecord;
typedef char* bJSC__JSModuleRecord_buf;
typedef struct bJSC__ThrowScope { unsigned char bytes[8]; } bJSC__ThrowScope;
@@ -78,6 +81,7 @@ typedef struct ZigString { const unsigned char* ptr; size_t len; } ZigString;
typedef bJSC__ThrowScope JSC__ThrowScope; // JSC::ThrowScope
typedef bJSC__PropertyName JSC__PropertyName; // JSC::PropertyName
typedef bJSC__JSObject JSC__JSObject; // JSC::JSObject
typedef ErrorableZigString ErrorableZigString;
typedef bWTF__ExternalStringImpl WTF__ExternalStringImpl; // WTF::ExternalStringImpl
typedef struct JSC__AsyncIteratorPrototype JSC__AsyncIteratorPrototype; // JSC::AsyncIteratorPrototype
typedef bWTF__StringImpl WTF__StringImpl; // WTF::StringImpl
@@ -164,6 +168,7 @@ typedef struct ZigString { const unsigned char* ptr; size_t len; } ZigString;
class ScriptArguments;
}
typedef ErrorableZigString ErrorableZigString;
typedef int64_t JSC__JSValue;
using JSC__JSCell = JSC::JSCell;
using JSC__Exception = JSC::Exception;
@@ -531,13 +536,12 @@ CPP_DECL JSC__JSGlobalObject* Zig__GlobalObject__create(JSC__VM* arg0, void* arg
#ifdef __cplusplus
ZIG_DECL JSC__JSValue Zig__GlobalObject__createImportMetaProperties(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSValue JSValue2, JSC__JSModuleRecord* arg3, JSC__JSValue JSValue4);
ZIG_DECL JSC__JSValue Zig__GlobalObject__eval(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSValue JSValue2, JSC__JSValue JSValue3, JSC__JSValue JSValue4, JSC__JSValue JSValue5, JSC__JSValue JSValue6);
ZIG_DECL JSC__JSInternalPromise* Zig__GlobalObject__fetch(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSValue JSValue2, JSC__JSValue JSValue3, JSC__JSValue JSValue4);
ZIG_DECL JSC__JSInternalPromise* Zig__GlobalObject__import(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSString* arg2, JSC__JSValue JSValue3, const JSC__SourceOrigin* arg4);
ZIG_DECL ErrorableZigString Zig__GlobalObject__fetch(JSC__JSGlobalObject* arg0, ZigString arg1, ZigString arg2);
ZIG_DECL ErrorableZigString Zig__GlobalObject__import(JSC__JSGlobalObject* arg0, ZigString arg1, ZigString arg2);
ZIG_DECL void Zig__GlobalObject__onCrash();
ZIG_DECL JSC__JSValue Zig__GlobalObject__promiseRejectionTracker(JSC__JSGlobalObject* arg0, JSC__JSPromise* arg1, uint32_t JSPromiseRejectionOperation2);
ZIG_DECL JSC__JSValue Zig__GlobalObject__reportUncaughtException(JSC__JSGlobalObject* arg0, JSC__Exception* arg1);
ZIG_DECL ZigString Zig__GlobalObject__resolve(JSC__JSGlobalObject* arg0, JSC__JSModuleLoader* arg1, JSC__JSValue JSValue2, JSC__JSValue JSValue3, const JSC__SourceOrigin* arg4);
ZIG_DECL ErrorableZigString Zig__GlobalObject__resolve(JSC__JSGlobalObject* arg0, ZigString arg1, ZigString arg2);
#endif

File diff suppressed because one or more lines are too long

View File

@@ -1,11 +1,14 @@
#include "headers.h"
#include "root.h"
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/VM.h>
#include <JavaScriptCore/Identifier.h>
#include <JavaScriptCore/JSValue.h>
#include <JavaScriptCore/JSString.h>
#include <JavaScriptCore/ThrowScope.h>
#include <JavaScriptCore/Error.h>
#include <JavaScriptCore/Exception.h>
template<class CppType, typename ZigType>
class Wrap {
@@ -83,6 +86,11 @@ static const JSC::ArgList makeArgs(JSC__JSValue* v, size_t count) {
return JSC::ArgList(args);
}
namespace Zig {
static const JSC::Identifier toIdentifier(ZigString str, JSC::JSGlobalObject* global) {
if (str.len == 0 || str.ptr == nullptr) {
return JSC::Identifier::EmptyIdentifier;
@@ -99,3 +107,76 @@ static const WTF::String toString(ZigString str) {
return WTF::String(WTF::StringImpl::createWithoutCopying(str.ptr, str.len));
}
static const JSC::JSString* toJSString(ZigString str, JSC::JSGlobalObject* global) {
return JSC::jsOwnedString(global->vm(), toString(str));
}
static const ZigString ZigStringEmpty = ZigString{nullptr, 0};
static const unsigned char __dot_char = '.';
static const ZigString ZigStringCwd = ZigString{&__dot_char, 1};
static ZigString toZigString(WTF::String str) {
return str.isEmpty() ? ZigStringEmpty : ZigString{ str.characters8(), str.length() };
}
static ZigString toZigString(WTF::String* str) {
return str->isEmpty() ? ZigStringEmpty : ZigString{ str->characters8(), str->length() };
}
static ZigString toZigString(WTF::StringImpl& str) {
return str.isEmpty() ? ZigStringEmpty : ZigString{ str.characters8(), str.length() };
}
static ZigString toZigString(WTF::StringView& str) {
return str.isEmpty() ? ZigStringEmpty : ZigString{ str.characters8(), str.length() };
}
static ZigString toZigString(JSC::JSString& str, JSC::JSGlobalObject *global) {
return toZigString(str.value(global));
}
static ZigString toZigString(JSC::JSString* str, JSC::JSGlobalObject *global) {
return toZigString(str->value(global));
}
static ZigString toZigString(JSC::Identifier& str, JSC::JSGlobalObject *global) {
return toZigString(str.string());
}
static ZigString toZigString(JSC::Identifier* str, JSC::JSGlobalObject *global) {
return toZigString(str->string());
}
static void throwException(JSC::ThrowScope& scope, ZigString msg, JSC::JSGlobalObject* global) {
auto str = toJSString(msg, global);
scope.throwException(global, JSC::Exception::create(global->vm(), JSC::JSValue(str)));
}
static ZigString toZigString(JSC::JSValue val, JSC::JSGlobalObject* global) {
auto scope = DECLARE_THROW_SCOPE(global->vm());
WTF::String str = val.toWTFString(global);
if (scope.exception()) {
scope.clearException();
scope.release();
return ZigStringEmpty;
}
scope.release();
return toZigString(str);
}
}

View File

@@ -0,0 +1,120 @@
const std = @import("std");
const Fs = @import("../../fs.zig");
const resolver = @import("../../resolver/resolver.zig");
const ast = @import("../../import_record.zig");
const NodeModuleBundle = @import("../../node_module_bundle.zig").NodeModuleBundle;
const logger = @import("../../logger.zig");
const Api = @import("../../api/schema.zig").Api;
const options = @import("../../options.zig");
const Bundler = @import("../../bundler.zig").ServeBundler;
const js_printer = @import("../../js_printer.zig");
const hash_map = @import("../../hash_map.zig");
const http = @import("../../http.zig");
usingnamespace @import("./node_env_buf_map.zig");
pub const DefaultSpeedyDefines = struct {
pub const Keys = struct {
const window = "window";
};
pub const Values = struct {
const window = "undefined";
};
};
pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args: Api.TransformOptions) !Api.TransformOptions {
var args = _args;
args.platform = Api.Platform.speedy;
args.serve = false;
args.write = false;
args.resolve = Api.ResolveMode.lazy;
args.generate_node_module_bundle = false;
// We inline process.env.* at bundle time but process.env is a proxy object which will otherwise return undefined.
var env_map = try getNodeEnvMap(allocator);
var env_count = env_map.count();
if (args.define) |def| {
for (def.keys) |key| {
env_count += @boolToInt((env_map.get(key) == null));
}
}
var needs_node_env = env_map.get("NODE_ENV") == null;
var needs_window_undefined = true;
var needs_regenerate = args.define == null and env_count > 0;
if (args.define) |def| {
if (def.keys.len != env_count) {
needs_regenerate = true;
}
for (def.keys) |key| {
if (strings.eql(key, "process.env.NODE_ENV")) {
needs_node_env = false;
} else if (strings.eql(key, "window")) {
needs_window_undefined = false;
}
}
}
var extras_count = @intCast(usize, @boolToInt(needs_node_env)) + @intCast(usize, @boolToInt(needs_window_undefined));
if (needs_regenerate) {
var new_list = try allocator.alloc([]const u8, env_count * 2 + extras_count * 2);
var keys = new_list[0 .. new_list.len / 2];
var values = new_list[keys.len..];
var new_map = Api.StringMap{
.keys = keys,
.values = values,
};
var iter = env_map.iterator();
var last: usize = 0;
while (iter.next()) |entry| {
keys[last] = entry.key_ptr.*;
var value = entry.value_ptr.*;
if (value.len == 0 or value[0] != '"' or value[value.len - 1] != '"') {
value = try std.fmt.allocPrint(allocator, "\"{s}\"", .{value});
}
values[last] = value;
last += 1;
}
if (args.define) |def| {
var from_env = keys[0..last];
for (def.keys) |pre, i| {
if (env_map.get(pre) != null) {
for (from_env) |key, j| {
if (strings.eql(key, pre)) {
values[j] = def.values[i];
}
}
} else {
keys[last] = pre;
values[last] = def.values[i];
last += 1;
}
}
}
if (needs_node_env) {
keys[last] = options.DefaultUserDefines.NodeEnv.Key;
values[last] = options.DefaultUserDefines.NodeEnv.Value;
last += 1;
}
if (needs_window_undefined) {
keys[last] = DefaultSpeedyDefines.Keys.window;
values[last] = DefaultSpeedyDefines.Values.window;
last += 1;
}
args.define = new_map;
}
return args;
}

View File

@@ -15,111 +15,7 @@ const http = @import("../../http.zig");
usingnamespace @import("./node_env_buf_map.zig");
usingnamespace @import("./base.zig");
usingnamespace @import("./webcore/response.zig");
const DefaultSpeedyDefines = struct {
pub const Keys = struct {
const window = "window";
};
pub const Values = struct {
const window = "undefined";
};
};
pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args: Api.TransformOptions) !Api.TransformOptions {
var args = _args;
args.platform = Api.Platform.speedy;
args.serve = false;
args.write = false;
args.resolve = Api.ResolveMode.lazy;
args.generate_node_module_bundle = false;
// We inline process.env.* at bundle time but process.env is a proxy object which will otherwise return undefined.
var env_map = try getNodeEnvMap(allocator);
var env_count = env_map.count();
if (args.define) |def| {
for (def.keys) |key| {
env_count += @boolToInt((env_map.get(key) == null));
}
}
var needs_node_env = env_map.get("NODE_ENV") == null;
var needs_window_undefined = true;
var needs_regenerate = args.define == null and env_count > 0;
if (args.define) |def| {
if (def.keys.len != env_count) {
needs_regenerate = true;
}
for (def.keys) |key| {
if (strings.eql(key, "process.env.NODE_ENV")) {
needs_node_env = false;
} else if (strings.eql(key, "window")) {
needs_window_undefined = false;
}
}
}
var extras_count = @intCast(usize, @boolToInt(needs_node_env)) + @intCast(usize, @boolToInt(needs_window_undefined));
if (needs_regenerate) {
var new_list = try allocator.alloc([]const u8, env_count * 2 + extras_count * 2);
var keys = new_list[0 .. new_list.len / 2];
var values = new_list[keys.len..];
var new_map = Api.StringMap{
.keys = keys,
.values = values,
};
var iter = env_map.iterator();
var last: usize = 0;
while (iter.next()) |entry| {
keys[last] = entry.key_ptr.*;
var value = entry.value_ptr.*;
if (value.len == 0 or value[0] != '"' or value[value.len - 1] != '"') {
value = try std.fmt.allocPrint(allocator, "\"{s}\"", .{value});
}
values[last] = value;
last += 1;
}
if (args.define) |def| {
var from_env = keys[0..last];
for (def.keys) |pre, i| {
if (env_map.get(pre) != null) {
for (from_env) |key, j| {
if (strings.eql(key, pre)) {
values[j] = def.values[i];
}
}
} else {
keys[last] = pre;
values[last] = def.values[i];
last += 1;
}
}
}
if (needs_node_env) {
keys[last] = options.DefaultUserDefines.NodeEnv.Key;
values[last] = options.DefaultUserDefines.NodeEnv.Value;
last += 1;
}
if (needs_window_undefined) {
keys[last] = DefaultSpeedyDefines.Keys.window;
values[last] = DefaultSpeedyDefines.Values.window;
last += 1;
}
args.define = new_map;
}
return args;
}
usingnamespace @import("./config.zig");
// If you read JavascriptCore/API/JSVirtualMachine.mm - https://github.com/WebKit/WebKit/blob/acff93fb303baa670c055cb24c2bad08691a01a0/Source/JavaScriptCore/API/JSVirtualMachine.mm#L101
// We can see that it's sort of like std.mem.Allocator but for JSGlobalContextRef, to support Automatic Reference Counting

View File

@@ -0,0 +1,99 @@
const std = @import("std");
const Fs = @import("../../fs.zig");
const resolver = @import("../../resolver/resolver.zig");
const ast = @import("../../import_record.zig");
const NodeModuleBundle = @import("../../node_module_bundle.zig").NodeModuleBundle;
const logger = @import("../../logger.zig");
const Api = @import("../../api/schema.zig").Api;
const options = @import("../../options.zig");
const Bundler = @import("../../bundler.zig").ServeBundler;
const js_printer = @import("../../js_printer.zig");
const hash_map = @import("../../hash_map.zig");
const http = @import("../../http.zig");
usingnamespace @import("./node_env_buf_map.zig");
usingnamespace @import("./config.zig");
usingnamespace @import("./bindings/bindings.zig");
usingnamespace @import("./bindings/exports.zig");
pub const VirtualMachine = struct {
global: *JSGlobalObject,
allocator: *std.mem.Allocator,
node_modules: ?*NodeModuleBundle = null,
bundler: Bundler,
watcher: ?*http.Watcher = null,
console: ZigConsoleClient,
pub threadlocal var vm: *VirtualMachine = undefined;
pub fn init(
allocator: *std.mem.Allocator,
_args: Api.TransformOptions,
existing_bundle: ?*NodeModuleBundle,
_log: ?*logger.Log,
) !*VirtualMachine {
var log: *logger.Log = undefined;
if (_log) |__log| {
log = __log;
} else {
log = try allocator.create(logger.Log);
}
vm = try allocator.create(VirtualMachine);
vm.* = VirtualMachine{
.global = undefined,
.allocator = allocator,
.bundler = try Bundler.init(
allocator,
log,
try configureTransformOptionsForSpeedy(allocator, _args),
existing_bundle,
),
.console = ZigConsoleClient.init(Output.errorWriter(), Output.writer()),
.node_modules = existing_bundle,
.log = log,
};
vm.global = js.ZigGlobalObject.create(null, &vm.console);
return vm;
}
};
pub const ModuleLoader = struct {
pub threadlocal var global_error_buf: [4096]u8 = undefined;
pub const RequireCacheType = std.AutoHashMap(http.Watcher.HashType, *CommonJSModule);
pub threadlocal var require_cache: RequireCacheType = undefined;
pub fn require(global: *JSGlobalObject, input: []const u8, from: *CommonJSModule) anyerror!resolver.Result {}
pub inline fn hashid(input: []const u8) http.Watcher.HashType {
return http.Watcher.getHash(input);
}
pub inline fn resolve(global: *JSGlobalObject, input: []const u8, from: *CommonJSModule) anyerror!resolver.Result {
std.debug.assert(global == VirtualMachine.vm.global);
return try VirtualMachine.vm.bundler.resolver.resolve(input, from.path.dirWithTrailingSlash(), .require);
}
inline fn _requireResolve(global: *JSGlobalObject, specifier: []const u8, referrer: []const u8) anyerror![]const u8 {
std.debug.assert(global == VirtualMachine.vm.global);
var result: resolver.Result = try VirtualMachine.vm.bundler.resolver.resolve(specifier, Fs.PathName.init(referrer).dirWithTrailingSlash(), .import);
return result.path_pair.primary.text;
}
pub fn load(global: *JSGlobalObject, )
pub fn requireResolve(global: *JSGlobalObject, specifier: ZigString, referrer: ZigString) ErrorableZigString {
return _requireResolve(global, specifier.slice(), referrer.slice()) catch |err| {
return ErrorableZigString.err(err, std.fmt.bufPrint(
&global_error_buf,
"Resolve failed: {s} while resolving \"{s}\" in \"{s}\"",
.{
@errorName(err),
specifier.slice(),
referrer.slice(),
},
) catch "ResolveError");
};
}
};