diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/wasm2c/src/ir-util.cc | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/wasm2c/src/ir-util.cc')
-rw-r--r-- | third_party/wasm2c/src/ir-util.cc | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/third_party/wasm2c/src/ir-util.cc b/third_party/wasm2c/src/ir-util.cc new file mode 100644 index 0000000000..ee9262cc0c --- /dev/null +++ b/third_party/wasm2c/src/ir-util.cc @@ -0,0 +1,271 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "wabt/ir-util.h" + +#include <algorithm> +#include <array> +#include <cassert> +#include <cinttypes> +#include <cstdarg> +#include <cstdio> +#include <iterator> +#include <map> +#include <string> +#include <vector> + +#include "wabt/cast.h" +#include "wabt/common.h" +#include "wabt/expr-visitor.h" +#include "wabt/ir-util.h" +#include "wabt/ir.h" +#include "wabt/literal.h" +#include "wabt/stream.h" + +#define WABT_TRACING 0 +#include "wabt/tracing.h" + +using namespace wabt; + +const Label* ModuleContext::GetLabel(const Var& var) const { + if (var.is_name()) { + for (Index i = GetLabelStackSize(); i > 0; --i) { + auto label = &label_stack_[i - 1]; + if (label->name == var.name()) { + return label; + } + } + } else if (var.index() < GetLabelStackSize()) { + auto label = &label_stack_[GetLabelStackSize() - var.index() - 1]; + return label; + } + return nullptr; +} + +Index ModuleContext::GetLabelArity(const Var& var) const { + auto label = GetLabel(var); + if (!label) { + return 0; + } + + return label->label_type == LabelType::Loop ? label->param_types.size() + : label->result_types.size(); +} + +Index ModuleContext::GetFuncParamCount(const Var& var) const { + const Func* func = module.GetFunc(var); + return func ? func->GetNumParams() : 0; +} + +Index ModuleContext::GetFuncResultCount(const Var& var) const { + const Func* func = module.GetFunc(var); + return func ? func->GetNumResults() : 0; +} + +void ModuleContext::BeginBlock(LabelType label_type, const Block& block) { + label_stack_.emplace_back(label_type, block.label, block.decl.sig.param_types, + block.decl.sig.result_types); +} + +void ModuleContext::EndBlock() { + label_stack_.pop_back(); +} + +void ModuleContext::BeginFunc(const Func& func) { + label_stack_.clear(); + label_stack_.emplace_back(LabelType::Func, std::string(), TypeVector(), + func.decl.sig.result_types); + current_func_ = &func; +} + +void ModuleContext::EndFunc() { + current_func_ = nullptr; +} + +ModuleContext::Arities ModuleContext::GetExprArity(const Expr& expr) const { + switch (expr.type()) { + case ExprType::AtomicNotify: + case ExprType::AtomicRmw: + case ExprType::Binary: + case ExprType::Compare: + case ExprType::TableGrow: + return {2, 1}; + + case ExprType::AtomicStore: + case ExprType::Store: + case ExprType::TableSet: + return {2, 0}; + + case ExprType::Block: + return {0, cast<BlockExpr>(&expr)->block.decl.sig.GetNumResults()}; + + case ExprType::Br: + return {GetLabelArity(cast<BrExpr>(&expr)->var), 1, true}; + + case ExprType::BrIf: { + Index arity = GetLabelArity(cast<BrIfExpr>(&expr)->var); + return {arity + 1, arity}; + } + + case ExprType::BrTable: + return {GetLabelArity(cast<BrTableExpr>(&expr)->default_target) + 1, 1, + true}; + + case ExprType::Call: { + const Var& var = cast<CallExpr>(&expr)->var; + return {GetFuncParamCount(var), GetFuncResultCount(var)}; + } + + case ExprType::ReturnCall: { + const Var& var = cast<ReturnCallExpr>(&expr)->var; + return {GetFuncParamCount(var), GetFuncResultCount(var), true}; + } + + case ExprType::CallIndirect: { + const auto* ci_expr = cast<CallIndirectExpr>(&expr); + return {ci_expr->decl.GetNumParams() + 1, ci_expr->decl.GetNumResults()}; + } + + case ExprType::CallRef: { + const Var& var = cast<CallRefExpr>(&expr)->function_type_index; + return {GetFuncParamCount(var) + 1, GetFuncResultCount(var)}; + } + + case ExprType::ReturnCallIndirect: { + const auto* rci_expr = cast<ReturnCallIndirectExpr>(&expr); + return {rci_expr->decl.GetNumParams() + 1, rci_expr->decl.GetNumResults(), + true}; + } + + case ExprType::Const: + case ExprType::GlobalGet: + case ExprType::LocalGet: + case ExprType::MemorySize: + case ExprType::TableSize: + case ExprType::RefNull: + case ExprType::RefFunc: + return {0, 1}; + + case ExprType::Unreachable: + return {0, 1, true}; + + case ExprType::DataDrop: + case ExprType::ElemDrop: + case ExprType::AtomicFence: + case ExprType::CodeMetadata: + return {0, 0}; + + case ExprType::MemoryInit: + case ExprType::TableInit: + case ExprType::MemoryFill: + case ExprType::MemoryCopy: + case ExprType::TableCopy: + case ExprType::TableFill: + return {3, 0}; + + case ExprType::AtomicLoad: + case ExprType::Convert: + case ExprType::Load: + case ExprType::LocalTee: + case ExprType::MemoryGrow: + case ExprType::Unary: + case ExprType::TableGet: + case ExprType::RefIsNull: + case ExprType::LoadSplat: + case ExprType::LoadZero: + return {1, 1}; + + case ExprType::Drop: + case ExprType::GlobalSet: + case ExprType::LocalSet: + return {1, 0}; + + case ExprType::If: + return {1, cast<IfExpr>(&expr)->true_.decl.sig.GetNumResults()}; + + case ExprType::Loop: + return {0, cast<LoopExpr>(&expr)->block.decl.sig.GetNumResults()}; + + case ExprType::Nop: + return {0, 0}; + + case ExprType::Return: + return {static_cast<Index>(current_func_->decl.sig.result_types.size()), + 1, true}; + + case ExprType::Rethrow: + return {0, 0, true}; + + case ExprType::AtomicRmwCmpxchg: + case ExprType::AtomicWait: + case ExprType::Select: + return {3, 1}; + + case ExprType::Throw: { + auto throw_ = cast<ThrowExpr>(&expr); + Index operand_count = 0; + if (Tag* tag = module.GetTag(throw_->var)) { + operand_count = tag->decl.sig.param_types.size(); + } + return {operand_count, 0, true}; + } + + case ExprType::Try: + return {0, cast<TryExpr>(&expr)->block.decl.sig.GetNumResults()}; + + case ExprType::Ternary: + return {3, 1}; + + case ExprType::SimdLaneOp: { + const Opcode opcode = cast<SimdLaneOpExpr>(&expr)->opcode; + switch (opcode) { + case Opcode::I8X16ExtractLaneS: + case Opcode::I8X16ExtractLaneU: + case Opcode::I16X8ExtractLaneS: + case Opcode::I16X8ExtractLaneU: + case Opcode::I32X4ExtractLane: + case Opcode::I64X2ExtractLane: + case Opcode::F32X4ExtractLane: + case Opcode::F64X2ExtractLane: + return {1, 1}; + + case Opcode::I8X16ReplaceLane: + case Opcode::I16X8ReplaceLane: + case Opcode::I32X4ReplaceLane: + case Opcode::I64X2ReplaceLane: + case Opcode::F32X4ReplaceLane: + case Opcode::F64X2ReplaceLane: + return {2, 1}; + + default: + fprintf(stderr, "Invalid Opcode for expr type: %s\n", + GetExprTypeName(expr)); + assert(0); + return {0, 0}; + } + } + + case ExprType::SimdLoadLane: + case ExprType::SimdStoreLane: { + return {2, 1}; + } + + case ExprType::SimdShuffleOp: + return {2, 1}; + } + + WABT_UNREACHABLE; +} |