Construct the closure scope chain in one pass, which lets us skip the vec allocation.
This commit is contained in:
parent
2b90c61a69
commit
1b62ead082
|
@ -61,15 +61,37 @@ impl<'gc> Scope<'gc> {
|
|||
|
||||
/// Construct a closure scope to be used as the parent of all local scopes
|
||||
/// when invoking a function.
|
||||
///
|
||||
/// This function filters With scopes from the scope chain. If all scopes
|
||||
/// are filtered (somehow), this function constructs and returns a new,
|
||||
/// single global scope with a bare object.
|
||||
pub fn new_closure_scope(
|
||||
mut parent: GcCell<'gc, Self>,
|
||||
mc: MutationContext<'gc, '_>,
|
||||
) -> GcCell<'gc, Self> {
|
||||
let mut closure_scope_list = Vec::new();
|
||||
let mut bottom_scope = None;
|
||||
let mut top_scope: Option<GcCell<'gc, Self>> = None;
|
||||
|
||||
loop {
|
||||
if parent.read().class != ScopeClass::With {
|
||||
closure_scope_list.push(parent);
|
||||
let next_scope = GcCell::allocate(
|
||||
mc,
|
||||
Self {
|
||||
parent: None,
|
||||
class: parent.read().class,
|
||||
values: parent.read().values,
|
||||
},
|
||||
);
|
||||
|
||||
if let None = bottom_scope {
|
||||
bottom_scope = Some(next_scope);
|
||||
}
|
||||
|
||||
if let Some(ref scope) = top_scope {
|
||||
scope.write(mc).parent = Some(next_scope);
|
||||
}
|
||||
|
||||
top_scope = Some(next_scope);
|
||||
}
|
||||
|
||||
let grandparent = parent.read().parent;
|
||||
|
@ -80,30 +102,16 @@ impl<'gc> Scope<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
let mut parent_scope = None;
|
||||
for scope in closure_scope_list.iter().rev() {
|
||||
parent_scope = Some(GcCell::allocate(
|
||||
mc,
|
||||
Scope {
|
||||
parent: parent_scope,
|
||||
class: scope.read().class,
|
||||
values: scope.read().values,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(parent_scope) = parent_scope {
|
||||
parent_scope
|
||||
} else {
|
||||
bottom_scope.unwrap_or_else(|| {
|
||||
GcCell::allocate(
|
||||
mc,
|
||||
Scope {
|
||||
Self {
|
||||
parent: None,
|
||||
class: ScopeClass::Global,
|
||||
values: GcCell::allocate(mc, Object::bare_object()),
|
||||
},
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Construct a scope for use with `tellTarget` code where the timeline
|
||||
|
|
Loading…
Reference in New Issue