/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/wasm/basic-block-calculator.cc
111 строк
3 KB
Michaël Zasso
deps: update V8 to 14.6.202.33
24 апр 2026, 19:01
Не верифицирован
24 апр 2026, 19:01
f1e0b83
Код
Авторство
О чём код?
// Copyright 2025 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/wasm/basic-block-calculator.h" #include "src/wasm/function-body-decoder.h" namespace v8::internal::wasm { void BasicBlockCalculator::StartNewBlock(Decoder* decoder) { current_basic_block_++; current_basic_block_start_pos_ = decoder->position(); } void BasicBlockCalculator::EndCurrentBlock(Decoder* decoder) { DCHECK_GE(current_basic_block_, 0); DCHECK_GE(decoder->position(), current_basic_block_start_pos_); int final_instruction_length = OpcodeLength(decoder->pc(), decoder->end()); basic_block_ranges_.emplace_back( current_basic_block_start_pos_, decoder->position() + final_instruction_length - 1); } void BasicBlockCalculator::ComputeBasicBlocks() { DCHECK(basic_block_ranges_.empty()); // Basic block rules. // ------------------ // 1. The first basic block starts at function offset 0. // 2. The 'else' instructions and the 'end' instructions end the current // block. They are the last instruction in the basic block and the next // instruction will start a new block. Likewise, all branch, call, tail-call, // 'unreachable', 'return', 'if' and throw instructions end the current block. // 3. The 'loop' instructions end the current block and start a new block. // 4. The first instruction after the end of a block starts a new block. // There can be unreachable instructions in between, which are not part of // any block. // 5. The last basic block ends at the offset of the final function 'end' // instruction. BodyLocalDecls locals; BytecodeIterator iterator(start_, end_, &locals, zone_); DCHECK_LT(0, locals.encoded_size); // Start function. current_basic_block_ = 0; current_basic_block_start_pos_ = 0; bool at_block_end = false; for (; iterator.has_next(); iterator.next()) { WasmOpcode opcode = iterator.current(); if (at_block_end) { StartNewBlock(&iterator); at_block_end = false; } switch (opcode) { case kExprLoop: DCHECK_GE(current_basic_block_, 0); if (iterator.position() > current_basic_block_start_pos_) { basic_block_ranges_.emplace_back(current_basic_block_start_pos_, iterator.position() - 1); StartNewBlock(&iterator); } break; case kExprEnd: case kExprIf: case kExprElse: case kExprUnreachable: case kExprBr: case kExprBrTable: case kExprReturn: case kExprDelegate: case kExprRethrow: case kExprThrow: case kExprThrowRef: case kExprCatch: case kExprCatchAll: case kExprBrIf: case kExprBrOnNull: case kExprBrOnNonNull: case kExprBrOnCast: case kExprBrOnCastFail: case kExprBrOnCastDescEq: case kExprBrOnCastDescEqFail: case kExprReturnCall: case kExprReturnCallIndirect: case kExprReturnCallRef: case kExprCallFunction: case kExprCallIndirect: case kExprCallRef: EndCurrentBlock(&iterator); at_block_end = true; break; default: break; } } if (!at_block_end) { basic_block_ranges_.emplace_back(current_basic_block_start_pos_, iterator.position() - 1); } } } // namespace v8::internal::wasm