From 1b45938aadd6e03e9210d88436be9c393623fb42 Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Fri, 4 Mar 2016 17:09:47 -0800 Subject: Make initial and max memory sizes be in pages instead of bytes The AST and everything that uses it treats the values as pages. Javascript continues to use bytes. This matches v8 and sexpr-wasm, and the consensus from live discussion and PR209 in the spec. --- src/wasm-binary.h | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) (limited to 'src/wasm-binary.h') diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 8a03ca843..47da374c1 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -402,18 +402,10 @@ public: void writeMemory() { if (wasm->memory.max == 0) return; if (debug) std::cerr << "== writeMemory" << std::endl; - o << int8_t(BinaryConsts::Memory); - if (wasm->memory.initial == 0) { // XXX diverge from v8, 0 means 0, 1 and above are powers of 2 starting at 0 - o << int8_t(0); - } else { - o << int8_t(std::min(ceil(log2(wasm->memory.initial)), 31.0) + 1); // up to 31 bits, don't let ceil get us to UINT_MAX which can overflow - } - if (wasm->memory.max == 0) { - o << int8_t(0); - } else { - o << int8_t(std::min(ceil(log2(wasm->memory.max)), 31.0) + 1); - } - o << int8_t(1); // export memory + o << int8_t(BinaryConsts::Memory) + << LEB128(wasm->memory.initial) + << LEB128(wasm->memory.max) + << int8_t(1); // export memory } void writeSignatures() { @@ -1088,10 +1080,8 @@ public: void readMemory() { if (debug) std::cerr << "== readMemory" << std::endl; - size_t initial = getInt8(); - wasm.memory.initial = initial == 0 ? 0 : std::pow(2, initial - 1); - size_t max = getInt8(); - wasm.memory.max = max == 0 ? 0 : std::pow(2, max - 1); + wasm.memory.initial = getLEB128(); + wasm.memory.max = getLEB128(); verifyInt8(1); // export memory } @@ -1671,4 +1661,3 @@ public: } // namespace wasm #endif // wasm_wasm_binary_h - -- cgit v1.2.3 From 0c0850ed5e2a2e82ad42f803894defcc53692ccd Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Wed, 9 Mar 2016 13:05:41 -0800 Subject: Implement rotates --- check.py | 2 +- src/passes/Print.cpp | 2 ++ src/wasm-binary.h | 8 ++++++++ src/wasm-interpreter.h | 4 ++++ src/wasm-s-parser.h | 6 +++++- src/wasm.h | 29 ++++++++++++++++++++++++++++- test/spec | 2 +- 7 files changed, 49 insertions(+), 4 deletions(-) (limited to 'src/wasm-binary.h') diff --git a/check.py b/check.py index 926282eab..272e1394c 100755 --- a/check.py +++ b/check.py @@ -354,7 +354,7 @@ for t in tests: print '\n[ checking binaryen-shell spec testcases... ]\n' if len(requested) == 0: - BLACKLIST = ['i32.wast', 'i64.wast'] + BLACKLIST = [] spec_tests = [os.path.join('spec', t) for t in sorted(os.listdir(os.path.join('test', 'spec'))) if t not in BLACKLIST] else: spec_tests = requested[:] diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 91c4040f6..b69f7a977 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -284,6 +284,8 @@ struct PrintSExpression : public WasmVisitor { case Shl: o << "shl"; break; case ShrU: o << "shr_u"; break; case ShrS: o << "shr_s"; break; + case RotL: o << "rotl"; break; + case RotR: o << "rotr"; break; case Div: o << "div"; break; case CopySign: o << "copysign"; break; case Min: o << "min"; break; diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 47da374c1..715c06287 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -287,6 +287,10 @@ enum ASTNodes { F64ConvertF32 = 0xb2, F64ReinterpretI64 = 0xb3, I64ReinterpretF64 = 0xb5, + I32RotR = 0xb6, + I32RotL = 0xb7, + I64RotR = 0xb8, + I64RotL = 0xb9, I32ReinterpretF32 = 0xfe, // XXX not in v8 spec doc I32LoadMem8S = 0x20, @@ -883,6 +887,8 @@ public: case Shl: INT_TYPED_CODE(Shl);; case ShrU: INT_TYPED_CODE(ShrU); case ShrS: INT_TYPED_CODE(ShrS); + case RotL: INT_TYPED_CODE(RotL); + case RotR: INT_TYPED_CODE(RotR); case Div: FLOAT_TYPED_CODE(Div); case CopySign: FLOAT_TYPED_CODE(CopySign); case Min: FLOAT_TYPED_CODE(Min); @@ -1593,6 +1599,8 @@ public: INT_TYPED_CODE(Shl); INT_TYPED_CODE(ShrU); INT_TYPED_CODE(ShrS); + INT_TYPED_CODE(RotL); + INT_TYPED_CODE(RotR); FLOAT_TYPED_CODE(Div); FLOAT_TYPED_CODE(CopySign); FLOAT_TYPED_CODE(Min); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 2edaad846..f6a3e1027 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -464,6 +464,8 @@ private: case Shl: return left.shl(right.and_(Literal(int32_t(31)))); case ShrU: return left.shrU(right.and_(Literal(int32_t(31)))); case ShrS: return left.shrS(right.and_(Literal(int32_t(31)))); + case RotL: return left.rotL(right); + case RotR: return left.rotR(right); case Eq: return left.eq(right); case Ne: return left.ne(right); case LtS: return left.ltS(right); @@ -505,6 +507,8 @@ private: case Shl: return left.shl(right.and_(Literal(int64_t(63)))); case ShrU: return left.shrU(right.and_(Literal(int64_t(63)))); case ShrS: return left.shrS(right.and_(Literal(int64_t(63)))); + case RotL: return left.rotL(right); + case RotR: return left.rotR(right); case Eq: return left.eq(right); case Ne: return left.ne(right); case LtS: return left.ltS(right); diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 1cd614c1d..cfabbf52d 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -430,7 +430,8 @@ public: WasmType type = stringToWasmType(str, false, true); // Local copy to index into op without bounds checking. constexpr size_t maxNameSize = 15; - char op[maxNameSize + 1] = { '\0' }; + char op[maxNameSize + 1]; + memset(op, 0, maxNameSize + 1); // ensure the whole string is cleared. strncpy(op, dot + 1, maxNameSize); switch (op[0]) { case 'a': { @@ -523,6 +524,9 @@ public: if (op[2] == 'm') return makeBinary(s, op[4] == 'u' ? BinaryOp::RemU : BinaryOp::RemS, type); if (op[2] == 'i') return makeUnary(s, isWasmTypeFloat(type) ? UnaryOp::ReinterpretInt : UnaryOp::ReinterpretFloat, type); } + if (op[1] == 'o' && op[2] == 't') { + return makeBinary(s, op[3] == 'l' ? BinaryOp::RotL : BinaryOp::RotR, type); + } abort_on(op); } case 's': { diff --git a/src/wasm.h b/src/wasm.h index ce6b9d294..26b5e18e1 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -45,6 +45,7 @@ #include #include +#include #include #include #include @@ -503,6 +504,32 @@ public: default: WASM_UNREACHABLE(); } } + template + static T rol(T val, T count) { + T mask = sizeof(T) * CHAR_BIT - 1; + count &= mask; + return (val << count) | (val >> (-count & mask)); + } + Literal rotL(const Literal& other) const { + switch (type) { + case WasmType::i32: return Literal(rol(uint32_t(i32), uint32_t(other.i32))); + case WasmType::i64: return Literal(rol(uint64_t(i64), uint64_t(other.i64))); + default: WASM_UNREACHABLE(); + } + } + template + static T ror (T val, T count) { + T mask = sizeof(T) * CHAR_BIT - 1; + count &= mask; + return (val >> count) | (val << (-count & mask)); + } + Literal rotR(const Literal& other) const { + switch (type) { + case WasmType::i32: return Literal(ror(uint32_t(i32), uint32_t(other.i32))); + case WasmType::i64: return Literal(ror(uint64_t(i64), uint64_t(other.i64))); + default: WASM_UNREACHABLE(); + } + } Literal eq(const Literal& other) const { switch (type) { @@ -676,7 +703,7 @@ enum UnaryOp { enum BinaryOp { Add, Sub, Mul, // int or float - DivS, DivU, RemS, RemU, And, Or, Xor, Shl, ShrU, ShrS, // int + DivS, DivU, RemS, RemU, And, Or, Xor, Shl, ShrU, ShrS, RotL, RotR, // int Div, CopySign, Min, Max, // float // relational ops Eq, Ne, // int or float diff --git a/test/spec b/test/spec index 3fdec99e9..6e6134562 160000 --- a/test/spec +++ b/test/spec @@ -1 +1 @@ -Subproject commit 3fdec99e94434b58d7477834c2be6b81c1aea918 +Subproject commit 6e6134562e70299bea9e85fc845e5ce210e96db6 -- cgit v1.2.3