aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/scripts/generate-classes.ts
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-10-28 18:57:33 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-10-28 18:57:33 -0700
commit280c45c2693546dbc915a0812e855ddda1734739 (patch)
tree996c27af28d736a39d24fd048e8d5271ae8cbf61 /src/bun.js/scripts/generate-classes.ts
parent8bb080fc7c5e59412c32053b629748a7cbb9ffbf (diff)
downloadbun-280c45c2693546dbc915a0812e855ddda1734739.tar.gz
bun-280c45c2693546dbc915a0812e855ddda1734739.tar.zst
bun-280c45c2693546dbc915a0812e855ddda1734739.zip
Upgrade WebKit
Diffstat (limited to 'src/bun.js/scripts/generate-classes.ts')
-rw-r--r--src/bun.js/scripts/generate-classes.ts145
1 files changed, 131 insertions, 14 deletions
diff --git a/src/bun.js/scripts/generate-classes.ts b/src/bun.js/scripts/generate-classes.ts
index 21fba1807..39608dc22 100644
--- a/src/bun.js/scripts/generate-classes.ts
+++ b/src/bun.js/scripts/generate-classes.ts
@@ -246,6 +246,8 @@ export function generateHashTable(
const rows = [];
for (const name in props) {
+ if ("internal" in props[name]) continue;
+
rows.push(propRow(symbolName, typeName, name, props[name], wrapped));
}
@@ -549,13 +551,16 @@ ${
function renderCachedFieldsHeader(typeName, klass, proto) {
const rows = [];
for (const name in klass) {
- if ("cache" in klass[name] && klass[name].cache === true) {
+ if (
+ ("cache" in klass[name] && klass[name].cache === true) ||
+ klass[name]?.internal
+ ) {
rows.push(`mutable JSC::WriteBarrier<JSC::Unknown> m_${name};`);
}
}
for (const name in proto) {
- if (proto[name]?.cache === true) {
+ if (proto[name]?.cache === true || klass[name]?.internal) {
rows.push(`mutable JSC::WriteBarrier<JSC::Unknown> m_${name};`);
}
}
@@ -702,23 +707,24 @@ JSC_DEFINE_CUSTOM_GETTER(js${typeName}Constructor, (JSGlobalObject * lexicalGlob
}
for (const name in proto) {
- if ("cache" in proto[name]) {
+ if ("cache" in proto[name] || proto[name]?.internal) {
const cacheName =
typeof proto[name].cache === "string"
? `m_${proto[name].cache}`
: `m_${name}`;
- rows.push(`
+ if ("cache" in proto[name]) {
+ rows.push(`
JSC_DEFINE_CUSTOM_GETTER(${symbolName(
- typeName,
- name
- )}GetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
+ typeName,
+ name
+ )}GetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, 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));
+ typeName
+ )}*>(JSValue::decode(thisValue));
JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject);
if (JSValue cachedValue = thisObject->${cacheName}.get())
@@ -733,7 +739,10 @@ JSC_DEFINE_CUSTOM_GETTER(${symbolName(
RETURN_IF_EXCEPTION(throwScope, {});
thisObject->${cacheName}.set(vm, thisObject, result);
RELEASE_AND_RETURN(throwScope, JSValue::encode(result));
-}
+}`);
+ }
+ rows.push(`
+
extern "C" void ${symbolName(
typeName,
name
@@ -745,6 +754,18 @@ extern "C" void ${symbolName(
)}*>(JSValue::decode(thisValue));
thisObject->${cacheName}.set(vm, thisObject, JSValue::decode(value));
}
+
+extern "C" EncodedJSValue ${symbolName(
+ typeName,
+ name
+ )}GetCachedValue(JSC::EncodedJSValue thisValue)
+{
+ auto* thisObject = jsCast<${className(
+ typeName
+ )}*>(JSValue::decode(thisValue));
+ return JSValue::encode(thisObject->${cacheName}.get());
+}
+
`);
} else if (
"getter" in proto[name] ||
@@ -847,6 +868,40 @@ function generateClassHeader(typeName, obj: ClassDefinition) {
? "static size_t estimatedSize(JSCell* cell, VM& vm);"
: "";
+ var weakOwner = "";
+ var weakInit = "";
+
+ if (obj.hasPendingActivity) {
+ weakOwner = `
+ JSC::Weak<${name}> m_weakThis;
+ bool internalHasPendingActivity();
+ bool hasPendingActivity() {
+ if (!m_ctx)
+ return false;
+
+ return this->internalHasPendingActivity();
+ }
+
+ class Owner final : public JSC::WeakHandleOwner {
+ public:
+ bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void* context, JSC::AbstractSlotVisitor&, const char**) final
+ {
+ auto* controller = JSC::jsCast<${name}*>(handle.slot()->asCell());
+ return controller->hasPendingActivity();
+ }
+ void finalize(JSC::Handle<JSC::Unknown>, void* context) final {}
+ };
+
+ static JSC::WeakHandleOwner* getOwner()
+ {
+ static NeverDestroyed<Owner> m_owner;
+ return &m_owner.get();
+ }
+ `;
+ weakInit = `
+ m_weakThis = JSC::Weak<${name}>(vm, this, getOwner());
+`;
+ }
return `
class ${name} final : public JSC::JSDestructibleObject {
public:
@@ -901,10 +956,13 @@ function generateClassHeader(typeName, obj: ClassDefinition) {
: Base(vm, structure)
{
m_ctx = sinkPtr;
+ ${weakInit.trim()}
}
void finishCreation(JSC::VM&);
+ ${weakOwner}
+
${DECLARE_VISIT_CHILDREN}
${renderCachedFieldsHeader(typeName, klass, proto)}
@@ -913,14 +971,24 @@ function generateClassHeader(typeName, obj: ClassDefinition) {
}
function generateClassImpl(typeName, obj: ClassDefinition) {
- const { klass: fields, finalize, proto, construct, estimatedSize } = obj;
+ const {
+ klass: fields,
+ finalize,
+ proto,
+ construct,
+ estimatedSize,
+ hasPendingActivity = false,
+ } = obj;
const name = className(typeName);
const DEFINE_VISIT_CHILDREN_LIST = [
...Object.entries(fields),
...Object.entries(proto),
]
- .filter(([name, { cache = false }]) => cache === true)
+ .filter(
+ ([name, { cache = false, internal = false }]) =>
+ (cache || internal) === true
+ )
.map(([name]) => ` visitor.append(thisObject->m_${name});`)
.join("\n");
@@ -955,6 +1023,15 @@ DEFINE_VISIT_CHILDREN(${name});
var output = ``;
+ if (hasPendingActivity) {
+ output += `
+ extern "C" bool ${symbolName(typeName, "hasPendingActivity")}(void* ptr);
+ ${name}::internalHasPendingActivity() {
+ return ${symbolName(typeName, "hasPendingActivity")}(m_ctx);
+ }
+`;
+ }
+
if (finalize) {
output += `
${name}::~${name}()
@@ -989,6 +1066,7 @@ void ${name}::finishCreation(VM& vm)
ASSERT(inherits(info()));
}
+
${name}* ${name}::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* ctx) {
${name}* ptr = new (NotNull, JSC::allocateCell<${name}>(vm)) ${name}(vm, structure, ctx);
ptr->finishCreation(vm);
@@ -1079,6 +1157,7 @@ function generateZig(
finalize,
noConstructor,
estimatedSize,
+ hasPendingActivity = false,
} = {} as ClassDefinition
) {
const exports = new Map<string, string>();
@@ -1095,6 +1174,13 @@ function generateZig(
exports.set(`estimatedSize`, symbolName(typeName, "estimatedSize"));
}
+ if (hasPendingActivity) {
+ exports.set(
+ "hasPendingActivity",
+ symbolName(typeName, "hasPendingActivity")
+ );
+ }
+
Object.values(klass).map((a) =>
appendSymbols(exports, (name) => classSymbolName(typeName, name), a)
);
@@ -1103,15 +1189,23 @@ function generateZig(
);
const externs = Object.entries(proto)
- .filter(([name, { cache }]) => cache && typeof cache !== "string")
+ .filter(
+ ([name, { cache, internal }]) =>
+ (cache && typeof cache !== "string") || internal
+ )
.map(
([name, { cache }]) =>
`extern fn ${protoSymbolName(
typeName,
name
)}SetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void;
+
+ extern fn ${protoSymbolName(
+ typeName,
+ name
+ )}GetCachedValue(JSC.JSValue) JSC.JSValue;
- /// Set the cached value for ${name} on ${typeName}
+ /// \`${typeName}.${name}\` setter
/// This value will be visited by the garbage collector.
pub fn ${name}SetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void {
JSC.markBinding(@src());
@@ -1120,6 +1214,20 @@ function generateZig(
name
)}SetCachedValue(thisValue, globalObject, value);
}
+
+ /// \`${typeName}.${name}\` getter
+ /// This value will be visited by the garbage collector.
+ pub fn ${name}GetCached(thisValue: JSC.JSValue) ?JSC.JSValue {
+ JSC.markBinding(@src());
+ const result = ${protoSymbolName(
+ typeName,
+ name
+ )}GetCachedValue(thisValue);
+ if (result == .zero)
+ return null;
+
+ return result;
+ }
`.trim() + "\n"
)
.join("\n");
@@ -1281,6 +1389,15 @@ pub const ${className(typeName)} = struct {
return ${symbolName(typeName, "dangerouslySetPtr")}(value, ptr);
}
+ /// Detach the ptr from the thisValue
+ pub fn detachPtr(_: *${typeName}, value: JSC.JSValue) void {
+ JSC.markBinding(@src());
+ std.debug.assert(${symbolName(
+ typeName,
+ "dangerouslySetPtr"
+ )}(value, null));
+ }
+
extern fn ${symbolName(typeName, "fromJS")}(JSC.JSValue) ?*${typeName};
extern fn ${symbolName(
typeName,