| // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| #include "vm/ffi/native_assets.h" | |
| #include "vm/hash_table.h" | |
| #include "vm/object_store.h" | |
| #include "vm/symbols.h" | |
| namespace dart { | |
| ArrayPtr GetNativeAssetsMap(Thread* thread) { | |
| Zone* const zone = thread->zone(); | |
| ObjectStore* const object_store = thread->isolate_group()->object_store(); | |
| auto& native_assets_map = | |
| Array::Handle(zone, object_store->native_assets_map()); | |
| if (!native_assets_map.IsNull()) { | |
| return native_assets_map.ptr(); | |
| } | |
| const auto& native_assets_library = | |
| Library::Handle(zone, object_store->native_assets_library()); | |
| if (native_assets_library.IsNull()) { | |
| // Kernel compilation can happen without a native assets library. | |
| return Array::null(); | |
| } | |
| auto& pragma = Object::Handle(zone); | |
| const bool pragma_found = native_assets_library.FindPragma( | |
| thread, /*only_core=*/false, native_assets_library, | |
| Symbols::vm_ffi_native_assets(), | |
| /*multiple=*/false, &pragma); | |
| ASSERT(pragma_found); | |
| // This map is formatted as follows: | |
| // | |
| // '<target_string>': { | |
| // '<asset_uri>': ['<path_type>', '<path (optional)>'] | |
| // } | |
| // | |
| // It is generated by: pkg/vm/lib/native_assets/synthesizer.dart | |
| const auto& abi_map = Map::Cast(pragma); | |
| const auto& current_abi = String::Handle( | |
| zone, String::NewFormatted("%s_%s", kTargetOperatingSystemName, | |
| kTargetArchitectureName)); | |
| Map::Iterator abi_iterator(abi_map); | |
| auto& abi = String::Handle(zone); | |
| auto& asset_map = Map::Handle(zone); | |
| while (abi_iterator.MoveNext()) { | |
| abi = String::RawCast(abi_iterator.CurrentKey()); | |
| if (abi.Equals(current_abi)) { | |
| asset_map = Map::RawCast(abi_iterator.CurrentValue()); | |
| break; | |
| } | |
| } | |
| const intptr_t asset_map_length = asset_map.IsNull() ? 0 : asset_map.Length(); | |
| NativeAssetsMap map( | |
| HashTables::New<NativeAssetsMap>(asset_map_length, Heap::kOld)); | |
| if (!asset_map.IsNull()) { | |
| String& asset = String::Handle(zone); | |
| Array& path = Array::Handle(zone); | |
| Map::Iterator iterator2(asset_map); | |
| bool duplicate_asset = false; | |
| while (iterator2.MoveNext()) { | |
| asset = String::RawCast(iterator2.CurrentKey()); | |
| path = Array::RawCast(iterator2.CurrentValue()); | |
| duplicate_asset = map.UpdateOrInsert(asset, path); | |
| ASSERT(!duplicate_asset); | |
| } | |
| } | |
| native_assets_map = map.Release().ptr(); | |
| object_store->set_native_assets_map(native_assets_map); | |
| return native_assets_map.ptr(); | |
| } | |
| } // namespace dart |