Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/asm2wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1772,6 +1772,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
assert(views.find(heap) != views.end());
View& view = views[heap];
auto ret = allocator.alloc<Store>();
ret->isAtomic = false;
ret->bytes = view.bytes;
ret->offset = 0;
ret->align = view.bytes;
Expand Down Expand Up @@ -1843,6 +1844,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
assert(views.find(heap) != views.end());
View& view = views[heap];
auto ret = allocator.alloc<Load>();
ret->isAtomic = false;
ret->bytes = view.bytes;
ret->signed_ = view.signed_;
ret->offset = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ BinaryenExpressionRef BinaryenLoad(BinaryenModuleRef module, uint32_t bytes, int
auto id = noteExpression(ret);
std::cout << " expressions[" << id << "] = BinaryenLoad(the_module, " << bytes << ", " << int(signed_) << ", " << offset << ", " << align << ", " << type << ", expressions[" << expressions[ptr] << "]);\n";
}

ret->isAtomic = false;
ret->bytes = bytes;
ret->signed_ = !!signed_;
ret->offset = offset;
Expand All @@ -566,7 +566,7 @@ BinaryenExpressionRef BinaryenStore(BinaryenModuleRef module, uint32_t bytes, ui
auto id = noteExpression(ret);
std::cout << " expressions[" << id << "] = BinaryenStore(the_module, " << bytes << ", " << offset << ", " << align << ", expressions[" << expressions[ptr] << "], expressions[" << expressions[value] << "], " << type << ");\n";
}

ret->isAtomic = false;
ret->bytes = bytes;
ret->offset = offset;
ret->align = align ? align : bytes;
Expand Down
2 changes: 1 addition & 1 deletion src/compiler-support.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

// If control flow reaches the point of the WASM_UNREACHABLE(), the program is
// undefined.
#if __has_builtin(__builtin_unreachable)
#if __has_builtin(__builtin_unreachable) && defined(NDEBUG)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this change do?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means that it uses __builtin_unreachable only in release mode, and aborts in debug mode. Makes catching bugs easier.

