mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 21:57:35 +00:00
LibJS: Implement import.meta for bytecode
This commit is contained in:
parent
a1692931af
commit
d29bd55b48
8 changed files with 78 additions and 49 deletions
|
@ -3492,7 +3492,6 @@ Completion MetaProperty::execute(Interpreter& interpreter) const
|
||||||
{
|
{
|
||||||
InterpreterNodeScope node_scope { interpreter, *this };
|
InterpreterNodeScope node_scope { interpreter, *this };
|
||||||
auto& vm = interpreter.vm();
|
auto& vm = interpreter.vm();
|
||||||
auto& realm = *vm.current_realm();
|
|
||||||
|
|
||||||
// NewTarget : new . target
|
// NewTarget : new . target
|
||||||
if (m_type == MetaProperty::Type::NewTarget) {
|
if (m_type == MetaProperty::Type::NewTarget) {
|
||||||
|
@ -3502,49 +3501,7 @@ Completion MetaProperty::execute(Interpreter& interpreter) const
|
||||||
|
|
||||||
// ImportMeta : import . meta
|
// ImportMeta : import . meta
|
||||||
if (m_type == MetaProperty::Type::ImportMeta) {
|
if (m_type == MetaProperty::Type::ImportMeta) {
|
||||||
// 1. Let module be GetActiveScriptOrModule().
|
return Value(vm.get_import_meta());
|
||||||
auto script_or_module = interpreter.vm().get_active_script_or_module();
|
|
||||||
|
|
||||||
// 2. Assert: module is a Source Text Module Record.
|
|
||||||
VERIFY(script_or_module.has<NonnullGCPtr<Module>>());
|
|
||||||
VERIFY(script_or_module.get<NonnullGCPtr<Module>>());
|
|
||||||
VERIFY(is<SourceTextModule>(*script_or_module.get<NonnullGCPtr<Module>>()));
|
|
||||||
auto& module = static_cast<SourceTextModule&>(*script_or_module.get<NonnullGCPtr<Module>>());
|
|
||||||
|
|
||||||
// 3. Let importMeta be module.[[ImportMeta]].
|
|
||||||
auto* import_meta = module.import_meta();
|
|
||||||
|
|
||||||
// 4. If importMeta is empty, then
|
|
||||||
if (import_meta == nullptr) {
|
|
||||||
// a. Set importMeta to OrdinaryObjectCreate(null).
|
|
||||||
import_meta = Object::create(realm, nullptr);
|
|
||||||
|
|
||||||
// b. Let importMetaValues be HostGetImportMetaProperties(module).
|
|
||||||
auto import_meta_values = interpreter.vm().host_get_import_meta_properties(module);
|
|
||||||
|
|
||||||
// c. For each Record { [[Key]], [[Value]] } p of importMetaValues, do
|
|
||||||
for (auto& entry : import_meta_values) {
|
|
||||||
// i. Perform ! CreateDataPropertyOrThrow(importMeta, p.[[Key]], p.[[Value]]).
|
|
||||||
MUST(import_meta->create_data_property_or_throw(entry.key, entry.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// d. Perform HostFinalizeImportMeta(importMeta, module).
|
|
||||||
interpreter.vm().host_finalize_import_meta(import_meta, module);
|
|
||||||
|
|
||||||
// e. Set module.[[ImportMeta]] to importMeta.
|
|
||||||
module.set_import_meta({}, import_meta);
|
|
||||||
|
|
||||||
// f. Return importMeta.
|
|
||||||
return Value { import_meta };
|
|
||||||
}
|
|
||||||
// 5. Else,
|
|
||||||
else {
|
|
||||||
// a. Assert: Type(importMeta) is Object.
|
|
||||||
// Note: This is always true by the type.
|
|
||||||
|
|
||||||
// b. Return importMeta.
|
|
||||||
return Value { import_meta };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
|
|
|
@ -2884,10 +2884,8 @@ Bytecode::CodeGenerationErrorOr<void> MetaProperty::generate_bytecode(Bytecode::
|
||||||
|
|
||||||
// ImportMeta : import . meta
|
// ImportMeta : import . meta
|
||||||
if (m_type == MetaProperty::Type::ImportMeta) {
|
if (m_type == MetaProperty::Type::ImportMeta) {
|
||||||
return Bytecode::CodeGenerationError {
|
generator.emit<Bytecode::Op::GetImportMeta>();
|
||||||
this,
|
return {};
|
||||||
"Unimplemented meta property: import.meta"sv,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
O(GetIterator) \
|
O(GetIterator) \
|
||||||
O(GetMethod) \
|
O(GetMethod) \
|
||||||
O(GetNewTarget) \
|
O(GetNewTarget) \
|
||||||
|
O(GetImportMeta) \
|
||||||
O(GetObjectPropertyIterator) \
|
O(GetObjectPropertyIterator) \
|
||||||
O(GetPrivateById) \
|
O(GetPrivateById) \
|
||||||
O(GetVariable) \
|
O(GetVariable) \
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <LibJS/Runtime/Reference.h>
|
#include <LibJS/Runtime/Reference.h>
|
||||||
#include <LibJS/Runtime/RegExpObject.h>
|
#include <LibJS/Runtime/RegExpObject.h>
|
||||||
#include <LibJS/Runtime/Value.h>
|
#include <LibJS/Runtime/Value.h>
|
||||||
|
#include <LibJS/SourceTextModule.h>
|
||||||
|
|
||||||
namespace JS::Bytecode {
|
namespace JS::Bytecode {
|
||||||
|
|
||||||
|
@ -762,6 +763,12 @@ ThrowCompletionOr<void> GetNewTarget::execute_impl(Bytecode::Interpreter& interp
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThrowCompletionOr<void> GetImportMeta::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||||
|
{
|
||||||
|
interpreter.accumulator() = interpreter.vm().get_import_meta();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void Jump::replace_references_impl(BasicBlock const& from, BasicBlock const& to)
|
void Jump::replace_references_impl(BasicBlock const& from, BasicBlock const& to)
|
||||||
{
|
{
|
||||||
if (m_true_target.has_value() && &m_true_target->block() == &from)
|
if (m_true_target.has_value() && &m_true_target->block() == &from)
|
||||||
|
@ -1896,6 +1903,11 @@ DeprecatedString GetNewTarget::to_deprecated_string_impl(Bytecode::Executable co
|
||||||
return "GetNewTarget"sv;
|
return "GetNewTarget"sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeprecatedString GetImportMeta::to_deprecated_string_impl(Bytecode::Executable const&) const
|
||||||
|
{
|
||||||
|
return "GetImportMeta"sv;
|
||||||
|
}
|
||||||
|
|
||||||
DeprecatedString TypeofVariable::to_deprecated_string_impl(Bytecode::Executable const& executable) const
|
DeprecatedString TypeofVariable::to_deprecated_string_impl(Bytecode::Executable const& executable) const
|
||||||
{
|
{
|
||||||
return DeprecatedString::formatted("TypeofVariable {} ({})", m_identifier, executable.identifier_table->get(m_identifier));
|
return DeprecatedString::formatted("TypeofVariable {} ({})", m_identifier, executable.identifier_table->get(m_identifier));
|
||||||
|
|
|
@ -1538,6 +1538,19 @@ public:
|
||||||
void replace_references_impl(Register, Register) { }
|
void replace_references_impl(Register, Register) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GetImportMeta final : public Instruction {
|
||||||
|
public:
|
||||||
|
explicit GetImportMeta()
|
||||||
|
: Instruction(Type::GetImportMeta)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
|
||||||
|
DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const;
|
||||||
|
void replace_references_impl(BasicBlock const&, BasicBlock const&) { }
|
||||||
|
void replace_references_impl(Register, Register) { }
|
||||||
|
};
|
||||||
|
|
||||||
class TypeofVariable final : public Instruction {
|
class TypeofVariable final : public Instruction {
|
||||||
public:
|
public:
|
||||||
explicit TypeofVariable(IdentifierTableIndex identifier)
|
explicit TypeofVariable(IdentifierTableIndex identifier)
|
||||||
|
|
|
@ -682,6 +682,52 @@ Value VM::get_new_target()
|
||||||
return verify_cast<FunctionEnvironment>(*env).new_target();
|
return verify_cast<FunctionEnvironment>(*env).new_target();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 13.3.12.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-meta-properties-runtime-semantics-evaluation
|
||||||
|
// ImportMeta branch only
|
||||||
|
Object* VM::get_import_meta()
|
||||||
|
{
|
||||||
|
// 1. Let module be GetActiveScriptOrModule().
|
||||||
|
auto script_or_module = get_active_script_or_module();
|
||||||
|
|
||||||
|
// 2. Assert: module is a Source Text Module Record.
|
||||||
|
auto& module = verify_cast<SourceTextModule>(*script_or_module.get<NonnullGCPtr<Module>>());
|
||||||
|
|
||||||
|
// 3. Let importMeta be module.[[ImportMeta]].
|
||||||
|
auto* import_meta = module.import_meta();
|
||||||
|
|
||||||
|
// 4. If importMeta is empty, then
|
||||||
|
if (import_meta == nullptr) {
|
||||||
|
// a. Set importMeta to OrdinaryObjectCreate(null).
|
||||||
|
import_meta = Object::create(*current_realm(), nullptr);
|
||||||
|
|
||||||
|
// b. Let importMetaValues be HostGetImportMetaProperties(module).
|
||||||
|
auto import_meta_values = host_get_import_meta_properties(module);
|
||||||
|
|
||||||
|
// c. For each Record { [[Key]], [[Value]] } p of importMetaValues, do
|
||||||
|
for (auto& entry : import_meta_values) {
|
||||||
|
// i. Perform ! CreateDataPropertyOrThrow(importMeta, p.[[Key]], p.[[Value]]).
|
||||||
|
MUST(import_meta->create_data_property_or_throw(entry.key, entry.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// d. Perform HostFinalizeImportMeta(importMeta, module).
|
||||||
|
host_finalize_import_meta(import_meta, module);
|
||||||
|
|
||||||
|
// e. Set module.[[ImportMeta]] to importMeta.
|
||||||
|
module.set_import_meta({}, import_meta);
|
||||||
|
|
||||||
|
// f. Return importMeta.
|
||||||
|
return import_meta;
|
||||||
|
}
|
||||||
|
// 5. Else,
|
||||||
|
else {
|
||||||
|
// a. Assert: Type(importMeta) is Object.
|
||||||
|
// Note: This is always true by the type.
|
||||||
|
|
||||||
|
// b. Return importMeta.
|
||||||
|
return import_meta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 9.4.5 GetGlobalObject ( ), https://tc39.es/ecma262/#sec-getglobalobject
|
// 9.4.5 GetGlobalObject ( ), https://tc39.es/ecma262/#sec-getglobalobject
|
||||||
Object& VM::get_global_object()
|
Object& VM::get_global_object()
|
||||||
{
|
{
|
||||||
|
|
|
@ -219,6 +219,8 @@ public:
|
||||||
|
|
||||||
Value get_new_target();
|
Value get_new_target();
|
||||||
|
|
||||||
|
Object* get_import_meta();
|
||||||
|
|
||||||
Object& get_global_object();
|
Object& get_global_object();
|
||||||
|
|
||||||
CommonPropertyNames names;
|
CommonPropertyNames names;
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
virtual ThrowCompletionOr<ResolvedBinding> resolve_export(VM& vm, DeprecatedFlyString const& export_name, Vector<ResolvedBinding> resolve_set = {}) override;
|
virtual ThrowCompletionOr<ResolvedBinding> resolve_export(VM& vm, DeprecatedFlyString const& export_name, Vector<ResolvedBinding> resolve_set = {}) override;
|
||||||
|
|
||||||
Object* import_meta() { return m_import_meta; }
|
Object* import_meta() { return m_import_meta; }
|
||||||
void set_import_meta(Badge<MetaProperty>, Object* import_meta) { m_import_meta = import_meta; }
|
void set_import_meta(Badge<VM>, Object* import_meta) { m_import_meta = import_meta; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ThrowCompletionOr<void> initialize_environment(VM& vm) override;
|
virtual ThrowCompletionOr<void> initialize_environment(VM& vm) override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue