#include "asm_v_wasm.h"
#include "asmjs/shared-constants.h"
#include "shared-constants.h"
#include <pass.h>
#include <wasm-builder.h>
#include <wasm.h>
namespace wasm {
static Name load_ptr("load_ptr");
static Name load_val_i32("load_val_i32");
static Name load_val_i64("load_val_i64");
static Name load_val_f32("load_val_f32");
static Name load_val_f64("load_val_f64");
static Name store_ptr("store_ptr");
static Name store_val_i32("store_val_i32");
static Name store_val_i64("store_val_i64");
static Name store_val_f32("store_val_f32");
static Name store_val_f64("store_val_f64");
struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> {
void visitLoad(Load* curr) {
id++;
Builder builder(*getModule());
auto indexType = getModule()->memory.indexType;
auto offset = builder.makeConstPtr(curr->offset.addr);
curr->ptr = builder.makeCall(load_ptr,
{builder.makeConst(int32_t(id)),
builder.makeConst(int32_t(curr->bytes)),
offset,
curr->ptr},
indexType);
Name target;
switch (curr->type.getBasic()) {
case Type::i32:
target = load_val_i32;
break;
case Type::i64:
target = load_val_i64;
break;
case Type::f32:
target = load_val_f32;
break;
case Type::f64:
target = load_val_f64;
break;
default:
return; }
replaceCurrent(builder.makeCall(
target, {builder.makeConst(int32_t(id)), curr}, curr->type));
}
void visitStore(Store* curr) {
id++;
Builder builder(*getModule());
auto indexType = getModule()->memory.indexType;
auto offset = builder.makeConstPtr(curr->offset.addr);
curr->ptr = builder.makeCall(store_ptr,
{builder.makeConst(int32_t(id)),
builder.makeConst(int32_t(curr->bytes)),
offset,
curr->ptr},
indexType);
Name target;
switch (curr->value->type.getBasic()) {
case Type::i32:
target = store_val_i32;
break;
case Type::i64:
target = store_val_i64;
break;
case Type::f32:
target = store_val_f32;
break;
case Type::f64:
target = store_val_f64;
break;
default:
return; }
curr->value = builder.makeCall(
target, {builder.makeConst(int32_t(id)), curr->value}, curr->value->type);
}
void visitModule(Module* curr) {
auto indexType = curr->memory.indexType;
addImport(
curr, load_ptr, {Type::i32, Type::i32, indexType, indexType}, indexType);
addImport(curr, load_val_i32, {Type::i32, Type::i32}, Type::i32);
addImport(curr, load_val_i64, {Type::i32, Type::i64}, Type::i64);
addImport(curr, load_val_f32, {Type::i32, Type::f32}, Type::f32);
addImport(curr, load_val_f64, {Type::i32, Type::f64}, Type::f64);
addImport(
curr, store_ptr, {Type::i32, Type::i32, indexType, indexType}, indexType);
addImport(curr, store_val_i32, {Type::i32, Type::i32}, Type::i32);
addImport(curr, store_val_i64, {Type::i32, Type::i64}, Type::i64);
addImport(curr, store_val_f32, {Type::i32, Type::f32}, Type::f32);
addImport(curr, store_val_f64, {Type::i32, Type::f64}, Type::f64);
}
private:
Index id;
void addImport(Module* curr, Name name, Type params, Type results) {
auto import = new Function;
import->name = name;
import->module = ENV;
import->base = name;
import->sig = Signature(params, results);
curr->addFunction(import);
}
};
Pass* createInstrumentMemoryPass() { return new InstrumentMemory(); }
}