/*
* Copyright 2017 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.
*/
#ifndef WABT_EXPR_VISITOR_H_
#define WABT_EXPR_VISITOR_H_
#include "wabt/common.h"
#include "wabt/ir.h"
namespace wabt {
class ExprVisitor {
public:
class Delegate;
class DelegateNop;
explicit ExprVisitor(Delegate* delegate);
Result VisitExpr(Expr*);
Result VisitExprList(ExprList&);
Result VisitFunc(Func*);
private:
enum class State {
Default,
Block,
IfTrue,
IfFalse,
Loop,
Try,
Catch,
};
Result HandleDefaultState(Expr*);
void PushDefault(Expr*);
void PopDefault();
void PushExprlist(State state, Expr*, ExprList&);
void PopExprlist();
void PushCatch(Expr*, Index catch_index, ExprList&);
void PopCatch();
Delegate* delegate_;
// Use parallel arrays instead of array of structs so we can avoid allocating
// unneeded objects. ExprList::iterator has no default constructor, so it
// must only be allocated for states that use it.
std::vector<State> state_stack_;
std::vector<Expr*> expr_stack_;
std::vector<ExprList::iterator> expr_iter_stack_;
std::vector<Index> catch_index_stack_;
};
class ExprVisitor::Delegate {
public:
virtual ~Delegate() {}
virtual Result OnBinaryExpr(BinaryExpr*) =
0;
virtual Result BeginBlockExpr(BlockExpr*) =
0;
virtual Result EndBlockExpr(BlockExpr*) =
0;
virtual Result OnBrExpr(BrExpr*) =
0;
virtual Result OnBrIfExpr(BrIfExpr*) =
0;
virtual Result OnBrTableExpr(BrTableExpr*) =
0;
virtual Result OnCallExpr(CallExpr*) =
0;
virtual Result OnCallIndirectExpr(CallIndirectExpr*) =
0;
virtual Result OnCallRefExpr(CallRefExpr*) =
0;
virtual Result OnCodeMetadataExpr(CodeMetadataExpr*) =
0;
virtual Result OnCompareExpr(CompareExpr*) =
0;
virtual Result OnConstExpr(ConstExpr*) =
0;
virtual Result OnConvertExpr(ConvertExpr*) =
0;
virtual Result OnDropExpr(DropExpr*) =
0;
virtual Result OnGlobalGetExpr(GlobalGetExpr*) =
0;
virtual Result OnGlobalSetExpr(GlobalSetExpr*) =
0;
virtual Result BeginIfExpr(IfExpr*) =
0;
virtual Result AfterIfTrueExpr(IfExpr*) =
0;
virtual Result EndIfExpr(IfExpr*) =
0;
virtual Result OnLoadExpr(LoadExpr*) =
0;
virtual Result OnLocalGetExpr(LocalGetExpr*) =
0;
virtual Result OnLocalSetExpr(LocalSetExpr*) =
0;
virtual Result OnLocalTeeExpr(LocalTeeExpr*) =
0;
virtual Result BeginLoopExpr(LoopExpr*) =
0;
virtual Result EndLoopExpr(LoopExpr*) =
0;
virtual Result OnMemoryCopyExpr(MemoryCopyExpr*) =
0;
virtual Result OnDataDropExpr(DataDropExpr*) =
0;
virtual Result OnMemoryFillExpr(MemoryFillExpr*) =
0;
virtual Result OnMemoryGrowExpr(MemoryGrowExpr*) =
0;
virtual Result OnMemoryInitExpr(MemoryInitExpr*) =
0;
virtual Result OnMemorySizeExpr(MemorySizeExpr*) =
0;
virtual Result OnTableCopyExpr(TableCopyExpr*) =
0;
virtual Result OnElemDropExpr(ElemDropExpr*) =
0;
virtual Result OnTableInitExpr(TableInitExpr*) =
0;
virtual Result OnTableGetExpr(TableGetExpr*) =
0;
virtual Result OnTableSetExpr(TableSetExpr*) =
0;
virtual Result OnTableGrowExpr(TableGrowExpr*) =
0;
virtual Result OnTableSizeExpr(TableSizeExpr*) =
0;
virtual Result OnTableFillExpr(TableFillExpr*) =
0;
virtual Result OnRefFuncExpr(RefFuncExpr*) =
0;
virtual Result OnRefNullExpr(RefNullExpr*) =
0;
virtual Result OnRefIsNullExpr(RefIsNullExpr*) =
0;
virtual Result OnNopExpr(NopExpr*) =
0;
virtual Result OnReturnExpr(ReturnExpr*) =
0;
virtual Result OnReturnCallExpr(ReturnCallExpr*) =
0;
virtual Result OnReturnCallIndirectExpr(ReturnCallIndirectExpr*) =
0;
virtual Result OnSelectExpr(SelectExpr*) =
0;
virtual Result OnStoreExpr(StoreExpr*) =
0;
virtual Result OnUnaryExpr(UnaryExpr*) =
0;
virtual Result OnUnreachableExpr(UnreachableExpr*) =
0;
virtual Result BeginTryExpr(TryExpr*) =
0;
virtual Result OnCatchExpr(TryExpr*,
Catch*) =
0;
virtual Result OnDelegateExpr(TryExpr*) =
0;
virtual Result EndTryExpr(TryExpr*) =
0;
virtual Result OnThrowExpr(ThrowExpr*) =
0;
virtual Result OnRethrowExpr(RethrowExpr*) =
0;
virtual Result OnAtomicWaitExpr(AtomicWaitExpr*) =
0;
virtual Result OnAtomicFenceExpr(AtomicFenceExpr*) =
0;
virtual Result OnAtomicNotifyExpr(AtomicNotifyExpr*) =
0;
virtual Result OnAtomicLoadExpr(AtomicLoadExpr*) =
0;
virtual Result OnAtomicStoreExpr(AtomicStoreExpr*) =
0;
virtual Result OnAtomicRmwExpr(AtomicRmwExpr*) =
0;
virtual Result OnAtomicRmwCmpxchgExpr(AtomicRmwCmpxchgExpr*) =
0;
virtual Result OnTernaryExpr(TernaryExpr*) =
0;
virtual Result OnSimdLaneOpExpr(SimdLaneOpExpr*) =
0;
virtual Result OnSimdLoadLaneExpr(SimdLoadLaneExpr*) =
0;
virtual Result OnSimdStoreLaneExpr(SimdStoreLaneExpr*) =
0;
virtual Result OnSimdShuffleOpExpr(SimdShuffleOpExpr*) =
0;
virtual Result OnLoadSplatExpr(LoadSplatExpr*) =
0;
virtual Result OnLoadZeroExpr(LoadZeroExpr*) =
0;
};
class ExprVisitor::DelegateNop :
public ExprVisitor::Delegate {
public:
Result OnBinaryExpr(BinaryExpr*) override {
return Result::Ok; }
Result BeginBlockExpr(BlockExpr*) override {
return Result::Ok; }
Result EndBlockExpr(BlockExpr*) override {
return Result::Ok; }
Result OnBrExpr(BrExpr*) override {
return Result::Ok; }
Result OnBrIfExpr(BrIfExpr*) override {
return Result::Ok; }
Result OnBrTableExpr(BrTableExpr*) override {
return Result::Ok; }
Result OnCallExpr(CallExpr*) override {
return Result::Ok; }
Result OnCallIndirectExpr(CallIndirectExpr*) override {
return Result::Ok; }
Result OnCallRefExpr(CallRefExpr*) override {
return Result::Ok; }
Result OnCodeMetadataExpr(CodeMetadataExpr*) override {
return Result::Ok; }
Result OnCompareExpr(CompareExpr*) override {
return Result::Ok; }
Result OnConstExpr(ConstExpr*) override {
return Result::Ok; }
Result OnConvertExpr(ConvertExpr*) override {
return Result::Ok; }
Result OnDropExpr(DropExpr*) override {
return Result::Ok; }
Result OnGlobalGetExpr(GlobalGetExpr*) override {
return Result::Ok; }
Result OnGlobalSetExpr(GlobalSetExpr*) override {
return Result::Ok; }
Result BeginIfExpr(IfExpr*) override {
return Result::Ok; }
Result AfterIfTrueExpr(IfExpr*) override {
return Result::Ok; }
Result EndIfExpr(IfExpr*) override {
return Result::Ok; }
Result OnLoadExpr(LoadExpr*) override {
return Result::Ok; }
Result OnLocalGetExpr(LocalGetExpr*) override {
return Result::Ok; }
Result OnLocalSetExpr(LocalSetExpr*) override {
return Result::Ok; }
Result OnLocalTeeExpr(LocalTeeExpr*) override {
return Result::Ok; }
Result BeginLoopExpr(LoopExpr*) override {
return Result::Ok; }
Result EndLoopExpr(LoopExpr*) override {
return Result::Ok; }
Result OnMemoryCopyExpr(MemoryCopyExpr*) override {
return Result::Ok; }
Result OnDataDropExpr(DataDropExpr*) override {
return Result::Ok; }
Result OnMemoryFillExpr(MemoryFillExpr*) override {
return Result::Ok; }
Result OnMemoryGrowExpr(MemoryGrowExpr*) override {
return Result::Ok; }
Result OnMemoryInitExpr(MemoryInitExpr*) override {
return Result::Ok; }
Result OnMemorySizeExpr(MemorySizeExpr*) override {
return Result::Ok; }
Result OnTableCopyExpr(TableCopyExpr*) override {
return Result::Ok; }
Result OnElemDropExpr(ElemDropExpr*) override {
return Result::Ok; }
Result OnTableInitExpr(TableInitExpr*) override {
return Result::Ok; }
Result OnTableGetExpr(TableGetExpr*) override {
return Result::Ok; }
Result OnTableSetExpr(TableSetExpr*) override {
return Result::Ok; }
Result OnTableGrowExpr(TableGrowExpr*) override {
return Result::Ok; }
Result OnTableSizeExpr(TableSizeExpr*) override {
return Result::Ok; }
Result OnTableFillExpr(TableFillExpr*) override {
return Result::Ok; }
Result OnRefFuncExpr(RefFuncExpr*) override {
return Result::Ok; }
Result OnRefNullExpr(RefNullExpr*) override {
return Result::Ok; }
Result OnRefIsNullExpr(RefIsNullExpr*) override {
return Result::Ok; }
Result OnNopExpr(NopExpr*) override {
return Result::Ok; }
Result OnReturnExpr(ReturnExpr*) override {
return Result::Ok; }
Result OnReturnCallExpr(ReturnCallExpr*) override {
return Result::Ok; }
Result OnReturnCallIndirectExpr(ReturnCallIndirectExpr*) override {
return Result::Ok;
}
Result OnSelectExpr(SelectExpr*) override {
return Result::Ok; }
Result OnStoreExpr(StoreExpr*) override {
return Result::Ok; }
Result OnUnaryExpr(UnaryExpr*) override {
return Result::Ok; }
Result OnUnreachableExpr(UnreachableExpr*) override {
return Result::Ok; }
Result BeginTryExpr(TryExpr*) override {
return Result::Ok; }
Result OnCatchExpr(TryExpr*,
Catch*) override {
return Result::Ok; }
Result OnDelegateExpr(TryExpr*) override {
return Result::Ok; }
Result EndTryExpr(TryExpr*) override {
return Result::Ok; }
Result OnThrowExpr(ThrowExpr*) override {
return Result::Ok; }
Result OnRethrowExpr(RethrowExpr*) override {
return Result::Ok; }
Result OnAtomicWaitExpr(AtomicWaitExpr*) override {
return Result::Ok; }
Result OnAtomicFenceExpr(AtomicFenceExpr*) override {
return Result::Ok; }
Result OnAtomicNotifyExpr(AtomicNotifyExpr*) override {
return Result::Ok; }
Result OnAtomicLoadExpr(AtomicLoadExpr*) override {
return Result::Ok; }
Result OnAtomicStoreExpr(AtomicStoreExpr*) override {
return Result::Ok; }
Result OnAtomicRmwExpr(AtomicRmwExpr*) override {
return Result::Ok; }
Result OnAtomicRmwCmpxchgExpr(AtomicRmwCmpxchgExpr*) override {
return Result::Ok;
}
Result OnTernaryExpr(TernaryExpr*) override {
return Result::Ok; }
Result OnSimdLaneOpExpr(SimdLaneOpExpr*) override {
return Result::Ok; }
Result OnSimdLoadLaneExpr(SimdLoadLaneExpr*) override {
return Result::Ok; }
Result OnSimdStoreLaneExpr(SimdStoreLaneExpr*) override {
return Result::Ok; }
Result OnSimdShuffleOpExpr(SimdShuffleOpExpr*) override {
return Result::Ok; }
Result OnLoadSplatExpr(LoadSplatExpr*) override {
return Result::Ok; }
Result OnLoadZeroExpr(LoadZeroExpr*) override {
return Result::Ok; }
};
}
// namespace wabt
#endif // WABT_EXPR_VISITOR_H_