@@ -1029,6 +1029,9 @@ pub fn evaluate_expr<'gc>(mc: &MutationContext<'gc>, env: &JSObjectDataPtr<'gc>,
10291029
10301030 match func_val {
10311031 Value :: Function ( name) => {
1032+ if let Some ( res) = call_native_function ( mc, & name, this_val. clone ( ) , & eval_args, env) ? {
1033+ return Ok ( res) ;
1034+ }
10321035 if name == "eval" {
10331036 let first_arg = eval_args. get ( 0 ) . cloned ( ) . unwrap_or ( Value :: Undefined ) ;
10341037 if let Value :: String ( script_str) = first_arg {
@@ -1178,6 +1181,33 @@ pub fn evaluate_expr<'gc>(mc: &MutationContext<'gc>, env: &JSObjectDataPtr<'gc>,
11781181 let method = & name[ 6 ..] ;
11791182 Ok ( handle_array_static_method ( mc, method, & eval_args, env) ?)
11801183 }
1184+ } else if name. starts_with ( "Map." ) {
1185+ if let Some ( method) = name. strip_prefix ( "Map.prototype." ) {
1186+ let this_v = this_val. clone ( ) . unwrap_or ( Value :: Undefined ) ;
1187+ if let Value :: Object ( obj) = this_v {
1188+ if let Some ( map_val) = obj_get_key_value ( & obj, & "__map__" . into ( ) ) ? {
1189+ if let Value :: Map ( map_ptr) = & * map_val. borrow ( ) {
1190+ Ok ( crate :: js_map:: handle_map_instance_method ( mc, map_ptr, method, & eval_args, env) ?)
1191+ } else {
1192+ Err ( EvalError :: Js ( raise_eval_error ! (
1193+ "TypeError: Map.prototype method called on incompatible receiver"
1194+ ) ) )
1195+ }
1196+ } else {
1197+ Err ( EvalError :: Js ( raise_eval_error ! (
1198+ "TypeError: Map.prototype method called on incompatible receiver"
1199+ ) ) )
1200+ }
1201+ } else if let Value :: Map ( map_ptr) = this_v {
1202+ Ok ( crate :: js_map:: handle_map_instance_method ( mc, & map_ptr, method, & eval_args, env) ?)
1203+ } else {
1204+ Err ( EvalError :: Js ( raise_eval_error ! (
1205+ "TypeError: Map.prototype method called on non-object receiver"
1206+ ) ) )
1207+ }
1208+ } else {
1209+ Err ( EvalError :: Js ( raise_eval_error ! ( format!( "Unknown Map function: {}" , name) ) ) )
1210+ }
11811211 } else {
11821212 Err ( EvalError :: Js ( raise_eval_error ! ( format!( "Unknown native function: {}" , name) ) ) )
11831213 }
@@ -1438,6 +1468,8 @@ pub fn evaluate_expr<'gc>(mc: &MutationContext<'gc>, env: &JSObjectDataPtr<'gc>,
14381468 return Ok ( Value :: Object ( new_obj) ) ;
14391469 } else if name == & crate :: unicode:: utf8_to_utf16 ( "Date" ) {
14401470 return Ok ( crate :: js_date:: handle_date_constructor ( mc, & eval_args, env) ?) ;
1471+ } else if name == & crate :: unicode:: utf8_to_utf16 ( "Map" ) {
1472+ return Ok ( crate :: js_map:: handle_map_constructor ( mc, & eval_args, env) ?) ;
14411473 }
14421474 }
14431475 }
@@ -1689,7 +1721,7 @@ fn evaluate_function_expression<'gc>(
16891721
16901722fn get_property_with_accessors < ' gc > (
16911723 mc : & MutationContext < ' gc > ,
1692- _env : & JSObjectDataPtr < ' gc > ,
1724+ env : & JSObjectDataPtr < ' gc > ,
16931725 obj : & JSObjectDataPtr < ' gc > ,
16941726 key : & PropertyKey < ' gc > ,
16951727) -> Result < Value < ' gc > , EvalError < ' gc > > {
@@ -1698,14 +1730,14 @@ fn get_property_with_accessors<'gc>(
16981730 match val {
16991731 Value :: Property { getter, value, .. } => {
17001732 if let Some ( g) = getter {
1701- return call_accessor ( mc, obj, & * g) ;
1733+ return call_accessor ( mc, env , obj, & * g) ;
17021734 }
17031735 if let Some ( v) = value {
17041736 return Ok ( v. borrow ( ) . clone ( ) ) ;
17051737 }
17061738 Ok ( Value :: Undefined )
17071739 }
1708- Value :: Getter ( ..) => call_accessor ( mc, obj, & val) ,
1740+ Value :: Getter ( ..) => call_accessor ( mc, env , obj, & val) ,
17091741 _ => Ok ( val) ,
17101742 }
17111743 } else {
@@ -1750,12 +1782,74 @@ fn set_property_with_accessors<'gc>(
17501782 }
17511783}
17521784
1785+ fn call_native_function < ' gc > (
1786+ mc : & MutationContext < ' gc > ,
1787+ name : & str ,
1788+ this_val : Option < Value < ' gc > > ,
1789+ args : & [ Value < ' gc > ] ,
1790+ env : & JSObjectDataPtr < ' gc > ,
1791+ ) -> Result < Option < Value < ' gc > > , EvalError < ' gc > > {
1792+ if name == "MapIterator.prototype.next" {
1793+ let this_v = this_val. clone ( ) . unwrap_or ( Value :: Undefined ) ;
1794+ if let Value :: Object ( obj) = this_v {
1795+ return Ok ( Some ( crate :: js_map:: handle_map_iterator_next ( mc, & obj, env) . map_err ( EvalError :: Js ) ?) ) ;
1796+ } else {
1797+ return Err ( EvalError :: Js ( raise_eval_error ! (
1798+ "TypeError: MapIterator.prototype.next called on non-object"
1799+ ) ) ) ;
1800+ }
1801+ }
1802+
1803+ if name. starts_with ( "Map." ) {
1804+ if let Some ( method) = name. strip_prefix ( "Map.prototype." ) {
1805+ let this_v = this_val. clone ( ) . unwrap_or ( Value :: Undefined ) ;
1806+ if let Value :: Object ( obj) = this_v {
1807+ if let Some ( map_val) = crate :: core:: obj_get_key_value ( & obj, & "__map__" . into ( ) ) . map_err ( EvalError :: Js ) ? {
1808+ if let Value :: Map ( map_ptr) = & * map_val. borrow ( ) {
1809+ return Ok ( Some (
1810+ crate :: js_map:: handle_map_instance_method ( mc, map_ptr, method, args, env) . map_err ( EvalError :: Js ) ?,
1811+ ) ) ;
1812+ } else {
1813+ return Err ( EvalError :: Js ( raise_eval_error ! (
1814+ "TypeError: Map.prototype method called on incompatible receiver"
1815+ ) ) ) ;
1816+ }
1817+ } else {
1818+ return Err ( EvalError :: Js ( raise_eval_error ! (
1819+ "TypeError: Map.prototype method called on incompatible receiver"
1820+ ) ) ) ;
1821+ }
1822+ } else if let Value :: Map ( map_ptr) = this_v {
1823+ return Ok ( Some (
1824+ crate :: js_map:: handle_map_instance_method ( mc, & map_ptr, method, args, env) . map_err ( EvalError :: Js ) ?,
1825+ ) ) ;
1826+ } else {
1827+ return Err ( EvalError :: Js ( raise_eval_error ! (
1828+ "TypeError: Map.prototype method called on non-object receiver"
1829+ ) ) ) ;
1830+ }
1831+ }
1832+ }
1833+ Ok ( None )
1834+ }
1835+
17531836fn call_accessor < ' gc > (
17541837 mc : & MutationContext < ' gc > ,
1838+ env : & JSObjectDataPtr < ' gc > ,
17551839 receiver : & JSObjectDataPtr < ' gc > ,
17561840 accessor : & Value < ' gc > ,
17571841) -> Result < Value < ' gc > , EvalError < ' gc > > {
17581842 match accessor {
1843+ Value :: Function ( name) => {
1844+ if let Some ( res) = call_native_function ( mc, name, Some ( Value :: Object ( * receiver) ) , & [ ] , env) ? {
1845+ Ok ( res)
1846+ } else {
1847+ Err ( EvalError :: Js ( crate :: raise_type_error!( format!(
1848+ "Accessor function {} not supported" ,
1849+ name
1850+ ) ) ) )
1851+ }
1852+ }
17591853 Value :: Getter ( body, captured_env, _) => {
17601854 let call_env = crate :: core:: new_js_object_data ( mc) ;
17611855 call_env. borrow_mut ( mc) . prototype = Some ( * captured_env) ;
0 commit comments