2 * Copyright 2017 WebAssembly Community Group participants
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "wabt/expr-visitor.h"
19 #include "wabt/cast.h"
24 ExprVisitor::ExprVisitor(Delegate
* delegate
) : delegate_(delegate
) {}
26 Result
ExprVisitor::VisitExpr(Expr
* root_expr
) {
29 expr_iter_stack_
.clear();
30 catch_index_stack_
.clear();
32 PushDefault(root_expr
);
34 while (!state_stack_
.empty()) {
35 State state
= state_stack_
.back();
36 auto* expr
= expr_stack_
.back();
41 CHECK_RESULT(HandleDefaultState(expr
));
45 auto block_expr
= cast
<BlockExpr
>(expr
);
46 auto& iter
= expr_iter_stack_
.back();
47 if (iter
!= block_expr
->block
.exprs
.end()) {
48 PushDefault(&*iter
++);
50 CHECK_RESULT(delegate_
->EndBlockExpr(block_expr
));
57 auto if_expr
= cast
<IfExpr
>(expr
);
58 auto& iter
= expr_iter_stack_
.back();
59 if (iter
!= if_expr
->true_
.exprs
.end()) {
60 PushDefault(&*iter
++);
62 CHECK_RESULT(delegate_
->AfterIfTrueExpr(if_expr
));
64 PushExprlist(State::IfFalse
, expr
, if_expr
->false_
);
69 case State::IfFalse
: {
70 auto if_expr
= cast
<IfExpr
>(expr
);
71 auto& iter
= expr_iter_stack_
.back();
72 if (iter
!= if_expr
->false_
.end()) {
73 PushDefault(&*iter
++);
75 CHECK_RESULT(delegate_
->EndIfExpr(if_expr
));
82 auto loop_expr
= cast
<LoopExpr
>(expr
);
83 auto& iter
= expr_iter_stack_
.back();
84 if (iter
!= loop_expr
->block
.exprs
.end()) {
85 PushDefault(&*iter
++);
87 CHECK_RESULT(delegate_
->EndLoopExpr(loop_expr
));
94 auto try_expr
= cast
<TryExpr
>(expr
);
95 auto& iter
= expr_iter_stack_
.back();
96 if (iter
!= try_expr
->block
.exprs
.end()) {
97 PushDefault(&*iter
++);
100 switch (try_expr
->kind
) {
102 if (!try_expr
->catches
.empty()) {
103 Catch
& catch_
= try_expr
->catches
[0];
104 CHECK_RESULT(delegate_
->OnCatchExpr(try_expr
, &catch_
));
105 PushCatch(expr
, 0, catch_
.exprs
);
107 CHECK_RESULT(delegate_
->EndTryExpr(try_expr
));
110 case TryKind::Delegate
:
111 CHECK_RESULT(delegate_
->OnDelegateExpr(try_expr
));
114 CHECK_RESULT(delegate_
->EndTryExpr(try_expr
));
122 auto try_expr
= cast
<TryExpr
>(expr
);
123 Index catch_index
= catch_index_stack_
.back();
124 auto& iter
= expr_iter_stack_
.back();
125 if (iter
!= try_expr
->catches
[catch_index
].exprs
.end()) {
126 PushDefault(&*iter
++);
130 if (catch_index
< try_expr
->catches
.size()) {
131 Catch
& catch_
= try_expr
->catches
[catch_index
];
132 CHECK_RESULT(delegate_
->OnCatchExpr(try_expr
, &catch_
));
133 PushCatch(expr
, catch_index
, catch_
.exprs
);
135 CHECK_RESULT(delegate_
->EndTryExpr(try_expr
));
146 Result
ExprVisitor::VisitExprList(ExprList
& exprs
) {
147 for (Expr
& expr
: exprs
)
148 CHECK_RESULT(VisitExpr(&expr
));
152 Result
ExprVisitor::VisitFunc(Func
* func
) {
153 return VisitExprList(func
->exprs
);
156 Result
ExprVisitor::HandleDefaultState(Expr
* expr
) {
157 switch (expr
->type()) {
158 case ExprType::AtomicLoad
:
159 CHECK_RESULT(delegate_
->OnAtomicLoadExpr(cast
<AtomicLoadExpr
>(expr
)));
162 case ExprType::AtomicStore
:
163 CHECK_RESULT(delegate_
->OnAtomicStoreExpr(cast
<AtomicStoreExpr
>(expr
)));
166 case ExprType::AtomicRmw
:
167 CHECK_RESULT(delegate_
->OnAtomicRmwExpr(cast
<AtomicRmwExpr
>(expr
)));
170 case ExprType::AtomicRmwCmpxchg
:
172 delegate_
->OnAtomicRmwCmpxchgExpr(cast
<AtomicRmwCmpxchgExpr
>(expr
)));
175 case ExprType::AtomicWait
:
176 CHECK_RESULT(delegate_
->OnAtomicWaitExpr(cast
<AtomicWaitExpr
>(expr
)));
179 case ExprType::AtomicFence
:
180 CHECK_RESULT(delegate_
->OnAtomicFenceExpr(cast
<AtomicFenceExpr
>(expr
)));
183 case ExprType::AtomicNotify
:
184 CHECK_RESULT(delegate_
->OnAtomicNotifyExpr(cast
<AtomicNotifyExpr
>(expr
)));
187 case ExprType::Binary
:
188 CHECK_RESULT(delegate_
->OnBinaryExpr(cast
<BinaryExpr
>(expr
)));
191 case ExprType::Block
: {
192 auto block_expr
= cast
<BlockExpr
>(expr
);
193 CHECK_RESULT(delegate_
->BeginBlockExpr(block_expr
));
194 PushExprlist(State::Block
, expr
, block_expr
->block
.exprs
);
199 CHECK_RESULT(delegate_
->OnBrExpr(cast
<BrExpr
>(expr
)));
203 CHECK_RESULT(delegate_
->OnBrIfExpr(cast
<BrIfExpr
>(expr
)));
206 case ExprType::BrTable
:
207 CHECK_RESULT(delegate_
->OnBrTableExpr(cast
<BrTableExpr
>(expr
)));
211 CHECK_RESULT(delegate_
->OnCallExpr(cast
<CallExpr
>(expr
)));
214 case ExprType::CallIndirect
:
215 CHECK_RESULT(delegate_
->OnCallIndirectExpr(cast
<CallIndirectExpr
>(expr
)));
218 case ExprType::CallRef
:
219 CHECK_RESULT(delegate_
->OnCallRefExpr(cast
<CallRefExpr
>(expr
)));
222 case ExprType::CodeMetadata
:
223 CHECK_RESULT(delegate_
->OnCodeMetadataExpr(cast
<CodeMetadataExpr
>(expr
)));
226 case ExprType::Compare
:
227 CHECK_RESULT(delegate_
->OnCompareExpr(cast
<CompareExpr
>(expr
)));
230 case ExprType::Const
:
231 CHECK_RESULT(delegate_
->OnConstExpr(cast
<ConstExpr
>(expr
)));
234 case ExprType::Convert
:
235 CHECK_RESULT(delegate_
->OnConvertExpr(cast
<ConvertExpr
>(expr
)));
239 CHECK_RESULT(delegate_
->OnDropExpr(cast
<DropExpr
>(expr
)));
242 case ExprType::GlobalGet
:
243 CHECK_RESULT(delegate_
->OnGlobalGetExpr(cast
<GlobalGetExpr
>(expr
)));
246 case ExprType::GlobalSet
:
247 CHECK_RESULT(delegate_
->OnGlobalSetExpr(cast
<GlobalSetExpr
>(expr
)));
251 auto if_expr
= cast
<IfExpr
>(expr
);
252 CHECK_RESULT(delegate_
->BeginIfExpr(if_expr
));
253 PushExprlist(State::IfTrue
, expr
, if_expr
->true_
.exprs
);
258 CHECK_RESULT(delegate_
->OnLoadExpr(cast
<LoadExpr
>(expr
)));
261 case ExprType::LoadSplat
:
262 CHECK_RESULT(delegate_
->OnLoadSplatExpr(cast
<LoadSplatExpr
>(expr
)));
265 case ExprType::LoadZero
:
266 CHECK_RESULT(delegate_
->OnLoadZeroExpr(cast
<LoadZeroExpr
>(expr
)));
269 case ExprType::LocalGet
:
270 CHECK_RESULT(delegate_
->OnLocalGetExpr(cast
<LocalGetExpr
>(expr
)));
273 case ExprType::LocalSet
:
274 CHECK_RESULT(delegate_
->OnLocalSetExpr(cast
<LocalSetExpr
>(expr
)));
277 case ExprType::LocalTee
:
278 CHECK_RESULT(delegate_
->OnLocalTeeExpr(cast
<LocalTeeExpr
>(expr
)));
281 case ExprType::Loop
: {
282 auto loop_expr
= cast
<LoopExpr
>(expr
);
283 CHECK_RESULT(delegate_
->BeginLoopExpr(loop_expr
));
284 PushExprlist(State::Loop
, expr
, loop_expr
->block
.exprs
);
288 case ExprType::MemoryCopy
:
289 CHECK_RESULT(delegate_
->OnMemoryCopyExpr(cast
<MemoryCopyExpr
>(expr
)));
292 case ExprType::DataDrop
:
293 CHECK_RESULT(delegate_
->OnDataDropExpr(cast
<DataDropExpr
>(expr
)));
296 case ExprType::MemoryFill
:
297 CHECK_RESULT(delegate_
->OnMemoryFillExpr(cast
<MemoryFillExpr
>(expr
)));
300 case ExprType::MemoryGrow
:
301 CHECK_RESULT(delegate_
->OnMemoryGrowExpr(cast
<MemoryGrowExpr
>(expr
)));
304 case ExprType::MemoryInit
:
305 CHECK_RESULT(delegate_
->OnMemoryInitExpr(cast
<MemoryInitExpr
>(expr
)));
308 case ExprType::MemorySize
:
309 CHECK_RESULT(delegate_
->OnMemorySizeExpr(cast
<MemorySizeExpr
>(expr
)));
312 case ExprType::TableCopy
:
313 CHECK_RESULT(delegate_
->OnTableCopyExpr(cast
<TableCopyExpr
>(expr
)));
316 case ExprType::ElemDrop
:
317 CHECK_RESULT(delegate_
->OnElemDropExpr(cast
<ElemDropExpr
>(expr
)));
320 case ExprType::TableInit
:
321 CHECK_RESULT(delegate_
->OnTableInitExpr(cast
<TableInitExpr
>(expr
)));
324 case ExprType::TableGet
:
325 CHECK_RESULT(delegate_
->OnTableGetExpr(cast
<TableGetExpr
>(expr
)));
328 case ExprType::TableSet
:
329 CHECK_RESULT(delegate_
->OnTableSetExpr(cast
<TableSetExpr
>(expr
)));
332 case ExprType::TableGrow
:
333 CHECK_RESULT(delegate_
->OnTableGrowExpr(cast
<TableGrowExpr
>(expr
)));
336 case ExprType::TableSize
:
337 CHECK_RESULT(delegate_
->OnTableSizeExpr(cast
<TableSizeExpr
>(expr
)));
340 case ExprType::TableFill
:
341 CHECK_RESULT(delegate_
->OnTableFillExpr(cast
<TableFillExpr
>(expr
)));
344 case ExprType::RefFunc
:
345 CHECK_RESULT(delegate_
->OnRefFuncExpr(cast
<RefFuncExpr
>(expr
)));
348 case ExprType::RefNull
:
349 CHECK_RESULT(delegate_
->OnRefNullExpr(cast
<RefNullExpr
>(expr
)));
352 case ExprType::RefIsNull
:
353 CHECK_RESULT(delegate_
->OnRefIsNullExpr(cast
<RefIsNullExpr
>(expr
)));
357 CHECK_RESULT(delegate_
->OnNopExpr(cast
<NopExpr
>(expr
)));
360 case ExprType::Rethrow
:
361 CHECK_RESULT(delegate_
->OnRethrowExpr(cast
<RethrowExpr
>(expr
)));
364 case ExprType::Return
:
365 CHECK_RESULT(delegate_
->OnReturnExpr(cast
<ReturnExpr
>(expr
)));
368 case ExprType::ReturnCall
:
369 CHECK_RESULT(delegate_
->OnReturnCallExpr(cast
<ReturnCallExpr
>(expr
)));
372 case ExprType::ReturnCallIndirect
:
373 CHECK_RESULT(delegate_
->OnReturnCallIndirectExpr(
374 cast
<ReturnCallIndirectExpr
>(expr
)));
377 case ExprType::Select
:
378 CHECK_RESULT(delegate_
->OnSelectExpr(cast
<SelectExpr
>(expr
)));
381 case ExprType::Store
:
382 CHECK_RESULT(delegate_
->OnStoreExpr(cast
<StoreExpr
>(expr
)));
385 case ExprType::Throw
:
386 CHECK_RESULT(delegate_
->OnThrowExpr(cast
<ThrowExpr
>(expr
)));
389 case ExprType::Try
: {
390 auto try_expr
= cast
<TryExpr
>(expr
);
391 CHECK_RESULT(delegate_
->BeginTryExpr(try_expr
));
392 PushExprlist(State::Try
, expr
, try_expr
->block
.exprs
);
396 case ExprType::Unary
:
397 CHECK_RESULT(delegate_
->OnUnaryExpr(cast
<UnaryExpr
>(expr
)));
400 case ExprType::Ternary
:
401 CHECK_RESULT(delegate_
->OnTernaryExpr(cast
<TernaryExpr
>(expr
)));
404 case ExprType::SimdLaneOp
: {
405 CHECK_RESULT(delegate_
->OnSimdLaneOpExpr(cast
<SimdLaneOpExpr
>(expr
)));
409 case ExprType::SimdLoadLane
: {
410 CHECK_RESULT(delegate_
->OnSimdLoadLaneExpr(cast
<SimdLoadLaneExpr
>(expr
)));
414 case ExprType::SimdStoreLane
: {
416 delegate_
->OnSimdStoreLaneExpr(cast
<SimdStoreLaneExpr
>(expr
)));
420 case ExprType::SimdShuffleOp
: {
422 delegate_
->OnSimdShuffleOpExpr(cast
<SimdShuffleOpExpr
>(expr
)));
426 case ExprType::Unreachable
:
427 CHECK_RESULT(delegate_
->OnUnreachableExpr(cast
<UnreachableExpr
>(expr
)));
434 void ExprVisitor::PushDefault(Expr
* expr
) {
435 state_stack_
.emplace_back(State::Default
);
436 expr_stack_
.emplace_back(expr
);
439 void ExprVisitor::PopDefault() {
440 state_stack_
.pop_back();
441 expr_stack_
.pop_back();
444 void ExprVisitor::PushExprlist(State state
, Expr
* expr
, ExprList
& expr_list
) {
445 state_stack_
.emplace_back(state
);
446 expr_stack_
.emplace_back(expr
);
447 expr_iter_stack_
.emplace_back(expr_list
.begin());
450 void ExprVisitor::PopExprlist() {
451 state_stack_
.pop_back();
452 expr_stack_
.pop_back();
453 expr_iter_stack_
.pop_back();
456 void ExprVisitor::PushCatch(Expr
* expr
,
458 ExprList
& expr_list
) {
459 state_stack_
.emplace_back(State::Catch
);
460 expr_stack_
.emplace_back(expr
);
461 expr_iter_stack_
.emplace_back(expr_list
.begin());
462 catch_index_stack_
.emplace_back(catch_index
);
465 void ExprVisitor::PopCatch() {
466 state_stack_
.pop_back();
467 expr_stack_
.pop_back();
468 expr_iter_stack_
.pop_back();
469 catch_index_stack_
.pop_back();