avm2: Ignore duplicate definitions

This commit is contained in:
EmperorBale 2023-02-23 02:48:19 -08:00 committed by Bale
parent 01af1af4d9
commit 5bc3c696b5
4 changed files with 21 additions and 33 deletions

View File

@ -182,25 +182,18 @@ impl<'gc> Domain<'gc> {
/// Export a definition from a script into the current application domain.
///
/// This returns an error if the name is already defined in the current or
/// any parent domains.
/// This does nothing if the definition already exists.
pub fn export_definition(
&mut self,
name: QName<'gc>,
script: Script<'gc>,
mc: MutationContext<'gc, '_>,
) -> Result<(), Error<'gc>> {
) {
if self.has_definition(name) {
return Err(format!(
"VerifyError: Attempted to redefine existing name {}",
name.local_name()
)
.into());
return;
}
self.0.write(mc).defs.insert(name, script);
Ok(())
}
pub fn export_class(
@ -208,9 +201,8 @@ impl<'gc> Domain<'gc> {
name: QName<'gc>,
class: GcCell<'gc, Class<'gc>>,
mc: MutationContext<'gc, '_>,
) -> Result<(), Error<'gc>> {
) {
self.0.write(mc).classes.insert(name, class);
Ok(())
}
pub fn domain_memory(&self) -> ByteArrayObject<'gc> {

View File

@ -218,7 +218,7 @@ fn function<'gc>(
);
let method = Method::from_builtin(nf, name, mc);
let as3fn = FunctionObject::from_method(activation, method, scope, None, None).into();
domain.export_definition(qname, script, mc)?;
domain.export_definition(qname, script, mc);
global.install_const_late(mc, qname, as3fn, activation.avm2().classes().function);
Ok(())
@ -234,7 +234,7 @@ fn dynamic_class<'gc>(
script: Script<'gc>,
// The `ClassObject` of the `Class` class
class_class: ClassObject<'gc>,
) -> Result<(), Error<'gc>> {
) {
let (_, mut global, mut domain) = script.init();
let class = class_object.inner_class_definition();
let name = class.read().name();
@ -290,8 +290,8 @@ fn class<'gc>(
class_object.into(),
activation.avm2().classes().class,
);
domain.export_definition(class_name, script, activation.context.gc_context)?;
domain.export_class(class_name, class_def, activation.context.gc_context)?;
domain.export_definition(class_name, script, activation.context.gc_context);
domain.export_class(class_name, class_def, activation.context.gc_context);
Ok(class_object)
}
@ -397,9 +397,9 @@ pub fn load_player_globals<'gc>(
// From this point, `globals` is safe to be modified
dynamic_class(mc, object_class, script, class_class)?;
dynamic_class(mc, fn_class, script, class_class)?;
dynamic_class(mc, class_class, script, class_class)?;
dynamic_class(mc, object_class, script, class_class);
dynamic_class(mc, fn_class, script, class_class);
dynamic_class(mc, class_class, script, class_class);
// After this point, it is safe to initialize any other classes.
// Make sure to initialize superclasses *before* their subclasses!

View File

@ -123,7 +123,7 @@ pub fn class_init<'gc>(
int_vector_class.into(),
class_class,
);
domain.export_definition(int_vector_name, script, activation.context.gc_context)?;
domain.export_definition(int_vector_name, script, activation.context.gc_context);
let uint_class = activation.avm2().classes().uint;
let uint_vector_class = this.apply(activation, &[uint_class.into()])?;
@ -139,7 +139,7 @@ pub fn class_init<'gc>(
uint_vector_class.into(),
class_class,
);
domain.export_definition(uint_vector_name, script, activation.context.gc_context)?;
domain.export_definition(uint_vector_name, script, activation.context.gc_context);
let number_class = activation.avm2().classes().number;
let number_vector_class = this.apply(activation, &[number_class.into()])?;
@ -155,7 +155,7 @@ pub fn class_init<'gc>(
number_vector_class.into(),
class_class,
);
domain.export_definition(number_vector_name, script, activation.context.gc_context)?;
domain.export_definition(number_vector_name, script, activation.context.gc_context);
let object_vector_class = this.apply(activation, &[Value::Null])?;
let object_vector_name = QName::new(vector_internal_namespace, "Vector$object");
@ -170,7 +170,7 @@ pub fn class_init<'gc>(
object_vector_class.into(),
class_class,
);
domain.export_definition(object_vector_name, script, activation.context.gc_context)?;
domain.export_definition(object_vector_name, script, activation.context.gc_context);
}
Ok(Value::Undefined)

View File

@ -462,17 +462,13 @@ impl<'gc> Script<'gc> {
for abc_trait in script.traits.iter() {
let newtrait = Trait::from_abc_trait(unit, abc_trait, activation)?;
write.domain.export_definition(
newtrait.name(),
*self,
activation.context.gc_context,
)?;
write
.domain
.export_definition(newtrait.name(), *self, activation.context.gc_context);
if let TraitKind::Class { class, .. } = newtrait.kind() {
write.domain.export_class(
newtrait.name(),
*class,
activation.context.gc_context,
)?;
write
.domain
.export_class(newtrait.name(), *class, activation.context.gc_context);
}
write.traits.push(newtrait);