current commit
261004.7 · deps: update V8 to 15.2.124.38
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_MODULE_INL_H_
#define V8_OBJECTS_MODULE_INL_H_

#include "src/objects/module.h"
// Include the non-inl header before the rest of the headers.

#include "src/objects/js-promise-inl.h"
#include "src/objects/oddball-predicates-inl.h"
#include "src/objects/scope-info.h"
#include "src/objects/source-text-module.h"
#include "src/objects/string-inl.h"
#include "src/objects/synthetic-module.h"
#include "src/objects/tagged-field-inl.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

Tagged<Object> ScriptOrModule::resource_name() const {
  return resource_name_.load();
}
void ScriptOrModule::set_resource_name(Tagged<Object> value,
                                       WriteBarrierMode mode) {
  resource_name_.store(this, value, mode);
}

Tagged<FixedArray> ScriptOrModule::host_defined_options() const {
  return host_defined_options_.load();
}
void ScriptOrModule::set_host_defined_options(Tagged<FixedArray> value,
                                              WriteBarrierMode mode) {
  host_defined_options_.store(this, value, mode);
}

BOOL_ACCESSORS(SourceTextModule, flags, has_toplevel_await,
               HasToplevelAwaitBit::kShift)
BIT_FIELD_ACCESSORS(SourceTextModule, flags, async_evaluation_ordinal,
                    SourceTextModule::AsyncEvaluationOrdinalBits)

BIT_FIELD_ACCESSORS(ModuleRequest, flags, position, ModuleRequest::PositionBits)

inline void ModuleRequest::set_phase(ModuleImportPhase phase) {
  DCHECK(PhaseBits::is_valid(phase));
  uint32_t hints = flags();
  hints = PhaseBits::update(hints, phase);
  set_flags(hints);
}

inline ModuleImportPhase ModuleRequest::phase() const {
  ModuleImportPhase value = PhaseBits::decode(flags());
  DCHECK(value == ModuleImportPhase::kDefer ||
         value == ModuleImportPhase::kEvaluation ||
         value == ModuleImportPhase::kSource);
  return static_cast<ModuleImportPhase>(value);
}

struct Module::Hash {
  V8_INLINE size_t operator()(Tagged<Module> module) const {
    return module->hash();
  }
};

Tagged<SourceTextModuleInfo> SourceTextModule::info() const {
  return GetSharedFunctionInfo()->scope_info()->ModuleDescriptorInfo();
}

Tagged<FixedArray> SourceTextModuleInfo::module_requests() const {
  return Cast<FixedArray>(get(kModuleRequestsIndex));
}

Tagged<FixedArray> SourceTextModuleInfo::special_exports() const {
  return Cast<FixedArray>(get(kSpecialExportsIndex));
}

Tagged<FixedArray> SourceTextModuleInfo::regular_exports() const {
  return Cast<FixedArray>(get(kRegularExportsIndex));
}

Tagged<FixedArray> SourceTextModuleInfo::regular_imports() const {
  return Cast<FixedArray>(get(kRegularImportsIndex));
}

Tagged<FixedArray> SourceTextModuleInfo::namespace_imports() const {
  return Cast<FixedArray>(get(kNamespaceImportsIndex));
}

// TODO(crbug.com/401059828): make it DEBUG only, once investigation is over.
bool SourceTextModuleInfo::Equals(Tagged<SourceTextModuleInfo> other) const {
  return regular_exports() == other->regular_exports() &&
         regular_imports() == other->regular_imports() &&
         special_exports() == other->special_exports() &&
         namespace_imports() == other->namespace_imports() &&
         module_requests() == other->module_requests();
}

struct ModuleHandleHash {
  V8_INLINE size_t operator()(DirectHandle<Module> module) const {
    return module->hash();
  }
};

struct ModuleHandleEqual {
  V8_INLINE bool operator()(DirectHandle<Module> lhs,
                            DirectHandle<Module> rhs) const {
    return *lhs == *rhs;
  }
};

