allow zig js host functions to return JSError (#15120)

This commit is contained in:
Meghan Denny
2024-11-13 21:11:56 -08:00
committed by GitHub
parent 32ddf343ee
commit fdd8d35845
70 changed files with 827 additions and 876 deletions

View File

@@ -294,7 +294,7 @@ function propRow(
return `{ "${name}"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute${extraPropertyAttributes}), NoIntrinsic, { HashTableValue::GetterSetterType, ${getter}, 0 } }
`.trim();
} else if (getter && !supportsObjectCreate && writable) {
return `{ "${name}"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute${extraPropertyAttributes}), NoIntrinsic, { HashTableValue::GetterSetterType, ${getter}, ${setter} } }
return `{ "${name}"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute${extraPropertyAttributes}), NoIntrinsic, { HashTableValue::GetterSetterType, ${getter}, ${setter} } }
`.trim();
} else if (getter && supportsObjectCreate) {
setter = getter.replace("Get", "Set");
@@ -356,14 +356,14 @@ function generatePrototype(typeName, obj) {
if (obj.construct) {
externs += `
extern JSC_CALLCONV void* JSC_HOST_CALL_ATTRIBUTES ${classSymbolName(typeName, "construct")}(JSC::JSGlobalObject*, JSC::CallFrame*);
extern JSC_CALLCONV void* JSC_HOST_CALL_ATTRIBUTES ${classSymbolName(typeName, "construct")}(JSC::JSGlobalObject*, JSC::CallFrame*);
JSC_DECLARE_CUSTOM_GETTER(js${typeName}Constructor);
`;
}
if (obj.wantsThis) {
externs += `
extern JSC_CALLCONV void* JSC_HOST_CALL_ATTRIBUTES ${classSymbolName(typeName, "_setThis")}(JSC::JSGlobalObject*, void*, JSC::EncodedJSValue);
extern JSC_CALLCONV void* JSC_HOST_CALL_ATTRIBUTES ${classSymbolName(typeName, "_setThis")}(JSC::JSGlobalObject*, void*, JSC::EncodedJSValue);
`;
}
@@ -809,11 +809,11 @@ function renderCallbacksZig(typeName, callbacks: Record<string, string>) {
out += "\n};\n";
out += `
pub fn callbacks(_: *const ${typeName}, instance: JSC.JSValue) Callbacks {
return .{.instance = instance };
}
`;
return "\n" + out;
@@ -1027,10 +1027,10 @@ JSC_DEFINE_CUSTOM_GETTER(${symbolName(typeName, name)}GetterWrap, (JSGlobalObjec
}
JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
if (JSValue cachedValue = thisObject->${cacheName}.get())
return JSValue::encode(cachedValue);
JSC::JSValue result = JSC::JSValue::decode(
${symbolName(typeName, proto[name].getter)}(thisObject->wrapped(),${
proto[name].this!! ? " thisValue, " : ""
@@ -1523,7 +1523,7 @@ extern JSC_CALLCONV void* JSC_HOST_CALL_ATTRIBUTES ${typeName}__fromJSDirect(JSC
Zig::GlobalObject* globalObject = jsDynamicCast<Zig::GlobalObject*>(object->globalObject());
if (UNLIKELY(globalObject == nullptr || cell->structureID() != globalObject->${className(typeName)}Structure()->id())) {
if (UNLIKELY(globalObject == nullptr || cell->structureID() != globalObject->${className(typeName)}Structure()->id())) {
return nullptr;
}
@@ -1691,8 +1691,8 @@ function generateZig(
function renderMethods() {
const exports = new Map();
var output = `
const JavaScriptCoreBindings = struct {
const JavaScriptCoreBindings = struct {
`;
if (estimatedSize) {
@@ -1748,7 +1748,10 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${classSymbolName(typeName, "call")}(globalObject: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue {
if (comptime Environment.enable_logs) zig("${typeName}<d>({})<r>", .{callFrame});
return @call(.always_inline, wrapHostFunction(${typeName}.call), .{globalObject, callFrame});
return @call(.always_inline, ${typeName}.call, .{globalObject, callFrame}) catch |err| switch (err) {
error.JSError => .zero,
error.OutOfMemory => globalObject.throwOutOfMemoryValue(),
};
}
`;
}
@@ -1801,7 +1804,10 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${names.fn}(thisValue: *${typeName}, globalObject: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame${proto[name].passThis ? ", js_this_value: JSC.JSValue" : ""}) callconv(JSC.conv) JSC.JSValue {
if (comptime Environment.enable_logs) zig("<d>${typeName}.<r>${name}<d>({})<r>", .{callFrame});
return @call(.always_inline, ${proto[name].passThis ? 'wrapMethodWithThis' : 'wrapMethod'}(${typeName}, ${typeName}.${fn}), .{thisValue, globalObject, callFrame${proto[name].passThis ? ", js_this_value" : ""}});
return @call(.always_inline, ${typeName}.${fn}, .{thisValue, globalObject, callFrame${proto[name].passThis ? ", js_this_value" : ""}}) catch |err| switch (err) {
error.JSError => .zero,
error.OutOfMemory => globalObject.throwOutOfMemoryValue(),
};
}
`;
}
@@ -1848,7 +1854,10 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${names.fn}(globalObject: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue {
if (comptime Environment.enable_logs) JSC.markBinding(@src());
return @call(.always_inline, ${typeName}.${fn}, .{globalObject, callFrame});
return @call(.always_inline, ${typeName}.${fn}, .{globalObject, callFrame}) catch |err| switch (err) {
error.JSError => .zero,
error.OutOfMemory => globalObject.throwOutOfMemoryValue(),
};
}
`;
}

View File

@@ -205,28 +205,19 @@ export function getJS2NativeZig(gs2NativeZigPath: string) {
...wrapperCalls
.filter(x => x.type === "zig")
.flatMap(x => [
`const ${symbol({
`export fn ${symbol({
type: "zig",
symbol: x.symbol_target,
filename: x.filename,
})} = JSC.toJSHostFunction(@import(${JSON.stringify(path.relative(path.dirname(gs2NativeZigPath), x.filename))}).${x.symbol_target});`,
})}(global: *JSC.JSGlobalObject, call_frame: *JSC.CallFrame) callconv(JSC.conv) JSC.JSValue {`,
`
const function = @import(${JSON.stringify(path.relative(path.dirname(gs2NativeZigPath), x.filename))});
return @call(.always_inline, function.${x.symbol_target}, .{global, call_frame}) catch |err| switch (err) {
error.JSError => .zero,
error.OutOfMemory => global.throwOutOfMemoryValue(),
};`,
"}",
]),
"comptime {",
...wrapperCalls
.filter(x => x.type === "zig")
.flatMap(x => {
const s = symbol({
type: "zig",
symbol: x.symbol_target,
filename: x.filename,
});
return ` @export(${s}, .{ .name = "${s}" });`;
}),
...nativeCalls.filter(x => x.type === "zig").flatMap(call => ` _ = &${symbol(call)}_workaround;`),
...wrapperCalls
.filter(x => x.type === "zig")
.flatMap(x => ` _ = &${symbol({ type: "zig", symbol: x.symbol_target, filename: x.filename })};`),
"}",
].join("\n");
}