mirror of
https://github.com/oven-sh/bun
synced 2026-02-15 05:12:29 +00:00
Lots of stuff (#7027)
* Use debug mode by default * Enable build with assertions enabled * Update cli.zig * Update bun-linux-build.yml * Fixes * Fix `ASSERT_ENABLED` * try this * Update Dockerfile * mimalloc debug * Update CMakeLists.txt * `Bun.deepMatch` - fix assertion failures cc @dylan-conway, looks like we need to use `putDirectMayBeIndex` and check for `isCell` more carefully. * Object.create support in code generator and callbacks wrapper * Remove unused file * zig upgrade * zls * Fix various errors * Support `BuiltinAccessor` in create_hash_table script * Fix assertion failure in `process.mainModule` * Fix assertion failure in `onerror` * Fix assertion failure when creating a Worker * Fix asssertion failure when loading lots of files in bun test * Fix assertion failure when termating a `Worker` * Add helper for converting BunString to a WTFString * Fix assertion failure in notifyNeedTermination * Add more debug logs in `bun test` * Fix compiler warning in usockets * Fix assertion failure with `Worker` termination (another) * Fix assertion failure in `coerceToInt64` * Fix assertion failure in `BroadcastChannel` * Fix assertion failure in `Headers.prototype.getAll` * Fixes #7067 * Add heap analyzer label for CommonJS modules * Fix assertion failure in module.require && module.require.resolve * Remove unused code * Fix assertion failure in debugger * Fix crash in debugger * Fix assertion failures in bun:sqlite * Bump zig * Bump WebKit * Fix assertion failure in JSPromise::reject && JSInternalPromise::reject * Fix assertion failure in ReadableStream::cancel * Fix assertion failure in AsyncContextFrame::create * Fix assertion failure in bun:sqlite * Fix assertion failure in mocks * Fix assertion failure in ServerWebSocket.close * Fix assertion failure in N-API with subclasses * [napi] Make promises cheaper * undo * Don't check for exceptions in ObjectInitializationScope * Add separate entry point for test runner that doesn't generate code * Don't deref builtin code * Fix preload test * Fix assertion failure in memoryUsage() * Fix preload test, part 2 * Ensure that the env map for a Worker is empty after it is used * The pointer for the Arena allocator used in parsing should not change * Terminate thread on exit * Start to implement scriptExecutionStatus * Update worker.test.ts * Fix Dirent.name setter * Update settings.json * Fix assertion failure in node:http * Use correct value for `JSFinalObject::maxInlineCapacity` * JSFinalObject::maxInlineCapacity x2 * Don't strip when assertions are enabled * Make `m_wasTerminated` atomic * Preserve directives in the transpiler cc @ctjlewis * Workaround assertion failure in ServerWebSocket.sendBinary and ServerWebSocket.sendText * windows * Buffer lockfile serialization in-memory * PR feedback * PR feedback * PR feedback * Windows * quotes * Update CMakeLists.txt * Update bun-linux-build.yml * Update bun-linux-build.yml * Move this code to BunString.cpp * Update BunString.cpp --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
This commit is contained in:
@@ -36,6 +36,7 @@ export interface ClassDefinition {
|
||||
estimatedSize?: boolean;
|
||||
hasPendingActivity?: boolean;
|
||||
isEventEmitter?: boolean;
|
||||
supportsObjectCreate?: boolean;
|
||||
|
||||
getInternalProperties?: boolean;
|
||||
|
||||
@@ -44,6 +45,8 @@ export interface ClassDefinition {
|
||||
configurable?: boolean;
|
||||
enumerable?: boolean;
|
||||
structuredClone?: boolean | { transferable: boolean; tag: number };
|
||||
|
||||
callbacks?: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface CustomField {
|
||||
|
||||
@@ -103,11 +103,15 @@ while (<IN>) {
|
||||
} elsif (length($att)) {
|
||||
my $get = $val;
|
||||
my $put = "0";
|
||||
my $type = "PropertyAttribute::Property";
|
||||
if ($att =~ m/Builtin/) {
|
||||
$type = "PropertyAttribute::BuiltinAccessor";
|
||||
}
|
||||
if (!($att =~ m/ReadOnly/)) {
|
||||
$put = "set" . jsc_ucfirst($val);
|
||||
}
|
||||
$hasSetter = "true";
|
||||
push(@values, { "type" => "PropertyAttribute::Property", "get" => $get, "put" => $put });
|
||||
push(@values, { "type" => $type, "get" => $get, "put" => $put });
|
||||
} else {
|
||||
push(@values, { "type" => "Lexer", "value" => $val });
|
||||
}
|
||||
@@ -476,6 +480,10 @@ sub output() {
|
||||
$firstValue = $values[$i]{"function"};
|
||||
$secondValue = $values[$i]{"params"};
|
||||
$intrinsic = $values[$i]{"intrinsic"};
|
||||
} elsif ($values[$i]{"type"} eq "PropertyAttribute::BuiltinAccessor") {
|
||||
$typeTag = "BuiltinAccessor";
|
||||
$firstValue = $values[$i]{"get"};
|
||||
$secondValue = $values[$i]{"put"};
|
||||
} elsif ($values[$i]{"type"} eq "PropertyAttribute::Property") {
|
||||
$typeTag = "GetterSetter";
|
||||
$firstValue = $values[$i]{"get"};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import path from "path";
|
||||
import type { Field, ClassDefinition } from "./class-definitions";
|
||||
import { writeIfNotChanged } from "./helpers";
|
||||
import { camelCase, pascalCase } from "change-case";
|
||||
|
||||
const files = process.argv.slice(2);
|
||||
const outBase = files.pop();
|
||||
@@ -174,6 +175,7 @@ function propRow(
|
||||
prop: Field,
|
||||
isWrapped = true,
|
||||
defaultPropertyAttributes,
|
||||
supportsObjectCreate = false,
|
||||
) {
|
||||
var {
|
||||
defaultValue,
|
||||
@@ -246,8 +248,12 @@ function propRow(
|
||||
{ "${name}"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute${extraPropertyAttributes}), NoIntrinsic, { HashTableValue::GetterSetterType, ${getter}, ${setter} } }
|
||||
`.trim();
|
||||
} else if (defaultValue) {
|
||||
} else if (getter) {
|
||||
} else if (getter && !supportsObjectCreate) {
|
||||
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) {
|
||||
setter = getter.replace("Get", "Set");
|
||||
return `{ "${name}"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor ${extraPropertyAttributes}), NoIntrinsic, { HashTableValue::GetterSetterType, &${getter}, &${setter} } }
|
||||
`.trim();
|
||||
} else if (setter) {
|
||||
return `{ "${name}"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute${extraPropertyAttributes}), NoIntrinsic, { HashTableValue::GetterSetterType, 0, ${setter} } }
|
||||
@@ -275,7 +281,17 @@ export function generateHashTable(nameToUse, symbolName, typeName, obj, props =
|
||||
if ("internal" in props[name] || "value" in props[name]) continue;
|
||||
if (name.startsWith("@@")) continue;
|
||||
|
||||
rows.push(propRow(symbolName, typeName, name, props[name], wrapped, defaultPropertyAttributes));
|
||||
rows.push(
|
||||
propRow(
|
||||
symbolName,
|
||||
typeName,
|
||||
name,
|
||||
props[name],
|
||||
wrapped,
|
||||
defaultPropertyAttributes,
|
||||
obj.supportsObjectCreate || false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (rows.length === 0) {
|
||||
@@ -344,7 +360,7 @@ ${
|
||||
${"finalize" in obj ? `extern "C" void ${classSymbolName(typeName, "finalize")}(void*);` : ""}
|
||||
${obj.call ? `extern "C" JSC_DECLARE_HOST_FUNCTION(${classSymbolName(typeName, "call")});` : ""}
|
||||
|
||||
${renderDecls(protoSymbolName, typeName, protoFields)}
|
||||
${renderDecls(protoSymbolName, typeName, protoFields, obj.supportsObjectCreate || false)}
|
||||
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(${proto}, ${proto}::Base);
|
||||
|
||||
${generateHashTable(
|
||||
@@ -476,7 +492,7 @@ function generateConstructorImpl(typeName, obj: ClassDefinition) {
|
||||
const hashTableIdentifier = hashTable.length ? `${name}TableValues` : "";
|
||||
return `
|
||||
${obj.estimatedSize ? `extern "C" size_t ${symbolName(typeName, "estimatedSize")}(void* ptr);` : ""}
|
||||
${renderStaticDecls(classSymbolName, typeName, fields)}
|
||||
${renderStaticDecls(classSymbolName, typeName, fields, obj.supportsObjectCreate || false)}
|
||||
${hashTable}
|
||||
|
||||
void ${name}::finishCreation(VM& vm, JSC::JSGlobalObject* globalObject, ${prototypeName(typeName)}* prototype)
|
||||
@@ -581,7 +597,128 @@ function renderCachedFieldsHeader(typeName, klass, proto, values) {
|
||||
return rows.join("\n");
|
||||
}
|
||||
|
||||
function renderDecls(symbolName, typeName, proto) {
|
||||
function renderCallbacksHeader(typeName, callbacks: Record<string, string>) {
|
||||
const rows: string[] = [];
|
||||
for (const name in callbacks) {
|
||||
rows.push(`mutable WriteBarrier<JSObject> m_callback_${name};`);
|
||||
}
|
||||
|
||||
return rows.join("\n");
|
||||
}
|
||||
|
||||
function renderCallbacksCppImpl(typeName, callbacks: Record<string, string>) {
|
||||
const rows: string[] = [];
|
||||
if (Object.keys(callbacks).length === 0) return "";
|
||||
for (const name in callbacks) {
|
||||
rows.push(
|
||||
`
|
||||
extern "C" EncodedJSValue ${symbolName(typeName, "_callback_get_" + name)}(JSC::EncodedJSValue encodedThisValue) {
|
||||
auto* thisObject = jsCast<${className(typeName)}*>(JSValue::decode(encodedThisValue));
|
||||
return JSValue::encode(thisObject->m_callback_${name}.get());
|
||||
}
|
||||
|
||||
extern "C" void ${symbolName(
|
||||
typeName,
|
||||
"_callback_set_" + name,
|
||||
)}(JSC::EncodedJSValue encodedThisValue, JSC::EncodedJSValue encodedCallback) {
|
||||
auto* thisObject = jsCast<${className(typeName)}*>(JSValue::decode(encodedThisValue));
|
||||
JSValue callback = JSValue::decode(encodedCallback);
|
||||
#if ASSERT_ENABLED
|
||||
if (!callback.isEmpty()) {
|
||||
ASSERT(callback.isObject());
|
||||
ASSERT(callback.isCallable());
|
||||
}
|
||||
#endif
|
||||
if (callback.isEmpty()) {
|
||||
thisObject->m_callback_${name}.clear();
|
||||
} else {
|
||||
thisObject->m_callback_${name}.set(thisObject->vm(), thisObject, callback.getObject());
|
||||
}
|
||||
}
|
||||
`,
|
||||
);
|
||||
}
|
||||
|
||||
rows.push(`
|
||||
extern "C" void ${symbolName(typeName, "_setAllCallbacks")}(JSC::EncodedJSValue encodedThisValue, ${Object.keys(
|
||||
callbacks,
|
||||
)
|
||||
.map((_, i) => `JSC::EncodedJSValue encodedCallback${i}`)
|
||||
.join(", ")}) {
|
||||
auto* thisObject = jsCast<${className(typeName)}*>(JSValue::decode(encodedThisValue));
|
||||
${Object.keys(callbacks)
|
||||
.map(
|
||||
(name, i) => `
|
||||
JSValue callback${i} = JSValue::decode(encodedCallback${i});
|
||||
if (!callback${i}.isEmpty()) {
|
||||
thisObject->m_callback_${name}.set(thisObject->vm(), thisObject, callback${i}.getObject());
|
||||
}
|
||||
`,
|
||||
)
|
||||
.join("\n")}
|
||||
}
|
||||
|
||||
`);
|
||||
|
||||
return rows.join("\n");
|
||||
}
|
||||
|
||||
function renderCallbacksZig(typeName, callbacks: Record<string, string>) {
|
||||
if (Object.keys(callbacks).length === 0) return "";
|
||||
|
||||
var out =
|
||||
"\n" +
|
||||
`pub const Callbacks = struct {
|
||||
instance: JSC.JSValue,` +
|
||||
"\n";
|
||||
|
||||
for (const name in callbacks) {
|
||||
const get = symbolName(typeName, "_callback_get_" + name);
|
||||
const set = symbolName(typeName, "_callback_set_" + name);
|
||||
out += `
|
||||
extern fn ${get}(JSC.JSValue) JSC.JSValue;
|
||||
extern fn ${set}(JSC.JSValue, JSC.JSValue) void;
|
||||
pub const ${pascalCase(name)}Callback = JSC.Codegen.CallbackWrapper(${get}, ${set});
|
||||
pub fn ${camelCase(
|
||||
name,
|
||||
)}(cb: @This(), thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, args: []const JSC.JSValue) ?JSC.JSValue {
|
||||
return ${pascalCase(name)}Callback.call(.{.instance = cb.instance}, thisValue, globalObject, args);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
out = out.trim();
|
||||
|
||||
out += `
|
||||
extern fn ${symbolName(typeName, "_setAllCallbacks")}(JSC.JSValue, ${Object.keys(callbacks)
|
||||
.map((a, i) => `callback${i}: JSC.JSValue`)
|
||||
.join(", ")}) void;
|
||||
|
||||
pub inline fn set(this: @This(), values: struct {
|
||||
${Object.keys(callbacks)
|
||||
.map((name, i) => `${camelCase(name)}: JSC.JSValue = .zero,`)
|
||||
.join("\n")}
|
||||
}) void {
|
||||
${symbolName(typeName, "_setAllCallbacks")}(this.instance, ${Object.keys(callbacks)
|
||||
.map((name, i) => `values.${camelCase(name)}`)
|
||||
.join(", ")},);
|
||||
}
|
||||
`;
|
||||
|
||||
out += "\n};\n";
|
||||
|
||||
out += `
|
||||
|
||||
pub fn callbacks(_: *const ${typeName}, instance: JSC.JSValue) Callbacks {
|
||||
return .{.instance = instance };
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
return "\n" + out;
|
||||
}
|
||||
|
||||
function renderDecls(symbolName, typeName, proto, supportsObjectCreate = false) {
|
||||
const rows = [];
|
||||
|
||||
for (const name in proto) {
|
||||
@@ -598,6 +735,10 @@ function renderDecls(symbolName, typeName, proto) {
|
||||
`.trim(),
|
||||
"\n",
|
||||
);
|
||||
|
||||
if (supportsObjectCreate && !("setter" in proto[name])) {
|
||||
rows.push("\n" + `static JSC_DECLARE_CUSTOM_SETTER(${symbolName(typeName, name)}SetterWrap);` + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if ("setter" in proto[name] || ("accessor" in proto[name] && proto[name].setter)) {
|
||||
@@ -606,7 +747,7 @@ function renderDecls(symbolName, typeName, proto) {
|
||||
!!proto[name].this ? " JSC::EncodedJSValue thisValue, " : ""
|
||||
} JSC::JSGlobalObject* lexicalGlobalObject, JSC::EncodedJSValue value);`,
|
||||
`
|
||||
JSC_DECLARE_CUSTOM_SETTER(${symbolName(typeName, name)}SetterWrap);
|
||||
static JSC_DECLARE_CUSTOM_SETTER(${symbolName(typeName, name)}SetterWrap);
|
||||
`.trim(),
|
||||
"\n",
|
||||
);
|
||||
@@ -647,7 +788,7 @@ function renderDecls(symbolName, typeName, proto) {
|
||||
return rows.join("\n");
|
||||
}
|
||||
|
||||
function renderStaticDecls(symbolName, typeName, fields) {
|
||||
function renderStaticDecls(symbolName, typeName, fields, supportsObjectCreate = false) {
|
||||
const rows = [];
|
||||
|
||||
for (const name in fields) {
|
||||
@@ -706,6 +847,8 @@ function renderFieldsImpl(
|
||||
) {
|
||||
const rows: string[] = [];
|
||||
|
||||
const supportsObjectCreate = obj.supportsObjectCreate || false;
|
||||
|
||||
if (obj.construct) {
|
||||
rows.push(`
|
||||
|
||||
@@ -728,16 +871,17 @@ JSC_DEFINE_CUSTOM_GETTER(js${typeName}Constructor, (JSGlobalObject * lexicalGlob
|
||||
if ("cache" in proto[name] || proto[name]?.internal) {
|
||||
const cacheName = typeof proto[name].cache === "string" ? `m_${proto[name].cache}` : `m_${name}`;
|
||||
if ("cache" in proto[name]) {
|
||||
rows.push(`
|
||||
if (!supportsObjectCreate) {
|
||||
rows.push(`
|
||||
JSC_DEFINE_CUSTOM_GETTER(${symbolName(
|
||||
typeName,
|
||||
name,
|
||||
)}GetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
|
||||
typeName,
|
||||
name,
|
||||
)}GetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue encodedThisValue, PropertyName attributeName))
|
||||
{
|
||||
auto& vm = lexicalGlobalObject->vm();
|
||||
Zig::GlobalObject *globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
${className(typeName)}* thisObject = jsCast<${className(typeName)}*>(JSValue::decode(thisValue));
|
||||
${className(typeName)}* thisObject = jsCast<${className(typeName)}*>(JSValue::decode(encodedThisValue));
|
||||
JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
|
||||
|
||||
if (JSValue cachedValue = thisObject->${cacheName}.get())
|
||||
@@ -745,34 +889,91 @@ JSC_DEFINE_CUSTOM_GETTER(${symbolName(
|
||||
|
||||
JSC::JSValue result = JSC::JSValue::decode(
|
||||
${symbolName(typeName, proto[name].getter)}(thisObject->wrapped(),${
|
||||
proto[name].this!! ? " thisValue, " : ""
|
||||
} globalObject)
|
||||
proto[name].this!! ? " encodedThisValue, " : ""
|
||||
} globalObject)
|
||||
);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
thisObject->${cacheName}.set(vm, thisObject, result);
|
||||
RELEASE_AND_RETURN(throwScope, JSValue::encode(result));
|
||||
}`);
|
||||
} else {
|
||||
rows.push(`
|
||||
JSC_DEFINE_CUSTOM_GETTER(${symbolName(
|
||||
typeName,
|
||||
name,
|
||||
)}GetterWrap, (JSGlobalObject * globalObject, EncodedJSValue encodedThisValue, PropertyName attributeName))
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
${className(typeName)}* thisObject = jsDynamicCast<${className(
|
||||
typeName,
|
||||
)}*>(JSValue::decode(encodedThisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
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, " : ""
|
||||
} globalObject)
|
||||
);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
thisObject->${cacheName}.set(vm, thisObject, result);
|
||||
RELEASE_AND_RETURN(throwScope, JSValue::encode(result));
|
||||
}`);
|
||||
}
|
||||
}
|
||||
rows.push(writeBarrier(symbolName, typeName, name, cacheName));
|
||||
} else if ("getter" in proto[name] || ("accessor" in proto[name] && proto[name].getter)) {
|
||||
rows.push(`
|
||||
if (!supportsObjectCreate) {
|
||||
rows.push(`
|
||||
JSC_DEFINE_CUSTOM_GETTER(${symbolName(
|
||||
typeName,
|
||||
name,
|
||||
)}GetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
|
||||
typeName,
|
||||
name,
|
||||
)}GetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue encodedThisValue, PropertyName attributeName))
|
||||
{
|
||||
auto& vm = lexicalGlobalObject->vm();
|
||||
Zig::GlobalObject *globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
${className(typeName)}* thisObject = jsCast<${className(typeName)}*>(JSValue::decode(thisValue));
|
||||
${className(typeName)}* thisObject = jsCast<${className(typeName)}*>(JSValue::decode(encodedThisValue));
|
||||
JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
|
||||
JSC::EncodedJSValue result = ${symbolName(typeName, proto[name].getter)}(thisObject->wrapped(),${
|
||||
!!proto[name].this ? " thisValue, " : ""
|
||||
} globalObject);
|
||||
!!proto[name].this ? " encodedThisValue, " : ""
|
||||
} globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
RELEASE_AND_RETURN(throwScope, result);
|
||||
}
|
||||
`);
|
||||
} else {
|
||||
rows.push(`
|
||||
JSC_DEFINE_CUSTOM_GETTER(${symbolName(
|
||||
typeName,
|
||||
name,
|
||||
)}GetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue encodedThisValue, PropertyName attributeName))
|
||||
{
|
||||
auto& vm = lexicalGlobalObject->vm();
|
||||
Zig::GlobalObject *globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
${className(typeName)}* thisObject = jsDynamicCast<${className(
|
||||
typeName,
|
||||
)}*>(JSValue::decode(encodedThisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
|
||||
JSC::EncodedJSValue result = ${symbolName(typeName, proto[name].getter)}(thisObject->wrapped(),${
|
||||
!!proto[name].this ? " encodedThisValue, " : ""
|
||||
} globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
RELEASE_AND_RETURN(throwScope, result);
|
||||
}
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
if ("setter" in proto[name] || ("accessor" in proto[name] && proto[name].setter)) {
|
||||
@@ -781,20 +982,41 @@ JSC_DEFINE_CUSTOM_GETTER(${symbolName(
|
||||
JSC_DEFINE_CUSTOM_SETTER(${symbolName(
|
||||
typeName,
|
||||
name,
|
||||
)}SetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName))
|
||||
)}SetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue encodedThisValue, EncodedJSValue encodedValue, PropertyName attributeName))
|
||||
{
|
||||
auto& vm = lexicalGlobalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
${className(typeName)}* thisObject = jsCast<${className(typeName)}*>(JSValue::decode(thisValue));
|
||||
${className(typeName)}* thisObject = jsCast<${className(typeName)}*>(JSValue::decode(encodedThisValue));
|
||||
JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
|
||||
auto result = ${symbolName(typeName, proto[name].setter || proto[name].accessor.setter)}(thisObject->wrapped(),${
|
||||
!!proto[name].this ? " thisValue, " : ""
|
||||
!!proto[name].this ? " encodedThisValue, " : ""
|
||||
} lexicalGlobalObject, encodedValue);
|
||||
|
||||
RELEASE_AND_RETURN(throwScope, result);
|
||||
}
|
||||
`,
|
||||
);
|
||||
} else if (supportsObjectCreate) {
|
||||
rows.push(
|
||||
`
|
||||
JSC_DEFINE_CUSTOM_SETTER(${symbolName(
|
||||
typeName,
|
||||
name,
|
||||
)}SetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue encodedThisValue, EncodedJSValue encodedValue, PropertyName attributeName))
|
||||
{
|
||||
auto& vm = lexicalGlobalObject->vm();
|
||||
auto throwScope = DECLARE_THROW_SCOPE(vm);
|
||||
JSValue thisValue = JSValue::decode(encodedThisValue);
|
||||
if (!thisValue.isObject()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JSObject *thisObject = asObject(thisValue);
|
||||
thisObject->putDirect(vm, attributeName, JSValue::decode(encodedValue), 0);
|
||||
return true;
|
||||
}
|
||||
`,
|
||||
);
|
||||
}
|
||||
|
||||
if ("fn" in proto[name]) {
|
||||
@@ -844,12 +1066,13 @@ JSC_DEFINE_CUSTOM_SETTER(${symbolName(
|
||||
|
||||
var extraIncludes = [];
|
||||
function generateClassHeader(typeName, obj: ClassDefinition) {
|
||||
var { klass, proto, JSType = "ObjectType", values = [] } = obj;
|
||||
var { klass, proto, JSType = "ObjectType", values = [], callbacks = {} } = obj;
|
||||
const name = className(typeName);
|
||||
|
||||
const DECLARE_VISIT_CHILDREN =
|
||||
values.length ||
|
||||
obj.estimatedSize ||
|
||||
Object.keys(callbacks).length ||
|
||||
obj.hasPendingActivity ||
|
||||
[...Object.values(klass), ...Object.values(proto)].find(a => !!a.cache)
|
||||
? "DECLARE_VISIT_CHILDREN;\ntemplate<typename Visitor> void visitAdditionalChildren(Visitor&);\nDECLARE_VISIT_OUTPUT_CONSTRAINTS;\n"
|
||||
@@ -975,6 +1198,7 @@ function generateClassHeader(typeName, obj: ClassDefinition) {
|
||||
${DECLARE_VISIT_CHILDREN}
|
||||
|
||||
${renderCachedFieldsHeader(typeName, klass, proto, values)}
|
||||
${callbacks ? renderCallbacksHeader(typeName, obj.callbacks) : ""}
|
||||
};
|
||||
${suffix}
|
||||
`;
|
||||
@@ -989,14 +1213,19 @@ function generateClassImpl(typeName, obj: ClassDefinition) {
|
||||
estimatedSize,
|
||||
hasPendingActivity = false,
|
||||
getInternalProperties = false,
|
||||
callbacks = {},
|
||||
} = obj;
|
||||
const name = className(typeName);
|
||||
|
||||
const DEFINE_VISIT_CHILDREN_LIST = [...Object.entries(fields), ...Object.entries(proto)]
|
||||
let DEFINE_VISIT_CHILDREN_LIST = [...Object.entries(fields), ...Object.entries(proto)]
|
||||
.filter(([name, { cache = false, internal = false }]) => (cache || internal) === true)
|
||||
.map(([name]) => ` visitor.append(thisObject->m_${name});`)
|
||||
.map(([name]) => `visitor.append(thisObject->m_${name});`)
|
||||
.join("\n");
|
||||
|
||||
for (const name in callbacks) {
|
||||
DEFINE_VISIT_CHILDREN_LIST += "\n" + ` visitor.append(thisObject->m_callback_${name});`;
|
||||
}
|
||||
|
||||
const values = (obj.values || [])
|
||||
.map(val => {
|
||||
return `visitor.append(thisObject->m_${val});`;
|
||||
@@ -1045,6 +1274,8 @@ void ${name}::visitOutputConstraintsImpl(JSCell *cell, Visitor& visitor)
|
||||
|
||||
DEFINE_VISIT_OUTPUT_CONSTRAINTS(${name});
|
||||
|
||||
${renderCallbacksCppImpl(typeName, callbacks)}
|
||||
|
||||
|
||||
|
||||
`.trim();
|
||||
@@ -1234,6 +1465,7 @@ function generateZig(
|
||||
hasPendingActivity = false,
|
||||
structuredClone = false,
|
||||
getInternalProperties = false,
|
||||
callbacks = {},
|
||||
} = {} as ClassDefinition,
|
||||
) {
|
||||
const exports = new Map<string, string>();
|
||||
@@ -1306,6 +1538,11 @@ function generateZig(
|
||||
)
|
||||
.join("\n");
|
||||
|
||||
var renderedCallbacks = "";
|
||||
if (Object.keys(callbacks).length) {
|
||||
renderedCallbacks = renderCallbacksZig(typeName, callbacks);
|
||||
}
|
||||
|
||||
function typeCheck() {
|
||||
var output = "";
|
||||
|
||||
@@ -1521,6 +1758,8 @@ pub const ${className(typeName)} = struct {
|
||||
|
||||
extern fn ${typeName}__dangerouslySetPtr(JSC.JSValue, ?*${typeName}) bool;
|
||||
|
||||
${renderedCallbacks}
|
||||
|
||||
comptime {
|
||||
${typeCheck()}
|
||||
if (!JSC.is_bindgen) {
|
||||
|
||||
Reference in New Issue
Block a user