HELLO·Android
系统源代码
IT资讯
技术文章
我的收藏
注册
登录
-
我收藏的文章
创建代码块
我的代码块
我的账号
Android 10
|
10.0.0_r6
下载
查看原文件
收藏
根目录
external
v8
src
objects
module.cc
// 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. #include
#include
#include "src/objects/module.h" #include "src/accessors.h" #include "src/api-inl.h" #include "src/ast/modules.h" #include "src/objects-inl.h" #include "src/objects/hash-table-inl.h" #include "src/objects/js-generator-inl.h" #include "src/objects/module-inl.h" namespace v8 { namespace internal { namespace { struct ModuleHandleHash { V8_INLINE size_t operator()(Handle
module) const { return module->hash(); } }; struct ModuleHandleEqual { V8_INLINE bool operator()(Handle
lhs, Handle
rhs) const { return *lhs == *rhs; } }; struct StringHandleHash { V8_INLINE size_t operator()(Handle
string) const { return string->Hash(); } }; struct StringHandleEqual { V8_INLINE bool operator()(Handle
lhs, Handle
rhs) const { return lhs->Equals(*rhs); } }; class UnorderedStringSet : public std::unordered_set
, StringHandleHash, StringHandleEqual, ZoneAllocator
>> { public: explicit UnorderedStringSet(Zone* zone) : std::unordered_set
, StringHandleHash, StringHandleEqual, ZoneAllocator
>>( 2 /* bucket count */, StringHandleHash(), StringHandleEqual(), ZoneAllocator
>(zone)) {} }; class UnorderedModuleSet : public std::unordered_set
, ModuleHandleHash, ModuleHandleEqual, ZoneAllocator
>> { public: explicit UnorderedModuleSet(Zone* zone) : std::unordered_set
, ModuleHandleHash, ModuleHandleEqual, ZoneAllocator
>>( 2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(), ZoneAllocator
>(zone)) {} }; class UnorderedStringMap : public std::unordered_map< Handle
, Handle
, StringHandleHash, StringHandleEqual, ZoneAllocator
, Handle
>>> { public: explicit UnorderedStringMap(Zone* zone) : std::unordered_map< Handle
, Handle
, StringHandleHash, StringHandleEqual, ZoneAllocator
, Handle
>>>( 2 /* bucket count */, StringHandleHash(), StringHandleEqual(), ZoneAllocator
, Handle
>>( zone)) {} }; } // anonymous namespace class Module::ResolveSet : public std::unordered_map< Handle
, UnorderedStringSet*, ModuleHandleHash, ModuleHandleEqual, ZoneAllocator
, UnorderedStringSet*>>> { public: explicit ResolveSet(Zone* zone) : std::unordered_map
, UnorderedStringSet*, ModuleHandleHash, ModuleHandleEqual, ZoneAllocator
, UnorderedStringSet*>>>( 2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(), ZoneAllocator
, UnorderedStringSet*>>( zone)), zone_(zone) {} Zone* zone() const { return zone_; } private: Zone* zone_; }; namespace { int ExportIndex(int cell_index) { DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index), ModuleDescriptor::kExport); return cell_index - 1; } int ImportIndex(int cell_index) { DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index), ModuleDescriptor::kImport); return -cell_index - 1; } } // anonymous namespace void Module::CreateIndirectExport(Isolate* isolate, Handle
module, Handle
name, Handle
entry) { Handle
exports(module->exports(), isolate); DCHECK(exports->Lookup(name)->IsTheHole(isolate)); exports = ObjectHashTable::Put(exports, name, entry); module->set_exports(*exports); } void Module::CreateExport(Isolate* isolate, Handle
module, int cell_index, Handle
names) { DCHECK_LT(0, names->length()); Handle
cell = isolate->factory()->NewCell(isolate->factory()->undefined_value()); module->regular_exports()->set(ExportIndex(cell_index), *cell); Handle
exports(module->exports(), isolate); for (int i = 0, n = names->length(); i < n; ++i) { Handle
name(String::cast(names->get(i)), isolate); DCHECK(exports->Lookup(name)->IsTheHole(isolate)); exports = ObjectHashTable::Put(exports, name, cell); } module->set_exports(*exports); } Cell* Module::GetCell(int cell_index) { DisallowHeapAllocation no_gc; Object* cell; switch (ModuleDescriptor::GetCellIndexKind(cell_index)) { case ModuleDescriptor::kImport: cell = regular_imports()->get(ImportIndex(cell_index)); break; case ModuleDescriptor::kExport: cell = regular_exports()->get(ExportIndex(cell_index)); break; case ModuleDescriptor::kInvalid: UNREACHABLE(); break; } return Cell::cast(cell); } Handle
Module::LoadVariable(Isolate* isolate, Handle
module, int cell_index) { return handle(module->GetCell(cell_index)->value(), isolate); } void Module::StoreVariable(Handle
module, int cell_index, Handle
value) { DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index), ModuleDescriptor::kExport); module->GetCell(cell_index)->set_value(*value); } #ifdef DEBUG void Module::PrintStatusTransition(Status new_status) { if (FLAG_trace_module_status) { StdoutStream os; os << "Changing module status from " << status() << " to " << new_status << " for "; script()->GetNameOrSourceURL()->Print(os); #ifndef OBJECT_PRINT os << "\n"; #endif // OBJECT_PRINT } } #endif // DEBUG void Module::SetStatus(Status new_status) { DisallowHeapAllocation no_alloc; DCHECK_LE(status(), new_status); DCHECK_NE(new_status, Module::kErrored); #ifdef DEBUG PrintStatusTransition(new_status); #endif // DEBUG set_status(new_status); } void Module::ResetGraph(Isolate* isolate, Handle
module) { DCHECK_NE(module->status(), kInstantiating); DCHECK_NE(module->status(), kEvaluating); if (module->status() != kPreInstantiating) return; Handle
requested_modules(module->requested_modules(), isolate); Reset(isolate, module); for (int i = 0; i < requested_modules->length(); ++i) { Handle
descendant(requested_modules->get(i), isolate); if (descendant->IsModule()) { ResetGraph(isolate, Handle
::cast(descendant)); } else { DCHECK(descendant->IsUndefined(isolate)); } } } void Module::Reset(Isolate* isolate, Handle
module) { Factory* factory = isolate->factory(); DCHECK(module->status() == kPreInstantiating || module->status() == kInstantiating); DCHECK(module->exception()->IsTheHole(isolate)); DCHECK(module->import_meta()->IsTheHole(isolate)); // The namespace object cannot exist, because it would have been created // by RunInitializationCode, which is called only after this module's SCC // succeeds instantiation. DCHECK(!module->module_namespace()->IsJSModuleNamespace()); Handle
exports = ObjectHashTable::New(isolate, module->info()->RegularExportCount()); Handle
regular_exports = factory->NewFixedArray(module->regular_exports()->length()); Handle
regular_imports = factory->NewFixedArray(module->regular_imports()->length()); Handle
requested_modules = factory->NewFixedArray(module->requested_modules()->length()); if (module->status() == kInstantiating) { module->set_code(JSFunction::cast(module->code())->shared()); } #ifdef DEBUG module->PrintStatusTransition(kUninstantiated); #endif // DEBUG module->set_status(kUninstantiated); module->set_exports(*exports); module->set_regular_exports(*regular_exports); module->set_regular_imports(*regular_imports); module->set_requested_modules(*requested_modules); module->set_dfs_index(-1); module->set_dfs_ancestor_index(-1); } void Module::RecordError(Isolate* isolate) { DisallowHeapAllocation no_alloc; DCHECK(exception()->IsTheHole(isolate)); Object* the_exception = isolate->pending_exception(); DCHECK(!the_exception->IsTheHole(isolate)); set_code(info()); #ifdef DEBUG PrintStatusTransition(Module::kErrored); #endif // DEBUG set_status(Module::kErrored); set_exception(the_exception); } Object* Module::GetException() { DisallowHeapAllocation no_alloc; DCHECK_EQ(status(), Module::kErrored); DCHECK(!exception()->IsTheHole()); return exception(); } SharedFunctionInfo* Module::GetSharedFunctionInfo() const { DisallowHeapAllocation no_alloc; DCHECK_NE(status(), Module::kEvaluating); DCHECK_NE(status(), Module::kEvaluated); switch (status()) { case kUninstantiated: case kPreInstantiating: DCHECK(code()->IsSharedFunctionInfo()); return SharedFunctionInfo::cast(code()); case kInstantiating: DCHECK(code()->IsJSFunction()); return JSFunction::cast(code())->shared(); case kInstantiated: DCHECK(code()->IsJSGeneratorObject()); return JSGeneratorObject::cast(code())->function()->shared(); case kEvaluating: case kEvaluated: case kErrored: UNREACHABLE(); } UNREACHABLE(); } MaybeHandle
Module::ResolveImport(Isolate* isolate, Handle
module, Handle
name, int module_request, MessageLocation loc, bool must_resolve, Module::ResolveSet* resolve_set) { Handle
requested_module( Module::cast(module->requested_modules()->get(module_request)), isolate); Handle
specifier( String::cast(module->info()->module_requests()->get(module_request)), isolate); MaybeHandle
result = Module::ResolveExport(isolate, requested_module, specifier, name, loc, must_resolve, resolve_set); DCHECK_IMPLIES(isolate->has_pending_exception(), result.is_null()); return result; } MaybeHandle
Module::ResolveExport(Isolate* isolate, Handle
module, Handle
module_specifier, Handle
export_name, MessageLocation loc, bool must_resolve, Module::ResolveSet* resolve_set) { DCHECK_GE(module->status(), kPreInstantiating); DCHECK_NE(module->status(), kEvaluating); Handle
object(module->exports()->Lookup(export_name), isolate); if (object->IsCell()) { // Already resolved (e.g. because it's a local export). return Handle
::cast(object); } // Check for cycle before recursing. { // Attempt insertion with a null string set. auto result = resolve_set->insert({module, nullptr}); UnorderedStringSet*& name_set = result.first->second; if (result.second) { // |module| wasn't in the map previously, so allocate a new name set. Zone* zone = resolve_set->zone(); name_set = new (zone->New(sizeof(UnorderedStringSet))) UnorderedStringSet(zone); } else if (name_set->count(export_name)) { // Cycle detected. if (must_resolve) { return isolate->Throw
( isolate->factory()->NewSyntaxError( MessageTemplate::kCyclicModuleDependency, export_name, module_specifier), &loc); } return MaybeHandle
(); } name_set->insert(export_name); } if (object->IsModuleInfoEntry()) { // Not yet resolved indirect export. Handle
entry = Handle
::cast(object); Handle
import_name(String::cast(entry->import_name()), isolate); Handle
登录后可以享受更多权益
您还没有登录,登录后您可以:
收藏Android系统代码
收藏喜欢的文章
多个平台共享账号
去登录
首次使用?从这里
注册