Install stream extras lazily

This commit is contained in:
Basilisk-Dev 2026-05-08 18:59:28 -04:00 • committed by wuggy
commit abeed80755
3 changed files with 38 additions and 3 deletions

View file

@ -932,6 +932,13 @@ CallStreamExtra(JSContext* cx, const char* name, HandleValue streamVal,
if (!JS_GetProperty(cx, global, name, &fun))
return false;
if (!fun.isObject() || !IsCallable(fun)) {
if (!InitStreamExtras(cx, global))
return false;
if (!JS_GetProperty(cx, global, name, &fun))
return false;
}
if (!fun.isObject() || !IsCallable(fun)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAM_METHOD_NOT_IMPLEMENTED, name);

View file

@ -951,6 +951,20 @@ LookupStdName(const JSAtomState& names, JSAtom* name, const JSStdName* table)
return nullptr;
}
static bool
IsStreamExtraName(JSFlatString* name)
{
return JS_FlatStringEqualsAscii(name, "WritableStream") ||
JS_FlatStringEqualsAscii(name, "WritableStreamDefaultWriter") ||
JS_FlatStringEqualsAscii(name, "WritableStreamDefaultController") ||
JS_FlatStringEqualsAscii(name, "TransformStream") ||
JS_FlatStringEqualsAscii(name, "TransformStreamDefaultController") ||
JS_FlatStringEqualsAscii(name, "TextEncoderStream") ||
JS_FlatStringEqualsAscii(name, "TextDecoderStream") ||
JS_FlatStringEqualsAscii(name, "CompressionStream") ||
JS_FlatStringEqualsAscii(name, "DecompressionStream");
}
/*
* Table of standard classes, indexed by JSProtoKey. For entries where the
* JSProtoKey does not correspond to a class with a meaningful constructor, we
@ -1041,11 +1055,27 @@ JS_ResolveStandardClass(JSContext* cx, HandleObject obj, HandleId id, bool* reso
if (!GlobalObject::ensureConstructor(cx, global, key))
return false;
if (key == JSProto_ReadableStream) {
RootedObject globalObj(cx, global);
if (!InitStreamExtras(cx, globalObj))
return false;
}
*resolved = true;
return true;
}
}
if (cx->options().streams() && IsStreamExtraName(idAtom)) {
RootedObject globalObj(cx, global);
if (!InitStreamExtras(cx, globalObj))
return false;
if (!HasOwnProperty(cx, globalObj, id, resolved))
return false;
return true;
}
// There is no such property to resolve. An ordinary resolve hook would
// just return true at this point. But the global object is special in one
// more way: its prototype chain is lazily initialized. That is,
@ -1075,6 +1105,7 @@ JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj
return atom == names.undefined ||
atom == names.globalThis ||
IsStreamExtraName(atom) ||
LookupStdName(names, atom, standard_class_names) ||
LookupStdName(names, atom, builtin_property_names);
}

View file

@ -465,9 +465,6 @@ GlobalObject::initStandardClasses(JSContext* cx, Handle<GlobalObject*> global)
return false;
}
if (cx->options().streams() && !InitStreamExtras(cx, global))
return false;
return true;
}