Skip to content

Commit ffe8514

Browse files
avm2: Store slot and disp ids as usize internally
Previously, they were being stored as u32s
1 parent 0c09f9b commit ffe8514

File tree

13 files changed

+134
-139
lines changed

13 files changed

+134
-139
lines changed

core/build_playerglobal/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ fn write_native_table(data: &[u8], out_dir: &Path) -> Result<Vec<u8>, Box<dyn st
461461
panic!("ASC should calculate slot ids for all slots; cannot apply NativeAccessible without a compiler-calculated slot id")
462462
} else {
463463
// Slots are 1-indexed!
464-
let slot_id = slot_id - 1;
464+
let slot_id = slot_id as usize - 1;
465465

466466
let (trait_name, const_name) =
467467
rust_path_and_trait_name(&abc, trait_, parent);
@@ -472,7 +472,7 @@ fn write_native_table(data: &[u8], out_dir: &Path) -> Result<Vec<u8>, Box<dyn st
472472
.entry(trait_name)
473473
.or_default()
474474
.push(quote! {
475-
pub const #const_name: u32 = #slot_id;
475+
pub const #const_name: usize = #slot_id;
476476
});
477477
}
478478
}
@@ -490,6 +490,7 @@ fn write_native_table(data: &[u8], out_dir: &Path) -> Result<Vec<u8>, Box<dyn st
490490
// add 1 if it's a class method, or subtract 2 if it's
491491
// an instance method.
492492
let disp_id = if is_class { disp_id + 1 } else { disp_id - 2 };
493+
let disp_id = disp_id as usize;
493494

494495
let (trait_name, const_name) =
495496
rust_path_and_trait_name(&abc, trait_, parent);
@@ -506,7 +507,7 @@ fn write_native_table(data: &[u8], out_dir: &Path) -> Result<Vec<u8>, Box<dyn st
506507
.entry(trait_name)
507508
.or_default()
508509
.push(quote! {
509-
pub const #const_name: u32 = #disp_id;
510+
pub const #const_name: usize = #disp_id;
510511
});
511512
}
512513
}

core/src/avm2/activation.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
10331033
let args = self.stack.get_args(arg_count as usize);
10341034
let receiver = self.pop_stack().null_check(self, None)?;
10351035

1036-
let value = receiver.call_method_with_args(index, args, self)?;
1036+
let value = receiver.call_method_with_args(index as usize, args, self)?;
10371037

10381038
if push_return_value {
10391039
self.push_stack(value);
@@ -1636,7 +1636,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
16361636
.null_check(self, None)?
16371637
.as_object()
16381638
.expect("Cannot get_slot on primitive");
1639-
let value = object.get_slot(index);
1639+
let value = object.get_slot(index as usize);
16401640

16411641
// We use `stack_top` instead of `pop_stack` and `push_stack` here
16421642
// because it allows us to skip the extra bounds checks and stack pointer
@@ -1655,7 +1655,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
16551655
.as_object()
16561656
.expect("Cannot set_slot on primitive");
16571657

1658-
object.set_slot(index, value, self)?;
1658+
object.set_slot(index as usize, value, self)?;
16591659

16601660
Ok(())
16611661
}
@@ -1668,7 +1668,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
16681668
.as_object()
16691669
.expect("Cannot set_slot on primitive");
16701670

1671-
object.set_slot_no_coerce(index, value, self.gc());
1671+
object.set_slot_no_coerce(index as usize, value, self.gc());
16721672

16731673
Ok(())
16741674
}
@@ -1679,7 +1679,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
16791679
self.global_scope()
16801680
.as_object()
16811681
.unwrap()
1682-
.set_slot(index, value, self)?;
1682+
.set_slot(index as usize, value, self)?;
16831683

16841684
Ok(())
16851685
}
@@ -1720,7 +1720,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
17201720
.as_object()
17211721
.expect("Cannot get_slot on primitive");
17221722

1723-
let ctor = source.get_slot(index);
1723+
let ctor = source.get_slot(index as usize);
17241724
let constructed_object = ctor.construct(self, args)?;
17251725

17261726
self.push_stack(constructed_object);

