summaryrefslogtreecommitdiff
path: root/src/wasm-delegations-fields.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm-delegations-fields.h')
-rw-r--r--src/wasm-delegations-fields.h584
1 files changed, 584 insertions, 0 deletions
diff --git a/src/wasm-delegations-fields.h b/src/wasm-delegations-fields.h
new file mode 100644
index 000000000..fef4a9f7c
--- /dev/null
+++ b/src/wasm-delegations-fields.h
@@ -0,0 +1,584 @@
+/*
+ * Copyright 2020 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.
+ */
+
+// Implements a switch on an expression class ID, and has a case for each id
+// in which it runs delegates on the fields and immediates. All the delegates
+// are optional, so you can just provide what you want, and no code will be
+// emitted for the others.
+//
+// (The only mandatory thing to define is DELEGATE_ID which is the key for the
+// switch.)
+//
+// All #defines used here are undefed automatically at the end for you.
+//
+// Child pointers are emitted in reverse order (which is convenient for walking
+// by pushing them to a stack first).
+
+// Emits code at the start of the case for a class.
+#ifndef DELEGATE_START
+#define DELEGATE_START(id)
+#endif
+
+// Emits code at the end of the case for a class.
+#ifndef DELEGATE_END
+#define DELEGATE_END(id)
+#endif
+
+// Emits code to handle a child pointer.
+#ifndef DELEGATE_FIELD_CHILD
+#define DELEGATE_FIELD_CHILD(id, name)
+#endif
+
+// Emits code to handle an optional child pointer (if this is not defined, then
+// DELEGATE_FIELD_CHILD is called on it).
+#ifndef DELEGATE_FIELD_OPTIONAL_CHILD
+#define DELEGATE_FIELD_OPTIONAL_CHILD(id, name) DELEGATE_FIELD_CHILD(id, name)
+#endif
+
+// Emits code to handle a variable-sized vector of child pointers.
+#ifndef DELEGATE_FIELD_CHILD_VECTOR
+#define DELEGATE_FIELD_CHILD_VECTOR(id, name)
+#endif
+
+// Emits code to handle an integer value (bool, enum, Index, int32, or int64).
+#ifndef DELEGATE_FIELD_INT
+#define DELEGATE_FIELD_INT(id, name)
+#endif
+
+// Emits code to handle a std::array of fixed size of integer values (like a
+// SIMD mask).
+#ifndef DELEGATE_FIELD_INT_ARRAY
+#define DELEGATE_FIELD_INT_ARRAY(id, name)
+#endif
+
+// Emits code to handle a Literal.
+#ifndef DELEGATE_FIELD_LITERAL
+#define DELEGATE_FIELD_LITERAL(id, name)
+#endif
+
+// Emits code to handle a name (like a call target).
+#ifndef DELEGATE_FIELD_NAME
+#define DELEGATE_FIELD_NAME(id, name)
+#endif
+
+// Emits code to handle a scope name (like a br target).
+#ifndef DELEGATE_FIELD_SCOPE_NAME
+#define DELEGATE_FIELD_SCOPE_NAME(id, name)
+#endif
+
+// Emits code to handle a variable-sized vector of scope names (like a switch's
+// targets).
+#ifndef DELEGATE_FIELD_SCOPE_NAME_VECTOR
+#define DELEGATE_FIELD_SCOPE_NAME_VECTOR(id, name)
+#endif
+
+// Emits code to handle a Signature.
+#ifndef DELEGATE_FIELD_SIGNATURE
+#define DELEGATE_FIELD_SIGNATURE(id, name)
+#endif
+
+// Emits code to handle a type.
+#ifndef DELEGATE_FIELD_TYPE
+#define DELEGATE_FIELD_TYPE(id, name)
+#endif
+
+// Emits code to handle an address.
+#ifndef DELEGATE_FIELD_ADDRESS
+#define DELEGATE_FIELD_ADDRESS(id, name)
+#endif
+
+switch (DELEGATE_ID) {
+ case Expression::Id::InvalidId:
+ case Expression::Id::NumExpressionIds: {
+ WASM_UNREACHABLE("unexpected expression type");
+ }
+ case Expression::Id::BlockId: {
+ DELEGATE_START(Block);
+ DELEGATE_FIELD_CHILD_VECTOR(Block, list);
+ DELEGATE_FIELD_SCOPE_NAME(Block, name);
+ DELEGATE_END(Block);
+ break;
+ }
+ case Expression::Id::IfId: {
+ DELEGATE_START(If);
+ DELEGATE_FIELD_OPTIONAL_CHILD(If, ifFalse);
+ DELEGATE_FIELD_CHILD(If, ifTrue);
+ DELEGATE_FIELD_CHILD(If, condition);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::LoopId: {
+ DELEGATE_START(Loop);
+ DELEGATE_FIELD_CHILD(Loop, body);
+ DELEGATE_FIELD_SCOPE_NAME(Loop, name);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::BreakId: {
+ DELEGATE_START(Break);
+ DELEGATE_FIELD_OPTIONAL_CHILD(Break, condition);
+ DELEGATE_FIELD_OPTIONAL_CHILD(Break, value);
+ DELEGATE_FIELD_SCOPE_NAME(Break, name);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::SwitchId: {
+ DELEGATE_START(Switch);
+ DELEGATE_FIELD_CHILD(Switch, condition);
+ DELEGATE_FIELD_OPTIONAL_CHILD(Switch, value);
+ DELEGATE_FIELD_SCOPE_NAME(Switch, default_);
+ DELEGATE_FIELD_SCOPE_NAME_VECTOR(Switch, targets);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::CallId: {
+ DELEGATE_START(Call);
+ DELEGATE_FIELD_CHILD_VECTOR(Call, operands);
+ DELEGATE_FIELD_NAME(Call, target);
+ DELEGATE_FIELD_INT(Call, isReturn);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::CallIndirectId: {
+ DELEGATE_START(CallIndirect);
+ DELEGATE_FIELD_CHILD(CallIndirect, target);
+ DELEGATE_FIELD_CHILD_VECTOR(CallIndirect, operands);
+ DELEGATE_FIELD_SIGNATURE(CallIndirect, sig);
+ DELEGATE_FIELD_INT(CallIndirect, isReturn);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::LocalGetId: {
+ DELEGATE_START(LocalGet);
+ DELEGATE_FIELD_INT(LocalGet, index);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::LocalSetId: {
+ DELEGATE_START(LocalSet);
+ DELEGATE_FIELD_CHILD(LocalSet, value);
+ DELEGATE_FIELD_INT(LocalSet, index);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::GlobalGetId: {
+ DELEGATE_START(GlobalGet);
+ DELEGATE_FIELD_INT(GlobalGet, name);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::GlobalSetId: {
+ DELEGATE_START(GlobalSet);
+ DELEGATE_FIELD_CHILD(GlobalSet, value);
+ DELEGATE_FIELD_INT(GlobalSet, name);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::LoadId: {
+ DELEGATE_START(Load);
+ DELEGATE_FIELD_CHILD(Load, ptr);
+ DELEGATE_FIELD_INT(Load, bytes);
+ DELEGATE_FIELD_INT(Load, signed_);
+ DELEGATE_FIELD_ADDRESS(Load, offset);
+ DELEGATE_FIELD_ADDRESS(Load, align);
+ DELEGATE_FIELD_INT(Load, isAtomic);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::StoreId: {
+ DELEGATE_START(Store);
+ DELEGATE_FIELD_CHILD(Store, value);
+ DELEGATE_FIELD_CHILD(Store, ptr);
+ DELEGATE_FIELD_INT(Store, bytes);
+ DELEGATE_FIELD_ADDRESS(Store, offset);
+ DELEGATE_FIELD_ADDRESS(Store, align);
+ DELEGATE_FIELD_INT(Store, isAtomic);
+ DELEGATE_FIELD_TYPE(Store, valueType);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::AtomicRMWId: {
+ DELEGATE_START(AtomicRMW);
+ DELEGATE_FIELD_CHILD(AtomicRMW, value);
+ DELEGATE_FIELD_CHILD(AtomicRMW, ptr);
+ DELEGATE_FIELD_INT(AtomicRMW, op);
+ DELEGATE_FIELD_INT(AtomicRMW, bytes);
+ DELEGATE_FIELD_ADDRESS(AtomicRMW, offset);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::AtomicCmpxchgId: {
+ DELEGATE_START(AtomicCmpxchg);
+ DELEGATE_FIELD_CHILD(AtomicCmpxchg, replacement);
+ DELEGATE_FIELD_CHILD(AtomicCmpxchg, expected);
+ DELEGATE_FIELD_CHILD(AtomicCmpxchg, ptr);
+ DELEGATE_FIELD_INT(AtomicCmpxchg, bytes);
+ DELEGATE_FIELD_ADDRESS(AtomicCmpxchg, offset);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::AtomicWaitId: {
+ DELEGATE_START(AtomicWait);
+ DELEGATE_FIELD_CHILD(AtomicWait, timeout);
+ DELEGATE_FIELD_CHILD(AtomicWait, expected);
+ DELEGATE_FIELD_CHILD(AtomicWait, ptr);
+ DELEGATE_FIELD_ADDRESS(AtomicWait, offset);
+ DELEGATE_FIELD_TYPE(AtomicWait, expectedType);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::AtomicNotifyId: {
+ DELEGATE_START(AtomicNotify);
+ DELEGATE_FIELD_CHILD(AtomicNotify, notifyCount);
+ DELEGATE_FIELD_CHILD(AtomicNotify, ptr);
+ DELEGATE_FIELD_ADDRESS(AtomicNotify, offset);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::AtomicFenceId: {
+ DELEGATE_START(AtomicFence);
+ DELEGATE_FIELD_INT(AtomicFence, order);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::SIMDExtractId: {
+ DELEGATE_START(SIMDExtract);
+ DELEGATE_FIELD_CHILD(SIMDExtract, vec);
+ DELEGATE_FIELD_INT(SIMDExtract, op);
+ DELEGATE_FIELD_INT(SIMDExtract, index);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::SIMDReplaceId: {
+ DELEGATE_START(SIMDReplace);
+ DELEGATE_FIELD_CHILD(SIMDReplace, value);
+ DELEGATE_FIELD_CHILD(SIMDReplace, vec);
+ DELEGATE_FIELD_INT(SIMDReplace, op);
+ DELEGATE_FIELD_INT(SIMDReplace, index);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::SIMDShuffleId: {
+ DELEGATE_START(SIMDShuffle);
+ DELEGATE_FIELD_CHILD(SIMDShuffle, right);
+ DELEGATE_FIELD_CHILD(SIMDShuffle, left);
+ DELEGATE_FIELD_INT_ARRAY(SIMDShuffle, mask);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::SIMDTernaryId: {
+ DELEGATE_START(SIMDTernary);
+ DELEGATE_FIELD_CHILD(SIMDTernary, c);
+ DELEGATE_FIELD_CHILD(SIMDTernary, b);
+ DELEGATE_FIELD_CHILD(SIMDTernary, a);
+ DELEGATE_FIELD_INT(SIMDTernary, op);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::SIMDShiftId: {
+ DELEGATE_START(SIMDShift);
+ DELEGATE_FIELD_CHILD(SIMDShift, shift);
+ DELEGATE_FIELD_CHILD(SIMDShift, vec);
+ DELEGATE_FIELD_INT(SIMDShift, op);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::SIMDLoadId: {
+ DELEGATE_START(SIMDLoad);
+ DELEGATE_FIELD_CHILD(SIMDLoad, ptr);
+ DELEGATE_FIELD_INT(SIMDLoad, op);
+ DELEGATE_FIELD_ADDRESS(SIMDLoad, offset);
+ DELEGATE_FIELD_ADDRESS(SIMDLoad, align);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::SIMDLoadStoreLaneId: {
+ DELEGATE_START(SIMDLoadStoreLane);
+ DELEGATE_FIELD_CHILD(SIMDLoadStoreLane, vec);
+ DELEGATE_FIELD_CHILD(SIMDLoadStoreLane, ptr);
+ DELEGATE_FIELD_INT(SIMDLoadStoreLane, op);
+ DELEGATE_FIELD_ADDRESS(SIMDLoadStoreLane, offset);
+ DELEGATE_FIELD_ADDRESS(SIMDLoadStoreLane, align);
+ DELEGATE_FIELD_INT(SIMDLoadStoreLane, index);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::MemoryInitId: {
+ DELEGATE_START(MemoryInit);
+ DELEGATE_FIELD_CHILD(MemoryInit, size);
+ DELEGATE_FIELD_CHILD(MemoryInit, offset);
+ DELEGATE_FIELD_CHILD(MemoryInit, dest);
+ DELEGATE_FIELD_INT(MemoryInit, segment);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::DataDropId: {
+ DELEGATE_START(DataDrop);
+ DELEGATE_FIELD_INT(DataDrop, segment);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::MemoryCopyId: {
+ DELEGATE_START(MemoryCopy);
+ DELEGATE_FIELD_CHILD(MemoryCopy, size);
+ DELEGATE_FIELD_CHILD(MemoryCopy, source);
+ DELEGATE_FIELD_CHILD(MemoryCopy, dest);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::MemoryFillId: {
+ DELEGATE_START(MemoryFill);
+ DELEGATE_FIELD_CHILD(MemoryFill, size);
+ DELEGATE_FIELD_CHILD(MemoryFill, value);
+ DELEGATE_FIELD_CHILD(MemoryFill, dest);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::ConstId: {
+ DELEGATE_START(Const);
+ DELEGATE_FIELD_LITERAL(Const, value);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::UnaryId: {
+ DELEGATE_START(Unary);
+ DELEGATE_FIELD_CHILD(Unary, value);
+ DELEGATE_FIELD_INT(Unary, op);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::BinaryId: {
+ DELEGATE_START(Binary);
+ DELEGATE_FIELD_CHILD(Binary, right);
+ DELEGATE_FIELD_CHILD(Binary, left);
+ DELEGATE_FIELD_INT(Binary, op);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::SelectId: {
+ DELEGATE_START(Select);
+ DELEGATE_FIELD_CHILD(Select, condition);
+ DELEGATE_FIELD_CHILD(Select, ifFalse);
+ DELEGATE_FIELD_CHILD(Select, ifTrue);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::DropId: {
+ DELEGATE_START(Drop);
+ DELEGATE_FIELD_CHILD(Drop, value);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::ReturnId: {
+ DELEGATE_START(Return);
+ DELEGATE_FIELD_OPTIONAL_CHILD(Return, value);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::MemorySizeId: {
+ DELEGATE_START(MemorySize);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::MemoryGrowId: {
+ DELEGATE_START(MemoryGrow);
+ DELEGATE_FIELD_CHILD(MemoryGrow, delta);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::RefNullId: {
+ DELEGATE_START(RefNull);
+ DELEGATE_FIELD_TYPE(RefNull, type);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::RefIsNullId: {
+ DELEGATE_START(RefIsNull);
+ DELEGATE_FIELD_CHILD(RefIsNull, value);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::RefFuncId: {
+ DELEGATE_START(RefFunc);
+ DELEGATE_FIELD_NAME(RefFunc, func);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::RefEqId: {
+ DELEGATE_START(RefEq);
+ DELEGATE_FIELD_CHILD(RefEq, right);
+ DELEGATE_FIELD_CHILD(RefEq, left);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::TryId: {
+ DELEGATE_START(Try);
+ DELEGATE_FIELD_CHILD(Try, catchBody);
+ DELEGATE_FIELD_CHILD(Try, body);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::ThrowId: {
+ DELEGATE_START(Throw);
+ DELEGATE_FIELD_CHILD_VECTOR(Throw, operands);
+ DELEGATE_FIELD_NAME(Throw, event);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::RethrowId: {
+ DELEGATE_START(Rethrow);
+ DELEGATE_FIELD_CHILD(Rethrow, exnref);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::BrOnExnId: {
+ DELEGATE_START(BrOnExn);
+ DELEGATE_FIELD_CHILD(BrOnExn, exnref);
+ DELEGATE_FIELD_SCOPE_NAME(BrOnExn, name);
+ DELEGATE_FIELD_NAME(BrOnExn, event);
+ DELEGATE_FIELD_TYPE(BrOnExn, sent);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::NopId: {
+ DELEGATE_START(Nop);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::UnreachableId: {
+ DELEGATE_START(Unreachable);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::PopId: {
+ DELEGATE_START(Pop);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::TupleMakeId: {
+ DELEGATE_START(TupleMake);
+ DELEGATE_FIELD_CHILD_VECTOR(Tuple, operands);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::TupleExtractId: {
+ DELEGATE_START(TupleExtract);
+ DELEGATE_FIELD_CHILD(TupleExtract, tuple);
+ DELEGATE_FIELD_INT(TupleExtract, index);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::I31NewId: {
+ DELEGATE_START(I31New);
+ DELEGATE_FIELD_CHILD(I31New, value);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::I31GetId: {
+ DELEGATE_START(I31Get);
+ DELEGATE_FIELD_CHILD(I31Get, i31);
+ DELEGATE_FIELD_INT(I31Get, signed_);
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::RefTestId: {
+ DELEGATE_START(RefTest);
+ WASM_UNREACHABLE("TODO (gc): ref.test");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::RefCastId: {
+ DELEGATE_START(RefCast);
+ WASM_UNREACHABLE("TODO (gc): ref.cast");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::BrOnCastId: {
+ DELEGATE_START(BrOnCast);
+ WASM_UNREACHABLE("TODO (gc): br_on_cast");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::RttCanonId: {
+ DELEGATE_START(RttCanon);
+ WASM_UNREACHABLE("TODO (gc): rtt.canon");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::RttSubId: {
+ DELEGATE_START(RttSub);
+ WASM_UNREACHABLE("TODO (gc): rtt.sub");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::StructNewId: {
+ DELEGATE_START(StructNew);
+ WASM_UNREACHABLE("TODO (gc): struct.new");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::StructGetId: {
+ DELEGATE_START(StructGet);
+ WASM_UNREACHABLE("TODO (gc): struct.get");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::StructSetId: {
+ DELEGATE_START(StructSet);
+ WASM_UNREACHABLE("TODO (gc): struct.set");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::ArrayNewId: {
+ DELEGATE_START(ArrayNew);
+ WASM_UNREACHABLE("TODO (gc): array.new");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::ArrayGetId: {
+ DELEGATE_START(ArrayGet);
+ WASM_UNREACHABLE("TODO (gc): array.get");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::ArraySetId: {
+ DELEGATE_START(ArraySet);
+ WASM_UNREACHABLE("TODO (gc): array.set");
+ DELEGATE_END();
+ break;
+ }
+ case Expression::Id::ArrayLenId: {
+ DELEGATE_START(ArrayLen);
+ WASM_UNREACHABLE("TODO (gc): array.len");
+ DELEGATE_END();
+ break;
+ }
+}
+
+#undef DELEGATE_ID
+#undef DELEGATE_START
+#undef DELEGATE_END
+#undef DELEGATE_FIELD_CHILD
+#undef DELEGATE_FIELD_OPTIONAL_CHILD
+#undef DELEGATE_FIELD_CHILD_VECTOR
+#undef DELEGATE_FIELD_INT
+#undef DELEGATE_FIELD_INT_ARRAY
+#undef DELEGATE_FIELD_NAME
+#undef DELEGATE_FIELD_SCOPE_NAME
+#undef DELEGATE_FIELD_SCOPE_NAME_VECTOR
+#undef DELEGATE_FIELD_SIGNATURE
+#undef DELEGATE_FIELD_TYPE
+#undef DELEGATE_FIELD_ADDRESS