avm2: Use correct error when trying to construct something invalid
This commit is contained in:
parent
8bbf8f4ea1
commit
46381d181a
|
@ -1252,7 +1252,9 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
fn op_call(&mut self, arg_count: u32) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
let args = self.pop_stack_args(arg_count);
|
||||
let receiver = self.pop_stack();
|
||||
let function = self.pop_stack().as_callable(self, None, Some(receiver))?;
|
||||
let function = self
|
||||
.pop_stack()
|
||||
.as_callable(self, None, Some(receiver), false)?;
|
||||
let value = function.call(receiver, &args, self)?;
|
||||
|
||||
self.push_stack(value);
|
||||
|
@ -1277,7 +1279,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
#[allow(unreachable_code)]
|
||||
{
|
||||
let args = self.pop_stack_args(arg_count);
|
||||
let receiver = self.pop_stack().as_callable(self, None, None)?;
|
||||
let receiver = self.pop_stack().as_callable(self, None, None, false)?;
|
||||
|
||||
let value = receiver.call_method(index.0, &args, self)?;
|
||||
|
||||
|
@ -1321,6 +1323,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
self,
|
||||
Some(&multiname),
|
||||
Some(receiver.into()),
|
||||
false,
|
||||
)?;
|
||||
let value = function.call(Value::Null, &args, self)?;
|
||||
|
||||
|
@ -1858,7 +1861,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
|
|||
|
||||
fn op_construct(&mut self, arg_count: u32) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
let args = self.pop_stack_args(arg_count);
|
||||
let ctor = self.pop_stack().as_callable(self, None, None)?;
|
||||
let ctor = self.pop_stack().as_callable(self, None, None, true)?;
|
||||
|
||||
let object = ctor.construct(self, &args)?;
|
||||
|
||||
|
|
|
@ -422,7 +422,7 @@ pub fn for_each<'gc>(
|
|||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?;
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let receiver = args.get(1).cloned().unwrap_or(Value::Null);
|
||||
let mut iter = ArrayIter::new(activation, this)?;
|
||||
|
||||
|
@ -445,7 +445,7 @@ pub fn map<'gc>(
|
|||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?;
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let receiver = args.get(1).cloned().unwrap_or(Value::Null);
|
||||
let mut new_array = ArrayStorage::new(0);
|
||||
let mut iter = ArrayIter::new(activation, this)?;
|
||||
|
@ -470,7 +470,7 @@ pub fn filter<'gc>(
|
|||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?;
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let receiver = args.get(1).cloned().unwrap_or(Value::Null);
|
||||
let mut new_array = ArrayStorage::new(0);
|
||||
let mut iter = ArrayIter::new(activation, this)?;
|
||||
|
@ -499,7 +499,7 @@ pub fn every<'gc>(
|
|||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?;
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let receiver = args.get(1).cloned().unwrap_or(Value::Null);
|
||||
let mut iter = ArrayIter::new(activation, this)?;
|
||||
|
||||
|
@ -528,7 +528,7 @@ pub fn some<'gc>(
|
|||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?;
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let receiver = args.get(1).cloned().unwrap_or(Value::Null);
|
||||
let mut iter = ArrayIter::new(activation, this)?;
|
||||
|
||||
|
@ -1011,7 +1011,7 @@ pub fn sort<'gc>(
|
|||
args.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?,
|
||||
.as_callable(activation, None, None, false)?,
|
||||
),
|
||||
SortOptions::from_bits_truncate(
|
||||
args.get(1)
|
||||
|
@ -1022,7 +1022,7 @@ pub fn sort<'gc>(
|
|||
)
|
||||
} else {
|
||||
let arg = args.get(0).cloned().unwrap_or(Value::Undefined);
|
||||
if let Ok(callable) = arg.as_callable(activation, None, None) {
|
||||
if let Ok(callable) = arg.as_callable(activation, None, None, false) {
|
||||
(Some(callable), SortOptions::empty())
|
||||
} else {
|
||||
(
|
||||
|
|
|
@ -23,7 +23,7 @@ pub fn add_frame_script<'gc>(
|
|||
{
|
||||
for (frame_id, callable) in args.chunks_exact(2).map(|s| (s[0], s[1])) {
|
||||
let frame_id = frame_id.coerce_to_u32(activation)? as u16 + 1;
|
||||
let callable = callable.as_callable(activation, None, None).ok();
|
||||
let callable = callable.as_callable(activation, None, None, false).ok();
|
||||
|
||||
mc.register_frame_script(frame_id, callable, &mut activation.context);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,9 @@ pub fn add_event_listener<'gc>(
|
|||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let dispatch_list = dispatch_list(activation, this)?;
|
||||
let event_type = args.get_string(activation, 0)?;
|
||||
let listener = args.get_value(1).as_callable(activation, None, None)?;
|
||||
let listener = args
|
||||
.get_value(1)
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let use_capture = args.get_bool(2);
|
||||
let priority = args.get_i32(activation, 3)?;
|
||||
|
||||
|
@ -62,7 +64,9 @@ pub fn remove_event_listener<'gc>(
|
|||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let dispatch_list = dispatch_list(activation, this)?;
|
||||
let event_type = args.get_string(activation, 0)?;
|
||||
let listener = args.get_value(1).as_callable(activation, None, None)?;
|
||||
let listener = args
|
||||
.get_value(1)
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let use_capture = args.get_bool(2);
|
||||
|
||||
dispatch_list
|
||||
|
@ -152,6 +156,6 @@ pub fn to_string<'gc>(
|
|||
|
||||
object_proto
|
||||
.get_property(&name, activation)?
|
||||
.as_callable(activation, Some(&name), Some(object_proto.into()))?
|
||||
.as_callable(activation, Some(&name), Some(object_proto.into()), false)?
|
||||
.call(this.into(), args, activation)
|
||||
}
|
||||
|
|
|
@ -383,7 +383,7 @@ pub fn every<'gc>(
|
|||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?;
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let receiver = args.get(1).cloned().unwrap_or(Value::Null);
|
||||
let mut iter = ArrayIter::new(activation, this)?;
|
||||
|
||||
|
@ -412,7 +412,7 @@ pub fn some<'gc>(
|
|||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?;
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let receiver = args.get(1).cloned().unwrap_or(Value::Null);
|
||||
let mut iter = ArrayIter::new(activation, this)?;
|
||||
|
||||
|
@ -441,7 +441,7 @@ pub fn filter<'gc>(
|
|||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?;
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let receiver = args.get(1).cloned().unwrap_or(Value::Null);
|
||||
|
||||
let value_type = this
|
||||
|
@ -477,7 +477,7 @@ pub fn for_each<'gc>(
|
|||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?;
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let receiver = args.get(1).cloned().unwrap_or(Value::Null);
|
||||
let mut iter = ArrayIter::new(activation, this)?;
|
||||
|
||||
|
@ -570,7 +570,7 @@ pub fn map<'gc>(
|
|||
.get(0)
|
||||
.cloned()
|
||||
.unwrap_or(Value::Undefined)
|
||||
.as_callable(activation, None, None)?;
|
||||
.as_callable(activation, None, None, false)?;
|
||||
let receiver = args.get(1).cloned().unwrap_or(Value::Null);
|
||||
|
||||
let value_type = this
|
||||
|
@ -779,7 +779,10 @@ pub fn sort<'gc>(
|
|||
if let Some(vs) = this.as_vector_storage_mut(activation.context.gc_context) {
|
||||
let fn_or_options = args.get(0).cloned().unwrap_or(Value::Undefined);
|
||||
|
||||
let (compare_fnc, options) = if fn_or_options.as_callable(activation, None, None).is_ok() {
|
||||
let (compare_fnc, options) = if fn_or_options
|
||||
.as_callable(activation, None, None, false)
|
||||
.is_ok()
|
||||
{
|
||||
(
|
||||
Some(fn_or_options.as_object().unwrap()),
|
||||
SortOptions::empty(),
|
||||
|
|
|
@ -443,7 +443,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
let result = self
|
||||
.base()
|
||||
.get_property_local(multiname, activation)?
|
||||
.as_callable(activation, Some(multiname), Some(self_val))?;
|
||||
.as_callable(activation, Some(multiname), Some(self_val), false)?;
|
||||
|
||||
result.call(self_val, arguments, activation)
|
||||
}
|
||||
|
@ -466,6 +466,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
activation,
|
||||
Some(multiname),
|
||||
Some(Value::from(self.into())),
|
||||
false,
|
||||
)?;
|
||||
|
||||
obj.call(Value::from(self.into()), arguments, activation)
|
||||
|
@ -512,6 +513,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
activation,
|
||||
Some(multiname),
|
||||
Some(Value::from(self.into())),
|
||||
false,
|
||||
)?;
|
||||
|
||||
obj.call(Value::from(self.into()), arguments, activation)
|
||||
|
@ -884,6 +886,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
activation,
|
||||
Some(multiname),
|
||||
Some(Value::from(self.into())),
|
||||
true,
|
||||
)?;
|
||||
|
||||
ctor.construct(activation, args)
|
||||
|
|
|
@ -348,7 +348,7 @@ impl<'gc> TObject<'gc> for XmlListObject<'gc> {
|
|||
}
|
||||
|
||||
return method
|
||||
.as_callable(activation, Some(multiname), Some(self.into()))?
|
||||
.as_callable(activation, Some(multiname), Some(self.into()), false)?
|
||||
.call(self.into(), arguments, activation);
|
||||
}
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ impl<'gc> TObject<'gc> for XmlObject<'gc> {
|
|||
}
|
||||
|
||||
return method
|
||||
.as_callable(activation, Some(multiname), Some(self.into()))?
|
||||
.as_callable(activation, Some(multiname), Some(self.into()), false)?
|
||||
.call(self.into(), arguments, activation);
|
||||
}
|
||||
|
||||
|
|
|
@ -924,6 +924,7 @@ impl<'gc> Value<'gc> {
|
|||
activation: &mut Activation<'_, 'gc>,
|
||||
name: Option<&Multiname<'gc>>,
|
||||
receiver: Option<Value<'gc>>,
|
||||
as_constructor: bool,
|
||||
) -> Result<Object<'gc>, Error<'gc>> {
|
||||
match self.as_object() {
|
||||
Some(o) if o.as_class_object().is_some() || o.as_executable().is_some() => Ok(o),
|
||||
|
@ -934,16 +935,38 @@ impl<'gc> Value<'gc> {
|
|||
} else {
|
||||
"value".into()
|
||||
};
|
||||
let msg = if let Some(Value::Object(receiver)) = receiver {
|
||||
format!(
|
||||
"Error #1006: {} is not a function of class {}.",
|
||||
name,
|
||||
receiver.instance_of_class_name(activation.context.gc_context)
|
||||
let error = if as_constructor {
|
||||
if activation.context.swf.version() < 11 {
|
||||
type_error(
|
||||
activation,
|
||||
&format!("Error #1115: {} is not a constructor.", name),
|
||||
1115,
|
||||
)
|
||||
} else {
|
||||
type_error(
|
||||
activation,
|
||||
"Error #1007: Instantiation attempted on a non-constructor.",
|
||||
1007,
|
||||
)
|
||||
}
|
||||
} else if let Some(Value::Object(receiver)) = receiver {
|
||||
type_error(
|
||||
activation,
|
||||
&format!(
|
||||
"Error #1006: {} is not a function of class {}.",
|
||||
name,
|
||||
receiver.instance_of_class_name(activation.context.gc_context)
|
||||
),
|
||||
1006,
|
||||
)
|
||||
} else {
|
||||
format!("Error #1006: {} is not a function.", name)
|
||||
type_error(
|
||||
activation,
|
||||
&format!("Error #1006: {} is not a function.", name),
|
||||
1006,
|
||||
)
|
||||
};
|
||||
Err(Error::AvmError(type_error(activation, &msg, 1006)?))
|
||||
Err(Error::AvmError(error?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
num_ticks = 1
|
||||
known_failure = true
|
||||
|
|
Loading…
Reference in New Issue