diff --git a/EVMOneUnitTestsRunList.txt b/EVMOneUnitTestsRunList.txt index 574bccb22..aa3da5a00 100644 --- a/EVMOneUnitTestsRunList.txt +++ b/EVMOneUnitTestsRunList.txt @@ -91,6 +91,8 @@ multi_vm/evm.eip2929_sload_cold/external_vm multi_vm/evm.eip2929_sload_two_slots/external_vm multi_vm/evm.eip2929_sload_warm/external_vm multi_vm/evm.eip2929_delegatecall_cold/external_vm +multi_vm/evm.evmone_block_gas_cost_overflow_create/external_vm +multi_vm/evm.evmone_block_stack_req_overflow/external_vm multi_vm/evm.basefee_nominal_case/external_vm multi_vm/evm.push0/external_vm multi_vm/evm.push0_return_empty/external_vm diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 3be16ae44..f2efebee7 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -309,6 +309,8 @@ class Runtime final { const RuntimeConfig &getConfig() const { return Config; } + void setConfig(const RuntimeConfig &NewConfig) { Config = NewConfig; } + utils::Statistics &getStatistics() { return Stats; } void startCPUTracing(); diff --git a/src/vm/dt_evmc_vm.cpp b/src/vm/dt_evmc_vm.cpp index 386e258ad..8bc396668 100644 --- a/src/vm/dt_evmc_vm.cpp +++ b/src/vm/dt_evmc_vm.cpp @@ -21,6 +21,24 @@ namespace { using namespace zen::runtime; using namespace zen::common; +// JIT compilation limits (95% < 10KB) +const size_t MAX_JIT_BYTECODE_SIZE = 0x6000; + +// RAII helper for temporarily changing runtime configuration +class ScopedConfig { +public: + ScopedConfig(Runtime *Runtime, const RuntimeConfig &NewConfig) + : RT(Runtime), PreviousConfig(Runtime->getConfig()) { + RT->setConfig(NewConfig); + } + + ~ScopedConfig() { RT->setConfig(PreviousConfig); } + +private: + Runtime *RT; + RuntimeConfig PreviousConfig; +}; + // CRC32 checksum uint32_t crc32(const uint8_t *Data, size_t Size) { static uint32_t Table[256]; @@ -126,6 +144,14 @@ evmc_result execute(evmc_vm *EVMInstance, const evmc_host_interface *Host, if (!VM->RT) { VM->RT = Runtime::newEVMRuntime(VM->Config, VM->ExecHost.get()); } + // Use interpreter mode for large bytecode + std::unique_ptr TempConfig; + if (VM->Config.Mode == RunMode::MultipassMode && + CodeSize > MAX_JIT_BYTECODE_SIZE) { + RuntimeConfig NewConfig = VM->Config; + NewConfig.Mode = RunMode::InterpMode; + TempConfig = std::make_unique(VM->RT.get(), NewConfig); + } uint32_t CheckSum = crc32(Code, CodeSize); auto ModRet = VM->RT->loadEVMModule(std::to_string(CheckSum), Code, CodeSize);