/* * Copyright (c) 2021, Andreas Kling * Copyright (c) 2022, David Tuin * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace JS { struct ResolvedBinding { enum Type { BindingName, Namespace, Ambiguous, Null, }; static ResolvedBinding null() { return {}; } static ResolvedBinding ambiguous() { ResolvedBinding binding; binding.type = Ambiguous; return binding; } Type type { Null }; Module* module { nullptr }; FlyString export_name; bool is_valid() const { return type == BindingName || type == Namespace; } bool is_namespace() const { return type == Namespace; } bool is_ambiguous() const { return type == Ambiguous; } }; // 16.2.1.4 Abstract Module Records, https://tc39.es/ecma262/#sec-abstract-module-records class Module : public RefCounted , public Weakable { public: virtual ~Module() = default; Realm& realm() { return *m_realm.cell(); } Realm const& realm() const { return *m_realm.cell(); } StringView filename() const { return m_filename; } Environment* environment() { return m_environment.cell(); } ThrowCompletionOr get_module_namespace(VM& vm); virtual ThrowCompletionOr link(VM& vm) = 0; virtual ThrowCompletionOr evaluate(VM& vm) = 0; virtual ThrowCompletionOr> get_exported_names(VM& vm, Vector export_star_set = {}) = 0; virtual ThrowCompletionOr resolve_export(VM& vm, FlyString const& export_name, Vector resolve_set = {}) = 0; virtual ThrowCompletionOr inner_module_linking(VM& vm, Vector& stack, u32 index); virtual ThrowCompletionOr inner_module_evaluation(VM& vm, Vector& stack, u32 index); protected: Module(Realm&, String filename); void set_environment(Environment* environment) { m_environment = make_handle(environment); } private: Object* module_namespace_create(VM& vm, Vector unambiguous_names); // These handles are only safe as long as the VM they live in is valid. // But evaluated modules SHOULD be stored in the VM so unless you intentionally // destroy the VM but keep the modules this should not happen. Because VM // stores modules with a RefPtr we cannot just store the VM as that leads to // cycles. Handle m_realm; // [[Realm]] Handle m_environment; // [[Environment]] Handle m_namespace; // [[Namespace]] // Needed for potential lookups of modules. String m_filename; }; }