1+ use std:: ops:: { Index , IndexMut } ;
2+
13use crate :: {
24 ecmascript:: {
35 execution:: { Agent , JsResult } ,
@@ -7,8 +9,11 @@ use crate::{
79 } ,
810 } ,
911 heap:: { indexes:: MapIndex , GetHeapData , ObjectEntry , ObjectEntryPropertyDescriptor } ,
12+ Heap ,
1013} ;
1114
15+ use self :: data:: MapHeapData ;
16+
1217use super :: ordinary:: ordinary_set_prototype_of_check_loop;
1318
1419pub mod data;
@@ -52,6 +57,42 @@ impl From<Map> for Object {
5257 }
5358}
5459
60+ impl Index < Map > for Heap {
61+ type Output = MapHeapData ;
62+
63+ fn index ( & self , index : Map ) -> & Self :: Output {
64+ self . maps
65+ . get ( index. 0 . into_index ( ) )
66+ . expect ( "Map out of bounds" )
67+ . as_ref ( )
68+ . expect ( "Map slot empty" )
69+ }
70+ }
71+
72+ impl IndexMut < Map > for Heap {
73+ fn index_mut ( & mut self , index : Map ) -> & mut Self :: Output {
74+ self . maps
75+ . get_mut ( index. 0 . into_index ( ) )
76+ . expect ( "Map out of bounds" )
77+ . as_mut ( )
78+ . expect ( "Map slot empty" )
79+ }
80+ }
81+
82+ fn create_map_base_object ( agent : & mut Agent , map : Map , entries : & [ ObjectEntry ] ) -> OrdinaryObject {
83+ // TODO: An issue crops up if multiple realms are in play:
84+ // The prototype should not be dependent on the realm we're operating in
85+ // but should instead be bound to the realm the object was created in.
86+ // We'll have to cross this bridge at a later point, likely be designating
87+ // a "default realm" and making non-default realms always initialize ObjectHeapData.
88+ let prototype = agent. current_realm ( ) . intrinsics ( ) . map_prototype ( ) ;
89+ let object_index = agent
90+ . heap
91+ . create_object_with_prototype ( prototype. into ( ) , entries) ;
92+ agent. heap [ map] . object_index = Some ( object_index) ;
93+ OrdinaryObject :: from ( object_index)
94+ }
95+
5596impl OrdinaryObjectInternalSlots for Map {
5697 fn internal_extensible ( self , agent : & Agent ) -> bool {
5798 if let Some ( object_index) = agent. heap . get ( self . 0 ) . object_index {
@@ -64,9 +105,10 @@ impl OrdinaryObjectInternalSlots for Map {
64105 fn internal_set_extensible ( self , agent : & mut Agent , value : bool ) {
65106 if let Some ( object_index) = agent. heap . get ( self . 0 ) . object_index {
66107 OrdinaryObject :: from ( object_index) . internal_set_extensible ( agent, value)
67- } else {
108+ } else if !value {
68109 // Create base object and set inextensible
69- todo ! ( )
110+ let base = create_map_base_object ( agent, self , & [ ] ) ;
111+ base. internal_set_extensible ( agent, value) ;
70112 }
71113 }
72114
@@ -88,8 +130,9 @@ impl OrdinaryObjectInternalSlots for Map {
88130 if let Some ( object_index) = agent. heap . get ( self . 0 ) . object_index {
89131 OrdinaryObject :: from ( object_index) . internal_set_prototype ( agent, prototype)
90132 } else {
91- // Create base object and set inextensible
92- todo ! ( )
133+ // Create base object and set prototype
134+ let base = create_map_base_object ( agent, self , & [ ] ) ;
135+ base. internal_set_prototype ( agent, prototype) ;
93136 }
94137 }
95138}
@@ -151,15 +194,11 @@ impl InternalMethods for Map {
151194 if let Some ( object_index) = agent. heap . get ( self . 0 ) . object_index {
152195 OrdinaryObject :: from ( object_index) . internal_has_property ( agent, property_key)
153196 } else {
154- let prototype = agent. current_realm ( ) . intrinsics ( ) . map_prototype ( ) ;
155197 let new_entry = ObjectEntry {
156198 key : property_key,
157199 value : ObjectEntryPropertyDescriptor :: from ( property_descriptor) ,
158200 } ;
159- let object_index = agent
160- . heap
161- . create_object_with_prototype ( prototype. into_object ( ) , vec ! [ new_entry] ) ;
162- agent. heap . get_mut ( self . 0 ) . object_index = Some ( object_index) ;
201+ create_map_base_object ( agent, self , & [ new_entry] ) ;
163202 Ok ( true )
164203 }
165204 }
@@ -168,10 +207,8 @@ impl InternalMethods for Map {
168207 if let Some ( object_index) = agent. heap . get ( self . 0 ) . object_index {
169208 OrdinaryObject :: from ( object_index) . internal_has_property ( agent, property_key)
170209 } else {
171- let parent = self . internal_get_prototype_of ( agent) ?;
172- parent. map_or ( Ok ( false ) , |parent| {
173- parent. internal_has_property ( agent, property_key)
174- } )
210+ let parent = agent. current_realm ( ) . intrinsics ( ) . map_prototype ( ) ;
211+ parent. internal_has_property ( agent, property_key)
175212 }
176213 }
177214
@@ -184,10 +221,8 @@ impl InternalMethods for Map {
184221 if let Some ( object_index) = agent. heap . get ( self . 0 ) . object_index {
185222 OrdinaryObject :: from ( object_index) . internal_get ( agent, property_key, receiver)
186223 } else {
187- let parent = self . internal_get_prototype_of ( agent) ?;
188- parent. map_or ( Ok ( Value :: Undefined ) , |parent| {
189- parent. internal_get ( agent, property_key, receiver)
190- } )
224+ let parent = agent. current_realm ( ) . intrinsics ( ) . map_prototype ( ) ;
225+ parent. internal_get ( agent, property_key, receiver)
191226 }
192227 }
193228
0 commit comments