#include "ir/load-utils.h"
#include "ir/utils.h"
namespace wasm::ExpressionManipulator {
Expression*
flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) {
struct CopyTask {
Expression* original;
Expression** destPointer;
};
std::vector<CopyTask> tasks;
Expression* ret;
tasks.push_back({original, &ret});
while (!tasks.empty()) {
auto task = tasks.back();
tasks.pop_back();
auto* copy = custom(task.original);
if (copy) {
*task.destPointer = copy;
continue;
}
auto* original = task.original;
if (original == nullptr) {
*task.destPointer = nullptr;
continue;
}
#define DELEGATE_ID original->_id
#define DELEGATE_START(id) \
copy = wasm.allocator.alloc<id>(); \
[[maybe_unused]] auto* castOriginal = original->cast<id>(); \
[[maybe_unused]] auto* castCopy = copy->cast<id>();
#define DELEGATE_FIELD_CHILD(id, field) \
tasks.push_back({castOriginal->field, &castCopy->field});
#define DELEGATE_FIELD_CHILD_VECTOR(id, field) \
castCopy->field.resize(castOriginal->field.size()); \
for (Index i = 0; i < castOriginal->field.size(); i++) { \
tasks.push_back({castOriginal->field[i], &castCopy->field[i]}); \
}
#define COPY_FIELD(field) castCopy->field = castOriginal->field;
#define DELEGATE_FIELD_INT(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_LITERAL(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_NAME(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_TYPE(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_HEAPTYPE(id, field) COPY_FIELD(field)
#define DELEGATE_FIELD_ADDRESS(id, field) COPY_FIELD(field)
#define COPY_FIELD_LIST(field) \
for (Index i = 0; i < castOriginal->field.size(); i++) { \
castCopy->field[i] = castOriginal->field[i]; \
}
#define COPY_VECTOR(field) \
castCopy->field.resize(castOriginal->field.size()); \
COPY_FIELD_LIST(field)
#define COPY_ARRAY(field) \
assert(castCopy->field.size() == castOriginal->field.size()); \
COPY_FIELD_LIST(field)
#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field) COPY_VECTOR(field)
#define DELEGATE_FIELD_NAME_VECTOR(id, field) COPY_VECTOR(field)
#define DELEGATE_FIELD_TYPE_VECTOR(id, field) COPY_VECTOR(field)
#define DELEGATE_FIELD_INT_ARRAY(id, field) COPY_ARRAY(field)
#define DELEGATE_FIELD_INT_VECTOR(id, field) COPY_VECTOR(field)
#include "wasm-delegations-fields.def"
copy->type = original->type;
*task.destPointer = copy;
}
return ret;
}
void spliceIntoBlock(Block* block, Index index, Expression* add) {
block->list.insertAt(index, add);
block->finalize(block->type);
}
}