core/src/avm2/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ pub fn make_error_1025<'gc>(activation: &mut Activation<'_, 'gc>, index: u32) ->
252252
#[cold]
253253
pub fn make_error_1026<'gc>(
254254
activation: &mut Activation<'_, 'gc>,
255-
slot_id: u32,
255+
slot_id: usize,
256256
slot_count: usize,
257257
) -> Error<'gc> {
258258
let err = verify_error(

core/src/avm2/globals/flash/display/display_object.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ pub fn object_to_rectangle<'gc>(
934934
activation: &mut Activation<'_, 'gc>,
935935
object: Object<'gc>,
936936
) -> Result<Rectangle<Twips>, Error<'gc>> {
937-
const SLOTS: &[u32] = &[
937+
const SLOTS: &[usize] = &[
938938
rectangle_slots::X,
939939
rectangle_slots::Y,
940940
rectangle_slots::WIDTH,

core/src/avm2/globals/flash/events/mouse_event.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ pub fn update_after_event<'gc>(
4040
pub(super) fn local_to_stage_x<'gc>(
4141
activation: &mut Activation<'_, 'gc>,
4242
this: Object<'gc>,
43-
slot_x: u32,
44-
slot_y: u32,
43+
slot_x: usize,
44+
slot_y: usize,
4545
) -> Result<Value<'gc>, Error<'gc>> {
4646
if let Some(evt) = this.as_event() {
4747
let local_x = this.get_slot(slot_x).coerce_to_number(activation)?;
@@ -66,8 +66,8 @@ pub(super) fn local_to_stage_x<'gc>(
6666
pub(super) fn local_to_stage_y<'gc>(
6767
activation: &mut Activation<'_, 'gc>,
6868
this: Object<'gc>,
69-
slot_x: u32,
70-
slot_y: u32,
69+
slot_x: usize,
70+
slot_y: usize,
7171
) -> Result<Value<'gc>, Error<'gc>> {
7272
if let Some(evt) = this.as_event() {
7373
let local_x = this.get_slot(slot_x).coerce_to_number(activation)?;

core/src/avm2/object.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ pub trait TObject<'gc>: 'gc + Collect<'gc> + Debug + Into<Object<'gc>> + Clone +
399399
/// Retrieve a slot by its index.
400400
#[no_dynamic]
401401
#[inline(always)]
402-
fn get_slot(self, id: u32) -> Value<'gc> {
402+
fn get_slot(self, id: usize) -> Value<'gc> {
403403
let base = self.base();
404404

405405
base.get_slot(id)
@@ -409,7 +409,7 @@ pub trait TObject<'gc>: 'gc + Collect<'gc> + Debug + Into<Object<'gc>> + Clone +
409409
#[no_dynamic]
410410
fn set_slot(
411411
self,
412-
id: u32,
412+
id: usize,
413413
value: Value<'gc>,
414414
activation: &mut Activation<'_, 'gc>,
415415
) -> Result<(), Error<'gc>> {
@@ -422,7 +422,7 @@ pub trait TObject<'gc>: 'gc + Collect<'gc> + Debug + Into<Object<'gc>> + Clone +
422422
}
423423

424424
#[no_dynamic]
425-
fn set_slot_no_coerce(self, id: u32, value: Value<'gc>, mc: &Mutation<'gc>) {
425+
fn set_slot_no_coerce(self, id: usize, value: Value<'gc>, mc: &Mutation<'gc>) {
426426
let base = self.base();
427427

428428
base.set_slot(id, value, mc);
@@ -580,7 +580,7 @@ pub trait TObject<'gc>: 'gc + Collect<'gc> + Debug + Into<Object<'gc>> + Clone +
580580
fn install_bound_method(
581581
&self,
582582
mc: &Mutation<'gc>,
583-
disp_id: u32,
583+
disp_id: usize,
584584
function: FunctionObject<'gc>,
585585
) {
586586
let base = self.base();
@@ -691,7 +691,7 @@ pub trait TObject<'gc>: 'gc + Collect<'gc> + Debug + Into<Object<'gc>> + Clone +
691691
}
692692

693693
#[no_dynamic]
694-
fn get_bound_method(&self, id: u32) -> Option<FunctionObject<'gc>> {
694+
fn get_bound_method(&self, id: usize) -> Option<FunctionObject<'gc>> {
695695
let base = self.base();
696696
base.get_bound_method(id)
697697
}

core/src/avm2/object/class_object.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ impl<'gc> ClassObject<'gc> {
608608
self,
609609
activation: &mut Activation<'_, 'gc>,
610610
receiver: Object<'gc>,
611-
disp_id: u32,
611+
disp_id: usize,
612612
arguments: FunctionArgs<'_, 'gc>,
613613
) -> Result<Value<'gc>, Error<'gc>> {
614614
let full_method = self.instance_vtable().get_full_method(disp_id).unwrap();

core/src/avm2/object/script_object.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -290,22 +290,18 @@ impl<'gc> ScriptObjectWrapper<'gc> {
290290
}
291291

292292
#[inline(always)]
293-
pub fn get_slot(self, id: u32) -> Value<'gc> {
293+
pub fn get_slot(self, id: usize) -> Value<'gc> {
294294
self.0
295295
.slots
296-
.get(id as usize)
296+
.get(id)
297297
.cloned()
298298
.map(|s| s.get())
299299
.expect("Slot index out of bounds")
300300
}
301301

302302
/// Set a slot by its index.
303-
pub fn set_slot(self, id: u32, value: Value<'gc>, mc: &Mutation<'gc>) {
304-
let slot = self
305-
.0
306-
.slots
307-
.get(id as usize)
308-
.expect("Slot index out of bounds");
303+
pub fn set_slot(self, id: usize, value: Value<'gc>, mc: &Mutation<'gc>) {
304+
let slot = self.0.slots.get(id).expect("Slot index out of bounds");
309305

310306
Gc::write(mc, self.0);
311307
// SAFETY: We just triggered a write barrier on the Gc.
@@ -314,8 +310,8 @@ impl<'gc> ScriptObjectWrapper<'gc> {
314310
}
315311

316312
/// Retrieve a bound method from the method table.
317-
pub fn get_bound_method(self, id: u32) -> Option<FunctionObject<'gc>> {
318-
self.bound_methods().get(id as usize).and_then(|v| *v)
313+
pub fn get_bound_method(self, id: usize) -> Option<FunctionObject<'gc>> {
314+
self.bound_methods().get(id).and_then(|v| *v)
319315
}
320316

321317
pub fn has_own_dynamic_property(self, name: &Multiname<'gc>) -> bool {
@@ -379,16 +375,16 @@ impl<'gc> ScriptObjectWrapper<'gc> {
379375
pub fn install_bound_method(
380376
self,
381377
mc: &Mutation<'gc>,
382-
disp_id: u32,
378+
disp_id: usize,
383379
function: FunctionObject<'gc>,
384380
) {
385381
let mut bound_methods = self.bound_methods_mut(mc);
386382

387-
if bound_methods.len() <= disp_id as usize {
388-
bound_methods.resize_with(disp_id as usize + 1, Default::default);
383+
if bound_methods.len() <= disp_id {
384+
bound_methods.resize_with(disp_id + 1, Default::default);
389385
}
390386

391-
*bound_methods.get_mut(disp_id as usize).unwrap() = Some(function);
387+
*bound_methods.get_mut(disp_id).unwrap() = Some(function);
392388
}
393389

394390
/// Get the `Class` for this object.

core/src/avm2/optimizer/type_aware.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,8 @@ fn abstract_interpret_ops<'gc>(
14211421
locals.set_any(object_register as usize);
14221422
}
14231423
Op::GetSlot { index: slot_id } => {
1424+
let slot_id = slot_id as usize;
1425+
14241426
let stack_value = stack.pop(activation)?;
14251427

14261428
// The value must have a vtable
@@ -1450,6 +1452,8 @@ fn abstract_interpret_ops<'gc>(
14501452
}
14511453
}
14521454
Op::SetSlot { index: slot_id } => {
1455+
let slot_id = slot_id as usize;
1456+
14531457
let set_value = stack.pop(activation)?;
14541458
let stack_value = stack.pop(activation)?;
14551459

@@ -1475,7 +1479,9 @@ fn abstract_interpret_ops<'gc>(
14751479

14761480
// Skip the coercion when possible
14771481
if set_value.matches_type(resolved_value_class) {
1478-
optimize_op_to!(Op::SetSlotNoCoerce { index: slot_id });
1482+
optimize_op_to!(Op::SetSlotNoCoerce {
1483+
index: slot_id as u32
1484+
});
14791485
}
14801486
}
14811487
Op::GetPropertyStatic { multiname } => {
@@ -1576,9 +1582,13 @@ fn abstract_interpret_ops<'gc>(
15761582
vtable.set_slot_class(activation.gc(), slot_id, value_class);
15771583

15781584
if set_value.matches_type(resolved_value_class) {
1579-
optimize_op_to!(Op::SetSlotNoCoerce { index: slot_id });
1585+
optimize_op_to!(Op::SetSlotNoCoerce {
1586+
index: slot_id as u32
1587+
});
15801588
} else {
1581-
optimize_op_to!(Op::SetSlot { index: slot_id });
1589+
optimize_op_to!(Op::SetSlot {
1590+
index: slot_id as u32
1591+
});
15821592
}
15831593
}
15841594
Some(Property::Virtual {
@@ -1589,7 +1599,7 @@ fn abstract_interpret_ops<'gc>(
15891599

15901600
let mut result_op = Op::CallMethod {
15911601
num_args: 1,
1592-
index: disp_id,
1602+
index: disp_id as u32,
15931603
push_return_value: false,
15941604
};
15951605

@@ -1631,9 +1641,13 @@ fn abstract_interpret_ops<'gc>(
16311641
vtable.set_slot_class(activation.gc(), slot_id, value_class);
16321642

16331643
if set_value.matches_type(resolved_value_class) {
1634-
optimize_op_to!(Op::SetSlotNoCoerce { index: slot_id });
1644+
optimize_op_to!(Op::SetSlotNoCoerce {
1645+
index: slot_id as u32
1646+
});
16351647
} else {
1636-
optimize_op_to!(Op::SetSlot { index: slot_id });
1648+
optimize_op_to!(Op::SetSlot {
1649+
index: slot_id as u32
1650+
});
16371651
}
16381652
}
16391653
Some(Property::Virtual {
@@ -1643,7 +1657,7 @@ fn abstract_interpret_ops<'gc>(
16431657

16441658
let mut result_op = Op::CallMethod {
16451659
num_args: 1,
1646-
index: disp_id,
1660+
index: disp_id as u32,
16471661
push_return_value: false,
16481662
};
16491663

@@ -1740,7 +1754,7 @@ fn abstract_interpret_ops<'gc>(
17401754
Some(Property::Slot { slot_id })
17411755
| Some(Property::ConstSlot { slot_id }) => {
17421756
optimize_op_to!(Op::ConstructSlot {
1743-
index: slot_id,
1757+
index: slot_id as u32,
17441758
num_args
17451759
});
17461760

@@ -2235,7 +2249,12 @@ fn optimize_get_property<'gc>(
22352249

22362250
vtable.set_slot_class(activation.gc(), slot_id, value_class);
22372251

2238-
return Ok(Some((Op::GetSlot { index: slot_id }, resolved_value_class)));
2252+
return Ok(Some((
2253+
Op::GetSlot {
2254+
index: slot_id as u32,
2255+
},
2256+
resolved_value_class,
2257+
)));
22392258
}
22402259
Some(Property::Virtual {
22412260
get: Some(disp_id), ..
@@ -2244,7 +2263,7 @@ fn optimize_get_property<'gc>(
22442263

22452264
let mut result_op = Op::CallMethod {
22462265
num_args: 0,
2247-
index: disp_id,
2266+
index: disp_id as u32,
22482267
push_return_value: true,
22492268
};
22502269

@@ -2293,7 +2312,7 @@ fn optimize_call_property<'gc>(
22932312

22942313
let mut result_op = Op::CallMethod {
22952314
num_args,
2296-
index: disp_id,
2315+
index: disp_id as u32,
22972316
push_return_value,
22982317
};
22992318

0 commit comments

Comments
 (0)