| // 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 |