diff --git a/core/src/avm2.rs b/core/src/avm2.rs index c8a754138..8c35a967a 100644 --- a/core/src/avm2.rs +++ b/core/src/avm2.rs @@ -9,6 +9,7 @@ use crate::context::UpdateContext; use crate::string::AvmString; use fnv::FnvHashMap; use gc_arena::{Collect, GcCell, MutationContext}; +use std::cmp::Ordering; use swf::avm2::read::Reader; use swf::{DoAbc, DoAbcFlag}; @@ -346,7 +347,11 @@ impl<'gc> Avm2<'gc> { } /// Push a value onto the operand stack. - fn push(&mut self, value: impl Into>) { + fn push(&mut self, value: impl Into>, depth: usize, max: usize) { + if self.stack.len() - depth > max { + log::warn!("Avm2::push: Stack overflow"); + return; + } let mut value = value.into(); if let Value::Object(o) = value { if let Some(prim) = o.as_primitive() { @@ -360,11 +365,14 @@ impl<'gc> Avm2<'gc> { /// Retrieve the top-most value on the operand stack. #[allow(clippy::let_and_return)] - fn pop(&mut self) -> Value<'gc> { - let value = self.stack.pop().unwrap_or_else(|| { - log::warn!("Avm1::pop: Stack underflow"); - Value::Undefined - }); + fn pop(&mut self, depth: usize) -> Value<'gc> { + let value = match self.stack.len().cmp(&depth) { + Ordering::Equal | Ordering::Less => { + log::warn!("Avm2::pop: Stack underflow"); + Value::Undefined + } + Ordering::Greater => self.stack.pop().unwrap_or(Value::Undefined), + }; avm_debug!(self, "Stack pop {}: {:?}", self.stack.len(), value); @@ -388,10 +396,10 @@ impl<'gc> Avm2<'gc> { value } - fn pop_args(&mut self, arg_count: u32) -> Vec> { + fn pop_args(&mut self, arg_count: u32, depth: usize) -> Vec> { let mut args = vec![Value::Undefined; arg_count as usize]; for arg in args.iter_mut().rev() { - *arg = self.pop(); + *arg = self.pop(depth); } args } diff --git a/core/src/avm2/activation.rs b/core/src/avm2/activation.rs index 79e688bee..8f58a3251 100644 --- a/core/src/avm2/activation.rs +++ b/core/src/avm2/activation.rs @@ -664,6 +664,23 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { &self.context.avm2.scope_stack[self.scope_depth..] } + /// Pushes a value onto the stack. + pub fn push_stack(&mut self, value: impl Into>) { + let stack_depth = self.stack_depth; + let max_stack_size = self.max_stack_size; + self.avm2().push(value.into(), stack_depth, max_stack_size) + } + + pub fn pop_stack(&mut self) -> Value<'gc> { + let stack_depth = self.stack_depth; + self.avm2().pop(stack_depth) + } + + pub fn pop_stack_args(&mut self, arg_count: u32) -> Vec> { + let stack_depth = self.stack_depth; + self.avm2().pop_args(arg_count, stack_depth) + } + /// Get the superclass of the class that defined the currently-executing /// method, if it exists. /// @@ -863,7 +880,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } if matches { - self.context.avm2.push(error); + self.push_stack(error); let scope_depth = self.scope_depth; self.avm2().scope_stack.truncate(scope_depth); @@ -1109,7 +1126,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { fn op_push_byte(&mut self, value: u8) -> Result, Error<'gc>> { //TODO: Adobe Animate CC appears to generate signed byte values, and //JPEXS appears to take them. - self.context.avm2.push(value as i8 as i32); + self.push_stack(value as i8 as i32); Ok(FrameControl::Continue) } @@ -1118,12 +1135,12 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, value: Index, ) -> Result, Error<'gc>> { - self.context.avm2.push(self.pool_double(method, value)?); + self.push_stack(self.pool_double(method, value)?); Ok(FrameControl::Continue) } fn op_push_false(&mut self) -> Result, Error<'gc>> { - self.context.avm2.push(false); + self.push_stack(false); Ok(FrameControl::Continue) } @@ -1132,7 +1149,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, value: Index, ) -> Result, Error<'gc>> { - self.context.avm2.push(self.pool_int(method, value)?); + self.push_stack(self.pool_int(method, value)?); Ok(FrameControl::Continue) } @@ -1144,22 +1161,22 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { let ns = self.pool_namespace(method, value)?; let ns_object = NamespaceObject::from_namespace(self, ns)?; - self.context.avm2.push(ns_object); + self.push_stack(ns_object); Ok(FrameControl::Continue) } fn op_push_nan(&mut self) -> Result, Error<'gc>> { - self.context.avm2.push(f64::NAN); + self.push_stack(f64::NAN); Ok(FrameControl::Continue) } fn op_push_null(&mut self) -> Result, Error<'gc>> { - self.context.avm2.push(Value::Null); + self.push_stack(Value::Null); Ok(FrameControl::Continue) } fn op_push_short(&mut self, value: i16) -> Result, Error<'gc>> { - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -1168,12 +1185,12 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, value: Index, ) -> Result, Error<'gc>> { - self.context.avm2.push(self.pool_string(&method, value)?); + self.push_stack(self.pool_string(&method, value)?); Ok(FrameControl::Continue) } fn op_push_true(&mut self) -> Result, Error<'gc>> { - self.context.avm2.push(true); + self.push_stack(true); Ok(FrameControl::Continue) } @@ -1182,23 +1199,23 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, value: Index, ) -> Result, Error<'gc>> { - self.context.avm2.push(self.pool_uint(method, value)?); + self.push_stack(self.pool_uint(method, value)?); Ok(FrameControl::Continue) } fn op_push_undefined(&mut self) -> Result, Error<'gc>> { - self.context.avm2.push(Value::Undefined); + self.push_stack(Value::Undefined); Ok(FrameControl::Continue) } fn op_pop(&mut self) -> Result, Error<'gc>> { - self.context.avm2.pop(); + self.pop_stack(); Ok(FrameControl::Continue) } fn op_dup(&mut self) -> Result, Error<'gc>> { - self.context.avm2.push( + self.push_stack( self.context .avm2 .stack @@ -1211,12 +1228,12 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_get_local(&mut self, register_index: u32) -> Result, Error<'gc>> { - self.context.avm2.push(self.local_register(register_index)?); + self.push_stack(self.local_register(register_index)?); Ok(FrameControl::Continue) } fn op_set_local(&mut self, register_index: u32) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); + let value = self.pop_stack(); self.set_local_register(register_index, value)?; @@ -1230,12 +1247,12 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_call(&mut self, arg_count: u32) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(arg_count); - let receiver = self.context.avm2.pop().as_object(); - let function = self.context.avm2.pop().as_callable(self, None, receiver)?; + let args = self.pop_stack_args(arg_count); + let receiver = self.pop_stack().as_object(); + let function = self.pop_stack().as_callable(self, None, receiver)?; let value = function.call(receiver, &args, self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -1256,12 +1273,12 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { #[allow(unreachable_code)] { - let args = self.context.avm2.pop_args(arg_count); - let receiver = self.context.avm2.pop().as_callable(self, None, None)?; + let args = self.pop_stack_args(arg_count); + let receiver = self.pop_stack().as_callable(self, None, None)?; let value = receiver.call_method(index.0, &args, self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -1273,17 +1290,15 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { index: Index, arg_count: u32, ) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(arg_count); + let args = self.pop_stack_args(arg_count); let multiname = self.pool_multiname_and_initialize(method, index)?; let receiver = self - .context - .avm2 - .pop() + .pop_stack() .coerce_to_receiver(self, Some(&multiname))?; let value = receiver.call_property(&multiname, &args, self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -1294,12 +1309,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { index: Index, arg_count: u32, ) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(arg_count); + let args = self.pop_stack_args(arg_count); let multiname = self.pool_multiname_and_initialize(method, index)?; let receiver = self - .context - .avm2 - .pop() + .pop_stack() .coerce_to_receiver(self, Some(&multiname))?; let function = receiver.get_property(&multiname, self)?.as_callable( self, @@ -1308,7 +1321,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { )?; let value = function.call(None, &args, self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -1319,12 +1332,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { index: Index, arg_count: u32, ) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(arg_count); + let args = self.pop_stack_args(arg_count); let multiname = self.pool_multiname_and_initialize(method, index)?; let receiver = self - .context - .avm2 - .pop() + .pop_stack() .coerce_to_receiver(self, Some(&multiname))?; receiver.call_property(&multiname, &args, self)?; @@ -1338,15 +1349,15 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { index: Index, arg_count: u32, ) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(arg_count); - let receiver = self.context.avm2.pop().as_object(); + let args = self.pop_stack_args(arg_count); + let receiver = self.pop_stack().as_object(); let method = self.table_method(method, index, false)?; // TODO: What scope should the function be executed with? let scope = self.create_scopechain(); let function = FunctionObject::from_method(self, method, scope, None, None); let value = function.call(receiver, &args, self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -1357,19 +1368,17 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { index: Index, arg_count: u32, ) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(arg_count); + let args = self.pop_stack_args(arg_count); let multiname = self.pool_multiname_and_initialize(method, index)?; let receiver = self - .context - .avm2 - .pop() + .pop_stack() .coerce_to_receiver(self, Some(&multiname))?; let superclass_object = self.superclass_object(&multiname)?; let value = superclass_object.call_super(&multiname, receiver, &args, self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -1380,12 +1389,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { index: Index, arg_count: u32, ) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(arg_count); + let args = self.pop_stack_args(arg_count); let multiname = self.pool_multiname_and_initialize(method, index)?; let receiver = self - .context - .avm2 - .pop() + .pop_stack() .coerce_to_receiver(self, Some(&multiname))?; let superclass_object = self.superclass_object(&multiname)?; @@ -1396,7 +1403,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_return_value(&mut self) -> Result, Error<'gc>> { - let return_value = self.context.avm2.pop(); + let return_value = self.pop_stack(); Ok(FrameControl::Return(return_value)) } @@ -1414,10 +1421,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { // default path for static names if !multiname.has_lazy_component() { - let object = self.context.avm2.pop(); + let object = self.pop_stack(); let object = object.coerce_to_receiver(self, Some(&multiname))?; let value = object.get_property(&multiname, self)?; - self.context.avm2.push(value); + self.push_stack(value); return Ok(FrameControl::Continue); } @@ -1432,10 +1439,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { if !name_value.is_primitive() { let object = object.coerce_to_receiver(self, None)?; if let Some(dictionary) = object.as_dictionary_object() { - let _ = self.context.avm2.pop(); - let _ = self.context.avm2.pop(); + let _ = self.pop_stack(); + let _ = self.pop_stack(); let value = dictionary.get_property_by_object(name_value.as_object().unwrap()); - self.context.avm2.push(value); + self.push_stack(value); return Ok(FrameControl::Continue); } @@ -1444,10 +1451,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { // main path for dynamic names let multiname = multiname.fill_with_runtime_params(self)?; - let object = self.context.avm2.pop(); + let object = self.pop_stack(); let object = object.coerce_to_receiver(self, Some(&multiname))?; let value = object.get_property(&multiname, self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -1457,12 +1464,12 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, index: Index, ) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); + let value = self.pop_stack(); let multiname = self.pool_maybe_uninitialized_multiname(method, index)?; // default path for static names if !multiname.has_lazy_component() { - let object = self.context.avm2.pop(); + let object = self.pop_stack(); let mut object = object.coerce_to_receiver(self, Some(&multiname))?; object.set_property(&multiname, value, self)?; return Ok(FrameControl::Continue); @@ -1479,8 +1486,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { if !name_value.is_primitive() { let object = object.coerce_to_receiver(self, None)?; if let Some(dictionary) = object.as_dictionary_object() { - let _ = self.context.avm2.pop(); - let _ = self.context.avm2.pop(); + let _ = self.pop_stack(); + let _ = self.pop_stack(); dictionary.set_property_by_object( name_value.as_object().unwrap(), value, @@ -1494,7 +1501,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { // main path for dynamic names let multiname = multiname.fill_with_runtime_params(self)?; - let object = self.context.avm2.pop(); + let object = self.pop_stack(); let mut object = object.coerce_to_receiver(self, Some(&multiname))?; object.set_property(&multiname, value, self)?; @@ -1506,12 +1513,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, index: Index, ) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); + let value = self.pop_stack(); let multiname = self.pool_multiname_and_initialize(method, index)?; let mut object = self - .context - .avm2 - .pop() + .pop_stack() .coerce_to_receiver(self, Some(&multiname))?; object.init_property(&multiname, value, self)?; @@ -1528,10 +1533,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { // default path for static names if !multiname.has_lazy_component() { - let object = self.context.avm2.pop(); + let object = self.pop_stack(); let object = object.coerce_to_receiver(self, Some(&multiname))?; let did_delete = object.delete_property(self, &multiname)?; - self.context.avm2.push(did_delete); + self.push_stack(did_delete); return Ok(FrameControl::Continue); } @@ -1546,14 +1551,14 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { if !name_value.is_primitive() { let object = object.coerce_to_receiver(self, None)?; if let Some(dictionary) = object.as_dictionary_object() { - let _ = self.context.avm2.pop(); - let _ = self.context.avm2.pop(); + let _ = self.pop_stack(); + let _ = self.pop_stack(); dictionary.delete_property_by_object( name_value.as_object().unwrap(), self.context.gc_context, ); - self.context.avm2.push(true); + self.push_stack(true); return Ok(FrameControl::Continue); } } @@ -1561,11 +1566,11 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { // main path for dynamic names let multiname = multiname.fill_with_runtime_params(self)?; - let object = self.context.avm2.pop(); + let object = self.pop_stack(); let object = object.coerce_to_receiver(self, Some(&multiname))?; let did_delete = object.delete_property(self, &multiname)?; - self.context.avm2.push(did_delete); + self.push_stack(did_delete); Ok(FrameControl::Continue) } @@ -1577,16 +1582,14 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { ) -> Result, Error<'gc>> { let multiname = self.pool_multiname_and_initialize(method, index)?; let object = self - .context - .avm2 - .pop() + .pop_stack() .coerce_to_receiver(self, Some(&multiname))?; let superclass_object = self.superclass_object(&multiname)?; let value = superclass_object.get_super(&multiname, object, self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -1596,12 +1599,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, index: Index, ) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); + let value = self.pop_stack(); let multiname = self.pool_multiname_and_initialize(method, index)?; let object = self - .context - .avm2 - .pop() + .pop_stack() .coerce_to_receiver(self, Some(&multiname))?; let superclass_object = self.superclass_object(&multiname)?; @@ -1612,15 +1613,13 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_in(&mut self) -> Result, Error<'gc>> { - let obj = self.context.avm2.pop().coerce_to_object(self)?; - let name_value = self.context.avm2.pop(); + let obj = self.pop_stack().coerce_to_object(self)?; + let name_value = self.pop_stack(); if let Some(dictionary) = obj.as_dictionary_object() { if !name_value.is_primitive() { let obj_key = name_value.as_object().unwrap(); - self.context - .avm2 - .push(dictionary.has_property_by_object(obj_key)); + self.push_stack(dictionary.has_property_by_object(obj_key)); return Ok(FrameControl::Continue); } @@ -1630,7 +1629,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { let multiname = Multiname::public(name); let has_prop = obj.has_property_via_in(self, &multiname)?; - self.context.avm2.push(has_prop); + self.push_stack(has_prop); Ok(FrameControl::Continue) } @@ -1649,21 +1648,21 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { self.context.gc_context, )?; let so = ScriptObject::catch_scope(self.context.gc_context, &qname); - self.context.avm2.push(so); + self.push_stack(so); } Ok(FrameControl::Continue) } fn op_push_scope(&mut self) -> Result, Error<'gc>> { - let object = self.context.avm2.pop().coerce_to_object(self)?; + let object = self.pop_stack().coerce_to_object(self)?; self.avm2().scope_stack.push(Scope::new(object)); Ok(FrameControl::Continue) } fn op_push_with(&mut self) -> Result, Error<'gc>> { - let object = self.context.avm2.pop().coerce_to_object(self)?; + let object = self.pop_stack().coerce_to_object(self)?; self.avm2().scope_stack.push(Scope::new_with(object)); Ok(FrameControl::Continue) @@ -1679,9 +1678,9 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { let scope = self.outer.get(index as usize); if let Some(scope) = scope { - self.context.avm2.push(scope.values()); + self.push_stack(scope.values()); } else { - self.context.avm2.push(Value::Undefined); + self.push_stack(Value::Undefined); }; Ok(FrameControl::Continue) @@ -1691,16 +1690,16 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { let scope = self.avm2().scope_stack.get(index as usize).copied(); if let Some(scope) = scope { - self.context.avm2.push(scope.values()); + self.push_stack(scope.values()); } else { - self.context.avm2.push(Value::Undefined); + self.push_stack(Value::Undefined); }; Ok(FrameControl::Continue) } fn op_get_global_scope(&mut self) -> Result, Error<'gc>> { - self.context.avm2.push( + self.push_stack( self.global_scope() .map(|gs| gs.into()) .unwrap_or(Value::Null), @@ -1720,9 +1719,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { .find_definition(&multiname)? .or_else(|| self.global_scope()); - self.context - .avm2 - .push(result.map(|o| o.into()).unwrap_or(Value::Undefined)); + self.push_stack(result.map(|o| o.into()).unwrap_or(Value::Undefined)); Ok(FrameControl::Continue) } @@ -1739,7 +1736,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { .ok_or_else(|| format!("Property does not exist: {:?}", *multiname).into()); let result: Value<'gc> = found?.into(); - self.context.avm2.push(result); + self.push_stack(result); Ok(FrameControl::Continue) } @@ -1755,23 +1752,23 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { .resolve_definition(&multiname)? .ok_or_else(|| format!("Property does not exist: {:?}", *multiname).into()); - self.context.avm2.push(found?); + self.push_stack(found?); Ok(FrameControl::Continue) } fn op_get_slot(&mut self, index: u32) -> Result, Error<'gc>> { - let object = self.context.avm2.pop().coerce_to_receiver(self, None)?; + let object = self.pop_stack().coerce_to_receiver(self, None)?; let value = object.get_slot(index)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } fn op_set_slot(&mut self, index: u32) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); - let object = self.context.avm2.pop().coerce_to_receiver(self, None)?; + let value = self.pop_stack(); + let object = self.pop_stack().coerce_to_receiver(self, None)?; object.set_slot(index, value, self.context.gc_context)?; @@ -1785,13 +1782,13 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { .transpose()? .unwrap_or(Value::Undefined); - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } fn op_set_global_slot(&mut self, index: u32) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); + let value = self.pop_stack(); self.global_scope() .map(|global| global.set_slot(index, value, self.context.gc_context)) @@ -1801,12 +1798,12 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_construct(&mut self, arg_count: u32) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(arg_count); - let ctor = self.context.avm2.pop().as_callable(self, None, None)?; + let args = self.pop_stack_args(arg_count); + let ctor = self.pop_stack().as_callable(self, None, None)?; let object = ctor.construct(self, &args)?; - self.context.avm2.push(object); + self.push_stack(object); Ok(FrameControl::Continue) } @@ -1817,24 +1814,22 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { index: Index, arg_count: u32, ) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(arg_count); + let args = self.pop_stack_args(arg_count); let multiname = self.pool_multiname_and_initialize(method, index)?; let source = self - .context - .avm2 - .pop() + .pop_stack() .coerce_to_receiver(self, Some(&multiname))?; let object = source.construct_prop(&multiname, &args, self)?; - self.context.avm2.push(object); + self.push_stack(object); Ok(FrameControl::Continue) } fn op_construct_super(&mut self, arg_count: u32) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(arg_count); - let receiver = self.context.avm2.pop().coerce_to_receiver(self, None)?; + let args = self.pop_stack_args(arg_count); + let receiver = self.pop_stack().coerce_to_receiver(self, None)?; self.super_init(receiver, &args)?; @@ -1849,7 +1844,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { ScriptObject::custom_object(self.context.gc_context, None, None) }; - self.context.avm2.push(instance); + self.push_stack(instance); Ok(FrameControl::Continue) } @@ -1858,8 +1853,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { let mut object = self.context.avm2.classes().object.construct(self, &[])?; for _ in 0..num_args { - let value = self.context.avm2.pop(); - let name = self.context.avm2.pop(); + let value = self.pop_stack(); + let name = self.pop_stack(); object.set_property( &Multiname::public(name.coerce_to_string(self)?), @@ -1868,7 +1863,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { )?; } - self.context.avm2.push(object); + self.push_stack(object); Ok(FrameControl::Continue) } @@ -1883,7 +1878,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { let new_fn = FunctionObject::from_function(self, method_entry, scope)?; - self.context.avm2.push(new_fn); + self.push_stack(new_fn); Ok(FrameControl::Continue) } @@ -1893,7 +1888,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, index: Index, ) -> Result, Error<'gc>> { - let base_value = self.context.avm2.pop(); + let base_value = self.pop_stack(); let base_class = match base_value { Value::Object(o) => match o.as_class_object() { Some(cls) => Some(cls), @@ -1907,17 +1902,15 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { let new_class = ClassObject::from_class(self, class_entry, base_class)?; - self.context.avm2.push(new_class); + self.push_stack(new_class); Ok(FrameControl::Continue) } fn op_apply_type(&mut self, num_types: u32) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(num_types); + let args = self.pop_stack_args(num_types); let base = self - .context - .avm2 - .pop() + .pop_stack() .as_object() .ok_or("Cannot specialize null or undefined")?; @@ -1930,17 +1923,17 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } let applied = base.apply(self, &args[..])?; - self.context.avm2.push(applied); + self.push_stack(applied); Ok(FrameControl::Continue) } fn op_new_array(&mut self, num_args: u32) -> Result, Error<'gc>> { - let args = self.context.avm2.pop_args(num_args); + let args = self.pop_stack_args(num_args); let array = ArrayStorage::from_args(&args[..]); let array_obj = ArrayObject::from_storage(self, array)?; - self.context.avm2.push(array_obj); + self.push_stack(array_obj); Ok(FrameControl::Continue) } @@ -1950,59 +1943,59 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_coerce_b(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_boolean(); + let value = self.pop_stack().coerce_to_boolean(); - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } fn op_coerce_d(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_number(self)?; + let value = self.pop_stack().coerce_to_number(self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } fn op_coerce_i(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_i32(self)?; + let value = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } fn op_coerce_o(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); + let value = self.pop_stack(); let coerced = match value { Value::Undefined | Value::Null => Value::Null, _ => value.coerce_to_object(self)?.into(), }; - self.context.avm2.push(coerced); + self.push_stack(coerced); Ok(FrameControl::Continue) } fn op_coerce_s(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); + let value = self.pop_stack(); let coerced = match value { Value::Undefined | Value::Null => Value::Null, _ => value.coerce_to_string(self)?.into(), }; - self.context.avm2.push(coerced); + self.push_stack(coerced); Ok(FrameControl::Continue) } fn op_coerce_u(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_u32(self)?; + let value = self.pop_stack().coerce_to_u32(self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -2021,13 +2014,11 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { fn op_convert_o(&mut self) -> Result, Error<'gc>> { let value = self - .context - .avm2 - .pop() + .pop_stack() .coerce_to_object(self) .map_err(|_| "Cannot convert null or undefined to object")?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -2037,9 +2028,9 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_convert_s(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_string(self)?; + let value = self.pop_stack().coerce_to_string(self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -2047,10 +2038,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { fn op_check_filter(&mut self) -> Result, Error<'gc>> { let xml = self.avm2().classes().xml; let xml_list = self.avm2().classes().xml_list; - let value = self.context.avm2.pop().coerce_to_object(self)?; + let value = self.pop_stack().coerce_to_object(self)?; if value.is_of_type(xml, self) || value.is_of_type(xml_list, self) { - self.context.avm2.push(value); + self.push_stack(value); } else { return Err(Error::AvmError(type_error( self, @@ -2065,8 +2056,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_add(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); // TODO: Special handling required for `Date` and ECMA-357/E4X `XML` let sum_value = match (value1, value2) { @@ -2105,51 +2096,51 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } }; - self.context.avm2.push(sum_value); + self.push_stack(sum_value); Ok(FrameControl::Continue) } fn op_add_i(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_i32(self)?; - let value1 = self.context.avm2.pop().coerce_to_i32(self)?; + let value2 = self.pop_stack().coerce_to_i32(self)?; + let value1 = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value1 + value2); + self.push_stack(value1 + value2); Ok(FrameControl::Continue) } fn op_bitand(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_i32(self)?; - let value1 = self.context.avm2.pop().coerce_to_i32(self)?; + let value2 = self.pop_stack().coerce_to_i32(self)?; + let value1 = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value1 & value2); + self.push_stack(value1 & value2); Ok(FrameControl::Continue) } fn op_bitnot(&mut self) -> Result, Error<'gc>> { - let value1 = self.context.avm2.pop().coerce_to_i32(self)?; + let value1 = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(!value1); + self.push_stack(!value1); Ok(FrameControl::Continue) } fn op_bitor(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_i32(self)?; - let value1 = self.context.avm2.pop().coerce_to_i32(self)?; + let value2 = self.pop_stack().coerce_to_i32(self)?; + let value1 = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value1 | value2); + self.push_stack(value1 | value2); Ok(FrameControl::Continue) } fn op_bitxor(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_i32(self)?; - let value1 = self.context.avm2.pop().coerce_to_i32(self)?; + let value2 = self.pop_stack().coerce_to_i32(self)?; + let value1 = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value1 ^ value2); + self.push_stack(value1 ^ value2); Ok(FrameControl::Continue) } @@ -2171,26 +2162,26 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_decrement(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_number(self)?; + let value = self.pop_stack().coerce_to_number(self)?; - self.context.avm2.push(value - 1.0); + self.push_stack(value - 1.0); Ok(FrameControl::Continue) } fn op_decrement_i(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_i32(self)?; + let value = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value - 1); + self.push_stack(value - 1); Ok(FrameControl::Continue) } fn op_divide(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_number(self)?; - let value1 = self.context.avm2.pop().coerce_to_number(self)?; + let value2 = self.pop_stack().coerce_to_number(self)?; + let value1 = self.pop_stack().coerce_to_number(self)?; - self.context.avm2.push(value1 / value2); + self.push_stack(value1 / value2); Ok(FrameControl::Continue) } @@ -2212,85 +2203,85 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_increment(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_number(self)?; + let value = self.pop_stack().coerce_to_number(self)?; - self.context.avm2.push(value + 1.0); + self.push_stack(value + 1.0); Ok(FrameControl::Continue) } fn op_increment_i(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_i32(self)?; + let value = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value + 1); + self.push_stack(value + 1); Ok(FrameControl::Continue) } fn op_lshift(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_u32(self)?; - let value1 = self.context.avm2.pop().coerce_to_i32(self)?; + let value2 = self.pop_stack().coerce_to_u32(self)?; + let value1 = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value1 << (value2 & 0x1F)); + self.push_stack(value1 << (value2 & 0x1F)); Ok(FrameControl::Continue) } fn op_modulo(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_number(self)?; - let value1 = self.context.avm2.pop().coerce_to_number(self)?; + let value2 = self.pop_stack().coerce_to_number(self)?; + let value1 = self.pop_stack().coerce_to_number(self)?; - self.context.avm2.push(value1 % value2); + self.push_stack(value1 % value2); Ok(FrameControl::Continue) } fn op_multiply(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_number(self)?; - let value1 = self.context.avm2.pop().coerce_to_number(self)?; + let value2 = self.pop_stack().coerce_to_number(self)?; + let value1 = self.pop_stack().coerce_to_number(self)?; - self.context.avm2.push(value1 * value2); + self.push_stack(value1 * value2); Ok(FrameControl::Continue) } fn op_multiply_i(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_i32(self)?; - let value1 = self.context.avm2.pop().coerce_to_i32(self)?; + let value2 = self.pop_stack().coerce_to_i32(self)?; + let value1 = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value1 * value2); + self.push_stack(value1 * value2); Ok(FrameControl::Continue) } fn op_negate(&mut self) -> Result, Error<'gc>> { - let value1 = self.context.avm2.pop().coerce_to_number(self)?; + let value1 = self.pop_stack().coerce_to_number(self)?; - self.context.avm2.push(-value1); + self.push_stack(-value1); Ok(FrameControl::Continue) } fn op_negate_i(&mut self) -> Result, Error<'gc>> { - let value1 = self.context.avm2.pop().coerce_to_i32(self)?; + let value1 = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(-value1); + self.push_stack(-value1); Ok(FrameControl::Continue) } fn op_rshift(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_u32(self)?; - let value1 = self.context.avm2.pop().coerce_to_i32(self)?; + let value2 = self.pop_stack().coerce_to_u32(self)?; + let value1 = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value1 >> (value2 & 0x1F)); + self.push_stack(value1 >> (value2 & 0x1F)); Ok(FrameControl::Continue) } fn op_subtract(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); let sub_value: Value<'gc> = match (value1, value2) { // note: with not-yet-guaranteed assumption that Integer < 1<<28, this won't underflow. @@ -2303,35 +2294,35 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } }; - self.context.avm2.push(sub_value); + self.push_stack(sub_value); Ok(FrameControl::Continue) } fn op_subtract_i(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_i32(self)?; - let value1 = self.context.avm2.pop().coerce_to_i32(self)?; + let value2 = self.pop_stack().coerce_to_i32(self)?; + let value1 = self.pop_stack().coerce_to_i32(self)?; - self.context.avm2.push(value1 - value2); + self.push_stack(value1 - value2); Ok(FrameControl::Continue) } fn op_swap(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); - self.context.avm2.push(value2); - self.context.avm2.push(value1); + self.push_stack(value2); + self.push_stack(value1); Ok(FrameControl::Continue) } fn op_urshift(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop().coerce_to_u32(self)?; - let value1 = self.context.avm2.pop().coerce_to_u32(self)?; + let value2 = self.pop_stack().coerce_to_u32(self)?; + let value1 = self.pop_stack().coerce_to_u32(self)?; - self.context.avm2.push(value1 >> (value2 & 0x1F)); + self.push_stack(value1 >> (value2 & 0x1F)); Ok(FrameControl::Continue) } @@ -2353,7 +2344,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_boolean(); + let value = self.pop_stack().coerce_to_boolean(); if value { reader.seek(full_data, offset); @@ -2368,7 +2359,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_boolean(); + let value = self.pop_stack().coerce_to_boolean(); if !value { reader.seek(full_data, offset); @@ -2383,8 +2374,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if value1 == value2 { reader.seek(full_data, offset); @@ -2399,8 +2390,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if value1 != value2 { reader.seek(full_data, offset); @@ -2415,8 +2406,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if value1.abstract_eq(&value2, self)? { reader.seek(full_data, offset); @@ -2431,8 +2422,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if !value1.abstract_eq(&value2, self)? { reader.seek(full_data, offset); @@ -2447,8 +2438,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if value1.abstract_lt(&value2, self)? == Some(false) { reader.seek(full_data, offset); @@ -2463,8 +2454,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if value2.abstract_lt(&value1, self)? == Some(true) { reader.seek(full_data, offset); @@ -2479,8 +2470,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if value2.abstract_lt(&value1, self)? == Some(false) { reader.seek(full_data, offset); @@ -2495,8 +2486,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if value1.abstract_lt(&value2, self)? == Some(true) { reader.seek(full_data, offset); @@ -2511,8 +2502,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if value1.abstract_lt(&value2, self)?.unwrap_or(true) { reader.seek(full_data, offset); @@ -2527,8 +2518,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if !value2.abstract_lt(&value1, self)?.unwrap_or(false) { reader.seek(full_data, offset); @@ -2543,8 +2534,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if value2.abstract_lt(&value1, self)?.unwrap_or(true) { reader.seek(full_data, offset); @@ -2559,8 +2550,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); if !value1.abstract_lt(&value2, self)?.unwrap_or(false) { reader.seek(full_data, offset); @@ -2570,65 +2561,65 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_strict_equals(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); - self.context.avm2.push(value1 == value2); + self.push_stack(value1 == value2); Ok(FrameControl::Continue) } fn op_equals(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); let result = value1.abstract_eq(&value2, self)?; - self.context.avm2.push(result); + self.push_stack(result); Ok(FrameControl::Continue) } fn op_greater_equals(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); let result = !value1.abstract_lt(&value2, self)?.unwrap_or(true); - self.context.avm2.push(result); + self.push_stack(result); Ok(FrameControl::Continue) } fn op_greater_than(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); let result = value2.abstract_lt(&value1, self)?.unwrap_or(false); - self.context.avm2.push(result); + self.push_stack(result); Ok(FrameControl::Continue) } fn op_less_equals(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); let result = !value2.abstract_lt(&value1, self)?.unwrap_or(true); - self.context.avm2.push(result); + self.push_stack(result); Ok(FrameControl::Continue) } fn op_less_than(&mut self) -> Result, Error<'gc>> { - let value2 = self.context.avm2.pop(); - let value1 = self.context.avm2.pop(); + let value2 = self.pop_stack(); + let value1 = self.pop_stack(); let result = value1.abstract_lt(&value2, self)?.unwrap_or(false); - self.context.avm2.push(result); + self.push_stack(result); Ok(FrameControl::Continue) } @@ -2638,31 +2629,30 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_not(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop().coerce_to_boolean(); + let value = self.pop_stack().coerce_to_boolean(); - self.context.avm2.push(!value); + self.push_stack(!value); Ok(FrameControl::Continue) } fn op_has_next(&mut self) -> Result, Error<'gc>> { - let cur_index = self.context.avm2.pop().coerce_to_u32(self)?; + let cur_index = self.pop_stack().coerce_to_u32(self)?; - let object = self.context.avm2.pop(); + let object = self.pop_stack(); if matches!(object, Value::Undefined | Value::Null) { - self.context.avm2.push(0.0); + self.push_stack(0.0); } else { let object = object.coerce_to_object(self)?; if let Some(next_index) = object.get_next_enumerant(cur_index, self)? { - self.context.avm2.push(next_index); + self.push_stack(next_index); } else { - self.context.avm2.push(0.0); + self.push_stack(0.0); } } Ok(FrameControl::Continue) } - fn op_has_next_2( &mut self, object_register: u32, @@ -2692,7 +2682,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { cur_index = 0; } - self.context.avm2.push(cur_index != 0); + self.push_stack(cur_index != 0); self.set_local_register(index_register, cur_index)?; self.set_local_register( object_register, @@ -2703,23 +2693,23 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_next_name(&mut self) -> Result, Error<'gc>> { - let cur_index = self.context.avm2.pop().coerce_to_number(self)?; - let object = self.context.avm2.pop().coerce_to_receiver(self, None)?; + let cur_index = self.pop_stack().coerce_to_number(self)?; + let object = self.pop_stack().coerce_to_receiver(self, None)?; let name = object.get_enumerant_name(cur_index as u32, self)?; - self.context.avm2.push(name); + self.push_stack(name); Ok(FrameControl::Continue) } fn op_next_value(&mut self) -> Result, Error<'gc>> { - let cur_index = self.context.avm2.pop().coerce_to_number(self)?; - let object = self.context.avm2.pop().coerce_to_receiver(self, None)?; + let cur_index = self.pop_stack().coerce_to_number(self)?; + let object = self.pop_stack().coerce_to_receiver(self, None)?; let value = object.get_enumerant_value(cur_index as u32, self)?; - self.context.avm2.push(value); + self.push_stack(value); Ok(FrameControl::Continue) } @@ -2729,29 +2719,27 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, type_name_index: Index, ) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); + let value = self.pop_stack(); let multiname = self.pool_multiname_static(method, type_name_index)?; let type_object = self.resolve_class(&multiname)?; let is_instance_of = value.is_of_type(self, type_object); - self.context.avm2.push(is_instance_of); + self.push_stack(is_instance_of); Ok(FrameControl::Continue) } fn op_is_type_late(&mut self) -> Result, Error<'gc>> { let type_object = self - .context - .avm2 - .pop() + .pop_stack() .as_object() .and_then(|o| o.as_class_object()) .ok_or("Cannot check if value is of a type that is null, undefined, or not a class")?; - let value = self.context.avm2.pop(); + let value = self.pop_stack(); let is_instance_of = value.is_of_type(self, type_object); - self.context.avm2.push(is_instance_of); + self.push_stack(is_instance_of); Ok(FrameControl::Continue) } @@ -2761,15 +2749,15 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, type_name_index: Index, ) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); + let value = self.pop_stack(); let multiname = self.pool_multiname_static(method, type_name_index)?; let class = self.resolve_class(&multiname)?; if value.is_of_type(self, class) { - self.context.avm2.push(value); + self.push_stack(value); } else { - self.context.avm2.push(Value::Null); + self.push_stack(Value::Null); } Ok(FrameControl::Continue) @@ -2777,43 +2765,41 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { fn op_as_type_late(&mut self) -> Result, Error<'gc>> { let class = self - .context - .avm2 - .pop() + .pop_stack() .as_object() .and_then(|c| c.as_class_object()) .ok_or("Cannot coerce a value to a type that is null, undefined, or not a class")?; - let value = self.context.avm2.pop(); + let value = self.pop_stack(); if value.is_of_type(self, class) { - self.context.avm2.push(value); + self.push_stack(value); } else { - self.context.avm2.push(Value::Null); + self.push_stack(Value::Null); } Ok(FrameControl::Continue) } fn op_instance_of(&mut self) -> Result, Error<'gc>> { - let type_object = - self.context.avm2.pop().as_object().ok_or( - "Cannot check if value is of a type that is null, undefined, or not a class", - )?; - let value = self.context.avm2.pop().coerce_to_object(self).ok(); + let type_object = self + .pop_stack() + .as_object() + .ok_or("Cannot check if value is of a type that is null, undefined, or not a class")?; + let value = self.pop_stack().coerce_to_object(self).ok(); if let Some(value) = value { let is_instance_of = value.is_instance_of(self, type_object)?; - self.context.avm2.push(is_instance_of); + self.push_stack(is_instance_of); } else { - self.context.avm2.push(false); + self.push_stack(false); } Ok(FrameControl::Continue) } fn op_type_of(&mut self) -> Result, Error<'gc>> { - let value = self.context.avm2.pop(); + let value = self.pop_stack(); let type_name = match value { Value::Undefined => "undefined", @@ -2848,14 +2834,14 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { Value::String(_) => "string", }; - self.context.avm2.push(Value::String(type_name.into())); + self.push_stack(Value::String(type_name.into())); Ok(FrameControl::Continue) } /// Implements `Op::EscXAttr` fn op_esc_xattr(&mut self) -> Result, Error<'gc>> { - let s = self.context.avm2.pop().coerce_to_string(self)?; + let s = self.pop_stack().coerce_to_string(self)?; // Implementation of `EscapeAttributeValue` from ECMA-357(10.2.1.2) let mut r = WString::with_capacity(s.len(), s.is_wide()); @@ -2875,16 +2861,14 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { r.push_str(WStr::from_units(escape)); } - self.context - .avm2 - .push(AvmString::new(self.context.gc_context, r)); + self.push_stack(AvmString::new(self.context.gc_context, r)); Ok(FrameControl::Continue) } /// Implements `Op::EscXElem` fn op_esc_elem(&mut self) -> Result, Error<'gc>> { - let s = self.context.avm2.pop().coerce_to_string(self)?; + let s = self.pop_stack().coerce_to_string(self)?; // contrary to the avmplus documentation, this escapes the value on the top of the stack using EscapeElementValue from ECMA-357 *NOT* EscapeAttributeValue. // Implementation of `EscapeElementValue` from ECMA-357(10.2.1.1) @@ -2902,9 +2886,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { r.push_str(WStr::from_units(escape)); } - self.context - .avm2 - .push(AvmString::new(self.context.gc_context, r)); + self.push_stack(AvmString::new(self.context.gc_context, r)); Ok(FrameControl::Continue) } @@ -2918,7 +2900,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { reader: &mut Reader<'b>, full_data: &'b [u8], ) -> Result, Error<'gc>> { - let index = self.context.avm2.pop().coerce_to_i32(self)?; + let index = self.pop_stack().coerce_to_i32(self)?; let offset = case_offsets .get(index as usize) @@ -2937,7 +2919,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { method: Gc<'gc, BytecodeMethod<'gc>>, index: Index, ) -> Result, Error<'gc>> { - let val = self.context.avm2.pop(); + let val = self.pop_stack(); let type_name = self.pool_multiname_static_any(method, index)?; let param_type = self.resolve_type(&type_name)?; @@ -2947,7 +2929,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { val }; - self.context.avm2.push(x); + self.push_stack(x); Ok(FrameControl::Continue) } @@ -2961,8 +2943,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { /// Implements `Op::Si8` fn op_si8(&mut self) -> Result, Error<'gc>> { - let address = self.context.avm2.pop().coerce_to_i32(self)?; - let val = self.context.avm2.pop().coerce_to_i32(self)?; + let address = self.pop_stack().coerce_to_i32(self)?; + let val = self.pop_stack().coerce_to_i32(self)?; let dm = self.domain_memory(); let mut dm = dm @@ -2978,8 +2960,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { /// Implements `Op::Si16` fn op_si16(&mut self) -> Result, Error<'gc>> { - let address = self.context.avm2.pop().coerce_to_i32(self)?; - let val = self.context.avm2.pop().coerce_to_i32(self)?; + let address = self.pop_stack().coerce_to_i32(self)?; + let val = self.pop_stack().coerce_to_i32(self)?; let dm = self.domain_memory(); let mut dm = dm @@ -2995,8 +2977,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { /// Implements `Op::Si32` fn op_si32(&mut self) -> Result, Error<'gc>> { - let address = self.context.avm2.pop().coerce_to_i32(self)?; - let val = self.context.avm2.pop().coerce_to_i32(self)?; + let address = self.pop_stack().coerce_to_i32(self)?; + let val = self.pop_stack().coerce_to_i32(self)?; let dm = self.domain_memory(); let mut dm = dm @@ -3012,8 +2994,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { /// Implements `Op::Sf32` fn op_sf32(&mut self) -> Result, Error<'gc>> { - let address = self.context.avm2.pop().coerce_to_i32(self)?; - let val = self.context.avm2.pop().coerce_to_number(self)? as f32; + let address = self.pop_stack().coerce_to_i32(self)?; + let val = self.pop_stack().coerce_to_number(self)? as f32; let dm = self.domain_memory(); let mut dm = dm @@ -3029,8 +3011,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { /// Implements `Op::Sf64` fn op_sf64(&mut self) -> Result, Error<'gc>> { - let address = self.context.avm2.pop().coerce_to_i32(self)?; - let val = self.context.avm2.pop().coerce_to_number(self)?; + let address = self.pop_stack().coerce_to_i32(self)?; + let val = self.pop_stack().coerce_to_number(self)?; let dm = self.domain_memory(); let mut dm = dm @@ -3046,7 +3028,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { /// Implements `Op::Li8` fn op_li8(&mut self) -> Result, Error<'gc>> { - let address = self.context.avm2.pop().coerce_to_u32(self)? as usize; + let address = self.pop_stack().coerce_to_u32(self)? as usize; let dm = self.domain_memory(); let dm = dm @@ -3055,7 +3037,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { let val = dm.get(address); if let Some(val) = val { - self.context.avm2.push(val); + self.push_stack(val); } else { return Err("RangeError: The specified range is invalid".into()); } @@ -3065,95 +3047,87 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { /// Implements `Op::Li16` fn op_li16(&mut self) -> Result, Error<'gc>> { - let address = self.context.avm2.pop().coerce_to_u32(self)? as usize; + let address = self.pop_stack().coerce_to_u32(self)? as usize; let dm = self.domain_memory(); let dm = dm .as_bytearray() .ok_or_else(|| "Unable to get bytearray storage".to_string())?; let val = dm.read_at(2, address)?; - self.context - .avm2 - .push(u16::from_le_bytes(val.try_into().unwrap())); + self.push_stack(u16::from_le_bytes(val.try_into().unwrap())); Ok(FrameControl::Continue) } /// Implements `Op::Li32` fn op_li32(&mut self) -> Result, Error<'gc>> { - let address = self.context.avm2.pop().coerce_to_u32(self)? as usize; + let address = self.pop_stack().coerce_to_u32(self)? as usize; let dm = self.domain_memory(); let dm = dm .as_bytearray() .ok_or_else(|| "Unable to get bytearray storage".to_string())?; let val = dm.read_at(4, address)?; - self.context - .avm2 - .push(i32::from_le_bytes(val.try_into().unwrap())); + self.push_stack(i32::from_le_bytes(val.try_into().unwrap())); Ok(FrameControl::Continue) } /// Implements `Op::Lf32` fn op_lf32(&mut self) -> Result, Error<'gc>> { - let address = self.context.avm2.pop().coerce_to_u32(self)? as usize; + let address = self.pop_stack().coerce_to_u32(self)? as usize; let dm = self.domain_memory(); let dm = dm .as_bytearray() .ok_or_else(|| "Unable to get bytearray storage".to_string())?; let val = dm.read_at(4, address)?; - self.context - .avm2 - .push(f32::from_le_bytes(val.try_into().unwrap())); + self.push_stack(f32::from_le_bytes(val.try_into().unwrap())); Ok(FrameControl::Continue) } /// Implements `Op::Lf64` fn op_lf64(&mut self) -> Result, Error<'gc>> { - let address = self.context.avm2.pop().coerce_to_u32(self)? as usize; + let address = self.pop_stack().coerce_to_u32(self)? as usize; let dm = self.domain_memory(); let dm = dm .as_bytearray() .ok_or_else(|| "Unable to get bytearray storage".to_string())?; let val = dm.read_at(8, address)?; - self.context - .avm2 - .push(f64::from_le_bytes(val.try_into().unwrap())); + self.push_stack(f64::from_le_bytes(val.try_into().unwrap())); Ok(FrameControl::Continue) } /// Implements `Op::Sxi1` fn op_sxi1(&mut self) -> Result, Error<'gc>> { - let val = self.context.avm2.pop().coerce_to_i32(self)?; + let val = self.pop_stack().coerce_to_i32(self)?; let val = val.wrapping_shl(31).wrapping_shr(31); - self.context.avm2.push(Value::Integer(val)); + self.push_stack(Value::Integer(val)); Ok(FrameControl::Continue) } /// Implements `Op::Sxi8` fn op_sxi8(&mut self) -> Result, Error<'gc>> { - let val = self.context.avm2.pop().coerce_to_i32(self)?; + let val = self.pop_stack().coerce_to_i32(self)?; let val = (val.wrapping_shl(23).wrapping_shr(23) & 0xFF) as i8 as i32; - self.context.avm2.push(Value::Integer(val)); + self.push_stack(Value::Integer(val)); Ok(FrameControl::Continue) } /// Implements `Op::Sxi16` fn op_sxi16(&mut self) -> Result, Error<'gc>> { - let val = self.context.avm2.pop().coerce_to_i32(self)?; + let val = self.pop_stack().coerce_to_i32(self)?; let val = (val.wrapping_shl(15).wrapping_shr(15) & 0xFFFF) as i16 as i32; - self.context.avm2.push(Value::Integer(val)); + self.push_stack(Value::Integer(val)); Ok(FrameControl::Continue) } @@ -3242,7 +3216,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { } fn op_throw(&mut self) -> Result, Error<'gc>> { - let error_val = self.context.avm2.pop(); + let error_val = self.pop_stack(); Err(Error::AvmError(error_val)) } } diff --git a/core/src/avm2/multiname.rs b/core/src/avm2/multiname.rs index 0b8f0c0c6..20142c939 100644 --- a/core/src/avm2/multiname.rs +++ b/core/src/avm2/multiname.rs @@ -225,13 +225,13 @@ impl<'gc> Multiname<'gc> { activation: &mut Activation<'_, 'gc, '_>, ) -> Result> { let name = if self.has_lazy_name() { - Some(activation.avm2().pop().coerce_to_string(activation)?) + Some(activation.pop_stack().coerce_to_string(activation)?) } else { self.name }; let ns = if self.has_lazy_ns() { - let ns_value = activation.avm2().pop(); + let ns_value = activation.pop_stack(); let ns = ns_value.as_namespace()?; NamespaceSet::single(*ns) } else {