@@ -22,26 +22,26 @@ pub fn handle_generator_function_call(
2222 env : & JSObjectDataPtr ,
2323) -> Result < Value , JSError > {
2424 // Create a new generator object
25- let generator = Rc :: new ( RefCell :: new ( crate :: core:: JSGenerator {
25+ let generator = gc_arena :: Gc :: new ( mc , gc_arena :: lock :: RefLock :: new ( crate :: core:: JSGenerator {
2626 params : params. to_vec ( ) ,
2727 body : body. to_vec ( ) ,
2828 env : env. clone ( ) ,
2929 state : crate :: core:: GeneratorState :: NotStarted ,
3030 } ) ) ;
3131
3232 // Create a wrapper object for the generator
33- let gen_obj = Rc :: new ( RefCell :: new ( crate :: core:: JSObjectData :: new ( ) ) ) ;
33+ let gen_obj = gc_arena :: Gc :: new ( mc , gc_arena :: lock :: RefLock :: new ( crate :: core:: JSObjectData :: new ( ) ) ) ;
3434 // Store the actual generator data
35- gen_obj. borrow_mut ( ) . insert (
35+ gen_obj. borrow_mut ( mc ) . insert (
3636 crate :: core:: PropertyKey :: String ( "__generator__" . to_string ( ) ) ,
37- Rc :: new ( RefCell :: new ( Value :: Generator ( generator) ) ) ,
37+ gc_arena :: Gc :: new ( mc , gc_arena :: lock :: RefLock :: new ( Value :: Generator ( generator) ) ) ,
3838 ) ;
3939
4040 Ok ( Value :: Object ( gen_obj) )
4141}
4242
4343/// Handle generator instance method calls (like `gen.next()`, `gen.return()`, etc.)
44- pub fn handle_generator_instance_method (
44+ pub fn handle_generator_instance_method < ' gc > ( mc : & MutationContext < ' gc > ,
4545 generator : & Rc < RefCell < crate :: core:: JSGenerator > > ,
4646 method : & str ,
4747 args : & [ Expr ] ,
@@ -53,7 +53,7 @@ pub fn handle_generator_instance_method(
5353 let send_value = if args. is_empty ( ) {
5454 Value :: Undefined
5555 } else {
56- evaluate_expr ( env, & args[ 0 ] ) ?
56+ evaluate_expr ( mc , env, & args[ 0 ] ) ?
5757 } ;
5858
5959 generator_next ( generator, send_value)
@@ -63,7 +63,7 @@ pub fn handle_generator_instance_method(
6363 let return_value = if args. is_empty ( ) {
6464 Value :: Undefined
6565 } else {
66- evaluate_expr ( env, & args[ 0 ] ) ?
66+ evaluate_expr ( mc , env, & args[ 0 ] ) ?
6767 } ;
6868
6969 generator_return ( generator, return_value)
@@ -73,7 +73,7 @@ pub fn handle_generator_instance_method(
7373 let throw_value = if args. is_empty ( ) {
7474 Value :: Undefined
7575 } else {
76- evaluate_expr ( env, & args[ 0 ] ) ?
76+ evaluate_expr ( mc , env, & args[ 0 ] ) ?
7777 } ;
7878
7979 generator_throw ( generator, throw_value)
@@ -90,15 +90,15 @@ fn replace_first_yield_in_expr(expr: &Expr, send_value: &Value, replaced: &mut b
9090 Expr :: Yield ( _) => {
9191 if !* replaced {
9292 * replaced = true ;
93- Expr :: Value ( send_value . clone ( ) )
93+ Expr :: Var ( "__gen_throw_val" . to_string ( ) , None , None )
9494 } else {
9595 expr. clone ( )
9696 }
9797 }
9898 Expr :: YieldStar ( _) => {
9999 if !* replaced {
100100 * replaced = true ;
101- Expr :: Value ( send_value . clone ( ) )
101+ Expr :: Var ( "__gen_throw_val" . to_string ( ) , None , None )
102102 } else {
103103 expr. clone ( )
104104 }
@@ -304,7 +304,7 @@ fn replace_first_yield_statement_with_throw(stmt: &mut Statement, throw_value: &
304304 match & mut stmt. kind {
305305 StatementKind :: Expr ( e) => {
306306 if expr_contains_yield ( e) {
307- stmt. kind = StatementKind :: Throw ( Expr :: Value ( throw_value . clone ( ) ) ) ;
307+ stmt. kind = StatementKind :: Throw ( Expr :: Var ( "__gen_throw_val" . to_string ( ) , None , None ) ) ;
308308 return true ;
309309 }
310310 false
@@ -314,7 +314,7 @@ fn replace_first_yield_statement_with_throw(stmt: &mut Statement, throw_value: &
314314 if let Some ( expr) = expr_opt
315315 && expr_contains_yield ( expr)
316316 {
317- stmt. kind = StatementKind :: Throw ( Expr :: Value ( throw_value . clone ( ) ) ) ;
317+ stmt. kind = StatementKind :: Throw ( Expr :: Var ( "__gen_throw_val" . to_string ( ) , None , None ) ) ;
318318 return true ;
319319 }
320320 }
@@ -323,7 +323,7 @@ fn replace_first_yield_statement_with_throw(stmt: &mut Statement, throw_value: &
323323 StatementKind :: Const ( decls) => {
324324 for ( _, expr) in decls {
325325 if expr_contains_yield ( expr) {
326- stmt. kind = StatementKind :: Throw ( Expr :: Value ( throw_value . clone ( ) ) ) ;
326+ stmt. kind = StatementKind :: Throw ( Expr :: Var ( "__gen_throw_val" . to_string ( ) , None , None ) ) ;
327327 return true ;
328328 }
329329 }
@@ -447,7 +447,7 @@ fn find_first_yield_in_statements(stmts: &[Statement]) -> Option<(usize, Option<
447447
448448/// Execute generator.next()
449449fn generator_next ( generator : & Rc < RefCell < crate :: core:: JSGenerator > > , _send_value : Value ) -> Result < Value , JSError > {
450- let mut gen_obj = generator. borrow_mut ( ) ;
450+ let mut gen_obj = generator. borrow_mut ( mc ) ;
451451
452452 match & mut gen_obj. state {
453453 crate :: core:: GeneratorState :: NotStarted => {
@@ -465,17 +465,18 @@ fn generator_next(generator: &Rc<RefCell<crate::core::JSGenerator>>, _send_value
465465 // function-like frame whose prototype is the captured env.
466466 if let Some ( inner_expr_box) = yield_inner {
467467 let func_env = prepare_function_call_env ( Some ( & gen_obj. env ) , None , None , & [ ] , None , None ) ?;
468- match crate :: core:: evaluate_expr ( & func_env, & inner_expr_box) {
469- Ok ( val) => return Ok ( create_iterator_result ( val, false ) ) ,
470- Err ( _) => return Ok ( create_iterator_result ( Value :: Undefined , false ) ) ,
468+ crate :: core:: obj_set_key_value ( mc, & func_env, & "__gen_throw_val" . into ( ) , throw_value. clone ( ) ) ?;
469+ match crate :: core:: evaluate_expr ( mc, & func_env, & inner_expr_box) {
470+ Ok ( val) => return Ok ( create_iterator_result ( mc, val, false ) ) ,
471+ Err ( _) => return Ok ( create_iterator_result ( mc, Value :: Undefined , false ) ) ,
471472 }
472473 }
473474
474475 // No inner expression -> yield undefined
475- Ok ( create_iterator_result ( Value :: Undefined , false ) )
476+ Ok ( create_iterator_result ( mc , Value :: Undefined , false ) )
476477 } else {
477478 // Fallback to previous placeholder behavior
478- Ok ( create_iterator_result ( Value :: Number ( 42.0 ) , false ) )
479+ Ok ( create_iterator_result ( mc , Value :: Number ( 42.0 ) , false ) )
479480 }
480481 }
481482 crate :: core:: GeneratorState :: Suspended { pc, stack : _ } => {
@@ -486,7 +487,7 @@ fn generator_next(generator: &Rc<RefCell<crate::core::JSGenerator>>, _send_value
486487 let pc_val = * pc;
487488 if pc_val >= gen_obj. body . len ( ) {
488489 gen_obj. state = crate :: core:: GeneratorState :: Completed ;
489- return Ok ( create_iterator_result ( Value :: Undefined , true ) ) ;
490+ return Ok ( create_iterator_result ( mc , Value :: Undefined , true ) ) ;
490491 }
491492 // Clone the tail and replace first yield in the first statement
492493 let mut tail: Vec < Statement > = gen_obj. body [ pc_val..] . to_vec ( ) ;
@@ -496,29 +497,30 @@ fn generator_next(generator: &Rc<RefCell<crate::core::JSGenerator>>, _send_value
496497 }
497498
498499 let func_env = prepare_function_call_env ( Some ( & gen_obj. env ) , None , None , & [ ] , None , None ) ?;
500+ crate :: core:: obj_set_key_value ( mc, & func_env, & "__gen_throw_val" . into ( ) , throw_value. clone ( ) ) ?;
499501 // Execute the (possibly modified) tail
500- let result = crate :: core:: evaluate_statements ( & func_env, & tail) ;
502+ let result = crate :: core:: evaluate_statements ( mc , & func_env, & tail) ;
501503 gen_obj. state = crate :: core:: GeneratorState :: Completed ;
502504 match result {
503- Ok ( val) => Ok ( create_iterator_result ( val, true ) ) ,
504- Err ( _) => Ok ( create_iterator_result ( Value :: Undefined , true ) ) ,
505+ Ok ( val) => Ok ( create_iterator_result ( mc , val, true ) ) ,
506+ Err ( _) => Ok ( create_iterator_result ( mc , Value :: Undefined , true ) ) ,
505507 }
506508 }
507509 crate :: core:: GeneratorState :: Running { .. } => Err ( raise_eval_error ! ( "Generator is already running" ) ) ,
508- crate :: core:: GeneratorState :: Completed => Ok ( create_iterator_result ( Value :: Undefined , true ) ) ,
510+ crate :: core:: GeneratorState :: Completed => Ok ( create_iterator_result ( mc , Value :: Undefined , true ) ) ,
509511 }
510512}
511513
512514/// Execute generator.return()
513515fn generator_return ( generator : & Rc < RefCell < crate :: core:: JSGenerator > > , return_value : Value ) -> Result < Value , JSError > {
514- let mut gen_obj = generator. borrow_mut ( ) ;
516+ let mut gen_obj = generator. borrow_mut ( mc ) ;
515517 gen_obj. state = crate :: core:: GeneratorState :: Completed ;
516- Ok ( create_iterator_result ( return_value, true ) )
518+ Ok ( create_iterator_result ( mc , return_value, true ) )
517519}
518520
519521/// Execute generator.throw()
520522fn generator_throw ( generator : & Rc < RefCell < crate :: core:: JSGenerator > > , throw_value : Value ) -> Result < Value , JSError > {
521- let mut gen_obj = generator. borrow_mut ( ) ;
523+ let mut gen_obj = generator. borrow_mut ( mc ) ;
522524 match & mut gen_obj. state {
523525 crate :: core:: GeneratorState :: NotStarted => {
524526 // Throwing into a not-started generator throws synchronously
@@ -543,17 +545,18 @@ fn generator_throw(generator: &Rc<RefCell<crate::core::JSGenerator>>, throw_valu
543545 }
544546 if !replaced {
545547 // fallback: replace the top-level statement
546- tail[ 0 ] = StatementKind :: Throw ( Expr :: Value ( throw_value . clone ( ) ) ) . into ( ) ;
548+ tail[ 0 ] = StatementKind :: Throw ( Expr :: Var ( "__gen_throw_val" . to_string ( ) , None , None ) ) . into ( ) ;
547549 }
548550
549551 let func_env = prepare_function_call_env ( Some ( & gen_obj. env ) , None , None , & [ ] , None , None ) ?;
552+ crate :: core:: obj_set_key_value ( mc, & func_env, & "__gen_throw_val" . into ( ) , throw_value. clone ( ) ) ?;
550553
551554 // Execute the modified tail. If the throw is uncaught, evaluate_statements
552555 // will return Err and we should propagate that to the caller.
553- let result = crate :: core:: evaluate_statements ( & func_env, & tail) ;
556+ let result = crate :: core:: evaluate_statements ( mc , & func_env, & tail) ;
554557 gen_obj. state = crate :: core:: GeneratorState :: Completed ;
555558 match result {
556- Ok ( val) => Ok ( create_iterator_result ( val, true ) ) ,
559+ Ok ( val) => Ok ( create_iterator_result ( mc , val, true ) ) ,
557560 Err ( e) => Err ( e) ,
558561 }
559562 }
@@ -563,18 +566,18 @@ fn generator_throw(generator: &Rc<RefCell<crate::core::JSGenerator>>, throw_valu
563566}
564567
565568/// Create an iterator result object {value: value, done: done}
566- fn create_iterator_result ( value : Value , done : bool ) -> Value {
567- let obj = Rc :: new ( RefCell :: new ( crate :: core:: JSObjectData :: default ( ) ) ) ;
569+ fn create_iterator_result < ' gc > ( mc : & MutationContext < ' gc > , value : Value < ' gc > , done : bool ) -> Value < ' gc > {
570+ let obj = gc_arena :: Gc :: new ( mc , gc_arena :: lock :: RefLock :: new ( crate :: core:: JSObjectData :: default ( ) ) ) ;
568571
569572 // Set value property
570- obj. borrow_mut ( )
573+ obj. borrow_mut ( mc )
571574 . properties
572- . insert ( PropertyKey :: String ( "value" . to_string ( ) ) , Rc :: new ( RefCell :: new ( value) ) ) ;
575+ . insert ( PropertyKey :: String ( "value" . to_string ( ) ) , gc_arena :: Gc :: new ( mc , gc_arena :: lock :: RefLock :: new ( value) ) ) ;
573576
574577 // Set done property
575- obj. borrow_mut ( )
578+ obj. borrow_mut ( mc )
576579 . properties
577- . insert ( PropertyKey :: String ( "done" . to_string ( ) ) , Rc :: new ( RefCell :: new ( Value :: Boolean ( done) ) ) ) ;
580+ . insert ( PropertyKey :: String ( "done" . to_string ( ) ) , gc_arena :: Gc :: new ( mc , gc_arena :: lock :: RefLock :: new ( Value :: Boolean ( done) ) ) ) ;
578581
579582 Value :: Object ( obj)
580583}
0 commit comments