Allow methods to not hold a body.
Interface methods are specifically not allowed to be called: as a result, they don't get a method body. Existing code assumed a 1:1 relationship between methods and bodies, which causes spurious errors.
This commit is contained in:
parent
090fe56bd3
commit
5d89d4ed85
|
@ -139,7 +139,10 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
) -> Result<Self, Error> {
|
||||
let method = script.read().init().into_bytecode()?;
|
||||
let scope = Some(Scope::push_scope(None, global, context.gc_context));
|
||||
let num_locals = method.body().num_locals;
|
||||
let body: Result<_, Error> = method
|
||||
.body()
|
||||
.ok_or_else(|| "Cannot execute non-native method (for script) without body".into());
|
||||
let num_locals = body?.num_locals;
|
||||
let local_registers =
|
||||
GcCell::allocate(context.gc_context, RegisterSet::new(num_locals + 1));
|
||||
|
||||
|
@ -171,8 +174,11 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
this: Option<Object<'gc>>,
|
||||
arguments: &[Value<'gc>],
|
||||
base_proto: Option<Object<'gc>>,
|
||||
) -> Self {
|
||||
let num_locals = method.body().num_locals;
|
||||
) -> Result<Self, Error> {
|
||||
let body: Result<_, Error> = method
|
||||
.body()
|
||||
.ok_or_else(|| "Cannot execute non-native method without body".into());
|
||||
let num_locals = body?.num_locals;
|
||||
let num_declared_arguments = method.method().params.len() as u32;
|
||||
let local_registers = GcCell::allocate(
|
||||
context.gc_context,
|
||||
|
@ -191,7 +197,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
Ok(Self {
|
||||
avm2,
|
||||
this,
|
||||
arguments: None,
|
||||
|
@ -201,7 +207,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
local_scope: ScriptObject::bare_object(context.gc_context),
|
||||
scope,
|
||||
base_proto,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Execute a script initializer.
|
||||
|
@ -380,7 +386,10 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
method: Gc<'gc, BytecodeMethod<'gc>>,
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
let mut read = Reader::new(Cursor::new(method.body().code.as_ref()));
|
||||
let body: Result<_, Error> = method
|
||||
.body()
|
||||
.ok_or_else(|| "Cannot execute non-native method without body".into());
|
||||
let mut read = Reader::new(Cursor::new(body?.code.as_ref()));
|
||||
|
||||
loop {
|
||||
let result = self.do_next_opcode(method, context, &mut read);
|
||||
|
|
|
@ -107,7 +107,7 @@ impl<'gc> Executable<'gc> {
|
|||
reciever,
|
||||
arguments,
|
||||
base_proto,
|
||||
);
|
||||
)?;
|
||||
|
||||
activation.run_actions(bm.method, context)
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ pub struct BytecodeMethod<'gc> {
|
|||
pub abc_method: u32,
|
||||
|
||||
/// The ABC method body this function uses.
|
||||
pub abc_method_body: u32,
|
||||
pub abc_method_body: Option<u32>,
|
||||
}
|
||||
|
||||
impl<'gc> BytecodeMethod<'gc> {
|
||||
|
@ -74,14 +74,22 @@ impl<'gc> BytecodeMethod<'gc> {
|
|||
txunit,
|
||||
abc: CollectWrapper(txunit.abc()),
|
||||
abc_method: abc_method.0,
|
||||
abc_method_body: index as u32,
|
||||
abc_method_body: Some(index as u32),
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
Some(Gc::allocate(
|
||||
mc,
|
||||
Self {
|
||||
txunit,
|
||||
abc: CollectWrapper(txunit.abc()),
|
||||
abc_method: abc_method.0,
|
||||
abc_method_body: None,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// Get the underlying ABC file.
|
||||
|
@ -101,13 +109,14 @@ impl<'gc> BytecodeMethod<'gc> {
|
|||
}
|
||||
|
||||
/// Get a reference to the ABC method body entry this refers to.
|
||||
pub fn body(&self) -> &AbcMethodBody {
|
||||
&self
|
||||
.abc
|
||||
.0
|
||||
.method_bodies
|
||||
.get(self.abc_method_body as usize)
|
||||
.unwrap()
|
||||
///
|
||||
/// Some methods do not have bodies; this returns `None` in that case.
|
||||
pub fn body(&self) -> Option<&AbcMethodBody> {
|
||||
if let Some(abc_method_body) = self.abc_method_body {
|
||||
self.abc.0.method_bodies.get(abc_method_body as usize)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -427,7 +427,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
avm_debug!(
|
||||
"Installing trait {:?} of kind {:?}",
|
||||
trait_name,
|
||||
trait_entry.kind
|
||||
trait_entry.kind()
|
||||
);
|
||||
|
||||
match trait_entry.kind() {
|
||||
|
|
Loading…
Reference in New Issue