@@ -472,6 +472,139 @@ pub fn handle_object_method<'gc>(
472472 _ => Err ( raise_type_error ! ( "Object.getOwnPropertyNames called on non-object" ) ) ,
473473 }
474474 }
475+ "getOwnPropertyDescriptor" => {
476+ if args. len ( ) < 2 {
477+ return Err ( raise_type_error ! ( "Object.getOwnPropertyDescriptor requires at least two arguments" ) ) ;
478+ }
479+ let obj_val = args[ 0 ] . clone ( ) ;
480+ let obj = match obj_val {
481+ Value :: Object ( o) => o,
482+ _ => return Err ( raise_type_error ! ( "Object.getOwnPropertyDescriptor called on non-object" ) ) ,
483+ } ;
484+
485+ let prop_val = args[ 1 ] . clone ( ) ;
486+ let key = match prop_val {
487+ Value :: String ( s) => PropertyKey :: String ( utf16_to_utf8 ( & s) ) ,
488+ Value :: BigInt ( b) => PropertyKey :: String ( b. to_string ( ) ) ,
489+ Value :: Symbol ( sd) => PropertyKey :: Symbol ( sd) ,
490+ val => PropertyKey :: String ( value_to_string ( & val) ) ,
491+ } ;
492+
493+ if let Some ( val_rc) = object_get_key_value ( & obj, & key) {
494+ let desc_obj = new_js_object_data ( mc) ;
495+
496+ match & * val_rc. borrow ( ) {
497+ Value :: Property { value, getter, setter } => {
498+ if let Some ( v) = value {
499+ object_set_key_value ( mc, & desc_obj, "value" , v. borrow ( ) . clone ( ) ) ?;
500+ object_set_key_value ( mc, & desc_obj, "writable" , Value :: Boolean ( true ) ) ?;
501+ }
502+ if let Some ( g) = getter {
503+ match & * g. clone ( ) {
504+ Value :: Getter ( body, captured_env, _home) => {
505+ let func_obj = crate :: core:: new_js_object_data ( mc) ;
506+ let closure_data = crate :: core:: ClosureData {
507+ params : Vec :: new ( ) ,
508+ body : body. clone ( ) ,
509+ env : * captured_env,
510+ home_object : crate :: core:: GcCell :: new ( None ) ,
511+ captured_envs : Vec :: new ( ) ,
512+ bound_this : None ,
513+ is_arrow : false ,
514+ } ;
515+ let closure_val = crate :: core:: Value :: Closure ( crate :: core:: Gc :: new ( mc, closure_data) ) ;
516+ object_set_key_value ( mc, & func_obj, "__closure__" , closure_val) ?;
517+ object_set_key_value ( mc, & desc_obj, "get" , Value :: Object ( func_obj) ) ?;
518+ }
519+ other => {
520+ object_set_key_value ( mc, & desc_obj, "get" , other. clone ( ) ) ?;
521+ }
522+ }
523+ }
524+ if let Some ( s) = setter {
525+ match & * s. clone ( ) {
526+ Value :: Setter ( params, body, captured_env, _home) => {
527+ let func_obj = crate :: core:: new_js_object_data ( mc) ;
528+ let closure_data = crate :: core:: ClosureData {
529+ params : params. clone ( ) ,
530+ body : body. clone ( ) ,
531+ env : * captured_env,
532+ home_object : crate :: core:: GcCell :: new ( None ) ,
533+ captured_envs : Vec :: new ( ) ,
534+ bound_this : None ,
535+ is_arrow : false ,
536+ } ;
537+ let closure_val = crate :: core:: Value :: Closure ( crate :: core:: Gc :: new ( mc, closure_data) ) ;
538+ object_set_key_value ( mc, & func_obj, "__closure__" , closure_val) ?;
539+ object_set_key_value ( mc, & desc_obj, "set" , Value :: Object ( func_obj) ) ?;
540+ }
541+ other => {
542+ object_set_key_value ( mc, & desc_obj, "set" , other. clone ( ) ) ?;
543+ }
544+ }
545+ }
546+
547+ let enum_flag = Value :: Boolean ( obj. borrow ( ) . is_enumerable ( & key) ) ;
548+ object_set_key_value ( mc, & desc_obj, "enumerable" , enum_flag) ?;
549+ let config_flag = Value :: Boolean ( obj. borrow ( ) . is_configurable ( & key) ) ;
550+ object_set_key_value ( mc, & desc_obj, "configurable" , config_flag) ?;
551+ }
552+ Value :: Getter ( body, captured_env, _home_opt) => {
553+ let func_obj = crate :: core:: new_js_object_data ( mc) ;
554+ let closure_data = crate :: core:: ClosureData {
555+ params : Vec :: new ( ) ,
556+ body : body. clone ( ) ,
557+ env : * captured_env,
558+ home_object : crate :: core:: GcCell :: new ( None ) ,
559+ captured_envs : Vec :: new ( ) ,
560+ bound_this : None ,
561+ is_arrow : false ,
562+ } ;
563+ let closure_val = crate :: core:: Value :: Closure ( crate :: core:: Gc :: new ( mc, closure_data) ) ;
564+ object_set_key_value ( mc, & func_obj, "__closure__" , closure_val) ?;
565+ object_set_key_value ( mc, & desc_obj, "get" , Value :: Object ( func_obj) ) ?;
566+
567+ let enum_flag = Value :: Boolean ( obj. borrow ( ) . is_enumerable ( & key) ) ;
568+ object_set_key_value ( mc, & desc_obj, "enumerable" , enum_flag) ?;
569+ let config_flag = Value :: Boolean ( obj. borrow ( ) . is_configurable ( & key) ) ;
570+ object_set_key_value ( mc, & desc_obj, "configurable" , config_flag) ?;
571+ }
572+ Value :: Setter ( params, body, captured_env, _home_opt) => {
573+ let func_obj = crate :: core:: new_js_object_data ( mc) ;
574+ let closure_data = crate :: core:: ClosureData {
575+ params : params. clone ( ) ,
576+ body : body. clone ( ) ,
577+ env : * captured_env,
578+ home_object : crate :: core:: GcCell :: new ( None ) ,
579+ captured_envs : Vec :: new ( ) ,
580+ bound_this : None ,
581+ is_arrow : false ,
582+ } ;
583+ let closure_val = crate :: core:: Value :: Closure ( crate :: core:: Gc :: new ( mc, closure_data) ) ;
584+ object_set_key_value ( mc, & func_obj, "__closure__" , closure_val) ?;
585+ object_set_key_value ( mc, & desc_obj, "set" , Value :: Object ( func_obj) ) ?;
586+
587+ let enum_flag = Value :: Boolean ( obj. borrow ( ) . is_enumerable ( & key) ) ;
588+ object_set_key_value ( mc, & desc_obj, "enumerable" , enum_flag) ?;
589+ let config_flag = Value :: Boolean ( obj. borrow ( ) . is_configurable ( & key) ) ;
590+ object_set_key_value ( mc, & desc_obj, "configurable" , config_flag) ?;
591+ }
592+ other => {
593+ object_set_key_value ( mc, & desc_obj, "value" , other. clone ( ) ) ?;
594+ let writable_flag = Value :: Boolean ( obj. borrow ( ) . is_writable ( & key) ) ;
595+ object_set_key_value ( mc, & desc_obj, "writable" , writable_flag) ?;
596+ let enum_flag = Value :: Boolean ( obj. borrow ( ) . is_enumerable ( & key) ) ;
597+ object_set_key_value ( mc, & desc_obj, "enumerable" , enum_flag) ?;
598+ let config_flag = Value :: Boolean ( obj. borrow ( ) . is_configurable ( & key) ) ;
599+ object_set_key_value ( mc, & desc_obj, "configurable" , config_flag) ?;
600+ }
601+ }
602+
603+ Ok ( Value :: Object ( desc_obj) )
604+ } else {
605+ Ok ( Value :: Undefined )
606+ }
607+ }
475608 "getOwnPropertyDescriptors" => {
476609 if args. len ( ) != 1 {
477610 return Err ( raise_type_error ! ( "Object.getOwnPropertyDescriptors requires exactly one argument" ) ) ;
0 commit comments