blob: 6f7b5d420f09664e1b3ed10e50c982e5aaeda873 [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.
import 'package:analyzer/src/wolf/ir/coded_ir.dart';
import 'package:analyzer/src/wolf/ir/ir.dart';
import 'package:meta/meta.dart';
/// Evaluates [ir], passing in [args], and returns the result.
///
/// This interpreter is neither efficient nor full-featured, so it shouldn't be
/// used in production code. It is solely intended to allow unit tests to verify
/// that an instruction sequence behaves as it's expected to.
@visibleForTesting
Object? interpret(CodedIRContainer ir, List<Object?> args) =>
_IRInterpreter(ir).run(args);
class _IRInterpreter {
final CodedIRContainer ir;
final stack = <Object?>[];
_IRInterpreter(this.ir);
Object? run(List<Object?> args) {
var functionType = Opcode.function.decodeType(ir, 0);
var parameterCount = ir.countParameters(functionType);
if (args.length != parameterCount) {
throw StateError('Parameter count mismatch');
}
stack.addAll(args);
var address = 1;
while (true) {
switch (ir.opcodeAt(address)) {
case Opcode.end:
assert(stack.length == 1);
return stack.last;
case Opcode.literal:
var value = Opcode.literal.decodeValue(ir, address);
stack.add(ir.decodeLiteral(value));
case var opcode:
throw UnimplementedError(
'TODO(paulberry): implement ${opcode.describe()} in '
'_IRInterpreter');
}
address++;
}
}
}