Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
hybrid_execution.cpp
Go to the documentation of this file.
2
4
5namespace bb::avm2::simulation {
6
7// This context interface is a top-level enqueued one.
8// NOTE: For the moment this trace is not returning the context back.
10{
11 BB_BENCH_NAME("HybridExecution::execute");
12 external_call_stack.push(std::move(enqueued_call_context));
13
14 while (!external_call_stack.empty()) {
15 // We fix the context at this point. Even if the opcode changes the stack
16 // we'll always use this in the loop.
17 auto& context = *external_call_stack.top();
18
19 try {
20 auto pc = context.get_pc();
21
23
24 // We try to get the bytecode id. This can throw if the contract is not deployed or if we have retrieved too
25 // many unique class ids. Note: bytecode_id is tracked in context events, not in the top-level execution
26 // event. It is already included in the before_context_event (defaulting to 0 on error/not-found).
27 context.get_bytecode_manager().get_bytecode_id();
28
30
31 // We try to fetch an instruction.
32 Instruction instruction = context.get_bytecode_manager().read_instruction(pc);
33
34 debug("@", pc, " ", instruction.to_string());
35 context.set_next_pc(pc + static_cast<uint32_t>(instruction.size_in_bytes()));
36
38
39 // Resolve the operands.
40 AddressingEvent addressing_event; // FIXME(fcarreiro): shouldn't need this.
41 auto addressing = execution_components.make_addressing(addressing_event);
42 std::vector<Operand> resolved_operands = addressing->resolve(instruction, context.get_memory());
43
45 GasEvent gas_event; // FIXME(fcarreiro): shouldn't need this.
47 dispatch_opcode(instruction.get_exec_opcode(), context, resolved_operands);
48 }
49 // TODO(fcarreiro): handle this in a better way.
50 catch (const BytecodeRetrievalError& e) {
51 vinfo("Bytecode retrieval error:: ", e.what());
53 } catch (const InstructionFetchingError& e) {
54 vinfo("Instruction fetching error: ", e.what());
56 } catch (const AddressingException& e) {
57 vinfo("Addressing exception: ", e.what());
59 } catch (const RegisterValidationException& e) {
60 vinfo("Register validation exception: ", e.what());
62 } catch (const OutOfGasException& e) {
63 vinfo("Out of gas exception: ", e.what());
65 } catch (const OpcodeExecutionException& e) {
66 vinfo("Opcode execution exception: ", e.what());
68 } catch (const std::exception& e) {
69 // This is a coding error, we should not get here.
70 // All exceptions should fall in the above catch blocks.
71 info("An unhandled exception occurred: ", e.what());
72 throw e;
73 }
74
75 // We always do what follows. "Finally".
76 // Move on to the next pc.
77 context.set_pc(context.get_next_pc());
79
80 // If the context has halted, we need to exit the external call.
81 // The external call stack is expected to be popped.
82 if (context.halted()) {
84 }
85 }
86
87 return get_execution_result();
88}
89
90} // namespace bb::avm2::simulation
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:218
virtual std::unique_ptr< GasTrackerInterface > make_gas_tracker(GasEvent &gas_event, const Instruction &instruction, ContextInterface &context)=0
virtual std::unique_ptr< AddressingInterface > make_addressing(AddressingEvent &event)=0
std::unique_ptr< GasTrackerInterface > gas_tracker
void dispatch_opcode(ExecutionOpCode opcode, ContextInterface &context, const std::vector< Operand > &resolved_operands)
ExecutionComponentsProviderInterface & execution_components
void handle_exceptional_halt(ContextInterface &context)
std::stack< std::unique_ptr< ContextInterface > > external_call_stack
ExecutionResult get_execution_result() const
ExecutionIdManagerInterface & execution_id_manager
ExecutionResult execute(std::unique_ptr< ContextInterface > enqueued_call_context) override
#define vinfo(...)
Definition log.hpp:79
#define debug(...)
Definition log.hpp:61
void info(Args... args)
Definition log.hpp:74
GasEvent gas_event
Instruction instruction
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13