From 5a0cdf60bc33705480a466c788c9722ce30bbf6b Mon Sep 17 00:00:00 2001 From: CUB3D Date: Sun, 4 Apr 2021 21:09:28 +0100 Subject: [PATCH] avm2: Implement Op::Si8 and Op::Li8 badly --- core/src/avm2/activation.rs | 17 ++++++-- core/src/avm2/domain.rs | 14 ++++++ .../flash/system/application_domain.rs | 41 ++++++++++++++++++ core/tests/swfs/avm2/domain_memory/test.swf | Bin 775 -> 680 bytes 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/core/src/avm2/activation.rs b/core/src/avm2/activation.rs index faf78ed44..d0bab7ffc 100644 --- a/core/src/avm2/activation.rs +++ b/core/src/avm2/activation.rs @@ -2472,6 +2472,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { /// Implements `Op::Coerce` fn op_coerce(&mut self, _method: Gc<'gc, BytecodeMethod<'gc>>, _index: Index) -> Result, Error> { //TODO: should check if x is a subclass of the given type when object and typeerror if not, see "instr.cpp::coerceImpl (287)" + //TODO: update tests with typeof + description let val = self.context.avm2.pop(); @@ -2491,17 +2492,25 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> { /// Implements `Op::Si8` fn op_si8(&mut self) -> Result, Error> { - let _address = self.context.avm2.pop(); - let _val = self.context.avm2.pop(); + let address = self.context.avm2.pop(); + let val = self.context.avm2.pop(); + + let dm = self.scope().unwrap().read().globals().as_application_domain().unwrap().domain_memory().expect("Not domain memory?"); + let mut ba = dm.as_bytearray_mut(self.context.gc_context).unwrap(); + ba.write_bytes_at(&[val.coerce_to_i32(self)? as u8], address.coerce_to_i32(self)? as usize); Ok(FrameControl::Continue) } /// Implements `Op::Li8` fn op_li8(&mut self) -> Result, Error> { - let _address = self.context.avm2.pop(); + let address = self.context.avm2.pop().coerce_to_u32(self)? as usize; - self.context.avm2.push(Value::Number(321.0)); + let dm = self.scope().unwrap().read().globals().as_application_domain().unwrap().domain_memory().expect("Not domain memory?"); + let mut ba = dm.as_bytearray_mut(self.context.gc_context).unwrap(); + let x = ba.bytes().iter().nth(address).copied().unwrap(); + + self.context.avm2.push(Value::Integer(x as i32)); Ok(FrameControl::Continue) } diff --git a/core/src/avm2/domain.rs b/core/src/avm2/domain.rs index bc2e5b51c..b462714cb 100644 --- a/core/src/avm2/domain.rs +++ b/core/src/avm2/domain.rs @@ -3,6 +3,7 @@ use crate::avm2::activation::Activation; use crate::avm2::names::{Multiname, QName}; use crate::avm2::object::TObject; +use crate::avm2::object::Object; use crate::avm2::script::Script; use crate::avm2::value::Value; use crate::avm2::Error; @@ -23,6 +24,9 @@ struct DomainData<'gc> { /// The parent domain. parent: Option>, + + /// The bytearray used for storing domain memory + pub domain_memory: Option> } impl<'gc> Domain<'gc> { @@ -36,6 +40,7 @@ impl<'gc> Domain<'gc> { DomainData { defs: HashMap::new(), parent: None, + domain_memory: None, }, )) } @@ -47,6 +52,7 @@ impl<'gc> Domain<'gc> { DomainData { defs: HashMap::new(), parent: Some(parent), + domain_memory: None }, )) } @@ -146,4 +152,12 @@ impl<'gc> Domain<'gc> { Ok(()) } + + pub fn domain_memory(&self) -> Option> { + self.0.read().domain_memory + } + + pub fn set_domain_memory(&self, mc: MutationContext<'gc, '_>, domain_memory: Object<'gc>) { + self.0.write(mc).domain_memory = Some(domain_memory) + } } diff --git a/core/src/avm2/globals/flash/system/application_domain.rs b/core/src/avm2/globals/flash/system/application_domain.rs index fd9802525..5a60f76b6 100644 --- a/core/src/avm2/globals/flash/system/application_domain.rs +++ b/core/src/avm2/globals/flash/system/application_domain.rs @@ -118,6 +118,38 @@ pub fn has_definition<'gc>( Ok(Value::Undefined) } +/// `domainMemory` property setter +pub fn set_domain_memory<'gc>( + activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + args: &[Value<'gc>], +) -> Result, Error> { + if let Some(d) = args.get(0) { + let o = d.coerce_to_object(activation)?; + //TODO: same domain as the one in avm2? + if let Some(appdomain) = this.and_then(|this| this.as_application_domain()) { + appdomain.set_domain_memory(activation.context.gc_context, o); + } + } + + Ok(Value::Undefined) +} + +/// `domainMemory` property getter +pub fn domain_memory<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + if let Some(appdomain) = this.and_then(|this| this.as_application_domain()) { + if let Some(o) = appdomain.domain_memory() { + return Ok(o.into()); + } + } + + Ok(Value::Undefined) +} + /// Construct `ApplicationDomain`'s class. pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> { let class = Class::new( @@ -147,5 +179,14 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc> Method::from_builtin(has_definition), )); + write.define_instance_trait(Trait::from_setter( + QName::new(Namespace::public(), "domainMemory"), + Method::from_builtin(set_domain_memory), + )); + write.define_instance_trait(Trait::from_getter( + QName::new(Namespace::public(), "domainMemory"), + Method::from_builtin(domain_memory), + )); + class } diff --git a/core/tests/swfs/avm2/domain_memory/test.swf b/core/tests/swfs/avm2/domain_memory/test.swf index f4f0894918e4ec6b7e341f2770a7110392288a04..d44316ce1447d7e256f4354495fb6087aa599e56 100644 GIT binary patch delta 399 zcmV;A0dW3@2B-xIT31smw*vqGm$3;Y0e^0#gK^ID&P04N*lyxjr^k!ILfUxhFV|lB zDr`^n0EUylb-RXZ5ll}n)t98F&~kXBlW0J8afB1CQ8(3nDqGO8Kn(guygVD=D-(#@ZG|L;J*pvWLvy>3^x; zsuUTK4$rcBQVKF+)vF@JQwd}hzDrBc=-lvdz0ClMg+}~1KHRbs6hP9 zb|%`7V)KIH7~qSJ0>dvOEwLIlj%w=AK@t8q(Juh#Y@P!(pQA3 zjA#=J+~>2iL$2)x8Yzt1Dq=Oh&U_U*9mVD;4n9g>F?mM1eQq+LZg!S{4KzZRP>=_P zxusly?%BDNXveJ^W)MmG9;q8Uar{4^nya6<<=8;>|9EX7z7>et4YAIZ>^kt@@4*!F tR+1QeQ3Rbkl4aHoyBP?tRi|_0|NOG7HzUy#JB(e delta 495 zcmV@_I zl0;3B#Wb#K`z<}wK|f;_2h|sxjreu~^7kB#X?%zbH@aaiFFDlTzbEJUm4jj;4JzSE zKy}q^djt-PxV$rNK(FG7+9>5$6GL)`F_bYAnp~*L8WTS$50<8;*El zRYnKD!q)5cVY5;OIW;w$>4*Rj^qRJt@^eDR4u%sL1aI9TtSqJ+4}=&ItXzCs=BfmF zB~Hgdig~7isKeh<0qb63rR5*RsZ^?5jy)T?VJDr