1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 04:37:34 +00:00

LibJS: Add a fast path for creating per-iteration DeclarativeEnvironment

The steps for creating a DeclarativeEnvironment for each iteration of a
for-loop can be done equivalently to the spec without following the spec
directly. For each binding creating in the loop's init expression, we:

    1. Create a new binding in the new environment.
    2. Grab the current value of the binding in the old environment.
    3. Set the value in the new environment to the old value.

This can be replaced by initializing the bindings vector in the new
environment directly with the bindings in the old environment (but only
copying the bindings of the init statement).
This commit is contained in:
Timothy Flynn 2022-03-09 15:37:10 -05:00 committed by Andreas Kling
parent f37fbcf516
commit 27904b1060
3 changed files with 42 additions and 40 deletions

View file

@ -17,9 +17,21 @@ namespace JS {
class DeclarativeEnvironment : public Environment {
JS_ENVIRONMENT(DeclarativeEnvironment, Environment);
struct Binding {
FlyString name;
Value value;
bool strict { false };
bool mutable_ { false };
bool can_be_deleted { false };
bool initialized { false };
};
public:
static DeclarativeEnvironment* create_for_per_iteration_bindings(Badge<ForStatement>, DeclarativeEnvironment& other, size_t bindings_size);
DeclarativeEnvironment();
explicit DeclarativeEnvironment(Environment* parent_scope);
explicit DeclarativeEnvironment(Environment* parent_scope, Span<Binding const> bindings);
virtual ~DeclarativeEnvironment() override;
virtual ThrowCompletionOr<bool> has_binding(FlyString const& name, Optional<size_t>* = nullptr) const override;
@ -49,11 +61,6 @@ public:
ThrowCompletionOr<Value> get_binding_value_direct(GlobalObject&, size_t index, bool strict);
ThrowCompletionOr<void> set_mutable_binding_direct(GlobalObject&, size_t index, Value, bool strict);
void ensure_capacity(size_t capacity)
{
m_bindings.ensure_capacity(capacity);
}
protected:
virtual void visit_edges(Visitor&) override;
@ -71,15 +78,6 @@ private:
return it.index();
}
struct Binding {
FlyString name;
Value value;
bool strict { false };
bool mutable_ { false };
bool can_be_deleted { false };
bool initialized { false };
};
Vector<Binding> m_bindings;
};