summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2022-05-27 16:58:24 -0700
committerGitHub <noreply@github.com>2022-05-27 16:58:24 -0700
commit838de5c4f374396a15d5700ebb51c3e0a89b5840 (patch)
tree1969623c389959f8341637e58130d5dae8c50be6 /src/wasm
parent410b7c92ea2e36b6a938fc34b4fd11e2eeea9fb3 (diff)
downloadbinaryen-838de5c4f374396a15d5700ebb51c3e0a89b5840.tar.gz
binaryen-838de5c4f374396a15d5700ebb51c3e0a89b5840.tar.bz2
binaryen-838de5c4f374396a15d5700ebb51c3e0a89b5840.zip
[Parser] Replace Signedness with ternary Sign (#4698)
Previously we were tracking whether integer tokens were signed but we did not differentiate between positive and negative signs. Unfortunately, without differentiating them, there's no way to tell the difference between an in-bounds negative integer and a wildly out-of-bounds positive integer when trying to perform bounds checks for s32 tokens. Fix the problem by tracking not only whether there is a sign on an integer token, but also what the sign is.
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wat-lexer.cpp44
1 files changed, 21 insertions, 23 deletions
diff --git a/src/wasm/wat-lexer.cpp b/src/wasm/wat-lexer.cpp
index 1992e9bab..4bea32b59 100644
--- a/src/wasm/wat-lexer.cpp
+++ b/src/wasm/wat-lexer.cpp
@@ -123,7 +123,7 @@ std::optional<int> getHexDigit(char c) {
// The result of lexing an integer token fragment.
struct LexIntResult : LexResult {
uint64_t n;
- Signedness signedness;
+ Sign sign;
};
// Lexing context that accumulates lexed input to produce an integer token
@@ -133,8 +133,7 @@ struct LexIntCtx : LexCtx {
private:
uint64_t n = 0;
- Signedness signedness = Unsigned;
- bool negative = false;
+ Sign sign = NoSign;
bool overflow = false;
public:
@@ -143,13 +142,12 @@ public:
// Lex only the underlying span, ignoring the overflow and value.
std::optional<LexIntResult> lexedRaw() {
if (auto basic = LexCtx::lexed()) {
- return LexIntResult{*basic, 0, Unsigned};
+ return LexIntResult{*basic, 0, NoSign};
}
return {};
}
std::optional<LexIntResult> lexed() {
- // Check most significant bit for overflow of signed numbers.
if (overflow) {
return {};
}
@@ -157,28 +155,28 @@ public:
if (!basic) {
return {};
}
- if (signedness == Signed) {
- if (negative) {
- if (n > (1ull << 63)) {
- // TODO: Add error production for signed underflow.
- return {};
- }
- } else {
- if (n > (1ull << 63) - 1) {
- // TODO: Add error production for signed overflow.
- return {};
- }
+ // Check most significant bit for overflow of signed numbers.
+ if (sign == Neg) {
+ if (n > (1ull << 63)) {
+ // TODO: Add error production for signed underflow.
+ return {};
+ }
+ } else if (sign == Pos) {
+ if (n > (1ull << 63) - 1) {
+ // TODO: Add error production for signed overflow.
+ return {};
}
}
- return LexIntResult{*basic, negative ? -n : n, signedness};
+ return LexIntResult{*basic, sign == Neg ? -n : n, sign};
}
void takeSign() {
if (takePrefix("+"sv)) {
- signedness = Signed;
+ sign = Pos;
} else if (takePrefix("-"sv)) {
- signedness = Signed;
- negative = true;
+ sign = Neg;
+ } else {
+ sign = NoSign;
}
}
@@ -799,7 +797,7 @@ void Lexer::lexToken() {
} else if (auto t = ident(next())) {
tok = Token{t->span, IdTok{}};
} else if (auto t = integer(next())) {
- tok = Token{t->span, IntTok{t->n, t->signedness}};
+ tok = Token{t->span, IntTok{t->n, t->sign}};
} else if (auto t = float_(next())) {
tok = Token{t->span, FloatTok{t->nanPayload, t->d}};
} else if (auto t = str(next())) {
@@ -834,7 +832,7 @@ bool TextPos::operator==(const TextPos& other) const {
}
bool IntTok::operator==(const IntTok& other) const {
- return n == other.n && signedness == other.signedness;
+ return n == other.n && sign == other.sign;
}
bool FloatTok::operator==(const FloatTok& other) const {
@@ -872,7 +870,7 @@ std::ostream& operator<<(std::ostream& os, const RParenTok&) {
std::ostream& operator<<(std::ostream& os, const IdTok&) { return os << "id"; }
std::ostream& operator<<(std::ostream& os, const IntTok& tok) {
- return os << tok.n << (tok.signedness == Signed ? " signed" : " unsigned");
+ return os << (tok.sign == Pos ? "+" : tok.sign == Neg ? "-" : "") << tok.n;
}
std::ostream& operator<<(std::ostream& os, const FloatTok& tok) {