Module.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2022, David Tuin <davidot@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/DeprecatedFlyString.h>
  9. #include <LibJS/Heap/GCPtr.h>
  10. #include <LibJS/Runtime/Environment.h>
  11. #include <LibJS/Runtime/Realm.h>
  12. #include <LibJS/Script.h>
  13. namespace JS {
  14. struct ResolvedBinding {
  15. enum Type {
  16. BindingName,
  17. Namespace,
  18. Ambiguous,
  19. Null,
  20. };
  21. static ResolvedBinding null()
  22. {
  23. return {};
  24. }
  25. static ResolvedBinding ambiguous()
  26. {
  27. ResolvedBinding binding;
  28. binding.type = Ambiguous;
  29. return binding;
  30. }
  31. Type type { Null };
  32. GCPtr<Module> module;
  33. DeprecatedFlyString export_name;
  34. bool is_valid() const
  35. {
  36. return type == BindingName || type == Namespace;
  37. }
  38. bool is_namespace() const
  39. {
  40. return type == Namespace;
  41. }
  42. bool is_ambiguous() const
  43. {
  44. return type == Ambiguous;
  45. }
  46. };
  47. // 16.2.1.4 Abstract Module Records, https://tc39.es/ecma262/#sec-abstract-module-records
  48. class Module : public Cell {
  49. JS_CELL(Module, Cell);
  50. public:
  51. virtual ~Module() override;
  52. Realm& realm() { return *m_realm; }
  53. Realm const& realm() const { return *m_realm; }
  54. StringView filename() const { return m_filename; }
  55. Environment* environment() { return m_environment; }
  56. Script::HostDefined* host_defined() const { return m_host_defined; }
  57. ThrowCompletionOr<Object*> get_module_namespace(VM& vm);
  58. virtual ThrowCompletionOr<void> link(VM& vm) = 0;
  59. virtual ThrowCompletionOr<Promise*> evaluate(VM& vm) = 0;
  60. virtual ThrowCompletionOr<Vector<DeprecatedFlyString>> get_exported_names(VM& vm, Vector<Module*> export_star_set = {}) = 0;
  61. virtual ThrowCompletionOr<ResolvedBinding> resolve_export(VM& vm, DeprecatedFlyString const& export_name, Vector<ResolvedBinding> resolve_set = {}) = 0;
  62. virtual ThrowCompletionOr<u32> inner_module_linking(VM& vm, Vector<Module*>& stack, u32 index);
  63. virtual ThrowCompletionOr<u32> inner_module_evaluation(VM& vm, Vector<Module*>& stack, u32 index);
  64. protected:
  65. Module(Realm&, DeprecatedString filename, Script::HostDefined* host_defined = nullptr);
  66. virtual void visit_edges(Cell::Visitor&) override;
  67. void set_environment(Environment* environment)
  68. {
  69. m_environment = environment;
  70. }
  71. private:
  72. Object* module_namespace_create(VM& vm, Vector<DeprecatedFlyString> unambiguous_names);
  73. // These handles are only safe as long as the VM they live in is valid.
  74. // But evaluated modules SHOULD be stored in the VM so unless you intentionally
  75. // destroy the VM but keep the modules this should not happen. Because VM
  76. // stores modules with a RefPtr we cannot just store the VM as that leads to
  77. // cycles.
  78. GCPtr<Realm> m_realm; // [[Realm]]
  79. GCPtr<Environment> m_environment; // [[Environment]]
  80. GCPtr<Object> m_namespace; // [[Namespace]]
  81. Script::HostDefined* m_host_defined { nullptr }; // [[HostDefined]]
  82. // Needed for potential lookups of modules.
  83. DeprecatedString m_filename;
  84. };
  85. }