Bug 1882714 [wpt PR 44850] - Update wpt metadata, a=testonly
[gecko.git] / third_party / wasm2c / src / expr-visitor.cc
blob05cd2798ca6a214a101e48c61d50acb1a52ea2b1
1 /*
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"
20 #include "wabt/ir.h"
22 namespace wabt {
24 ExprVisitor::ExprVisitor(Delegate* delegate) : delegate_(delegate) {}
26 Result ExprVisitor::VisitExpr(Expr* root_expr) {
27 state_stack_.clear();
28 expr_stack_.clear();
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();
38 switch (state) {
39 case State::Default:
40 PopDefault();
41 CHECK_RESULT(HandleDefaultState(expr));
42 break;
44 case State::Block: {
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++);
49 } else {
50 CHECK_RESULT(delegate_->EndBlockExpr(block_expr));
51 PopExprlist();
53 break;
56 case State::IfTrue: {
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++);
61 } else {
62 CHECK_RESULT(delegate_->AfterIfTrueExpr(if_expr));
63 PopExprlist();
64 PushExprlist(State::IfFalse, expr, if_expr->false_);
66 break;
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++);
74 } else {
75 CHECK_RESULT(delegate_->EndIfExpr(if_expr));
76 PopExprlist();
78 break;
81 case State::Loop: {
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++);
86 } else {
87 CHECK_RESULT(delegate_->EndLoopExpr(loop_expr));
88 PopExprlist();
90 break;
93 case State::Try: {
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++);
98 } else {
99 PopExprlist();
100 switch (try_expr->kind) {
101 case TryKind::Catch:
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);
106 } else {
107 CHECK_RESULT(delegate_->EndTryExpr(try_expr));
109 break;
110 case TryKind::Delegate:
111 CHECK_RESULT(delegate_->OnDelegateExpr(try_expr));
112 break;
113 case TryKind::Plain:
114 CHECK_RESULT(delegate_->EndTryExpr(try_expr));
115 break;
118 break;
121 case State::Catch: {
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++);
127 } else {
128 PopCatch();
129 catch_index++;
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);
134 } else {
135 CHECK_RESULT(delegate_->EndTryExpr(try_expr));
138 break;
143 return Result::Ok;
146 Result ExprVisitor::VisitExprList(ExprList& exprs) {
147 for (Expr& expr : exprs)
148 CHECK_RESULT(VisitExpr(&expr));
149 return Result::Ok;
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)));
160 break;
162 case ExprType::AtomicStore:
163 CHECK_RESULT(delegate_->OnAtomicStoreExpr(cast<AtomicStoreExpr>(expr)));
164 break;
166 case ExprType::AtomicRmw:
167 CHECK_RESULT(delegate_->OnAtomicRmwExpr(cast<AtomicRmwExpr>(expr)));
168 break;
170 case ExprType::AtomicRmwCmpxchg:
171 CHECK_RESULT(
172 delegate_->OnAtomicRmwCmpxchgExpr(cast<AtomicRmwCmpxchgExpr>(expr)));
173 break;
175 case ExprType::AtomicWait:
176 CHECK_RESULT(delegate_->OnAtomicWaitExpr(cast<AtomicWaitExpr>(expr)));
177 break;
179 case ExprType::AtomicFence:
180 CHECK_RESULT(delegate_->OnAtomicFenceExpr(cast<AtomicFenceExpr>(expr)));
181 break;
183 case ExprType::AtomicNotify:
184 CHECK_RESULT(delegate_->OnAtomicNotifyExpr(cast<AtomicNotifyExpr>(expr)));
185 break;
187 case ExprType::Binary:
188 CHECK_RESULT(delegate_->OnBinaryExpr(cast<BinaryExpr>(expr)));
189 break;
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);
195 break;
198 case ExprType::Br:
199 CHECK_RESULT(delegate_->OnBrExpr(cast<BrExpr>(expr)));
200 break;
202 case ExprType::BrIf:
203 CHECK_RESULT(delegate_->OnBrIfExpr(cast<BrIfExpr>(expr)));
204 break;
206 case ExprType::BrTable:
207 CHECK_RESULT(delegate_->OnBrTableExpr(cast<BrTableExpr>(expr)));
208 break;
210 case ExprType::Call:
211 CHECK_RESULT(delegate_->OnCallExpr(cast<CallExpr>(expr)));
212 break;
214 case ExprType::CallIndirect:
215 CHECK_RESULT(delegate_->OnCallIndirectExpr(cast<CallIndirectExpr>(expr)));
216 break;
218 case ExprType::CallRef:
219 CHECK_RESULT(delegate_->OnCallRefExpr(cast<CallRefExpr>(expr)));
220 break;
222 case ExprType::CodeMetadata:
223 CHECK_RESULT(delegate_->OnCodeMetadataExpr(cast<CodeMetadataExpr>(expr)));
224 break;
226 case ExprType::Compare:
227 CHECK_RESULT(delegate_->OnCompareExpr(cast<CompareExpr>(expr)));
228 break;
230 case ExprType::Const:
231 CHECK_RESULT(delegate_->OnConstExpr(cast<ConstExpr>(expr)));
232 break;
234 case ExprType::Convert:
235 CHECK_RESULT(delegate_->OnConvertExpr(cast<ConvertExpr>(expr)));
236 break;
238 case ExprType::Drop:
239 CHECK_RESULT(delegate_->OnDropExpr(cast<DropExpr>(expr)));
240 break;
242 case ExprType::GlobalGet:
243 CHECK_RESULT(delegate_->OnGlobalGetExpr(cast<GlobalGetExpr>(expr)));
244 break;
246 case ExprType::GlobalSet:
247 CHECK_RESULT(delegate_->OnGlobalSetExpr(cast<GlobalSetExpr>(expr)));
248 break;
250 case ExprType::If: {
251 auto if_expr = cast<IfExpr>(expr);
252 CHECK_RESULT(delegate_->BeginIfExpr(if_expr));
253 PushExprlist(State::IfTrue, expr, if_expr->true_.exprs);
254 break;
257 case ExprType::Load:
258 CHECK_RESULT(delegate_->OnLoadExpr(cast<LoadExpr>(expr)));
259 break;
261 case ExprType::LoadSplat:
262 CHECK_RESULT(delegate_->OnLoadSplatExpr(cast<LoadSplatExpr>(expr)));
263 break;
265 case ExprType::LoadZero:
266 CHECK_RESULT(delegate_->OnLoadZeroExpr(cast<LoadZeroExpr>(expr)));
267 break;
269 case ExprType::LocalGet:
270 CHECK_RESULT(delegate_->OnLocalGetExpr(cast<LocalGetExpr>(expr)));
271 break;
273 case ExprType::LocalSet:
274 CHECK_RESULT(delegate_->OnLocalSetExpr(cast<LocalSetExpr>(expr)));
275 break;
277 case ExprType::LocalTee:
278 CHECK_RESULT(delegate_->OnLocalTeeExpr(cast<LocalTeeExpr>(expr)));
279 break;
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);
285 break;
288 case ExprType::MemoryCopy:
289 CHECK_RESULT(delegate_->OnMemoryCopyExpr(cast<MemoryCopyExpr>(expr)));
290 break;
292 case ExprType::DataDrop:
293 CHECK_RESULT(delegate_->OnDataDropExpr(cast<DataDropExpr>(expr)));
294 break;
296 case ExprType::MemoryFill:
297 CHECK_RESULT(delegate_->OnMemoryFillExpr(cast<MemoryFillExpr>(expr)));
298 break;
300 case ExprType::MemoryGrow:
301 CHECK_RESULT(delegate_->OnMemoryGrowExpr(cast<MemoryGrowExpr>(expr)));
302 break;
304 case ExprType::MemoryInit:
305 CHECK_RESULT(delegate_->OnMemoryInitExpr(cast<MemoryInitExpr>(expr)));
306 break;
308 case ExprType::MemorySize:
309 CHECK_RESULT(delegate_->OnMemorySizeExpr(cast<MemorySizeExpr>(expr)));
310 break;
312 case ExprType::TableCopy:
313 CHECK_RESULT(delegate_->OnTableCopyExpr(cast<TableCopyExpr>(expr)));
314 break;
316 case ExprType::ElemDrop:
317 CHECK_RESULT(delegate_->OnElemDropExpr(cast<ElemDropExpr>(expr)));
318 break;
320 case ExprType::TableInit:
321 CHECK_RESULT(delegate_->OnTableInitExpr(cast<TableInitExpr>(expr)));
322 break;
324 case ExprType::TableGet:
325 CHECK_RESULT(delegate_->OnTableGetExpr(cast<TableGetExpr>(expr)));
326 break;
328 case ExprType::TableSet:
329 CHECK_RESULT(delegate_->OnTableSetExpr(cast<TableSetExpr>(expr)));
330 break;
332 case ExprType::TableGrow:
333 CHECK_RESULT(delegate_->OnTableGrowExpr(cast<TableGrowExpr>(expr)));
334 break;
336 case ExprType::TableSize:
337 CHECK_RESULT(delegate_->OnTableSizeExpr(cast<TableSizeExpr>(expr)));
338 break;
340 case ExprType::TableFill:
341 CHECK_RESULT(delegate_->OnTableFillExpr(cast<TableFillExpr>(expr)));
342 break;
344 case ExprType::RefFunc:
345 CHECK_RESULT(delegate_->OnRefFuncExpr(cast<RefFuncExpr>(expr)));
346 break;
348 case ExprType::RefNull:
349 CHECK_RESULT(delegate_->OnRefNullExpr(cast<RefNullExpr>(expr)));
350 break;
352 case ExprType::RefIsNull:
353 CHECK_RESULT(delegate_->OnRefIsNullExpr(cast<RefIsNullExpr>(expr)));
354 break;
356 case ExprType::Nop:
357 CHECK_RESULT(delegate_->OnNopExpr(cast<NopExpr>(expr)));
358 break;
360 case ExprType::Rethrow:
361 CHECK_RESULT(delegate_->OnRethrowExpr(cast<RethrowExpr>(expr)));
362 break;
364 case ExprType::Return:
365 CHECK_RESULT(delegate_->OnReturnExpr(cast<ReturnExpr>(expr)));
366 break;
368 case ExprType::ReturnCall:
369 CHECK_RESULT(delegate_->OnReturnCallExpr(cast<ReturnCallExpr>(expr)));
370 break;
372 case ExprType::ReturnCallIndirect:
373 CHECK_RESULT(delegate_->OnReturnCallIndirectExpr(
374 cast<ReturnCallIndirectExpr>(expr)));
375 break;
377 case ExprType::Select:
378 CHECK_RESULT(delegate_->OnSelectExpr(cast<SelectExpr>(expr)));
379 break;
381 case ExprType::Store:
382 CHECK_RESULT(delegate_->OnStoreExpr(cast<StoreExpr>(expr)));
383 break;
385 case ExprType::Throw:
386 CHECK_RESULT(delegate_->OnThrowExpr(cast<ThrowExpr>(expr)));
387 break;
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);
393 break;
396 case ExprType::Unary:
397 CHECK_RESULT(delegate_->OnUnaryExpr(cast<UnaryExpr>(expr)));
398 break;
400 case ExprType::Ternary:
401 CHECK_RESULT(delegate_->OnTernaryExpr(cast<TernaryExpr>(expr)));
402 break;
404 case ExprType::SimdLaneOp: {
405 CHECK_RESULT(delegate_->OnSimdLaneOpExpr(cast<SimdLaneOpExpr>(expr)));
406 break;
409 case ExprType::SimdLoadLane: {
410 CHECK_RESULT(delegate_->OnSimdLoadLaneExpr(cast<SimdLoadLaneExpr>(expr)));
411 break;
414 case ExprType::SimdStoreLane: {
415 CHECK_RESULT(
416 delegate_->OnSimdStoreLaneExpr(cast<SimdStoreLaneExpr>(expr)));
417 break;
420 case ExprType::SimdShuffleOp: {
421 CHECK_RESULT(
422 delegate_->OnSimdShuffleOpExpr(cast<SimdShuffleOpExpr>(expr)));
423 break;
426 case ExprType::Unreachable:
427 CHECK_RESULT(delegate_->OnUnreachableExpr(cast<UnreachableExpr>(expr)));
428 break;
431 return Result::Ok;
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,
457 Index catch_index,
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();
472 } // namespace wabt