mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 00:57:36 +00:00
LibJS: Move global symbol map from SymbolObject to Interpreter
This allows different instances of the Interpreter to have their own global symbols. Also makes Symbol non-copyable and non-moveable.
This commit is contained in:
parent
4d8683b632
commit
d9db6bec42
6 changed files with 48 additions and 115 deletions
|
@ -48,6 +48,19 @@ 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));
|
||||||
|
m_well_known_symbol_map.set("asyncIterator", js_symbol(*this, "Symbol.asyncIterator", false));
|
||||||
|
m_well_known_symbol_map.set("match", js_symbol(*this, "Symbol.match", false));
|
||||||
|
m_well_known_symbol_map.set("matchAll", js_symbol(*this, "Symbol.matchAll", false));
|
||||||
|
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()
|
||||||
|
@ -201,6 +214,23 @@ Reference Interpreter::get_reference(const FlyString& name)
|
||||||
return { Reference::GlobalVariable, name };
|
return { Reference::GlobalVariable, name };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Symbol* Interpreter::get_global_symbol(const String& description)
|
||||||
|
{
|
||||||
|
auto result = m_global_symbol_map.get(description);
|
||||||
|
if (result.has_value())
|
||||||
|
return result.value();
|
||||||
|
|
||||||
|
auto new_global_symbol = js_symbol(*this, description, true);
|
||||||
|
m_global_symbol_map.set(description, 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);
|
||||||
|
@ -219,7 +249,11 @@ void Interpreter::gather_roots(Badge<Heap>, HashTable<Cell*>& roots)
|
||||||
roots.set(call_frame.environment);
|
roots.set(call_frame.environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolObject::gather_symbol_roots(roots);
|
for (auto& symbol : m_well_known_symbol_map)
|
||||||
|
roots.set(symbol.value);
|
||||||
|
|
||||||
|
for (auto& symbol : m_global_symbol_map)
|
||||||
|
roots.set(symbol.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value Interpreter::call(Function& function, Value this_value, Optional<MarkedValueList> arguments)
|
Value Interpreter::call(Function& function, Value this_value, Optional<MarkedValueList> arguments)
|
||||||
|
|
|
@ -111,6 +111,10 @@ public:
|
||||||
|
|
||||||
Reference get_reference(const FlyString& name);
|
Reference get_reference(const FlyString& name);
|
||||||
|
|
||||||
|
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*>&);
|
||||||
|
|
||||||
void enter_scope(const ScopeNode&, ArgumentVector, ScopeType, GlobalObject&);
|
void enter_scope(const ScopeNode&, ArgumentVector, ScopeType, GlobalObject&);
|
||||||
|
@ -217,6 +221,9 @@ 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 };
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
class Symbol final : public Cell {
|
class Symbol final : public Cell {
|
||||||
|
AK_MAKE_NONCOPYABLE(Symbol)
|
||||||
|
AK_MAKE_NONMOVABLE(Symbol)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Symbol(String, bool);
|
Symbol(String, bool);
|
||||||
virtual ~Symbol();
|
virtual ~Symbol();
|
||||||
|
|
|
@ -46,21 +46,8 @@ 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);
|
||||||
|
|
||||||
SymbolObject::initialize_well_known_symbols(interpreter);
|
for (auto& entry : interpreter.get_well_known_symbol_map({}))
|
||||||
|
define_property(entry.key, entry.value, 0);
|
||||||
define_property("iterator", SymbolObject::well_known_iterator(), 0);
|
|
||||||
define_property("asyncIterator", SymbolObject::well_known_async_terator(), 0);
|
|
||||||
define_property("match", SymbolObject::well_known_match(), 0);
|
|
||||||
define_property("matchAll", SymbolObject::well_known_match_all(), 0);
|
|
||||||
define_property("replace", SymbolObject::well_known_replace(), 0);
|
|
||||||
define_property("search", SymbolObject::well_known_search(), 0);
|
|
||||||
define_property("split", SymbolObject::well_known_split(), 0);
|
|
||||||
define_property("hasInstance", SymbolObject::well_known_has_instance(), 0);
|
|
||||||
define_property("isConcatSpreadable", SymbolObject::well_known_is_concat_spreadable(), 0);
|
|
||||||
define_property("unscopables", SymbolObject::well_known_unscopables(), 0);
|
|
||||||
define_property("species", SymbolObject::well_known_species(), 0);
|
|
||||||
define_property("toPrimitive", SymbolObject::well_known_to_primtive(), 0);
|
|
||||||
define_property("toStringTag", SymbolObject::well_known_to_string_tag(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolConstructor::~SymbolConstructor()
|
SymbolConstructor::~SymbolConstructor()
|
||||||
|
@ -89,7 +76,7 @@ JS_DEFINE_NATIVE_FUNCTION(SymbolConstructor::for_)
|
||||||
description = interpreter.argument(0).to_string(interpreter);
|
description = interpreter.argument(0).to_string(interpreter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SymbolObject::get_global(interpreter, description);
|
return interpreter.get_global_symbol(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_NATIVE_FUNCTION(SymbolConstructor::key_for)
|
JS_DEFINE_NATIVE_FUNCTION(SymbolConstructor::key_for)
|
||||||
|
|
|
@ -34,21 +34,6 @@
|
||||||
|
|
||||||
namespace JS {
|
namespace JS {
|
||||||
|
|
||||||
HashMap<String, Value> SymbolObject::s_global_symbol_map;
|
|
||||||
|
|
||||||
Value SymbolObject::s_well_known_iterator;
|
|
||||||
Value SymbolObject::s_well_known_async_terator;
|
|
||||||
Value SymbolObject::s_well_known_match;
|
|
||||||
Value SymbolObject::s_well_known_match_all;
|
|
||||||
Value SymbolObject::s_well_known_replace;
|
|
||||||
Value SymbolObject::s_well_known_search;
|
|
||||||
Value SymbolObject::s_well_known_split;
|
|
||||||
Value SymbolObject::s_well_known_has_instance;
|
|
||||||
Value SymbolObject::s_well_known_is_concat_spreadable;
|
|
||||||
Value SymbolObject::s_well_known_unscopables;
|
|
||||||
Value SymbolObject::s_well_known_species;
|
|
||||||
Value SymbolObject::s_well_known_to_primtive;
|
|
||||||
Value SymbolObject::s_well_known_to_string_tag;
|
|
||||||
|
|
||||||
SymbolObject* SymbolObject::create(GlobalObject& global_object, Symbol& primitive_symbol)
|
SymbolObject* SymbolObject::create(GlobalObject& global_object, Symbol& primitive_symbol)
|
||||||
{
|
{
|
||||||
|
@ -65,54 +50,6 @@ SymbolObject::~SymbolObject()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Value SymbolObject::get_global(Interpreter& interpreter, String description)
|
|
||||||
{
|
|
||||||
auto global_symbol = s_global_symbol_map.get(description);
|
|
||||||
if (global_symbol.has_value())
|
|
||||||
return global_symbol.value();
|
|
||||||
|
|
||||||
auto symbol = js_symbol(interpreter, description, true);
|
|
||||||
s_global_symbol_map.set(description, symbol);
|
|
||||||
return Value(symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SymbolObject::initialize_well_known_symbols(Interpreter& interpreter)
|
|
||||||
{
|
|
||||||
SymbolObject::s_well_known_iterator = Value(js_symbol(interpreter, "Symbol.iterator", false));
|
|
||||||
SymbolObject::s_well_known_async_terator = Value(js_symbol(interpreter, "Symbol.asyncIterator", false));
|
|
||||||
SymbolObject::s_well_known_match = Value(js_symbol(interpreter, "Symbol.match", false));
|
|
||||||
SymbolObject::s_well_known_match_all = Value(js_symbol(interpreter, "Symbol.matchAll", false));
|
|
||||||
SymbolObject::s_well_known_replace = Value(js_symbol(interpreter, "Symbol.replace", false));
|
|
||||||
SymbolObject::s_well_known_search = Value(js_symbol(interpreter, "Symbol.search", false));
|
|
||||||
SymbolObject::s_well_known_split = Value(js_symbol(interpreter, "Symbol.split", false));
|
|
||||||
SymbolObject::s_well_known_has_instance = Value(js_symbol(interpreter, "Symbol.hasInstance", false));
|
|
||||||
SymbolObject::s_well_known_is_concat_spreadable = Value(js_symbol(interpreter, "Symbol.isConcatSpreadable", false));
|
|
||||||
SymbolObject::s_well_known_unscopables = Value(js_symbol(interpreter, "Symbol.unscopables", false));
|
|
||||||
SymbolObject::s_well_known_species = Value(js_symbol(interpreter, "Symbol.species", false));
|
|
||||||
SymbolObject::s_well_known_to_primtive = Value(js_symbol(interpreter, "Symbol.toPrimitive", false));
|
|
||||||
SymbolObject::s_well_known_to_string_tag = Value(js_symbol(interpreter, "Symbol.toStringTag", false));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SymbolObject::gather_symbol_roots(HashTable<Cell*>& roots)
|
|
||||||
{
|
|
||||||
for (auto& global_symbol : s_global_symbol_map)
|
|
||||||
roots.set(&global_symbol.value.as_symbol());
|
|
||||||
|
|
||||||
roots.set(&s_well_known_iterator.as_symbol());
|
|
||||||
roots.set(&s_well_known_async_terator.as_symbol());
|
|
||||||
roots.set(&s_well_known_match.as_symbol());
|
|
||||||
roots.set(&s_well_known_match_all.as_symbol());
|
|
||||||
roots.set(&s_well_known_replace.as_symbol());
|
|
||||||
roots.set(&s_well_known_search.as_symbol());
|
|
||||||
roots.set(&s_well_known_split.as_symbol());
|
|
||||||
roots.set(&s_well_known_has_instance.as_symbol());
|
|
||||||
roots.set(&s_well_known_is_concat_spreadable.as_symbol());
|
|
||||||
roots.set(&s_well_known_unscopables.as_symbol());
|
|
||||||
roots.set(&s_well_known_species.as_symbol());
|
|
||||||
roots.set(&s_well_known_to_primtive.as_symbol());
|
|
||||||
roots.set(&s_well_known_to_string_tag.as_symbol());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SymbolObject::visit_children(Cell::Visitor& visitor)
|
void SymbolObject::visit_children(Cell::Visitor& visitor)
|
||||||
{
|
{
|
||||||
Object::visit_children(visitor);
|
Object::visit_children(visitor);
|
||||||
|
|
|
@ -46,51 +46,16 @@ public:
|
||||||
const String& description() const { return m_symbol.description(); }
|
const String& description() const { return m_symbol.description(); }
|
||||||
bool is_global() const { return m_symbol.is_global(); }
|
bool is_global() const { return m_symbol.is_global(); }
|
||||||
|
|
||||||
static Value get_global(Interpreter&, String description);
|
|
||||||
|
|
||||||
virtual Value value_of() const override
|
virtual Value value_of() const override
|
||||||
{
|
{
|
||||||
return Value(&m_symbol);
|
return Value(&m_symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initialize_well_known_symbols(Interpreter&);
|
|
||||||
static void gather_symbol_roots(HashTable<Cell*>& roots);
|
|
||||||
|
|
||||||
static Value well_known_iterator() { return s_well_known_iterator; };
|
|
||||||
static Value well_known_async_terator() { return s_well_known_async_terator; };
|
|
||||||
static Value well_known_match() { return s_well_known_match; };
|
|
||||||
static Value well_known_match_all() { return s_well_known_match_all; };
|
|
||||||
static Value well_known_replace() { return s_well_known_replace; };
|
|
||||||
static Value well_known_search() { return s_well_known_search; };
|
|
||||||
static Value well_known_split() { return s_well_known_split; };
|
|
||||||
static Value well_known_has_instance() { return s_well_known_has_instance; };
|
|
||||||
static Value well_known_is_concat_spreadable() { return s_well_known_is_concat_spreadable; };
|
|
||||||
static Value well_known_unscopables() { return s_well_known_unscopables; };
|
|
||||||
static Value well_known_species() { return s_well_known_species; };
|
|
||||||
static Value well_known_to_primtive() { return s_well_known_to_primtive; };
|
|
||||||
static Value well_known_to_string_tag() { return s_well_known_to_string_tag; };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void visit_children(Visitor&) override;
|
virtual void visit_children(Visitor&) override;
|
||||||
virtual bool is_symbol_object() const override { return true; }
|
virtual bool is_symbol_object() const override { return true; }
|
||||||
|
|
||||||
Symbol& m_symbol;
|
Symbol& m_symbol;
|
||||||
|
|
||||||
static HashMap<String, Value> s_global_symbol_map;
|
|
||||||
|
|
||||||
static Value s_well_known_iterator;
|
|
||||||
static Value s_well_known_async_terator;
|
|
||||||
static Value s_well_known_match;
|
|
||||||
static Value s_well_known_match_all;
|
|
||||||
static Value s_well_known_replace;
|
|
||||||
static Value s_well_known_search;
|
|
||||||
static Value s_well_known_split;
|
|
||||||
static Value s_well_known_has_instance;
|
|
||||||
static Value s_well_known_is_concat_spreadable;
|
|
||||||
static Value s_well_known_unscopables;
|
|
||||||
static Value s_well_known_species;
|
|
||||||
static Value s_well_known_to_primtive;
|
|
||||||
static Value s_well_known_to_string_tag;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue