Skip to content

Commit fb6c597

Browse files
committed
Unify all get property instructions into get_by_name generic function
1 parent f984105 commit fb6c597

File tree

1 file changed

+17
-69
lines changed

1 file changed

+17
-69
lines changed

core/engine/src/vm/opcode/get/property.rs

Lines changed: 17 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,25 @@ fn js_string_get(this: &JsValue, key: &PropertyKey) -> Option<JsValue> {
2222
}
2323

2424
pub(crate) fn get_by_name<const LENGTH: bool>(
25-
(dst, value, index): (VaryingOperand, VaryingOperand, VaryingOperand),
25+
(dst, object, receiver, index): (VaryingOperand, &JsValue, &JsValue, VaryingOperand),
2626
context: &mut Context,
2727
) -> JsResult<()> {
28-
let value_object = context.vm.get_register(value.into()).clone();
29-
3028
if LENGTH {
31-
if let Some(object) = value_object.as_object()
29+
if let Some(object) = object.as_object()
3230
&& object.is_array()
3331
{
3432
let value = object.borrow().properties().storage[0].clone();
3533
context.vm.set_register(dst.into(), value);
3634
return Ok(());
37-
} else if let Some(string) = value_object.as_string() {
35+
} else if let Some(string) = object.as_string() {
3836
context
3937
.vm
4038
.set_register(dst.into(), (string.len() as u32).into());
4139
return Ok(());
4240
}
4341
}
4442

45-
let object = value_object.base_class(context)?;
43+
let object = object.base_class(context)?;
4644

4745
let ic = &context.vm.frame().code_block().ic[usize::from(index)];
4846
let object_borrowed = object.borrow();
@@ -57,11 +55,11 @@ pub(crate) fn get_by_name<const LENGTH: bool>(
5755

5856
drop(object_borrowed);
5957
if slot.attributes.has_get() && result.is_object() {
60-
result = result.as_object().expect("should contain getter").call(
61-
&value_object,
62-
&[],
63-
context,
64-
)?;
58+
result =
59+
result
60+
.as_object()
61+
.expect("should contain getter")
62+
.call(receiver, &[], context)?;
6563
}
6664
context.vm.set_register(dst.into(), result);
6765
return Ok(());
@@ -72,7 +70,7 @@ pub(crate) fn get_by_name<const LENGTH: bool>(
7270
let key: PropertyKey = ic.name.clone().into();
7371

7472
let context = &mut InternalMethodPropertyContext::new(context);
75-
let result = object.__get__(&key, value_object, context)?;
73+
let result = object.__get__(&key, receiver.clone(), context)?;
7674

7775
// Cache the property.
7876
let slot = *context.slot();
@@ -93,10 +91,11 @@ pub(crate) struct GetLengthProperty;
9391
impl GetLengthProperty {
9492
#[inline(always)]
9593
pub(crate) fn operation(
96-
args: (VaryingOperand, VaryingOperand, VaryingOperand),
94+
(dst, object, index): (VaryingOperand, VaryingOperand, VaryingOperand),
9795
context: &mut Context,
9896
) -> JsResult<()> {
99-
get_by_name::<true>(args, context)
97+
let object = context.vm.get_register(object.into()).clone();
98+
get_by_name::<true>((dst, &object, &object, index), context)
10099
}
101100
}
102101

@@ -116,10 +115,11 @@ pub(crate) struct GetPropertyByName;
116115
impl GetPropertyByName {
117116
#[inline(always)]
118117
pub(crate) fn operation(
119-
args: (VaryingOperand, VaryingOperand, VaryingOperand),
118+
(dst, object, index): (VaryingOperand, VaryingOperand, VaryingOperand),
120119
context: &mut Context,
121120
) -> JsResult<()> {
122-
get_by_name::<false>(args, context)
121+
let object = context.vm.get_register(object.into()).clone();
122+
get_by_name::<false>((dst, &object, &object, index), context)
123123
}
124124
}
125125

@@ -149,59 +149,7 @@ impl GetPropertyByNameWithThis {
149149
) -> JsResult<()> {
150150
let receiver = context.vm.get_register(receiver.into()).clone();
151151
let object = context.vm.get_register(value.into()).clone();
152-
153-
let ic = &context.vm.frame().code_block().ic[usize::from(index)];
154-
155-
if ic.name == StaticJsStrings::LENGTH
156-
&& let Some(string) = object.as_string()
157-
{
158-
context
159-
.vm
160-
.set_register(dst.into(), (string.len() as u32).into());
161-
return Ok(());
162-
}
163-
164-
let object = object.base_class(context)?;
165-
let object_borrowed = object.borrow();
166-
if let Some((shape, slot)) = ic.match_or_reset(object_borrowed.shape()) {
167-
let mut result = if slot.attributes.contains(SlotAttributes::PROTOTYPE) {
168-
let prototype = shape.prototype().expect("prototype should have value");
169-
let prototype = prototype.borrow();
170-
prototype.properties().storage[slot.index as usize].clone()
171-
} else {
172-
object_borrowed.properties().storage[slot.index as usize].clone()
173-
};
174-
175-
drop(object_borrowed);
176-
if slot.attributes.has_get() && result.is_object() {
177-
result = result.as_object().expect("should contain getter").call(
178-
&receiver,
179-
&[],
180-
context,
181-
)?;
182-
}
183-
context.vm.set_register(dst.into(), result);
184-
return Ok(());
185-
}
186-
187-
drop(object_borrowed);
188-
189-
let key: PropertyKey = ic.name.clone().into();
190-
191-
let context = &mut InternalMethodPropertyContext::new(context);
192-
let result = object.__get__(&key, receiver.clone(), context)?;
193-
194-
// Cache the property.
195-
let slot = *context.slot();
196-
if slot.is_cachable() {
197-
let ic = &context.vm.frame().code_block.ic[usize::from(index)];
198-
let object_borrowed = object.borrow();
199-
let shape = object_borrowed.shape();
200-
ic.set(shape, slot);
201-
}
202-
203-
context.vm.set_register(dst.into(), result);
204-
Ok(())
152+
get_by_name::<false>((dst, &object, &receiver, index), context)
205153
}
206154
}
207155

0 commit comments

Comments
 (0)