Module.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 <LibJS/Heap/Handle.h>
  9. #include <LibJS/Runtime/Realm.h>
  10. namespace JS {
  11. struct ResolvedBinding {
  12. enum Type {
  13. BindingName,
  14. Namespace,
  15. Ambiguous,
  16. Null,
  17. };
  18. static ResolvedBinding null()
  19. {
  20. return {};
  21. }
  22. static ResolvedBinding ambiguous()
  23. {
  24. ResolvedBinding binding;
  25. binding.type = Ambiguous;
  26. return binding;
  27. }
  28. Type type { Null };
  29. Module* module { nullptr };
  30. FlyString export_name;
  31. bool is_valid() const
  32. {
  33. return type == BindingName || type == Namespace;
  34. }
  35. bool is_namespace() const
  36. {
  37. return type == Namespace;
  38. }
  39. bool is_ambiguous() const
  40. {
  41. return type == Ambiguous;
  42. }
  43. };
  44. // 16.2.1.4 Abstract Module Records, https://tc39.es/ecma262/#sec-abstract-module-records
  45. class Module : public RefCounted<Module> {
  46. public:
  47. virtual ~Module();
  48. Realm& realm() { return *m_realm.cell(); }
  49. Realm const& realm() const { return *m_realm.cell(); }
  50. StringView filename() const { return m_filename; }
  51. Environment* environment() { return m_environment.cell(); }
  52. ThrowCompletionOr<Object*> get_module_namespace(VM& vm);
  53. virtual ThrowCompletionOr<void> link(VM& vm) = 0;
  54. virtual ThrowCompletionOr<Promise*> evaluate(VM& vm) = 0;
  55. virtual ThrowCompletionOr<Vector<FlyString>> get_exported_names(VM& vm, Vector<Module*> export_star_set = {}) = 0;
  56. virtual ThrowCompletionOr<ResolvedBinding> resolve_export(VM& vm, FlyString const& export_name, Vector<ResolvedBinding> resolve_set = {}) = 0;
  57. virtual ThrowCompletionOr<u32> inner_module_linking(VM& vm, Vector<Module*>& stack, u32 index);
  58. virtual ThrowCompletionOr<u32> inner_module_evaluation(VM& vm, Vector<Module*>& stack, u32 index);
  59. protected:
  60. Module(Realm&, String filename);
  61. void set_environment(Environment* environment)
  62. {
  63. m_environment = make_handle(environment);
  64. }
  65. private:
  66. Object* module_namespace_create(VM& vm, Vector<FlyString> unambiguous_names);
  67. // These handles are only safe as long as the VM they live in is valid.
  68. // But evaluated modules SHOULD be stored in the VM so unless you intentionally
  69. // destroy the VM but keep the modules this should not happen. Because VM
  70. // stores modules with a RefPtr we cannot just store the VM as that leads to
  71. // cycles.
  72. Handle<Realm> m_realm; // [[Realm]]
  73. Handle<Environment> m_environment; // [[Environment]]
  74. Handle<Object> m_namespace; // [[Namespace]]
  75. // Needed for potential lookups of modules.
  76. String m_filename;
  77. };
  78. }