1313#include < LibJS/Bytecode/Op.h>
1414#include < LibJS/Bytecode/Register.h>
1515#include < LibJS/Runtime/ECMAScriptFunctionObject.h>
16+ #include < LibJS/Runtime/NativeJavaScriptBackedFunction.h>
1617#include < LibJS/Runtime/VM.h>
1718
1819namespace JS ::Bytecode {
1920
20- Generator::Generator (VM& vm, GC::Ptr<SharedFunctionInstanceData const > shared_function_instance_data, MustPropagateCompletion must_propagate_completion)
21+ Generator::Generator (VM& vm, GC::Ptr<SharedFunctionInstanceData const > shared_function_instance_data, MustPropagateCompletion must_propagate_completion, BuiltinAbstractOperationsEnabled builtin_abstract_operations_enabled )
2122 : m_vm(vm)
2223 , m_string_table(make<StringTable>())
2324 , m_identifier_table(make<IdentifierTable>())
@@ -26,6 +27,7 @@ Generator::Generator(VM& vm, GC::Ptr<SharedFunctionInstanceData const> shared_fu
2627 , m_accumulator(*this , Operand(Register::accumulator()))
2728 , m_this_value(*this , Operand(Register::this_value()))
2829 , m_must_propagate_completion(must_propagate_completion == MustPropagateCompletion::Yes)
30+ , m_builtin_abstract_operations_enabled(builtin_abstract_operations_enabled == BuiltinAbstractOperationsEnabled::Yes)
2931 , m_shared_function_instance_data(shared_function_instance_data)
3032{
3133}
@@ -215,9 +217,9 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(S
215217 return {};
216218}
217219
218- CodeGenerationErrorOr<GC::Ref<Executable>> Generator::compile (VM& vm, ASTNode const & node, FunctionKind enclosing_function_kind, GC::Ptr<SharedFunctionInstanceData const > shared_function_instance_data, MustPropagateCompletion must_propagate_completion, Vector<LocalVariable> local_variable_names)
220+ CodeGenerationErrorOr<GC::Ref<Executable>> Generator::compile (VM& vm, ASTNode const & node, FunctionKind enclosing_function_kind, GC::Ptr<SharedFunctionInstanceData const > shared_function_instance_data, MustPropagateCompletion must_propagate_completion, BuiltinAbstractOperationsEnabled builtin_abstract_operations_enabled, Vector<LocalVariable> local_variable_names)
219221{
220- Generator generator (vm, shared_function_instance_data, must_propagate_completion);
222+ Generator generator (vm, shared_function_instance_data, must_propagate_completion, builtin_abstract_operations_enabled );
221223
222224 if (is<Program>(node))
223225 generator.m_strict = static_cast <Program const &>(node).is_strict_mode () ? Strict::Yes : Strict::No;
@@ -498,12 +500,12 @@ CodeGenerationErrorOr<GC::Ref<Executable>> Generator::generate_from_ast_node(VM&
498500 Vector<LocalVariable> local_variable_names;
499501 if (is<ScopeNode>(node))
500502 local_variable_names = static_cast <ScopeNode const &>(node).local_variables_names ();
501- return compile (vm, node, enclosing_function_kind, {}, MustPropagateCompletion::Yes, move (local_variable_names));
503+ return compile (vm, node, enclosing_function_kind, {}, MustPropagateCompletion::Yes, BuiltinAbstractOperationsEnabled::No, move (local_variable_names));
502504}
503505
504- CodeGenerationErrorOr<GC::Ref<Executable>> Generator::generate_from_function (VM& vm, GC::Ref<SharedFunctionInstanceData const > shared_function_instance_data)
506+ CodeGenerationErrorOr<GC::Ref<Executable>> Generator::generate_from_function (VM& vm, GC::Ref<SharedFunctionInstanceData const > shared_function_instance_data, BuiltinAbstractOperationsEnabled builtin_abstract_operations_enabled )
505507{
506- return compile (vm, *shared_function_instance_data->m_ecmascript_code , shared_function_instance_data->m_kind , shared_function_instance_data, MustPropagateCompletion::No, shared_function_instance_data->m_local_variables_names );
508+ return compile (vm, *shared_function_instance_data->m_ecmascript_code , shared_function_instance_data->m_kind , shared_function_instance_data, MustPropagateCompletion::No, builtin_abstract_operations_enabled, shared_function_instance_data->m_local_variables_names );
507509}
508510
509511void Generator::grow (size_t additional_size)
@@ -1470,4 +1472,43 @@ ScopedOperand Generator::add_constant(Value value)
14701472 return append_new_constant ();
14711473}
14721474
1475+ CodeGenerationErrorOr<void > Generator::generate_builtin_abstract_operation (Identifier const & builtin_identifier, ReadonlySpan<CallExpression::Argument> arguments, ScopedOperand const &)
1476+ {
1477+ VERIFY (m_builtin_abstract_operations_enabled);
1478+ for (auto const & argument : arguments) {
1479+ if (argument.is_spread ) {
1480+ return CodeGenerationError {
1481+ argument.value .ptr (),
1482+ " Spread arguments not allowed for builtin abstract operations" sv,
1483+ };
1484+ }
1485+ }
1486+
1487+ auto const & operation_name = builtin_identifier.string ();
1488+
1489+ dbgln (" Unknown builtin abstract operation: '{}'" , operation_name);
1490+ return CodeGenerationError {
1491+ &builtin_identifier,
1492+ " Unknown builtin abstract operation" sv,
1493+ };
1494+ }
1495+
1496+ CodeGenerationErrorOr<Optional<ScopedOperand>> Generator::maybe_generate_builtin_constant (Identifier const & builtin_identifier)
1497+ {
1498+ auto const & constant_name = builtin_identifier.string ();
1499+
1500+ if (constant_name == " undefined" sv) {
1501+ return add_constant (js_undefined ());
1502+ }
1503+
1504+ if (!m_builtin_abstract_operations_enabled)
1505+ return OptionalNone {};
1506+
1507+ dbgln (" Unknown builtin constant: '{}'" , constant_name);
1508+ return CodeGenerationError {
1509+ &builtin_identifier,
1510+ " Unknown builtin constant" sv,
1511+ };
1512+ }
1513+
14731514}
0 commit comments