Module.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. #include <LibJS/CyclicModule.h>
  8. #include <LibJS/Module.h>
  9. #include <LibJS/Runtime/ModuleNamespaceObject.h>
  10. namespace JS {
  11. Module::Module(Realm& realm, String filename)
  12. : m_realm(make_handle(&realm))
  13. , m_filename(move(filename))
  14. {
  15. }
  16. Module::~Module()
  17. {
  18. }
  19. // 16.2.1.5.1.1 InnerModuleLinking ( module, stack, index ), https://tc39.es/ecma262/#sec-InnerModuleLinking
  20. ThrowCompletionOr<u32> Module::inner_module_linking(VM& vm, Vector<Module*>&, u32 index)
  21. {
  22. // Note: Until we have something extending module which is not SourceTextModule we crash.
  23. VERIFY_NOT_REACHED();
  24. // 1. If module is not a Cyclic Module Record, then
  25. // a. Perform ? module.Link().
  26. TRY(link(vm));
  27. // b. Return index.
  28. return index;
  29. }
  30. // 16.2.1.5.2.1 InnerModuleEvaluation ( module, stack, index ), https://tc39.es/ecma262/#sec-innermoduleevaluation
  31. ThrowCompletionOr<u32> Module::inner_module_evaluation(VM& vm, Vector<Module*>&, u32 index)
  32. {
  33. // Note: Until we have something extending module which is not SourceTextModule we crash.
  34. VERIFY_NOT_REACHED();
  35. // 1. If module is not a Cyclic Module Record, then
  36. // a. Let promise be ! module.Evaluate().
  37. auto* promise = TRY(evaluate(vm));
  38. // b. Assert: promise.[[PromiseState]] is not pending.
  39. VERIFY(promise->state() != Promise::State::Pending);
  40. // c. If promise.[[PromiseState]] is rejected, then
  41. if (promise->state() == Promise::State::Rejected) {
  42. // i. Return ThrowCompletion(promise.[[PromiseResult]]).
  43. return throw_completion(promise->result());
  44. }
  45. // d. Return index.
  46. return index;
  47. }
  48. // 16.2.1.10 GetModuleNamespace ( module ), https://tc39.es/ecma262/#sec-getmodulenamespace
  49. ThrowCompletionOr<Object*> Module::get_module_namespace(VM& vm)
  50. {
  51. // 1. Assert: If module is a Cyclic Module Record, then module.[[Status]] is not unlinked.
  52. // FIXME: How do we check this without breaking encapsulation?
  53. // 2. Let namespace be module.[[Namespace]].
  54. auto* namespace_ = m_namespace.is_null() ? nullptr : m_namespace.cell();
  55. // 3. If namespace is empty, then
  56. if (!namespace_) {
  57. // a. Let exportedNames be ? module.GetExportedNames().
  58. auto exported_names = TRY(get_exported_names(vm));
  59. // b. Let unambiguousNames be a new empty List.
  60. Vector<FlyString> unambiguous_names;
  61. // c. For each element name of exportedNames, do
  62. for (auto& name : exported_names) {
  63. // i. Let resolution be ? module.ResolveExport(name).
  64. auto resolution = TRY(resolve_export(vm, name));
  65. // ii. If resolution is a ResolvedBinding Record, append name to unambiguousNames.
  66. if (resolution.is_valid())
  67. unambiguous_names.append(name);
  68. }
  69. // d. Set namespace to ModuleNamespaceCreate(module, unambiguousNames).
  70. namespace_ = module_namespace_create(vm, unambiguous_names);
  71. VERIFY(!m_namespace.is_null());
  72. // Note: This set the local variable 'namespace' and not the member variable which is done by ModuleNamespaceCreate
  73. }
  74. // 4. Return namespace.
  75. return namespace_;
  76. }
  77. // 10.4.6.12 ModuleNamespaceCreate ( module, exports ), https://tc39.es/ecma262/#sec-modulenamespacecreate
  78. Object* Module::module_namespace_create(VM& vm, Vector<FlyString> unambiguous_names)
  79. {
  80. // 1. Assert: module.[[Namespace]] is empty.
  81. VERIFY(m_namespace.is_null());
  82. // 2. Let internalSlotsList be the internal slots listed in Table 34.
  83. // 3. Let M be ! MakeBasicObject(internalSlotsList).
  84. // 4. Set M's essential internal methods to the definitions specified in 10.4.6.
  85. // 5. Set M.[[Module]] to module.
  86. // 6. Let sortedExports be a List whose elements are the elements of exports ordered as if an Array of the same values had been sorted using %Array.prototype.sort% using undefined as comparefn.
  87. // 7. Set M.[[Exports]] to sortedExports.
  88. // 8. Create own properties of M corresponding to the definitions in 28.3.
  89. Object* module_namespace = vm.heap().allocate<ModuleNamespaceObject>(realm().global_object(), realm().global_object(), this, move(unambiguous_names));
  90. // 9. Set module.[[Namespace]] to M.
  91. m_namespace = make_handle(module_namespace);
  92. // 10. Return M.
  93. return module_namespace;
  94. }
  95. }