# define WASM_UNREACHABLE() __builtin_unreachable()
#elif defined(_MSC_VER)
# define WASM_UNREACHABLE() __assume(false)
Expand Down
8 changes: 6 additions & 2 deletions src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,9 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}
void visitLoad(Load *curr) {
o << '(';
prepareColor(o) << printWasmType(curr->type) << ".load";
prepareColor(o) << printWasmType(curr->type);
if (curr->isAtomic) o << ".atomic";
o << ".load";
if (curr->bytes < 4 || (curr->type == i64 && curr->bytes < 8)) {
if (curr->bytes == 1) {
o << '8';
Expand All @@ -322,7 +324,9 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}
void visitStore(Store *curr) {
o << '(';
prepareColor(o) << printWasmType(curr->valueType) << ".store";
prepareColor(o) << printWasmType(curr->valueType);
if (curr->isAtomic) o << ".atomic";
o << ".store";
if (curr->bytes < 4 || (curr->valueType == i64 && curr->bytes < 8)) {
if (curr->bytes == 1) {
o << '8';
Expand Down
2 changes: 2 additions & 0 deletions src/s2wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,7 @@ class S2WasmBuilder {
auto makeLoad = [&](WasmType type) {
skipComma();
auto curr = allocator->alloc<Load>();
curr->isAtomic = false;
curr->type = type;
int32_t bytes = getInt() / CHAR_BIT;
curr->bytes = bytes > 0 ? bytes : getWasmTypeSize(type);
Expand All @@ -939,6 +940,7 @@ class S2WasmBuilder {
};
auto makeStore = [&](WasmType type) {
auto curr = allocator->alloc<Store>();
curr->isAtomic = false;
curr->valueType = type;
s += strlen("store");
if(!isspace(*s)) {
Expand Down
25 changes: 22 additions & 3 deletions src/wasm-binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,26 @@ enum ASTNodes {
I32ReinterpretF32 = 0xbc,
I64ReinterpretF64 = 0xbd,
F32ReinterpretI32 = 0xbe,
F64ReinterpretI64 = 0xbf
F64ReinterpretI64 = 0xbf,

AtomicPrefix = 0xfe
};

enum AtomicOpcodes {
I32AtomicLoad = 0x10,
I64AtomicLoad = 0x11,
I32AtomicLoad8U = 0x12,
I32AtomicLoad16U = 0x13,
I64AtomicLoad8U = 0x14,
I64AtomicLoad16U = 0x15,
I64AtomicLoad32U = 0x16,
I32AtomicStore = 0x17,
I64AtomicStore = 0x18,
I32AtomicStore8 = 0x19,
I32AtomicStore16 = 0x1a,
I64AtomicStore8 = 0x1b,
I64AtomicStore16 = 0x1c,
I64AtomicStore32 = 0x1d
};

enum MemoryAccess {
Expand Down Expand Up @@ -812,8 +831,8 @@ class WasmBinaryBuilder {
void visitGetGlobal(GetGlobal *curr);
void visitSetGlobal(SetGlobal *curr);
void readMemoryAccess(Address& alignment, size_t bytes, Address& offset);
bool maybeVisitLoad(Expression*& out, uint8_t code);
bool maybeVisitStore(Expression*& out, uint8_t code);
bool maybeVisitLoad(Expression*& out, uint8_t code, bool isAtomic);
bool maybeVisitStore(Expression*& out, uint8_t code, bool isAtomic);
bool maybeVisitConst(Expression*& out, uint8_t code);
bool maybeVisitUnary(Expression*& out, uint8_t code);
bool maybeVisitBinary(Expression*& out, uint8_t code);
Expand Down
2 changes: 2 additions & 0 deletions src/wasm-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,14 @@ class Builder {
}
Load* makeLoad(unsigned bytes, bool signed_, uint32_t offset, unsigned align, Expression *ptr, WasmType type) {
auto* ret = allocator.alloc<Load>();
ret->isAtomic = false;
ret->bytes = bytes; ret->signed_ = signed_; ret->offset = offset; ret->align = align; ret->ptr = ptr;
ret->type = type;
return ret;
}
Store* makeStore(unsigned bytes, uint32_t offset, unsigned align, Expression *ptr, Expression *value, WasmType type) {
auto* ret = allocator.alloc<Store>();
ret->isAtomic = false;
ret->bytes = bytes; ret->offset = offset; ret->align = align; ret->ptr = ptr; ret->value = value; ret->valueType = type;
ret->finalize();
assert(isConcreteWasmType(ret->value->type) ? ret->value->type == type : true);
Expand Down
4 changes: 2 additions & 2 deletions src/wasm-s-parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ class SExpressionWasmBuilder {
Expression* makeBlock(Element& s);
Expression* makeThenOrElse(Element& s);
Expression* makeConst(Element& s, WasmType type);
Expression* makeLoad(Element& s, WasmType type);
Expression* makeStore(Element& s, WasmType type);
Expression* makeLoad(Element& s, WasmType type, bool isAtomic);
Expression* makeStore(Element& s, WasmType type, bool isAtomic);
Expression* makeIf(Element& s);
Expression* makeMaybeBlock(Element& s, size_t i, WasmType type);
Expression* makeLoop(Element& s);
Expand Down
10 changes: 10 additions & 0 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ class Expression {
HostId,
NopId,
UnreachableId,
AtomicRMWId,
NumExpressionIds
};
Id _id;
Expand Down Expand Up @@ -398,6 +399,7 @@ class Load : public SpecificExpression<Expression::LoadId> {
bool signed_;
Address offset;
Address align;
bool isAtomic;
Expression* ptr;

// type must be set during creation, cannot be inferred
Expand All @@ -413,6 +415,7 @@ class Store : public SpecificExpression<Expression::StoreId> {
uint8_t bytes;
Address offset;
Address align;
bool isAtomic;
Expression* ptr;
Expression* value;
WasmType valueType; // the store never returns a value
Expand Down Expand Up @@ -511,6 +514,13 @@ class Unreachable : public SpecificExpression<Expression::UnreachableId> {
Unreachable(MixedArena& allocator) : Unreachable() {}
};

class AtomicRMW : public SpecificExpression<Expression::AtomicRMWId> {
public:
AtomicRMW() {}
AtomicRMW(MixedArena& allocator) : AtomicRMW() {}
bool finalize();
};

// Globals

class Function {
Expand Down
Loading