1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:57:35 +00:00

LibJS/Bytecode: Add codegen for ImportCall

Also moved most of the AST ImportCall::execute() into a helper so we can
share the code.
This commit is contained in:
Andreas Kling 2023-06-24 15:22:16 +02:00
parent eb9298b54e
commit 8a5e71256d
8 changed files with 160 additions and 89 deletions

View file

@ -2725,4 +2725,22 @@ Bytecode::CodeGenerationErrorOr<void> OptionalChain::generate_bytecode(Bytecode:
return generate_optional_chain(generator, *this, current_value_register, current_base_register);
}
Bytecode::CodeGenerationErrorOr<void> ImportCall::generate_bytecode(Bytecode::Generator& generator) const
{
TRY(m_specifier->generate_bytecode(generator));
auto specifier_reg = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(specifier_reg);
if (m_options) {
TRY(m_options->generate_bytecode(generator));
} else {
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
}
auto options_reg = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(options_reg);
generator.emit<Bytecode::Op::ImportCall>(specifier_reg, options_reg);
return {};
}
}

View file

@ -42,6 +42,7 @@
O(GetVariable) \
O(GreaterThan) \
O(GreaterThanEquals) \
O(ImportCall) \
O(In) \
O(Increment) \
O(InstanceOf) \

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
*
@ -244,6 +244,23 @@ ThrowCompletionOr<void> Append::execute_impl(Bytecode::Interpreter& interpreter)
return {};
}
ThrowCompletionOr<void> ImportCall::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto& vm = interpreter.vm();
auto specifier = interpreter.reg(m_specifier);
auto options_value = interpreter.reg(m_options);
interpreter.accumulator() = TRY(perform_import_call(vm, specifier, options_value));
return {};
}
void ImportCall::replace_references_impl(Register from, Register to)
{
if (m_specifier == from)
m_specifier = to;
if (m_options == from)
m_options = to;
}
// FIXME: Since the accumulator is a Value, we store an object there and have to convert back and forth between that an Iterator records. Not great.
// Make sure to put this into the accumulator before the iterator object disappears from the stack to prevent the members from being GC'd.
static Object* iterator_to_object(VM& vm, Iterator iterator)
@ -1552,4 +1569,9 @@ DeprecatedString BlockDeclarationInstantiation::to_deprecated_string_impl(Byteco
return "BlockDeclarationInstantiation"sv;
}
DeprecatedString ImportCall::to_deprecated_string_impl(Bytecode::Executable const&) const
{
return DeprecatedString::formatted("ImportCall specifier:{} options:{}"sv, m_specifier, m_options);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
*
@ -351,6 +351,25 @@ private:
bool m_is_spread = false;
};
class ImportCall final : public Instruction {
public:
ImportCall(Register specifier, Register options)
: Instruction(Type::ImportCall)
, m_specifier(specifier)
, m_options(options)
{
}
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);
private:
Register m_specifier;
Register m_options;
};
class IteratorToArray final : public Instruction {
public:
IteratorToArray()