Implement multinames, sans runtime namespace support.

This commit is contained in:
David Wendt 2020-02-08 18:09:03 -05:00
parent 6bd94d6bc9
commit c65d93d063
1 changed files with 57 additions and 0 deletions

View File

@ -1,5 +1,6 @@
//! AVM2 names & namespacing //! AVM2 names & namespacing
use crate::avm2::Avm2;
use gc_arena::Collect; use gc_arena::Collect;
use swf::avm2::types::{AbcFile, Index, Multiname as AbcMultiname, Namespace as AbcNamespace}; use swf::avm2::types::{AbcFile, Index, Multiname as AbcMultiname, Namespace as AbcNamespace};
@ -70,3 +71,59 @@ pub struct QName {
ns: Namespace, ns: Namespace,
name: String, name: String,
} }
/// A `Multiname` consists of a name which could be resolved in one or more
/// potential namespaces.
///
/// All unresolved names are of the form `Multiname`, and the name resolution
/// process consists of searching each name space for a given name.
pub struct Multiname {
ns: Vec<Namespace>,
name: String,
}
impl Multiname {
/// Read a multiname from the ABC constant pool, copying it into the most
/// general form of multiname.
///
/// This does not yet support late-bound or runtime multinames.
pub fn from_abc_multiname(
file: &AbcFile,
multiname_index: Index<Multiname>,
avm: &mut Avm2<'_>,
) -> Option<Self> {
Some(
match file
.constant_pool
.multinames
.get(multiname_index.0 as usize)?
{
AbcMultiname::QName { namespace, name }
| AbcMultiname::QNameA { namespace, name } => Self {
ns: vec![Namespace::from_abc_namespace(file, namespace.clone())?],
name: file.constant_pool.strings.get(name.0 as usize)?.clone(),
},
AbcMultiname::Multiname {
namespace_set,
name,
}
| AbcMultiname::MultinameA {
namespace_set,
name,
} => Self {
ns: file
.constant_pool
.namespace_sets
.get(namespace_set.0 as usize)?
.iter()
.map(|ns| Namespace::from_abc_namespace(file, ns.clone()))
.filter(|ns| ns.is_some())
.map(|ns| ns.unwrap())
.collect(),
name: file.constant_pool.strings.get(name.0 as usize)?.clone(),
},
_ => return None,
},
)
}
}