class UnorderedModuleSet
    : public std::unordered_set<Handle<Module>, ModuleHandleHash,
                                ModuleHandleEqual,
                                ZoneAllocator<Handle<Module>>> {
 public:
  explicit UnorderedModuleSet(Zone* zone)
      : std::unordered_set<Handle<Module>, ModuleHandleHash, ModuleHandleEqual,
                           ZoneAllocator<Handle<Module>>>(
            2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(),
            ZoneAllocator<Handle<Module>>(zone)) {}
};

Handle<SourceTextModule> SourceTextModule::GetCycleRoot(
    Isolate* isolate) const {
  CHECK_GE(status(), kEvaluatingAsync);
  DCHECK(!IsTheHole(cycle_root()));
  Handle<SourceTextModule> root(Cast<SourceTextModule>(cycle_root()), isolate);
  return root;
}

void SourceTextModule::AddAsyncParentModule(
    Isolate* isolate, DirectHandle<SourceTextModule> module,
    DirectHandle<SourceTextModule> parent) {
  DirectHandle<ArrayList> async_parent_modules(module->async_parent_modules(),
                                               isolate);
  DirectHandle<ArrayList> new_array_list =
      ArrayList::Add(isolate, async_parent_modules, parent);
  module->set_async_parent_modules(*new_array_list);
}

Handle<SourceTextModule> SourceTextModule::GetAsyncParentModule(
    Isolate* isolate, uint32_t index) {
  Handle<SourceTextModule> module(
      Cast<SourceTextModule>(async_parent_modules()->get(index)), isolate);
  return module;
}

uint32_t SourceTextModule::AsyncParentModuleCount() {
  return async_parent_modules()->ulength().value();
}

bool SourceTextModule::HasAsyncEvaluationOrdinal() const {
  return async_evaluation_ordinal() >= kFirstAsyncEvaluationOrdinal;
}

bool SourceTextModule::HasPendingAsyncDependencies() {
  DCHECK_GE(pending_async_dependencies(), 0);
  return pending_async_dependencies() > 0;
}

void SourceTextModule::IncrementPendingAsyncDependencies() {
  set_pending_async_dependencies(pending_async_dependencies() + 1);
}

void SourceTextModule::DecrementPendingAsyncDependencies() {
  set_pending_async_dependencies(pending_async_dependencies() - 1);
}

Tagged<ObjectHashTable> Module::exports() const { return exports_.load(); }
void Module::set_exports(Tagged<ObjectHashTable> value, WriteBarrierMode mode) {
  exports_.store(this, value, mode);
}

int Module::hash() const { return hash_.load().value(); }
void Module::set_hash(int value) { hash_.store(this, Smi::FromInt(value)); }

int Module::status() const { return status_.load().value(); }
void Module::set_status(int value) { status_.store(this, Smi::FromInt(value)); }

Tagged<UnionOf<Cell, Undefined>> Module::module_namespace() const {
  return module_namespace_.load();
}
void Module::set_module_namespace(Tagged<UnionOf<Cell, Undefined>> value,
                                  WriteBarrierMode mode) {
  module_namespace_.store(this, value, mode);
}

Tagged<UnionOf<Cell, Undefined>> Module::deferred_module_namespace() const {
  return deferred_module_namespace_.load();
}
void Module::set_deferred_module_namespace(
    Tagged<UnionOf<Cell, Undefined>> value, WriteBarrierMode mode) {
  deferred_module_namespace_.store(this, value, mode);
}

Tagged<Module> JSModuleNamespace::module() const { return module_.load(); }

void JSModuleNamespace::set_module(Tagged<Module> value,
                                   WriteBarrierMode mode) {
  module_.store(this, value, mode);
}

Tagged<Object> Module::exception() const { return exception_.load(); }
void Module::set_exception(Tagged<Object> value, WriteBarrierMode mode) {
  exception_.store(this, value, mode);
}

Tagged<UnionOf<JSPromise, Undefined>> Module::top_level_capability() const {
  return top_level_capability_.load();
}
void Module::set_top_level_capability(
    Tagged<UnionOf<JSPromise, Undefined>> value, WriteBarrierMode mode) {
  top_level_capability_.store(this, value, mode);
}
}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_MODULE_INL_H_