author | Benjamin Bouvier <benj@benj.me> |
Wed, 21 Mar 2018 14:49:24 +0100 | |
changeset 413258 | 670d462e97cbd93bf7856ee6793ecd530394c928 |
parent 413257 | f8b79c586af6e9ee3cdd5b56fd8f84f8ce2d9900 |
child 413259 | f8a4c128ffd4989884dac54155430cffb04b947a |
push id | 33840 |
push user | apavel@mozilla.com |
push date | Fri, 13 Apr 2018 21:56:54 +0000 |
treeherder | mozilla-central@6547c27303bc [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | luke |
bugs | 1445272 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/wasm/WasmAST.h | file | annotate | diff | comparison | revisions | |
js/src/wasm/WasmTextToBinary.cpp | file | annotate | diff | comparison | revisions |
--- a/js/src/wasm/WasmAST.h +++ b/js/src/wasm/WasmAST.h @@ -204,16 +204,17 @@ enum class AstExprKind First, GetGlobal, GetLocal, GrowMemory, If, Load, Nop, Pop, + RefNull, Return, SetGlobal, SetLocal, TeeLocal, Store, TernaryOperator, UnaryOperator, Unreachable, @@ -1158,16 +1159,29 @@ class AstExtraConversionOperator final : op_(op), operand_(operand) {} NumericOp op() const { return op_; } AstExpr* operand() const { return operand_; } }; #endif +class AstRefNull final : public AstExpr +{ + ValType refType_; + public: + static const AstExprKind Kind = AstExprKind::RefNull; + explicit AstRefNull(ValType refType) + : AstExpr(Kind, ExprType::Limit), refType_(refType) + {} + ValType refType() const { + return refType_; + } +}; + // This is an artificial AST node which can fill operand slots in an AST // constructed from parsing or decoding stack-machine code that doesn't have // an inherent AST structure. class AstPop final : public AstExpr { public: static const AstExprKind Kind = AstExprKind::Pop; AstPop()
--- a/js/src/wasm/WasmTextToBinary.cpp +++ b/js/src/wasm/WasmTextToBinary.cpp @@ -110,16 +110,17 @@ class WasmToken Loop, Module, Mutable, Name, Nop, Offset, OpenParen, Param, + RefNull, Result, Return, SetGlobal, SetLocal, Shared, SignedInteger, Start, Store, @@ -326,16 +327,17 @@ class WasmToken case Drop: case GetGlobal: case GetLocal: case GrowMemory: case If: case Load: case Loop: case Nop: + case RefNull: case Return: case SetGlobal: case SetLocal: case Store: case TeeLocal: case TernaryOpcode: case UnaryOpcode: case Unreachable: @@ -883,16 +885,18 @@ WasmTokenStream::next() case '5': case '6': case '7': case '8': case '9': return literal(begin); case 'a': if (consume(u"align")) return WasmToken(WasmToken::Align, begin, cur_); if (consume(u"anyfunc")) return WasmToken(WasmToken::AnyFunc, begin, cur_); + if (consume(u"anyref")) + return WasmToken(WasmToken::ValueType, ValType::AnyRef, begin, cur_); #ifdef ENABLE_WASM_THREAD_OPS if (consume(u"atomic.wake")) return WasmToken(WasmToken::Wake, ThreadOp::Wake, begin, cur_); #endif break; case 'b': if (consume(u"block")) @@ -1660,16 +1664,23 @@ WasmTokenStream::next() return WasmToken(WasmToken::Param, begin, cur_); break; case 'r': if (consume(u"result")) return WasmToken(WasmToken::Result, begin, cur_); if (consume(u"return")) return WasmToken(WasmToken::Return, begin, cur_); + if (consume(u"ref.")) { + if (consume(u"null")) + return WasmToken(WasmToken::RefNull, begin, cur_); + if (consume(u"is_null")) + return WasmToken(WasmToken::UnaryOpcode, Op::RefIsNull, begin, cur_); + break; + } break; case 's': if (consume(u"select")) return WasmToken(WasmToken::TernaryOpcode, Op::Select, begin, cur_); if (consume(u"set_global")) return WasmToken(WasmToken::SetGlobal, begin, cur_); if (consume(u"set_local")) @@ -2928,16 +2939,29 @@ ParseGrowMemory(WasmParseContext& c, boo AstExpr* operand = ParseExpr(c, inParens); if (!operand) return nullptr; return new(c.lifo) AstGrowMemory(operand); } static AstExpr* +ParseRefNull(WasmParseContext& c) +{ + WasmToken token; + if (!c.ts.match(WasmToken::ValueType, &token, c.error)) + return nullptr; + if (token.valueType() != ValType::AnyRef) { + c.ts.generateError(token, "only anyref is supported for nullref", c.error); + return nullptr; + } + return new(c.lifo) AstRefNull(ValType::AnyRef); +} + +static AstExpr* ParseExprBody(WasmParseContext& c, WasmToken token, bool inParens) { if (!CheckRecursionLimitDontReport(c.stackLimit)) return nullptr; switch (token.kind()) { case WasmToken::Unreachable: return new(c.lifo) AstUnreachable; case WasmToken::AtomicCmpXchg: @@ -3003,16 +3027,18 @@ ParseExprBody(WasmParseContext& c, WasmT case WasmToken::UnaryOpcode: return ParseUnaryOperator(c, token.op(), inParens); case WasmToken::Nop: return new(c.lifo) AstNop(); case WasmToken::CurrentMemory: return new(c.lifo) AstCurrentMemory(); case WasmToken::GrowMemory: return ParseGrowMemory(c, inParens); + case WasmToken::RefNull: + return ParseRefNull(c); default: c.ts.generateError(token, c.error); return nullptr; } } static AstExpr* ParseExprInsideParens(WasmParseContext& c) @@ -4320,16 +4346,17 @@ ResolveWake(Resolver& r, AstWake& s) static bool ResolveExpr(Resolver& r, AstExpr& expr) { switch (expr.kind()) { case AstExprKind::Nop: case AstExprKind::Pop: case AstExprKind::Unreachable: case AstExprKind::CurrentMemory: + case AstExprKind::RefNull: return true; case AstExprKind::Drop: return ResolveDropOperator(r, expr.as<AstDrop>()); case AstExprKind::BinaryOperator: return ResolveBinaryOperator(r, expr.as<AstBinaryOperator>()); case AstExprKind::Block: return ResolveBlock(r, expr.as<AstBlock>()); case AstExprKind::Branch: @@ -4925,25 +4952,34 @@ EncodeWake(Encoder& e, AstWake& s) { return EncodeLoadStoreAddress(e, s.address()) && EncodeExpr(e, s.count()) && e.writeOp(ThreadOp::Wake) && EncodeLoadStoreFlags(e, s.address()); } static bool +EncodeRefNull(Encoder& e, AstRefNull& s) +{ + return e.writeOp(Op::RefNull) && + e.writeValType(s.refType()); +} + +static bool EncodeExpr(Encoder& e, AstExpr& expr) { switch (expr.kind()) { case AstExprKind::Pop: return true; case AstExprKind::Nop: return e.writeOp(Op::Nop); case AstExprKind::Unreachable: return e.writeOp(Op::Unreachable); + case AstExprKind::RefNull: + return EncodeRefNull(e, expr.as<AstRefNull>()); case AstExprKind::BinaryOperator: return EncodeBinaryOperator(e, expr.as<AstBinaryOperator>()); case AstExprKind::Block: return EncodeBlock(e, expr.as<AstBlock>()); case AstExprKind::Branch: return EncodeBranch(e, expr.as<AstBranch>()); case AstExprKind::Call: return EncodeCall(e, expr.as<AstCall>());