| // 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. |
| |
| /// Some aspects of Wasm bytecode cannot be determined until after |
| /// finalizing the module graph, e.g. indices of certain objects. We could |
| /// rebuild any parts of the module graph that need indices when we finalize the |
| /// module. This would ensure indices are always final, but at the cost of |
| /// copying objects that otherwise wouldn't need to be copied. A lighter weight |
| /// approach might be to use interfaces to hide indices before finalization. |
| /// |
| /// For the time being, we use [Finalizable] objects, which are part of the |
| /// module graph, but will throw if a user tries to access a non-final value. |
| class Finalizable<T> { |
| T? _value; |
| |
| set value(T v) => finalize(v); |
| |
| T get value { |
| final v = _value; |
| if (v == null) { |
| throw 'Value not yet finalized'; |
| } |
| return v; |
| } |
| |
| void finalize(T v) { |
| if (_value != null) { |
| throw 'Value already finalized'; |
| } |
| _value = v; |
| } |
| |
| bool get isFinal => _value == null; |
| |
| /// If we've been finalized, then print the finalized value, otherwise print a |
| /// sentinel(NF - Not Final). |
| @override |
| String toString() => isFinal ? '$_value' : '<NF>'; |
| } |
| |
| typedef FinalizableIndex = Finalizable<int>; |