// Copyright (c) 2020, 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. import 'package:kernel/ast.dart'; class UnboxingInfoMetadata { static const kBoxed = 0; static const kUnboxedIntCandidate = 1 << 0; static const kUnboxedDoubleCandidate = 1 << 1; static const kUnboxingCandidate = kUnboxedIntCandidate | kUnboxedDoubleCandidate; final List unboxedArgsInfo; int returnInfo; UnboxingInfoMetadata(int argsLen) : unboxedArgsInfo = [] { for (int i = 0; i < argsLen; i++) { unboxedArgsInfo.add(kUnboxingCandidate); } returnInfo = kUnboxingCandidate; } UnboxingInfoMetadata.readFromBinary(BinarySource source) : unboxedArgsInfo = List.generate( source.readUInt30(), (_) => source.readByte(), growable: true), returnInfo = source.readByte(); // Returns `true` if all arguments as well as the return value have to be // boxed. // // We don't have to write out metadata for fully boxed methods, because this // is the default. bool get isFullyBoxed { if (returnInfo != kBoxed) return false; for (int argInfo in unboxedArgsInfo) { if (argInfo != kBoxed) return false; } return true; } void writeToBinary(BinarySink sink) { sink.writeUInt30(unboxedArgsInfo.length); for (int val in unboxedArgsInfo) { sink.writeByte(val); } sink.writeByte(returnInfo); } @override String toString() { final sb = StringBuffer(); sb.write('('); for (int i = 0; i < unboxedArgsInfo.length; ++i) { final argInfo = unboxedArgsInfo[i]; sb.write(_stringifyUnboxingInfo(argInfo)); if (i != (unboxedArgsInfo.length - 1)) { sb.write(','); } } sb.write(')'); sb.write('->'); sb.write(_stringifyUnboxingInfo(returnInfo)); return sb.toString(); } static String _stringifyUnboxingInfo(int info) { if (info == UnboxingInfoMetadata.kUnboxedIntCandidate) { return 'i'; } else if (info == UnboxingInfoMetadata.kUnboxedDoubleCandidate) { return 'd'; } assert(info == 0); return 'b'; } } class UnboxingInfoMetadataRepository extends MetadataRepository { static const repositoryTag = 'vm.unboxing-info.metadata'; @override final String tag = repositoryTag; @override final Map mapping = {}; @override void writeToBinary( UnboxingInfoMetadata metadata, Node node, BinarySink sink) { metadata.writeToBinary(sink); } @override UnboxingInfoMetadata readFromBinary(Node node, BinarySource source) { return UnboxingInfoMetadata.readFromBinary(source); } }