Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
98224d6
fuzz atomic loads and stores
kripken Oct 9, 2017
162b311
refactor makeConcrete in -ttf
kripken Oct 12, 2017
923d6fd
refactor wake/wait finalization
kripken Oct 12, 2017
f83c017
fuzz atomics
kripken Oct 12, 2017
64ab0d5
add some asserts
kripken Oct 12, 2017
e98a918
test update
kripken Oct 12, 2017
9d31166
atomics support in interpreter
kripken Oct 12, 2017
d2d3d02
fixes
kripken Oct 12, 2017
675b7c8
very wip
kripken Oct 13, 2017
3e01950
ctors fix
kripken Oct 13, 2017
2bd2191
cleanup
kripken Oct 13, 2017
262ccd1
fix?
kripken Oct 13, 2017
1fb0ea9
fix
kripken Oct 13, 2017
ce49a95
fixes
kripken Oct 13, 2017
5eb762c
fix
kripken Oct 13, 2017
b464816
better
kripken Oct 13, 2017
95d04b5
fix
kripken Oct 13, 2017
4ae9400
fix
kripken Oct 13, 2017
5419aea
fix atomic store building bug
kripken Oct 14, 2017
fa7cec4
test update
kripken Oct 14, 2017
e439a24
validation fix
kripken Oct 15, 2017
2aceca1
fix
kripken Oct 15, 2017
7c76be7
fix
kripken Oct 15, 2017
dab7d3d
fix
kripken Oct 15, 2017
1623917
fix
kripken Oct 15, 2017
3b5648e
fix
kripken Oct 15, 2017
260c088
fix wait expectedType
kripken Oct 15, 2017
a22f66f
fix
kripken Oct 15, 2017
21a6aa2
Merge branch 'master' into atomics
kripken Oct 17, 2017
40baf85
atomics are unsigned
kripken Oct 17, 2017
2a7ee43
Merge remote-tracking branch 'origin/master' into atomics
kripken Oct 17, 2017
1ddb2c3
fix
kripken Oct 17, 2017
8422ed7
cleanup
kripken Oct 17, 2017
6912773
restore
kripken Oct 17, 2017
34a7be4
avoid unnecessary check in interpreter, the sign does not matter for …
kripken Oct 17, 2017
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
8 changes: 7 additions & 1 deletion src/asm2wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "pass.h"
#include "parsing.h"
#include "ast_utils.h"
#include "ast/bits.h"
#include "ast/branch-utils.h"
#include "ast/literal-utils.h"
#include "ast/trapping.h"
Expand Down Expand Up @@ -1884,7 +1885,12 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
View& view = views[heap];
wasm.memory.shared = true;
if (name == Atomics_load) {
return builder.makeAtomicLoad(view.bytes, view.signed_, 0, processUnshifted(ast[2][1], view.bytes), asmToWasmType(view.type));
Expression* ret = builder.makeAtomicLoad(view.bytes, 0, processUnshifted(ast[2][1], view.bytes), asmToWasmType(view.type));
if (view.signed_) {
// atomic loads are unsigned; add a signing
ret = Bits::makeSignExt(ret, view.bytes, wasm);
}
return ret;
} else if (name == Atomics_store) {
// asm.js stores return the value, wasm does not
auto type = asmToWasmType(view.type);
Expand Down
14 changes: 7 additions & 7 deletions src/ast/ExpressionManipulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,28 +97,28 @@ Expression* flexibleCopy(Expression* original, Module& wasm, CustomCopier custom
}
Expression* visitLoad(Load *curr) {
if (curr->isAtomic) {
return builder.makeAtomicLoad(curr->bytes, curr->signed_, curr->offset,
copy(curr->ptr), curr->type);
return builder.makeAtomicLoad(curr->bytes, curr->offset,
copy(curr->ptr), curr->type);
}
return builder.makeLoad(curr->bytes, curr->signed_, curr->offset, curr->align, copy(curr->ptr), curr->type);
}
Expression* visitStore(Store *curr) {
if (curr->isAtomic) {
return builder.makeAtomicStore(curr->bytes, curr->offset, copy(curr->ptr), copy(curr->value), curr->valueType);
return builder.makeAtomicStore(curr->bytes, curr->offset, copy(curr->ptr), copy(curr->value), curr->valueType);
}
return builder.makeStore(curr->bytes, curr->offset, curr->align, copy(curr->ptr), copy(curr->value), curr->valueType);
}
Expression* visitAtomicRMW(AtomicRMW* curr) {
return builder.makeAtomicRMW(curr->op, curr->bytes, curr->offset,
copy(curr->ptr), copy(curr->value), curr->type);
copy(curr->ptr), copy(curr->value), curr->type);
}
Expression* visitAtomicCmpxchg(AtomicCmpxchg* curr) {
return builder.makeAtomicCmpxchg(curr->bytes, curr->offset,
copy(curr->ptr), copy(curr->expected), copy(curr->replacement),
curr->type);
copy(curr->ptr), copy(curr->expected), copy(curr->replacement),
curr->type);
}
Expression* visitAtomicWait(AtomicWait* curr) {
return builder.makeAtomicWait(copy(curr->ptr), copy(curr->expected), copy(curr->timeout), curr->type);
return builder.makeAtomicWait(copy(curr->ptr), copy(curr->expected), copy(curr->timeout), curr->expectedType);
}
Expression* visitAtomicWake(AtomicWake* curr) {
return builder.makeAtomicWake(copy(curr->ptr), copy(curr->wakeCount));
Expand Down
39 changes: 39 additions & 0 deletions src/ast/bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#define wasm_ast_bits_h

#include "support/bits.h"
#include "wasm-builder.h"
#include "ast/literal-utils.h"

namespace wasm {

Expand Down Expand Up @@ -60,6 +62,43 @@ struct Bits {
}
WASM_UNREACHABLE();
}

static Expression* makeSignExt(Expression* value, Index bytes, Module& wasm) {
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Interesting. I guess when we add those to binaryen we can use them to replace makeSignExt etc.

Copy link
Member

Choose a reason for hiding this comment

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

Binaryen already has them: #1167

if (value->type == i32) {
if (bytes == 1 || bytes == 2) {
auto shifts = bytes == 1 ? 24 : 16;
Builder builder(wasm);
return builder.makeBinary(
ShrSInt32,
builder.makeBinary(
ShlInt32,
value,
LiteralUtils::makeFromInt32(shifts, i32, wasm)
),
LiteralUtils::makeFromInt32(shifts, i32, wasm)
);
}
assert(bytes == 4);
return value; // nothing to do
} else {
assert(value->type == i64);
if (bytes == 1 || bytes == 2 || bytes == 4) {
auto shifts = bytes == 1 ? 56 : (bytes == 2 ? 48 : 32);
Builder builder(wasm);
return builder.makeBinary(
ShrSInt64,
builder.makeBinary(
ShlInt64,
value,
LiteralUtils::makeFromInt32(shifts, i64, wasm)
),
LiteralUtils::makeFromInt32(shifts, i64, wasm)
);
}
assert(bytes == 8);
return value; // nothing to do
}
}
};

} // namespace wasm
Expand Down
2 changes: 1 addition & 1 deletion src/ast/global-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace wasm {

namespace GlobalUtils {
// find a global initialized to the value of an import, or null if no such global
inline Global* getGlobalInitializedToImport(Module&wasm, Name module, Name base) {
inline Global* getGlobalInitializedToImport(Module& wasm, Name module, Name base) {
// find the import
Name imported;
for (auto& import : wasm.imports) {
Expand Down
4 changes: 4 additions & 0 deletions src/passes/DeadCodeElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>>
case Expression::Id::HostId: DELEGATE(Host);
case Expression::Id::NopId: DELEGATE(Nop);
case Expression::Id::UnreachableId: break;
case Expression::Id::AtomicCmpxchgId: DELEGATE(AtomicCmpxchg);
case Expression::Id::AtomicRMWId: DELEGATE(AtomicRMW);
case Expression::Id::AtomicWaitId: DELEGATE(AtomicWait);
case Expression::Id::AtomicWakeId: DELEGATE(AtomicWake);
case Expression::Id::InvalidId:
default: WASM_UNREACHABLE();
}
Expand Down
6 changes: 6 additions & 0 deletions src/passes/Precompute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ class StandaloneExpressionRunner : public ExpressionRunner<StandaloneExpressionR
Flow visitAtomicCmpxchg(AtomicCmpxchg *curr) {
return Flow(NONSTANDALONE_FLOW);
}
Flow visitAtomicWait(AtomicWait *curr) {
return Flow(NONSTANDALONE_FLOW);
}
Flow visitAtomicWake(AtomicWake *curr) {
return Flow(NONSTANDALONE_FLOW);
}
Flow visitHost(Host *curr) {
return Flow(NONSTANDALONE_FLOW);
}
Expand Down
4 changes: 3 additions & 1 deletion src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,9 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}
static void printRMWSize(std::ostream& o, WasmType type, uint8_t bytes) {
prepareColor(o) << printWasmType(type) << ".atomic.rmw";
if (bytes != getWasmTypeSize(type)) {
if (type == unreachable) {
o << '?';
} else if (bytes != getWasmTypeSize(type)) {
if (bytes == 1) {
o << '8';
} else if (bytes == 2) {
Expand Down
9 changes: 8 additions & 1 deletion src/passes/SafeHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "asm_v_wasm.h"
#include "asmjs/shared-constants.h"
#include "wasm-builder.h"
#include "ast/bits.h"
#include "ast/import-utils.h"

namespace wasm {
Expand Down Expand Up @@ -229,7 +230,13 @@ struct SafeHeap : public Pass {
auto* load = module->allocator.alloc<Load>();
*load = style; // basically the same as the template we are given!
load->ptr = builder.makeGetLocal(2, i32);
block->list.push_back(load);
Expression* last = load;
if (load->isAtomic && load->signed_) {
// atomic loads cannot be signed, manually sign it
last = Bits::makeSignExt(load, load->bytes, *module);
load->signed_ = false;
}
block->list.push_back(last);
block->finalize(style.type);
func->body = block;
module->addFunction(func);
Expand Down
Loading