Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions crates/perry-hir/src/lower/expr_member.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,24 +1087,23 @@ fn lower_member_inner(ctx: &mut LoweringContext, member: &ast::MemberExpr) -> Re
{
if let ast::Expr::Ident(obj_ident) = member.obj.as_ref() {
if obj_ident.sym.as_ref() == property.as_str() {
// #2060: `<TypedArrayCtor>.prototype` must keep reading the
// constructor closure's *real* prototype object — the per-kind
// proto carries the reflectable `length`/`byteLength`/
// `byteOffset`/`buffer` accessor descriptors installed by
// `populate_builtin_prototype_methods`. Collapsing to
// `PropertyGet { GlobalGet(0), "prototype" }` would instead hit
// codegen's `0.0` no-value placeholder (a number), so
// `Object.getPrototypeOf(Int8Array.prototype)` returned null and
// the descriptor lookup found nothing. Leave the inner
// `PropertyGet { GlobalGet(0), <ctor> }` in place so the outer
// `.prototype` reads through the closure's dynamic-prop table.
// #2060 / #2142: `<Ctor>.prototype` must keep reading the
// constructor closure's *real* prototype object. Each
// built-in constructor closure carries a populated proto
// (allocated in `populate_global_this_builtins`, populated
// by `populate_builtin_prototype_methods`) — that is where
// typed-array accessor descriptors AND the reified
// built-in prototype method values live. Collapsing to
// `PropertyGet { GlobalGet(0), "prototype" }` would instead
// read `globalThis.prototype` (undefined), losing every
// method-value reachable through `<Ctor>.prototype.<m>`
// (which is the value-read form of #2142, distinct from
// the typeof-fold which fires at AST level).
let outer_is_prototype = matches!(
&member.prop,
ast::MemberProp::Ident(p) if p.sym.as_ref() == "prototype"
);
let is_typed_array_ctor =
crate::ir::typed_array_kind_for_name(property).is_some();
if !(outer_is_prototype && is_typed_array_ctor) {
if !outer_is_prototype {
object_expr = Expr::GlobalGet(0);
}
}
Expand Down
Loading