@@ -6,28 +6,34 @@ use crate::core::{
66use crate :: error:: JSError ;
77use crate :: js_promise;
88use crate :: unicode:: utf16_to_utf8;
9+ use gc_arena:: Mutation as MutationContext ;
910use std:: cell:: RefCell ;
1011use std:: collections:: HashSet ;
1112use std:: rc:: Rc ;
1213
1314/// Create the console object with logging functions
14- pub fn make_console_object ( ) -> Result < JSObjectDataPtr , JSError > {
15- let console_obj = new_js_object_data ( ) ;
16- obj_set_key_value ( & console_obj, & "log" . into ( ) , Value :: Function ( "console.log" . to_string ( ) ) ) ?;
15+ pub fn make_console_object < ' gc > ( mc : & MutationContext < ' gc > ) -> Result < JSObjectDataPtr < ' gc > , JSError > {
16+ let console_obj = new_js_object_data ( mc ) ;
17+ obj_set_key_value ( mc , & console_obj, & "log" . into ( ) , Value :: Function ( "console.log" . to_string ( ) ) ) ?;
1718 // Provide `console.error` as an alias to `console.log` for now
18- obj_set_key_value ( & console_obj, & "error" . into ( ) , Value :: Function ( "console.error" . to_string ( ) ) ) ?;
19+ obj_set_key_value ( mc , & console_obj, & "error" . into ( ) , Value :: Function ( "console.error" . to_string ( ) ) ) ?;
1920 Ok ( console_obj)
2021}
2122
22- fn format_console_value ( val : & Value , env : & JSObjectDataPtr ) -> Result < String , JSError > {
23+ fn format_console_value < ' gc > (
24+ mc : & MutationContext < ' gc > , // added mc
25+ val : & Value < ' gc > ,
26+ env : & JSObjectDataPtr < ' gc > ,
27+ ) -> Result < String , JSError > {
2328 let mut seen = HashSet :: new ( ) ;
24- format_value_pretty ( val, env, 0 , & mut seen, false )
29+ format_value_pretty ( mc , val, env, 0 , & mut seen, false )
2530}
2631
27- fn format_value_pretty (
28- val : & Value ,
29- env : & JSObjectDataPtr ,
30- _depth : usize ,
32+ fn format_value_pretty < ' gc > (
33+ mc : & MutationContext < ' gc > ,
34+ val : & Value < ' gc > ,
35+ env : & JSObjectDataPtr < ' gc > ,
36+ depth : usize ,
3137 seen : & mut HashSet < * const RefCell < crate :: core:: JSObjectData > > ,
3238 quote_strings : bool ,
3339) -> Result < String , JSError > {
@@ -47,13 +53,13 @@ fn format_value_pretty(
4753 Value :: Object ( obj) => {
4854 // If this object is a Promise wrapper (stores inner promise under "__promise"),
4955 // print it compactly like Node: `Promise { <pending> }` and avoid listing internal helpers.
50- if let Ok ( Some ( inner_rc) ) = obj_get_key_value ( obj, & "__promise" . into ( ) ) {
56+ if let Ok ( Some ( inner_rc) ) = obj_get_key_value ( mc , obj, & "__promise" . into ( ) ) {
5157 if let Value :: Promise ( p_rc) = & * inner_rc. borrow ( ) {
52- return format_promise ( p_rc, env, _depth , seen) ;
58+ return format_promise ( mc , p_rc, env, depth , seen) ;
5359 }
5460 }
5561 // If object looks like an Error (has non-empty "stack" string), print the stack directly
56- if let Ok ( Some ( stack_rc) ) = obj_get_key_value ( obj, & "stack" . into ( ) ) {
62+ if let Ok ( Some ( stack_rc) ) = obj_get_key_value ( mc , obj, & "stack" . into ( ) ) {
5763 if let Value :: String ( s) = & * stack_rc. borrow ( ) {
5864 let s_utf8 = crate :: unicode:: utf16_to_utf8 ( s) ;
5965 if !s_utf8. is_empty ( ) {
@@ -71,20 +77,20 @@ fn format_value_pretty(
7177 Ok ( Value :: String ( s) ) => Ok ( crate :: unicode:: utf16_to_utf8 ( & s) ) ,
7278 _ => Ok ( "[object Date]" . to_string ( ) ) ,
7379 }
74- } else if crate :: js_array:: is_array ( obj) {
80+ } else if crate :: js_array:: is_array ( mc , obj) {
7581 if seen. contains ( & Rc :: as_ptr ( obj) ) {
7682 return Ok ( "[Circular]" . to_string ( ) ) ;
7783 }
7884 seen. insert ( Rc :: as_ptr ( obj) ) ;
7985
80- let len = crate :: js_array:: get_array_length ( obj) . unwrap_or ( 0 ) ;
86+ let len = crate :: js_array:: get_array_length ( mc , obj) . unwrap_or ( 0 ) ;
8187 let mut s = String :: from ( "[" ) ;
8288 for i in 0 ..len {
8389 if i > 0 {
8490 s. push_str ( ", " ) ;
8591 }
86- if let Some ( val_rc) = obj_get_key_value ( obj, & i. to_string ( ) . into ( ) ) ? {
87- let val_str = format_value_pretty ( & val_rc. borrow ( ) , env, _depth + 1 , seen, true ) ?;
92+ if let Some ( val_rc) = obj_get_key_value ( mc , obj, & i. to_string ( ) . into ( ) ) ? {
93+ let val_str = format_value_pretty ( mc , & val_rc. borrow ( ) , env, depth + 1 , seen, true ) ?;
8894 s. push_str ( & val_str) ;
8995 } else if i == len - 1 {
9096 s. push ( ',' ) ;
@@ -95,7 +101,7 @@ fn format_value_pretty(
95101 Ok ( s)
96102 } else {
97103 // Check for boxed primitive
98- if let Some ( val_rc) = obj_get_key_value ( obj, & "__value__" . into ( ) ) ? {
104+ if let Some ( val_rc) = obj_get_key_value ( mc , obj, & "__value__" . into ( ) ) ? {
99105 let val = val_rc. borrow ( ) ;
100106 match * val {
101107 Value :: Boolean ( b) => return Ok ( format ! ( "[Boolean: {}]" , b) ) ,
@@ -114,7 +120,7 @@ fn format_value_pretty(
114120
115121 // Try to get class name
116122 let mut class_name = String :: new ( ) ;
117- if let Some ( proto_rc) = obj. borrow ( ) . prototype . clone ( ) . and_then ( |w| w . upgrade ( ) ) {
123+ if let Some ( proto_rc) = obj. borrow ( ) . prototype . clone ( ) {
118124 if let Some ( ctor_val_rc) = proto_rc
119125 . borrow ( )
120126 . properties
@@ -170,7 +176,7 @@ fn format_value_pretty(
170176 }
171177
172178 s. push_str ( ": " ) ;
173- let val_str = format_value_pretty ( & val_rc. borrow ( ) , env, _depth + 1 , seen, true ) ?;
179+ let val_str = format_value_pretty ( mc , & val_rc. borrow ( ) , env, depth + 1 , seen, true ) ?;
174180 s. push_str ( & val_str) ;
175181 }
176182 s. push ( '}' ) ;
@@ -234,28 +240,34 @@ fn format_value_pretty(
234240}
235241
236242// Helper to format a Promise (or an Rc<RefCell<JSPromise>>) in Node-like style.
237- fn format_promise (
238- p_rc : & Rc < RefCell < crate :: js_promise:: JSPromise > > ,
239- env : & JSObjectDataPtr ,
240- _depth : usize ,
243+ fn format_promise < ' gc > (
244+ mc : & MutationContext < ' gc > ,
245+ p_rc : & Rc < RefCell < crate :: js_promise:: JSPromise < ' gc > > > ,
246+ env : & JSObjectDataPtr < ' gc > ,
247+ depth : usize ,
241248 seen : & mut HashSet < * const RefCell < crate :: core:: JSObjectData > > ,
242249) -> Result < String , JSError > {
243250 let p = p_rc. borrow ( ) ;
244251 match & p. state {
245252 crate :: js_promise:: PromiseState :: Pending => Ok ( "Promise { <pending> }" . to_string ( ) ) ,
246253 crate :: js_promise:: PromiseState :: Fulfilled ( val) => {
247- let inner = format_value_pretty ( val, env, _depth + 1 , seen, false ) ?;
254+ let inner = format_value_pretty ( mc , val, env, depth + 1 , seen, false ) ?;
248255 Ok ( format ! ( "Promise {{ {} }}" , inner) )
249256 }
250257 crate :: js_promise:: PromiseState :: Rejected ( val) => {
251- let inner = format_value_pretty ( val, env, _depth + 1 , seen, false ) ?;
258+ let inner = format_value_pretty ( mc , val, env, depth + 1 , seen, false ) ?;
252259 Ok ( format ! ( "Promise {{ <rejected> {} }}" , inner) )
253260 }
254261 }
255262}
256263
257264/// Handle console object method calls
258- pub fn handle_console_method ( method : & str , args : & [ Expr ] , env : & JSObjectDataPtr ) -> Result < Value , JSError > {
265+ pub fn handle_console_method < ' gc > (
266+ mc : & MutationContext < ' gc > , // added mc
267+ method : & str ,
268+ args : & [ Expr ] ,
269+ env : & JSObjectDataPtr < ' gc > ,
270+ ) -> Result < Value < ' gc > , JSError > {
259271 match method {
260272 "log" | "error" => {
261273 // Instrument: record current tick and task-queue length when console.log is invoked
@@ -267,7 +279,7 @@ pub fn handle_console_method(method: &str, args: &[Expr], env: &JSObjectDataPtr)
267279
268280 let mut values = Vec :: new ( ) ;
269281 for arg in args {
270- values. push ( evaluate_expr ( env, arg) ?) ;
282+ values. push ( evaluate_expr ( mc , env, arg) ?) ;
271283 }
272284
273285 if values. is_empty ( ) {
@@ -295,7 +307,7 @@ pub fn handle_console_method(method: &str, args: &[Expr], env: &JSObjectDataPtr)
295307 if arg_idx < values. len ( ) {
296308 let val = & values[ arg_idx] ;
297309 match next_char {
298- 's' => output. push_str ( & format_console_value ( val, env) ?) ,
310+ 's' => output. push_str ( & format_console_value ( mc , val, env) ?) ,
299311 'd' | 'i' => {
300312 if let Value :: Number ( n) = val {
301313 output. push_str ( & format ! ( "{:.0}" , n) ) ;
@@ -311,7 +323,7 @@ pub fn handle_console_method(method: &str, args: &[Expr], env: &JSObjectDataPtr)
311323 }
312324 }
313325 'o' | 'O' => {
314- output. push_str ( & format_console_value ( val, env) ?) ;
326+ output. push_str ( & format_console_value ( mc , val, env) ?) ;
315327 }
316328 'c' => {
317329 // Ignore CSS
@@ -343,7 +355,7 @@ pub fn handle_console_method(method: &str, args: &[Expr], env: &JSObjectDataPtr)
343355
344356 if !formatted {
345357 // Just print first arg
346- output. push_str ( & format_console_value ( & values[ 0 ] , env) ?) ;
358+ output. push_str ( & format_console_value ( mc , & values[ 0 ] , env) ?) ;
347359 arg_idx = 0 ;
348360 }
349361
@@ -352,7 +364,7 @@ pub fn handle_console_method(method: &str, args: &[Expr], env: &JSObjectDataPtr)
352364 if !output. is_empty ( ) {
353365 output. push ( ' ' ) ;
354366 }
355- output. push_str ( & format_console_value ( values_i, env) ?) ;
367+ output. push_str ( & format_console_value ( mc , values_i, env) ?) ;
356368 }
357369
358370 println ! ( "{}" , output) ;
0 commit comments