avm2: Implement Op::Si8 and Op::Li8 badly
This commit is contained in:
parent
12a198f671
commit
5a0cdf60bc
|
@ -2472,6 +2472,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
/// Implements `Op::Coerce`
|
/// Implements `Op::Coerce`
|
||||||
fn op_coerce(&mut self, _method: Gc<'gc, BytecodeMethod<'gc>>, _index: Index<AbcMultiname>) -> Result<FrameControl<'gc>, Error> {
|
fn op_coerce(&mut self, _method: Gc<'gc, BytecodeMethod<'gc>>, _index: Index<AbcMultiname>) -> Result<FrameControl<'gc>, 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: 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();
|
let val = self.context.avm2.pop();
|
||||||
|
|
||||||
|
@ -2491,17 +2492,25 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
|
|
||||||
/// Implements `Op::Si8`
|
/// Implements `Op::Si8`
|
||||||
fn op_si8(&mut self) -> Result<FrameControl<'gc>, Error> {
|
fn op_si8(&mut self) -> Result<FrameControl<'gc>, Error> {
|
||||||
let _address = self.context.avm2.pop();
|
let address = self.context.avm2.pop();
|
||||||
let _val = 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)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implements `Op::Li8`
|
/// Implements `Op::Li8`
|
||||||
fn op_li8(&mut self) -> Result<FrameControl<'gc>, Error> {
|
fn op_li8(&mut self) -> Result<FrameControl<'gc>, 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)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use crate::avm2::activation::Activation;
|
use crate::avm2::activation::Activation;
|
||||||
use crate::avm2::names::{Multiname, QName};
|
use crate::avm2::names::{Multiname, QName};
|
||||||
use crate::avm2::object::TObject;
|
use crate::avm2::object::TObject;
|
||||||
|
use crate::avm2::object::Object;
|
||||||
use crate::avm2::script::Script;
|
use crate::avm2::script::Script;
|
||||||
use crate::avm2::value::Value;
|
use crate::avm2::value::Value;
|
||||||
use crate::avm2::Error;
|
use crate::avm2::Error;
|
||||||
|
@ -23,6 +24,9 @@ struct DomainData<'gc> {
|
||||||
|
|
||||||
/// The parent domain.
|
/// The parent domain.
|
||||||
parent: Option<Domain<'gc>>,
|
parent: Option<Domain<'gc>>,
|
||||||
|
|
||||||
|
/// The bytearray used for storing domain memory
|
||||||
|
pub domain_memory: Option<Object<'gc>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'gc> Domain<'gc> {
|
impl<'gc> Domain<'gc> {
|
||||||
|
@ -36,6 +40,7 @@ impl<'gc> Domain<'gc> {
|
||||||
DomainData {
|
DomainData {
|
||||||
defs: HashMap::new(),
|
defs: HashMap::new(),
|
||||||
parent: None,
|
parent: None,
|
||||||
|
domain_memory: None,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -47,6 +52,7 @@ impl<'gc> Domain<'gc> {
|
||||||
DomainData {
|
DomainData {
|
||||||
defs: HashMap::new(),
|
defs: HashMap::new(),
|
||||||
parent: Some(parent),
|
parent: Some(parent),
|
||||||
|
domain_memory: None
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -146,4 +152,12 @@ impl<'gc> Domain<'gc> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn domain_memory(&self) -> Option<Object<'gc>> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,38 @@ pub fn has_definition<'gc>(
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `domainMemory` property setter
|
||||||
|
pub fn set_domain_memory<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Option<Object<'gc>>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, 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<Object<'gc>>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, 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.
|
/// Construct `ApplicationDomain`'s class.
|
||||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||||
let class = Class::new(
|
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),
|
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
|
class
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue