Skip to content

Commit 2a3fd05

Browse files
committed
improve safety of map and set locks
1 parent 3fb8fd3 commit 2a3fd05

File tree

10 files changed

+586
-635
lines changed

10 files changed

+586
-635
lines changed

core/engine/src/builtins/map/map_iterator.rs

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//!
66
//! [spec]: https://tc39.es/ecma262/#sec-map-iterator-objects
77
8-
use super::ordered_map::{MapLock, OrderedMap};
8+
use super::ordered_map::OrderedMap;
99
use crate::{
1010
Context, JsData, JsResult,
1111
builtins::{
@@ -21,6 +21,22 @@ use crate::{
2121
};
2222
use boa_gc::{Finalize, Trace};
2323

24+
#[derive(Debug, Trace)]
25+
struct MapIteratorLock(JsObject<OrderedMap<JsValue>>);
26+
27+
impl MapIteratorLock {
28+
fn new(js_object: JsObject<OrderedMap<JsValue>>) -> Self {
29+
js_object.borrow_mut().data_mut().lock();
30+
Self(js_object)
31+
}
32+
}
33+
34+
impl Finalize for MapIteratorLock {
35+
fn finalize(&self) {
36+
self.0.borrow_mut().data_mut().unlock();
37+
}
38+
}
39+
2440
/// The Map Iterator object represents an iteration over a map. It implements the iterator protocol.
2541
///
2642
/// More information:
@@ -29,11 +45,10 @@ use boa_gc::{Finalize, Trace};
2945
/// [spec]: https://tc39.es/ecma262/#sec-map-iterator-objects
3046
#[derive(Debug, Finalize, Trace, JsData)]
3147
pub(crate) struct MapIterator {
32-
iterated_map: Option<JsObject>,
33-
map_next_index: usize,
48+
iterated_map: Option<MapIteratorLock>,
49+
next_index: usize,
3450
#[unsafe_ignore_trace]
35-
map_iteration_kind: PropertyNameKind,
36-
lock: MapLock,
51+
iteration_kind: PropertyNameKind,
3752
}
3853

3954
impl IntrinsicObject for MapIterator {
@@ -70,30 +85,21 @@ impl MapIterator {
7085
///
7186
/// [spec]: https://tc39.es/ecma262/#sec-createmapiterator
7287
pub(crate) fn create_map_iterator(
73-
map: &JsValue,
88+
map: JsObject<OrderedMap<JsValue>>,
7489
kind: PropertyNameKind,
7590
context: &mut Context,
76-
) -> JsResult<JsValue> {
77-
if let Some(map_obj) = map.as_object()
78-
&& let Some(mut map) = map_obj.downcast_mut::<OrderedMap<JsValue>>()
79-
{
80-
let lock = map.lock(map_obj.clone());
81-
let iter = Self {
82-
iterated_map: Some(map_obj.clone()),
83-
map_next_index: 0,
84-
map_iteration_kind: kind,
85-
lock,
86-
};
87-
let map_iterator = JsObject::from_proto_and_data_with_shared_shape(
88-
context.root_shape(),
89-
context.intrinsics().objects().iterator_prototypes().map(),
90-
iter,
91-
);
92-
return Ok(map_iterator.into());
93-
}
94-
Err(JsNativeError::typ()
95-
.with_message("`this` is not a Map")
96-
.into())
91+
) -> JsValue {
92+
let iter = Self {
93+
iterated_map: Some(MapIteratorLock::new(map)),
94+
next_index: 0,
95+
iteration_kind: kind,
96+
};
97+
let map_iterator = JsObject::from_proto_and_data_with_shared_shape(
98+
context.root_shape(),
99+
context.intrinsics().objects().iterator_prototypes().map(),
100+
iter,
101+
);
102+
map_iterator.into()
97103
}
98104

99105
/// %MapIteratorPrototype%.next( )
@@ -111,20 +117,19 @@ impl MapIterator {
111117
.and_then(JsObject::downcast_mut::<Self>)
112118
.ok_or_else(|| JsNativeError::typ().with_message("`this` is not a MapIterator"))?;
113119

114-
let item_kind = map_iterator.map_iteration_kind;
120+
let item_kind = map_iterator.iteration_kind;
115121

116122
if let Some(obj) = map_iterator.iterated_map.take() {
117123
let e = {
118-
let entries = obj
119-
.downcast_ref::<OrderedMap<JsValue>>()
120-
.expect("iterator should only iterate maps");
124+
let mut entries = obj.0.borrow_mut();
125+
let entries = entries.data_mut();
121126
let len = entries.full_len();
122127
loop {
123128
let element = entries
124-
.get_index(map_iterator.map_next_index)
129+
.get_index(map_iterator.next_index)
125130
.map(|(v, k)| (v.clone(), k.clone()));
126-
map_iterator.map_next_index += 1;
127-
if element.is_some() || map_iterator.map_next_index >= len {
131+
map_iterator.next_index += 1;
132+
if element.is_some() || map_iterator.next_index >= len {
128133
break element;
129134
}
130135
}

0 commit comments

Comments
 (0)