blob: 0880fd7af383a13fae0836251c36ab8cd7c8fef6 [file] [log] [blame]
// 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