mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 14:35:07 +00:00
LibJS: Use macros to enumerate well-known symbols
Not only is this a much nicer api (can't pass a typo'd string into the get_well_known_symbol function), it is also a bit more performant since there are no hashmap lookups.
This commit is contained in:
parent
2ea85355fe
commit
c485c86015
7 changed files with 42 additions and 31 deletions
|
@ -75,6 +75,21 @@
|
||||||
JS_ENUMERATE_NATIVE_OBJECTS \
|
JS_ENUMERATE_NATIVE_OBJECTS \
|
||||||
JS_ENUMERATE_ERROR_SUBCLASSES
|
JS_ENUMERATE_ERROR_SUBCLASSES
|
||||||
|
|
||||||
|
#define JS_ENUMERATE_WELL_KNOWN_SYMBOLS \
|
||||||
|
__JS_ENUMERATE(iterator, iterator) \
|
||||||
|
__JS_ENUMERATE(asyncIterator, async_iterator) \
|
||||||
|
__JS_ENUMERATE(match, match) \
|
||||||
|
__JS_ENUMERATE(matchAll, match_all) \
|
||||||
|
__JS_ENUMERATE(replace, replace) \
|
||||||
|
__JS_ENUMERATE(search, search) \
|
||||||
|
__JS_ENUMERATE(split, split) \
|
||||||
|
__JS_ENUMERATE(hasInstance, has_instance) \
|
||||||
|
__JS_ENUMERATE(isConcatSpreadable, is_concat_spreadable) \
|
||||||
|
__JS_ENUMERATE(unscopables, unscopables) \
|
||||||
|
__JS_ENUMERATE(species, species) \
|
||||||
|
__JS_ENUMERATE(toPrimitive, to_primitive) \
|
||||||
|
__JS_ENUMERATE(toStringTag, to_string_tag)
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
class ASTNode;
|
class ASTNode;
|
||||||
|
|
|
@ -48,19 +48,10 @@ Interpreter::Interpreter()
|
||||||
: m_heap(*this)
|
: m_heap(*this)
|
||||||
, m_console(*this)
|
, m_console(*this)
|
||||||
{
|
{
|
||||||
m_well_known_symbol_map.set("iterator", js_symbol(*this, "Symbol.iterator", false));
|
#define __JS_ENUMERATE(SymbolName, snake_name) \
|
||||||
m_well_known_symbol_map.set("asyncIterator", js_symbol(*this, "Symbol.asyncIterator", false));
|
m_well_known_symbol_##snake_name = js_symbol(*this, "Symbol." #SymbolName, false);
|
||||||
m_well_known_symbol_map.set("match", js_symbol(*this, "Symbol.match", false));
|
JS_ENUMERATE_WELL_KNOWN_SYMBOLS
|
||||||
m_well_known_symbol_map.set("matchAll", js_symbol(*this, "Symbol.matchAll", false));
|
#undef __JS_ENUMERATE
|
||||||
m_well_known_symbol_map.set("replace", js_symbol(*this, "Symbol.replace", false));
|
|
||||||
m_well_known_symbol_map.set("search", js_symbol(*this, "Symbol.search", false));
|
|
||||||
m_well_known_symbol_map.set("split", js_symbol(*this, "Symbol.split", false));
|
|
||||||
m_well_known_symbol_map.set("hasInstance", js_symbol(*this, "Symbol.hasInstance", false));
|
|
||||||
m_well_known_symbol_map.set("isConcatSpreadable", js_symbol(*this, "Symbol.isConcatSpreadable", false));
|
|
||||||
m_well_known_symbol_map.set("unscopables", js_symbol(*this, "Symbol.unscopables", false));
|
|
||||||
m_well_known_symbol_map.set("species", js_symbol(*this, "Symbol.species", false));
|
|
||||||
m_well_known_symbol_map.set("toPrimitive", js_symbol(*this, "Symbol.toPrimitive", false));
|
|
||||||
m_well_known_symbol_map.set("toStringTag", js_symbol(*this, "Symbol.toStringTag", false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Interpreter::~Interpreter()
|
Interpreter::~Interpreter()
|
||||||
|
@ -225,12 +216,6 @@ Symbol* Interpreter::get_global_symbol(const String& description)
|
||||||
return new_global_symbol;
|
return new_global_symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* Interpreter::get_well_known_symbol(const String& description) const
|
|
||||||
{
|
|
||||||
ASSERT(m_well_known_symbol_map.contains(description));
|
|
||||||
return m_well_known_symbol_map.get(description).value();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Interpreter::gather_roots(Badge<Heap>, HashTable<Cell*>& roots)
|
void Interpreter::gather_roots(Badge<Heap>, HashTable<Cell*>& roots)
|
||||||
{
|
{
|
||||||
roots.set(m_global_object);
|
roots.set(m_global_object);
|
||||||
|
@ -249,8 +234,10 @@ void Interpreter::gather_roots(Badge<Heap>, HashTable<Cell*>& roots)
|
||||||
roots.set(call_frame.environment);
|
roots.set(call_frame.environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& symbol : m_well_known_symbol_map)
|
#define __JS_ENUMERATE(SymbolName, snake_name) \
|
||||||
roots.set(symbol.value);
|
roots.set(well_known_symbol_##snake_name());
|
||||||
|
JS_ENUMERATE_WELL_KNOWN_SYMBOLS
|
||||||
|
#undef __JS_ENUMERATE
|
||||||
|
|
||||||
for (auto& symbol : m_global_symbol_map)
|
for (auto& symbol : m_global_symbol_map)
|
||||||
roots.set(symbol.value);
|
roots.set(symbol.value);
|
||||||
|
|
|
@ -112,8 +112,6 @@ public:
|
||||||
Reference get_reference(const FlyString& name);
|
Reference get_reference(const FlyString& name);
|
||||||
|
|
||||||
Symbol* get_global_symbol(const String& description);
|
Symbol* get_global_symbol(const String& description);
|
||||||
Symbol* get_well_known_symbol(const String& description) const;
|
|
||||||
const HashMap<String, Symbol*>& get_well_known_symbol_map(Badge<SymbolConstructor>) const { return m_well_known_symbol_map; };
|
|
||||||
|
|
||||||
void gather_roots(Badge<Heap>, HashTable<Cell*>&);
|
void gather_roots(Badge<Heap>, HashTable<Cell*>&);
|
||||||
|
|
||||||
|
@ -209,6 +207,11 @@ public:
|
||||||
const LexicalEnvironment* get_this_environment() const;
|
const LexicalEnvironment* get_this_environment() const;
|
||||||
Value get_new_target() const;
|
Value get_new_target() const;
|
||||||
|
|
||||||
|
#define __JS_ENUMERATE(SymbolName, snake_name) \
|
||||||
|
Symbol* well_known_symbol_##snake_name() const { return m_well_known_symbol_##snake_name; }
|
||||||
|
JS_ENUMERATE_WELL_KNOWN_SYMBOLS
|
||||||
|
#undef __JS_ENUMERATE
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Interpreter();
|
Interpreter();
|
||||||
|
|
||||||
|
@ -221,9 +224,6 @@ private:
|
||||||
|
|
||||||
Object* m_global_object { nullptr };
|
Object* m_global_object { nullptr };
|
||||||
|
|
||||||
HashMap<String, Symbol*> m_well_known_symbol_map;
|
|
||||||
HashMap<String, Symbol*> m_global_symbol_map;
|
|
||||||
|
|
||||||
Exception* m_exception { nullptr };
|
Exception* m_exception { nullptr };
|
||||||
|
|
||||||
ScopeType m_unwind_until { ScopeType::None };
|
ScopeType m_unwind_until { ScopeType::None };
|
||||||
|
@ -232,6 +232,13 @@ private:
|
||||||
bool m_underscore_is_last_value { false };
|
bool m_underscore_is_last_value { false };
|
||||||
|
|
||||||
Console m_console;
|
Console m_console;
|
||||||
|
|
||||||
|
HashMap<String, Symbol*> m_global_symbol_map;
|
||||||
|
|
||||||
|
#define __JS_ENUMERATE(SymbolName, snake_name) \
|
||||||
|
Symbol* m_well_known_symbol_##snake_name { nullptr };
|
||||||
|
JS_ENUMERATE_WELL_KNOWN_SYMBOLS
|
||||||
|
#undef __JS_ENUMERATE
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ void ArrayPrototype::initialize(Interpreter& interpreter, GlobalObject& global_o
|
||||||
// Use define_property here instead of define_native_function so that
|
// Use define_property here instead of define_native_function so that
|
||||||
// Object.is(Array.prototype[Symbol.iterator], Array.prototype.values)
|
// Object.is(Array.prototype[Symbol.iterator], Array.prototype.values)
|
||||||
// evaluates to true
|
// evaluates to true
|
||||||
define_property(interpreter.get_well_known_symbol("iterator"), get("values"), attr);
|
define_property(interpreter.well_known_symbol_iterator(), get("values"), attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayPrototype::~ArrayPrototype()
|
ArrayPrototype::~ArrayPrototype()
|
||||||
|
|
|
@ -36,7 +36,7 @@ Object* get_iterator(Object& obj, String hint, Value method)
|
||||||
if (method.is_empty()) {
|
if (method.is_empty()) {
|
||||||
if (hint == "async")
|
if (hint == "async")
|
||||||
TODO();
|
TODO();
|
||||||
method = obj.get(obj.interpreter().get_well_known_symbol("iterator"));
|
method = obj.get(obj.interpreter().well_known_symbol_iterator());
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ IteratorPrototype::IteratorPrototype(GlobalObject& global_object)
|
||||||
void IteratorPrototype::initialize(Interpreter& interpreter, GlobalObject& global_object)
|
void IteratorPrototype::initialize(Interpreter& interpreter, GlobalObject& global_object)
|
||||||
{
|
{
|
||||||
Object::initialize(interpreter, global_object);
|
Object::initialize(interpreter, global_object);
|
||||||
define_native_function(interpreter.get_well_known_symbol("iterator"), symbol_iterator, 0, Attribute::Writable | Attribute::Enumerable);
|
define_native_function(interpreter.well_known_symbol_iterator(), symbol_iterator, 0, Attribute::Writable | Attribute::Enumerable);
|
||||||
}
|
}
|
||||||
|
|
||||||
IteratorPrototype::~IteratorPrototype()
|
IteratorPrototype::~IteratorPrototype()
|
||||||
|
|
|
@ -46,8 +46,10 @@ void SymbolConstructor::initialize(Interpreter& interpreter, GlobalObject& globa
|
||||||
define_native_function("for", for_, 1, Attribute::Writable | Attribute::Configurable);
|
define_native_function("for", for_, 1, Attribute::Writable | Attribute::Configurable);
|
||||||
define_native_function("keyFor", key_for, 1, Attribute::Writable | Attribute::Configurable);
|
define_native_function("keyFor", key_for, 1, Attribute::Writable | Attribute::Configurable);
|
||||||
|
|
||||||
for (auto& entry : interpreter.get_well_known_symbol_map({}))
|
#define __JS_ENUMERATE(SymbolName, snake_name) \
|
||||||
define_property(entry.key, entry.value, 0);
|
define_property(#SymbolName, interpreter.well_known_symbol_##snake_name(), 0);
|
||||||
|
JS_ENUMERATE_WELL_KNOWN_SYMBOLS
|
||||||
|
#undef __JS_ENUMERATE
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolConstructor::~SymbolConstructor()
|
SymbolConstructor::~SymbolConstructor()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue