decode static method
The program bytes hold, verified.
Throws ExpressionBytecodeException for bytes that are not one, a version this build does not read, or a program verify refuses.
Implementation
static ExpressionBytecode decode(Uint8List bytes) {
final data = ByteData.sublistView(bytes);
var at = 0;
void need(int count) {
if (at + count > bytes.length) {
throw const ExpressionBytecodeException('the bytes end early');
}
}
int u16() {
need(2);
final v = data.getUint16(at, Endian.little);
at += 2;
return v;
}
need(4);
for (final byte in expressionBytecodeMagic) {
if (bytes[at++] != byte) {
throw const ExpressionBytecodeException('not F3DX bytecode');
}
}
final version = u16();
// Every version up to this build's is read; only a newer one, or none,
// is refused.
if (version > expressionBytecodeVersion || version < 1) {
throw ExpressionBytecodeException(
'bytecode version $version; this build reads up to '
'$expressionBytecodeVersion',
);
}
u16();
final lanes = u16();
final constantCount = u16();
final dimensionCount = u16();
final inputCount = u16();
final instructionCount = u16();
final resultLane = u16();
final resultWidth = u16();
final resultDimension = u16();
need(constantCount * 8);
final constants = Float64List(constantCount);
for (var i = 0; i < constantCount; i++) {
constants[i] = data.getFloat64(at, Endian.little);
at += 8;
}
// The exponents, then the byte that says a bool.
final stride = _Dim.count + 1;
need(dimensionCount * stride);
final dimensions = <_Dim>[
for (var i = 0; i < dimensionCount; i++)
_Dim(<int>[
for (var e = 0; e < _Dim.count; e++)
data.getInt8(at + i * stride + e),
], data.getUint8(at + i * stride + _Dim.count) != 0),
];
at += dimensionCount * stride;
final inputs = <ExpressionBytecodeInput>[];
for (var i = 0; i < inputCount; i++) {
final length = u16();
need(length);
final name = utf8.decode(bytes.sublist(at, at + length));
at += length;
inputs.add(ExpressionBytecodeInput(name, u16(), u16(), u16()));
}
final code = Uint16List(instructionCount * 8);
for (var i = 0; i < code.length; i++) {
code[i] = u16();
}
if (at != bytes.length) {
throw const ExpressionBytecodeException('bytes follow the program');
}
return ExpressionBytecode._(
dimensions,
lanes: lanes,
constants: constants,
inputs: inputs,
code: code,
resultLane: resultLane,
resultWidth: resultWidth,
resultDimension: resultDimension,
)..verify();
}