LibJS: Use FlyString for identifiers
This makes variable and property lookups a lot faster since comparing two FlyStrings is O(1).
This commit is contained in:
parent
4f72f6b886
commit
cccbe43056
Notes:
sideshowbarker
2024-07-19 08:11:10 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/cccbe430567
19 changed files with 67 additions and 57 deletions
|
@ -657,7 +657,7 @@ void MemberExpression::dump(int indent) const
|
|||
m_property->dump(indent + 1);
|
||||
}
|
||||
|
||||
String MemberExpression::computed_property_name(Interpreter& interpreter) const
|
||||
FlyString MemberExpression::computed_property_name(Interpreter& interpreter) const
|
||||
{
|
||||
if (!is_computed()) {
|
||||
ASSERT(m_property->is_identifier());
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
@ -130,13 +131,13 @@ class Expression : public ASTNode {
|
|||
|
||||
class FunctionNode {
|
||||
public:
|
||||
String name() const { return m_name; }
|
||||
const FlyString& name() const { return m_name; }
|
||||
const ScopeNode& body() const { return *m_body; }
|
||||
const Vector<String>& parameters() const { return m_parameters; };
|
||||
const Vector<FlyString>& parameters() const { return m_parameters; };
|
||||
|
||||
protected:
|
||||
FunctionNode(String name, NonnullRefPtr<ScopeNode> body, Vector<String> parameters = {})
|
||||
: m_name(move(name))
|
||||
FunctionNode(const FlyString& name, NonnullRefPtr<ScopeNode> body, Vector<FlyString> parameters = {})
|
||||
: m_name(name)
|
||||
, m_body(move(body))
|
||||
, m_parameters(move(parameters))
|
||||
{
|
||||
|
@ -145,9 +146,9 @@ protected:
|
|||
void dump(int indent, const char* class_name) const;
|
||||
|
||||
private:
|
||||
String m_name;
|
||||
FlyString m_name;
|
||||
NonnullRefPtr<ScopeNode> m_body;
|
||||
const Vector<String> m_parameters;
|
||||
const Vector<FlyString> m_parameters;
|
||||
};
|
||||
|
||||
class FunctionDeclaration final
|
||||
|
@ -156,7 +157,7 @@ class FunctionDeclaration final
|
|||
public:
|
||||
static bool must_have_name() { return true; }
|
||||
|
||||
FunctionDeclaration(String name, NonnullRefPtr<ScopeNode> body, Vector<String> parameters = {})
|
||||
FunctionDeclaration(String name, NonnullRefPtr<ScopeNode> body, Vector<FlyString> parameters = {})
|
||||
: FunctionNode(move(name), move(body), move(parameters))
|
||||
{
|
||||
}
|
||||
|
@ -173,8 +174,8 @@ class FunctionExpression final : public Expression
|
|||
public:
|
||||
static bool must_have_name() { return false; }
|
||||
|
||||
FunctionExpression(String name, NonnullRefPtr<ScopeNode> body, Vector<String> parameters = {})
|
||||
: FunctionNode(move(name), move(body), move(parameters))
|
||||
FunctionExpression(const FlyString& name, NonnullRefPtr<ScopeNode> body, Vector<FlyString> parameters = {})
|
||||
: FunctionNode(name, move(body), move(parameters))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -425,17 +426,13 @@ private:
|
|||
|
||||
class NullLiteral final : public Literal {
|
||||
public:
|
||||
explicit NullLiteral()
|
||||
{
|
||||
}
|
||||
explicit NullLiteral() {}
|
||||
|
||||
virtual Value execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "NullLiteral"; }
|
||||
|
||||
String m_value;
|
||||
};
|
||||
|
||||
class UndefinedLiteral final : public Literal {
|
||||
|
@ -453,12 +450,12 @@ private:
|
|||
|
||||
class Identifier final : public Expression {
|
||||
public:
|
||||
explicit Identifier(String string)
|
||||
: m_string(move(string))
|
||||
explicit Identifier(const FlyString& string)
|
||||
: m_string(string)
|
||||
{
|
||||
}
|
||||
|
||||
const String& string() const { return m_string; }
|
||||
const FlyString& string() const { return m_string; }
|
||||
|
||||
virtual Value execute(Interpreter&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
|
@ -467,7 +464,7 @@ public:
|
|||
private:
|
||||
virtual const char* class_name() const override { return "Identifier"; }
|
||||
|
||||
String m_string;
|
||||
FlyString m_string;
|
||||
};
|
||||
|
||||
class CallExpression : public Expression {
|
||||
|
@ -573,7 +570,7 @@ private:
|
|||
|
||||
class ObjectExpression : public Expression {
|
||||
public:
|
||||
ObjectExpression(HashMap<String, NonnullRefPtr<Expression>> properties = {})
|
||||
ObjectExpression(HashMap<FlyString, NonnullRefPtr<Expression>> properties = {})
|
||||
: m_properties(move(properties))
|
||||
{
|
||||
}
|
||||
|
@ -584,7 +581,7 @@ public:
|
|||
private:
|
||||
virtual const char* class_name() const override { return "ObjectExpression"; }
|
||||
|
||||
HashMap<String, NonnullRefPtr<Expression>> m_properties;
|
||||
HashMap<FlyString, NonnullRefPtr<Expression>> m_properties;
|
||||
};
|
||||
|
||||
class ArrayExpression : public Expression {
|
||||
|
@ -621,7 +618,7 @@ public:
|
|||
const Expression& object() const { return *m_object; }
|
||||
const Expression& property() const { return *m_property; }
|
||||
|
||||
String computed_property_name(Interpreter&) const;
|
||||
FlyString computed_property_name(Interpreter&) const;
|
||||
|
||||
private:
|
||||
virtual bool is_member_expression() const override { return true; }
|
||||
|
|
|
@ -65,7 +65,7 @@ Value Interpreter::run(const ScopeNode& scope_node, Vector<Argument> arguments,
|
|||
|
||||
void Interpreter::enter_scope(const ScopeNode& scope_node, Vector<Argument> arguments, ScopeType scope_type)
|
||||
{
|
||||
HashMap<String, Variable> scope_variables_with_declaration_type;
|
||||
HashMap<FlyString, Variable> scope_variables_with_declaration_type;
|
||||
for (auto& argument : arguments) {
|
||||
scope_variables_with_declaration_type.set(argument.name, { argument.value, DeclarationType::Var });
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ void Interpreter::do_return()
|
|||
dbg() << "FIXME: Implement Interpreter::do_return()";
|
||||
}
|
||||
|
||||
void Interpreter::declare_variable(String name, DeclarationType declaration_type)
|
||||
void Interpreter::declare_variable(const FlyString& name, DeclarationType declaration_type)
|
||||
{
|
||||
switch (declaration_type) {
|
||||
case DeclarationType::Var:
|
||||
|
@ -110,7 +110,7 @@ void Interpreter::declare_variable(String name, DeclarationType declaration_type
|
|||
}
|
||||
}
|
||||
|
||||
void Interpreter::set_variable(String name, Value value, bool first_assignment)
|
||||
void Interpreter::set_variable(const FlyString& name, Value value, bool first_assignment)
|
||||
{
|
||||
for (ssize_t i = m_scope_stack.size() - 1; i >= 0; --i) {
|
||||
auto& scope = m_scope_stack.at(i);
|
||||
|
@ -128,7 +128,7 @@ void Interpreter::set_variable(String name, Value value, bool first_assignment)
|
|||
global_object().put(move(name), move(value));
|
||||
}
|
||||
|
||||
Value Interpreter::get_variable(const String& name)
|
||||
Value Interpreter::get_variable(const FlyString& name)
|
||||
{
|
||||
for (ssize_t i = m_scope_stack.size() - 1; i >= 0; --i) {
|
||||
auto& scope = m_scope_stack.at(i);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Heap/Heap.h>
|
||||
|
@ -48,7 +49,7 @@ struct Variable {
|
|||
struct ScopeFrame {
|
||||
ScopeType type;
|
||||
NonnullRefPtr<ScopeNode> scope_node;
|
||||
HashMap<String, Variable> variables;
|
||||
HashMap<FlyString, Variable> variables;
|
||||
};
|
||||
|
||||
struct CallFrame {
|
||||
|
@ -57,7 +58,7 @@ struct CallFrame {
|
|||
};
|
||||
|
||||
struct Argument {
|
||||
String name;
|
||||
FlyString name;
|
||||
Value value;
|
||||
};
|
||||
|
||||
|
@ -75,9 +76,9 @@ public:
|
|||
|
||||
void do_return();
|
||||
|
||||
Value get_variable(const String& name);
|
||||
void set_variable(String name, Value, bool first_assignment = false);
|
||||
void declare_variable(String name, DeclarationType);
|
||||
Value get_variable(const FlyString& name);
|
||||
void set_variable(const FlyString& name, Value, bool first_assignment = false);
|
||||
void declare_variable(const FlyString& name, DeclarationType);
|
||||
|
||||
void gather_roots(Badge<Heap>, HashTable<Cell*>&);
|
||||
|
||||
|
@ -86,7 +87,11 @@ public:
|
|||
|
||||
Value call(Function*, Value this_value, const Vector<Value>& arguments);
|
||||
|
||||
CallFrame& push_call_frame() { m_call_stack.append({ js_undefined(), {} }); return m_call_stack.last(); }
|
||||
CallFrame& push_call_frame()
|
||||
{
|
||||
m_call_stack.append({ js_undefined(), {} });
|
||||
return m_call_stack.last();
|
||||
}
|
||||
void pop_call_frame() { m_call_stack.take_last(); }
|
||||
Value this_value() const
|
||||
{
|
||||
|
|
|
@ -271,7 +271,7 @@ NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
|
|||
|
||||
NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
||||
{
|
||||
HashMap<String, NonnullRefPtr<Expression>> properties;
|
||||
HashMap<FlyString, NonnullRefPtr<Expression>> properties;
|
||||
consume(TokenType::CurlyOpen);
|
||||
|
||||
while (!match(TokenType::CurlyClose)) {
|
||||
|
@ -471,7 +471,7 @@ NonnullRefPtr<FunctionNodeType> Parser::parse_function_node()
|
|||
name = consume(TokenType::Identifier).value();
|
||||
}
|
||||
consume(TokenType::ParenOpen);
|
||||
Vector<String> parameters;
|
||||
Vector<FlyString> parameters;
|
||||
while (match(TokenType::Identifier)) {
|
||||
auto parameter = consume(TokenType::Identifier).value();
|
||||
parameters.append(parameter);
|
||||
|
|
|
@ -59,7 +59,7 @@ void Array::visit_children(Cell::Visitor& visitor)
|
|||
visitor.visit(element);
|
||||
}
|
||||
|
||||
Optional<Value> Array::get_own_property(const String& property_name) const
|
||||
Optional<Value> Array::get_own_property(const FlyString& property_name) const
|
||||
{
|
||||
bool ok;
|
||||
i32 index = property_name.to_int(ok);
|
||||
|
@ -70,7 +70,7 @@ Optional<Value> Array::get_own_property(const String& property_name) const
|
|||
return Object::get_own_property(property_name);
|
||||
}
|
||||
|
||||
bool Array::put_own_property(const String& property_name, Value value)
|
||||
bool Array::put_own_property(const FlyString& property_name, Value value)
|
||||
{
|
||||
bool ok;
|
||||
i32 index = property_name.to_int(ok);
|
||||
|
|
|
@ -45,8 +45,8 @@ private:
|
|||
virtual const char* class_name() const override { return "Array"; }
|
||||
virtual void visit_children(Cell::Visitor&) override;
|
||||
virtual bool is_array() const override { return true; }
|
||||
virtual Optional<Value> get_own_property(const String& property_name) const override;
|
||||
virtual bool put_own_property(const String& property_name, Value) override;
|
||||
virtual Optional<Value> get_own_property(const FlyString& property_name) const override;
|
||||
virtual bool put_own_property(const FlyString& property_name, Value) override;
|
||||
|
||||
Vector<Value> m_elements;
|
||||
};
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <LibJS/Runtime/ConsoleObject.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <LibJS/Runtime/MathObject.h>
|
||||
|
||||
namespace JS {
|
||||
|
|
|
@ -44,7 +44,7 @@ Object::~Object()
|
|||
{
|
||||
}
|
||||
|
||||
Optional<Value> Object::get_own_property(const String& property_name) const
|
||||
Optional<Value> Object::get_own_property(const FlyString& property_name) const
|
||||
{
|
||||
auto value_here = m_properties.get(property_name);
|
||||
if (value_here.has_value() && value_here.value().is_object() && value_here.value().as_object()->is_native_property())
|
||||
|
@ -52,7 +52,7 @@ Optional<Value> Object::get_own_property(const String& property_name) const
|
|||
return value_here;
|
||||
}
|
||||
|
||||
bool Object::put_own_property(const String& property_name, Value value)
|
||||
bool Object::put_own_property(const FlyString& property_name, Value value)
|
||||
{
|
||||
auto value_here = m_properties.get(property_name);
|
||||
if (value_here.has_value() && value_here.value().is_object() && value_here.value().as_object()->is_native_property()) {
|
||||
|
@ -63,7 +63,7 @@ bool Object::put_own_property(const String& property_name, Value value)
|
|||
return true;
|
||||
}
|
||||
|
||||
Value Object::get(const String& property_name) const
|
||||
Value Object::get(const FlyString& property_name) const
|
||||
{
|
||||
const Object* object = this;
|
||||
while (object) {
|
||||
|
@ -75,7 +75,7 @@ Value Object::get(const String& property_name) const
|
|||
return js_undefined();
|
||||
}
|
||||
|
||||
void Object::put(const String& property_name, Value value)
|
||||
void Object::put(const FlyString& property_name, Value value)
|
||||
{
|
||||
Object* object = this;
|
||||
while (object) {
|
||||
|
@ -93,12 +93,12 @@ void Object::put(const String& property_name, Value value)
|
|||
put_own_property(property_name, value);
|
||||
}
|
||||
|
||||
void Object::put_native_function(String property_name, AK::Function<Value(Object*, Vector<Value>)> native_function)
|
||||
void Object::put_native_function(const FlyString& property_name, AK::Function<Value(Object*, Vector<Value>)> native_function)
|
||||
{
|
||||
put(property_name, heap().allocate<NativeFunction>(move(native_function)));
|
||||
}
|
||||
|
||||
void Object::put_native_property(String property_name, AK::Function<Value(Object*)> getter, AK::Function<void(Object*, Value)> setter)
|
||||
void Object::put_native_property(const FlyString& property_name, AK::Function<Value(Object*)> getter, AK::Function<void(Object*, Value)> setter)
|
||||
{
|
||||
put(property_name, heap().allocate<NativeProperty>(move(getter), move(setter)));
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ void Object::visit_children(Cell::Visitor& visitor)
|
|||
visitor.visit(it.value);
|
||||
}
|
||||
|
||||
bool Object::has_own_property(const String& property_name) const
|
||||
bool Object::has_own_property(const FlyString& property_name) const
|
||||
{
|
||||
return m_properties.get(property_name).has_value();
|
||||
}
|
||||
|
|
|
@ -40,14 +40,14 @@ public:
|
|||
Object();
|
||||
virtual ~Object();
|
||||
|
||||
Value get(const String& property_name) const;
|
||||
void put(const String& property_name, Value);
|
||||
Value get(const FlyString& property_name) const;
|
||||
void put(const FlyString& property_name, Value);
|
||||
|
||||
virtual Optional<Value> get_own_property(const String& property_name) const;
|
||||
virtual bool put_own_property(const String& property_name, Value);
|
||||
virtual Optional<Value> get_own_property(const FlyString& property_name) const;
|
||||
virtual bool put_own_property(const FlyString& property_name, Value);
|
||||
|
||||
void put_native_function(String property_name, AK::Function<Value(Object*, Vector<Value>)>);
|
||||
void put_native_property(String property_name, AK::Function<Value(Object*)> getter, AK::Function<void(Object*, Value)> setter);
|
||||
void put_native_function(const FlyString& property_name, AK::Function<Value(Object*, Vector<Value>)>);
|
||||
void put_native_property(const FlyString& property_name, AK::Function<Value(Object*)> getter, AK::Function<void(Object*, Value)> setter);
|
||||
|
||||
virtual bool is_array() const { return false; }
|
||||
virtual bool is_function() const { return false; }
|
||||
|
@ -62,7 +62,7 @@ public:
|
|||
const Object* prototype() const { return m_prototype; }
|
||||
void set_prototype(Object* prototype) { m_prototype = prototype; }
|
||||
|
||||
bool has_own_property(const String& property_name) const;
|
||||
bool has_own_property(const FlyString& property_name) const;
|
||||
enum class PreferredType {
|
||||
Default,
|
||||
String,
|
||||
|
@ -74,7 +74,7 @@ public:
|
|||
virtual Value to_string() const;
|
||||
|
||||
private:
|
||||
HashMap<String, Value> m_properties;
|
||||
HashMap<FlyString, Value> m_properties;
|
||||
Object* m_prototype { nullptr };
|
||||
};
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
ScriptFunction::ScriptFunction(const ScopeNode& body, Vector<String> parameters)
|
||||
ScriptFunction::ScriptFunction(const ScopeNode& body, Vector<FlyString> parameters)
|
||||
: m_body(body)
|
||||
, m_parameters(move(parameters))
|
||||
{
|
||||
|
|
|
@ -32,11 +32,11 @@ namespace JS {
|
|||
|
||||
class ScriptFunction final : public Function {
|
||||
public:
|
||||
ScriptFunction(const ScopeNode& body, Vector<String> parameters = {});
|
||||
ScriptFunction(const ScopeNode& body, Vector<FlyString> parameters = {});
|
||||
virtual ~ScriptFunction();
|
||||
|
||||
const ScopeNode& body() const { return m_body; }
|
||||
const Vector<String>& parameters() const { return m_parameters; };
|
||||
const Vector<FlyString>& parameters() const { return m_parameters; };
|
||||
|
||||
virtual Value call(Interpreter&, const Vector<Value>&) override;
|
||||
|
||||
|
@ -45,7 +45,7 @@ private:
|
|||
virtual const char* class_name() const override { return "ScriptFunction"; }
|
||||
|
||||
NonnullRefPtr<ScopeNode> m_body;
|
||||
const Vector<String> m_parameters;
|
||||
const Vector<FlyString> m_parameters;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
#include <LibWeb/Bindings/CanvasRenderingContext2DWrapper.h>
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
#include <LibWeb/Bindings/DocumentWrapper.h>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <LibJS/Runtime/Function.h>
|
||||
#include <LibWeb/Bindings/EventListenerWrapper.h>
|
||||
#include <LibWeb/Bindings/EventTargetWrapper.h>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
#include <LibWeb/Bindings/CanvasRenderingContext2DWrapper.h>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/FlyString.h>
|
||||
#include <LibJS/Runtime/Function.h>
|
||||
#include <LibWeb/Bindings/MouseEventWrapper.h>
|
||||
#include <LibWeb/DOM/MouseEvent.h>
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
#include <LibWeb/Bindings/DocumentWrapper.h>
|
||||
|
|
Loading…
Add table
Reference in a new issue