From cd2005a0a07674c887326acbd00eca869fdc4301 Mon Sep 17 00:00:00 2001 From: Andrew DiZenzo Date: Wed, 3 Jun 2026 16:23:12 +0000 Subject: [PATCH] fix(runtime): resolve generator function constructor lookups --- .../perry-runtime/src/object/field_get_set.rs | 20 +++++++++++++++++++ .../perry-runtime/src/object/global_this.rs | 20 +++++++++---------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/crates/perry-runtime/src/object/field_get_set.rs b/crates/perry-runtime/src/object/field_get_set.rs index 06e39572a1..82f8a83ecb 100644 --- a/crates/perry-runtime/src/object/field_get_set.rs +++ b/crates/perry-runtime/src/object/field_get_set.rs @@ -2474,6 +2474,26 @@ pub extern "C" fn js_object_get_field_by_name( if val.to_bits() != crate::value::TAG_UNDEFINED { return JSValue::from_bits(val.to_bits()); } + if name_str == "constructor" { + if let Some(ctor) = + crate::object::generator_function_constructor_of(obj as usize) + { + return JSValue::from_bits(ctor.to_bits()); + } + } + if name_str == "prototype" { + if let Some(proto) = + crate::object::generator_function_prototype_of(obj as usize) + { + return JSValue::from_bits(proto.to_bits()); + } + let func_value = crate::value::js_nanbox_pointer(obj as i64); + if let Some(proto) = + super::ordinary_function_prototype_value_for_read(func_value) + { + return JSValue::from_bits(proto.to_bits()); + } + } if name_str == "length" { let closure_value = crate::value::js_nanbox_pointer(obj as i64); if let Some(arity) = diff --git a/crates/perry-runtime/src/object/global_this.rs b/crates/perry-runtime/src/object/global_this.rs index 0d9c621145..e414d25a49 100644 --- a/crates/perry-runtime/src/object/global_this.rs +++ b/crates/perry-runtime/src/object/global_this.rs @@ -1695,17 +1695,15 @@ pub(crate) fn generator_function_proto_of(closure_ptr: usize) -> Option { /// `g.constructor` for a generator-function closure `g` → `%GeneratorFunction%` /// / `%AsyncGeneratorFunction%`. `None` for non-generator closures. (#3664) pub(crate) fn generator_function_constructor_of(closure_ptr: usize) -> Option { - let kind = closure_generator_kind(closure_ptr)?; - ensure_generator_intrinsics(); - let slot = match kind { - GeneratorKind::Sync => { - crate::object::GENERATOR_FUNCTION_INTRINSIC_PTR.load(Ordering::Acquire) - } - GeneratorKind::Async => { - crate::object::ASYNC_GENERATOR_FUNCTION_INTRINSIC_PTR.load(Ordering::Acquire) - } - }; - intrinsic_pointer_value(slot) + let proto = generator_function_proto_of(closure_ptr)?; + let proto_ptr = crate::value::js_nanbox_get_pointer(proto) as *const ObjectHeader; + if proto_ptr.is_null() { + return None; + } + let key = + crate::string::js_string_from_bytes(b"constructor".as_ptr(), "constructor".len() as u32); + let value = js_object_get_field_by_name(proto_ptr, key); + Some(f64::from_bits(value.bits())) } /// `g.prototype` for a generator-function closure `g`: a lazily-created object