Bug 1287220 - Baldr: update to binary version 0xc (r=luke)

MozReview-Commit-ID: EZmgEwtd4Yt
* * *
[mq]: fix-close-loop

MozReview-Commit-ID: IGx436dWetv
* * *
[mq]: ensure-webassembly-in-eval

MozReview-Commit-ID: J6eGrJPHN4A
* * *
[mq]: fix-unreachable

MozReview-Commit-ID: IBVUVuRRm4t
* * *
[mq]: update-names-section

MozReview-Commit-ID: 8LcjQh5lpcx
* * *
[mq]: skip-unknown

MozReview-Commit-ID: Ekj9t3ydS9a
This commit is contained in:
Dan Gohman 2016-09-23 09:13:15 -05:00
Родитель 903b01d434
Коммит 28d57ea0f3
162 изменённых файлов: 14684 добавлений и 6087 удалений

Просмотреть файл

@ -2955,7 +2955,6 @@ class MOZ_STACK_CLASS FunctionValidator
MOZ_ASSERT(expr == Expr::Br || expr == Expr::BrIf); MOZ_ASSERT(expr == Expr::Br || expr == Expr::BrIf);
MOZ_ASSERT(absolute < blockDepth_); MOZ_ASSERT(absolute < blockDepth_);
return encoder().writeExpr(expr) && return encoder().writeExpr(expr) &&
encoder().writeVarU32(0) && // break arity
encoder().writeVarU32(blockDepth_ - 1 - absolute); encoder().writeVarU32(blockDepth_ - 1 - absolute);
} }
void removeLabel(PropertyName* label, LabelMap* map) { void removeLabel(PropertyName* label, LabelMap* map) {
@ -2967,6 +2966,7 @@ class MOZ_STACK_CLASS FunctionValidator
public: public:
bool pushBreakableBlock() { bool pushBreakableBlock() {
return encoder().writeExpr(Expr::Block) && return encoder().writeExpr(Expr::Block) &&
encoder().writeFixedU8(uint8_t(ExprType::Void)) &&
breakableStack_.append(blockDepth_++); breakableStack_.append(blockDepth_++);
} }
bool popBreakableBlock() { bool popBreakableBlock() {
@ -2982,7 +2982,8 @@ class MOZ_STACK_CLASS FunctionValidator
} }
} }
blockDepth_++; blockDepth_++;
return encoder().writeExpr(Expr::Block); return encoder().writeExpr(Expr::Block) &&
encoder().writeFixedU8(uint8_t(ExprType::Void));
} }
bool popUnbreakableBlock(const NameVector* labels = nullptr) { bool popUnbreakableBlock(const NameVector* labels = nullptr) {
if (labels) { if (labels) {
@ -2995,6 +2996,7 @@ class MOZ_STACK_CLASS FunctionValidator
bool pushContinuableBlock() { bool pushContinuableBlock() {
return encoder().writeExpr(Expr::Block) && return encoder().writeExpr(Expr::Block) &&
encoder().writeFixedU8(uint8_t(ExprType::Void)) &&
continuableStack_.append(blockDepth_++); continuableStack_.append(blockDepth_++);
} }
bool popContinuableBlock() { bool popContinuableBlock() {
@ -3003,29 +3005,46 @@ class MOZ_STACK_CLASS FunctionValidator
} }
bool pushLoop() { bool pushLoop() {
return encoder().writeExpr(Expr::Loop) && return encoder().writeExpr(Expr::Block) &&
encoder().writeFixedU8(uint8_t(ExprType::Void)) &&
encoder().writeExpr(Expr::Loop) &&
encoder().writeFixedU8(uint8_t(ExprType::Void)) &&
breakableStack_.append(blockDepth_++) && breakableStack_.append(blockDepth_++) &&
continuableStack_.append(blockDepth_++); continuableStack_.append(blockDepth_++);
} }
bool popLoop() { bool popLoop() {
JS_ALWAYS_TRUE(continuableStack_.popCopy() == --blockDepth_); JS_ALWAYS_TRUE(continuableStack_.popCopy() == --blockDepth_);
JS_ALWAYS_TRUE(breakableStack_.popCopy() == --blockDepth_); JS_ALWAYS_TRUE(breakableStack_.popCopy() == --blockDepth_);
return encoder().writeExpr(Expr::End); return encoder().writeExpr(Expr::End) &&
encoder().writeExpr(Expr::End);
} }
bool pushIf() { bool pushIf(size_t* typeAt) {
++blockDepth_; ++blockDepth_;
return encoder().writeExpr(Expr::If); return encoder().writeExpr(Expr::If) &&
encoder().writePatchableFixedU7(typeAt);
} }
bool switchToElse() { bool switchToElse() {
MOZ_ASSERT(blockDepth_ > 0); MOZ_ASSERT(blockDepth_ > 0);
return encoder().writeExpr(Expr::Else); return encoder().writeExpr(Expr::Else);
} }
void setIfType(size_t typeAt, ExprType type) {
encoder().patchFixedU7(typeAt, uint8_t(type));
}
bool popIf() { bool popIf() {
MOZ_ASSERT(blockDepth_ > 0); MOZ_ASSERT(blockDepth_ > 0);
--blockDepth_; --blockDepth_;
return encoder().writeExpr(Expr::End); return encoder().writeExpr(Expr::End);
} }
bool popIf(size_t typeAt, ExprType type) {
MOZ_ASSERT(blockDepth_ > 0);
--blockDepth_;
if (!encoder().writeExpr(Expr::End))
return false;
setIfType(typeAt, type);
return true;
}
bool writeBreakIf() { bool writeBreakIf() {
return writeBr(breakableStack_.back(), Expr::BrIf); return writeBr(breakableStack_.back(), Expr::BrIf);
@ -3812,6 +3831,9 @@ IsLiteralOrConst(FunctionValidator& f, ParseNode* pn, NumLit* lit)
static bool static bool
CheckFinalReturn(FunctionValidator& f, ParseNode* lastNonEmptyStmt) CheckFinalReturn(FunctionValidator& f, ParseNode* lastNonEmptyStmt)
{ {
if (!f.encoder().writeExpr(Expr::End))
return false;
if (!f.hasAlreadyReturned()) { if (!f.hasAlreadyReturned()) {
f.setReturnedType(ExprType::Void); f.setReturnedType(ExprType::Void);
return true; return true;
@ -4142,34 +4164,34 @@ CheckStoreArray(FunctionValidator& f, ParseNode* lhs, ParseNode* rhs, Type* type
switch (viewType) { switch (viewType) {
case Scalar::Int8: case Scalar::Int8:
case Scalar::Uint8: case Scalar::Uint8:
if (!f.encoder().writeExpr(Expr::I32Store8)) if (!f.encoder().writeExpr(Expr::I32TeeStore8))
return false; return false;
break; break;
case Scalar::Int16: case Scalar::Int16:
case Scalar::Uint16: case Scalar::Uint16:
if (!f.encoder().writeExpr(Expr::I32Store16)) if (!f.encoder().writeExpr(Expr::I32TeeStore16))
return false; return false;
break; break;
case Scalar::Int32: case Scalar::Int32:
case Scalar::Uint32: case Scalar::Uint32:
if (!f.encoder().writeExpr(Expr::I32Store)) if (!f.encoder().writeExpr(Expr::I32TeeStore))
return false; return false;
break; break;
case Scalar::Float32: case Scalar::Float32:
if (rhsType.isFloatish()) { if (rhsType.isFloatish()) {
if (!f.encoder().writeExpr(Expr::F32Store)) if (!f.encoder().writeExpr(Expr::F32TeeStore))
return false; return false;
} else { } else {
if (!f.encoder().writeExpr(Expr::F64StoreF32)) if (!f.encoder().writeExpr(Expr::F64TeeStoreF32))
return false; return false;
} }
break; break;
case Scalar::Float64: case Scalar::Float64:
if (rhsType.isFloatish()) { if (rhsType.isFloatish()) {
if (!f.encoder().writeExpr(Expr::F32StoreF64)) if (!f.encoder().writeExpr(Expr::F32TeeStoreF64))
return false; return false;
} else { } else {
if (!f.encoder().writeExpr(Expr::F64Store)) if (!f.encoder().writeExpr(Expr::F64TeeStore))
return false; return false;
} }
break; break;
@ -4193,7 +4215,7 @@ CheckAssignName(FunctionValidator& f, ParseNode* lhs, ParseNode* rhs, Type* type
if (!CheckExpr(f, rhs, &rhsType)) if (!CheckExpr(f, rhs, &rhsType))
return false; return false;
if (!f.encoder().writeExpr(Expr::SetLocal)) if (!f.encoder().writeExpr(Expr::TeeLocal))
return false; return false;
if (!f.encoder().writeVarU32(lhsVar->slot)) if (!f.encoder().writeVarU32(lhsVar->slot))
return false; return false;
@ -4217,7 +4239,7 @@ CheckAssignName(FunctionValidator& f, ParseNode* lhs, ParseNode* rhs, Type* type
Type globType = global->varOrConstType(); Type globType = global->varOrConstType();
if (!(rhsType <= globType)) if (!(rhsType <= globType))
return f.failf(lhs, "%s is not a subtype of %s", rhsType.toChars(), globType.toChars()); return f.failf(lhs, "%s is not a subtype of %s", rhsType.toChars(), globType.toChars());
if (!f.encoder().writeExpr(Expr::SetGlobal)) if (!f.encoder().writeExpr(Expr::TeeGlobal))
return false; return false;
if (!f.encoder().writeVarU32(global->varOrConstIndex())) if (!f.encoder().writeVarU32(global->varOrConstIndex()))
return false; return false;
@ -4716,7 +4738,6 @@ CheckInternalCall(FunctionValidator& f, ParseNode* callNode, PropertyName* calle
if (!CheckCallArgs<CheckIsArgType>(f, callNode, &args)) if (!CheckCallArgs<CheckIsArgType>(f, callNode, &args))
return false; return false;
uint32_t arity = args.length();
Sig sig(Move(args), ret.canonicalToExprType()); Sig sig(Move(args), ret.canonicalToExprType());
ModuleValidator::Func* callee; ModuleValidator::Func* callee;
@ -4726,10 +4747,6 @@ CheckInternalCall(FunctionValidator& f, ParseNode* callNode, PropertyName* calle
if (!f.writeCall(callNode, Expr::Call)) if (!f.writeCall(callNode, Expr::Call))
return false; return false;
// Call arity
if (!f.encoder().writeVarU32(arity))
return false;
// Function's index, to find out the function's entry // Function's index, to find out the function's entry
if (!f.encoder().writeVarU32(callee->index())) if (!f.encoder().writeVarU32(callee->index()))
return false; return false;
@ -4805,18 +4822,13 @@ CheckFuncPtrCall(FunctionValidator& f, ParseNode* callNode, Type ret, Type* type
if (!CheckCallArgs<CheckIsArgType>(f, callNode, &args)) if (!CheckCallArgs<CheckIsArgType>(f, callNode, &args))
return false; return false;
uint32_t arity = args.length();
Sig sig(Move(args), ret.canonicalToExprType()); Sig sig(Move(args), ret.canonicalToExprType());
uint32_t tableIndex; uint32_t tableIndex;
if (!CheckFuncPtrTableAgainstExisting(f.m(), tableNode, name, Move(sig), mask, &tableIndex)) if (!CheckFuncPtrTableAgainstExisting(f.m(), tableNode, name, Move(sig), mask, &tableIndex))
return false; return false;
if (!f.writeCall(callNode, Expr::CallIndirect)) if (!f.writeCall(callNode, Expr::OldCallIndirect))
return false;
// Call arity
if (!f.encoder().writeVarU32(arity))
return false; return false;
// Call signature // Call signature
@ -4851,7 +4863,6 @@ CheckFFICall(FunctionValidator& f, ParseNode* callNode, unsigned ffiIndex, Type
if (!CheckCallArgs<CheckIsExternType>(f, callNode, &args)) if (!CheckCallArgs<CheckIsExternType>(f, callNode, &args))
return false; return false;
uint32_t arity = args.length();
Sig sig(Move(args), ret.canonicalToExprType()); Sig sig(Move(args), ret.canonicalToExprType());
uint32_t importIndex; uint32_t importIndex;
@ -4861,10 +4872,6 @@ CheckFFICall(FunctionValidator& f, ParseNode* callNode, unsigned ffiIndex, Type
if (!f.writeCall(callNode, Expr::CallImport)) if (!f.writeCall(callNode, Expr::CallImport))
return false; return false;
// Call arity
if (!f.encoder().writeVarU32(arity))
return false;
// Import index // Import index
if (!f.encoder().writeVarU32(importIndex)) if (!f.encoder().writeVarU32(importIndex))
return false; return false;
@ -5673,6 +5680,10 @@ CoerceResult(FunctionValidator& f, ParseNode* expr, Type expected, Type actual,
// | the thing we wanted to coerce | current position |> // | the thing we wanted to coerce | current position |>
switch (expected.which()) { switch (expected.which()) {
case Type::Void: case Type::Void:
if (!actual.isVoid()) {
if (!f.encoder().writeExpr(Expr::Drop))
return false;
}
break; break;
case Type::Int: case Type::Int:
if (!actual.isIntish()) if (!actual.isIntish())
@ -5925,6 +5936,10 @@ CheckComma(FunctionValidator& f, ParseNode* comma, Type* type)
if (!f.encoder().writeExpr(Expr::Block)) if (!f.encoder().writeExpr(Expr::Block))
return false; return false;
size_t typeAt;
if (!f.encoder().writePatchableFixedU7(&typeAt))
return false;
ParseNode* pn = operands; ParseNode* pn = operands;
for (; NextNode(pn); pn = NextNode(pn)) { for (; NextNode(pn); pn = NextNode(pn)) {
if (!CheckAsExprStatement(f, pn)) if (!CheckAsExprStatement(f, pn))
@ -5934,6 +5949,8 @@ CheckComma(FunctionValidator& f, ParseNode* comma, Type* type)
if (!CheckExpr(f, pn, type)) if (!CheckExpr(f, pn, type))
return false; return false;
f.encoder().patchFixedU7(typeAt, uint8_t(Type::canonicalize(*type).canonicalToExprType()));
return f.encoder().writeExpr(Expr::End); return f.encoder().writeExpr(Expr::End);
} }
@ -5953,7 +5970,8 @@ CheckConditional(FunctionValidator& f, ParseNode* ternary, Type* type)
if (!condType.isInt()) if (!condType.isInt())
return f.failf(cond, "%s is not a subtype of int", condType.toChars()); return f.failf(cond, "%s is not a subtype of int", condType.toChars());
if (!f.pushIf()) size_t typeAt;
if (!f.pushIf(&typeAt))
return false; return false;
Type thenType; Type thenType;
@ -5981,7 +5999,7 @@ CheckConditional(FunctionValidator& f, ParseNode* ternary, Type* type)
thenType.toChars(), elseType.toChars()); thenType.toChars(), elseType.toChars());
} }
if (!f.popIf()) if (!f.popIf(typeAt, Type::canonicalize(*type).canonicalToExprType()))
return false; return false;
return true; return true;
@ -6352,10 +6370,21 @@ CheckStatement(FunctionValidator& f, ParseNode* stmt);
static bool static bool
CheckAsExprStatement(FunctionValidator& f, ParseNode* expr) CheckAsExprStatement(FunctionValidator& f, ParseNode* expr)
{ {
Type ignored; if (expr->isKind(PNK_CALL)) {
if (expr->isKind(PNK_CALL)) Type ignored;
return CheckCoercedCall(f, expr, Type::Void, &ignored); return CheckCoercedCall(f, expr, Type::Void, &ignored);
return CheckExpr(f, expr, &ignored); }
Type resultType;
if (!CheckExpr(f, expr, &resultType))
return false;
if (!resultType.isVoid()) {
if (!f.encoder().writeExpr(Expr::Drop))
return false;
}
return true;
} }
static bool static bool
@ -6403,10 +6432,12 @@ CheckWhile(FunctionValidator& f, ParseNode* whileStmt, const NameVector* labels
ParseNode* body = BinaryRight(whileStmt); ParseNode* body = BinaryRight(whileStmt);
// A while loop `while(#cond) #body` is equivalent to: // A while loop `while(#cond) #body` is equivalent to:
// (loop $after_loop $top // (block $after_loop
// (brIf $after_loop (i32.eq 0 #cond)) // (loop $top
// #body // (brIf $after_loop (i32.eq 0 #cond))
// (br $top) // #body
// (br $top)
// )
// ) // )
if (labels && !f.addLabels(*labels, 0, 1)) if (labels && !f.addLabels(*labels, 0, 1))
return false; return false;
@ -6445,11 +6476,13 @@ CheckFor(FunctionValidator& f, ParseNode* forStmt, const NameVector* labels = nu
// A for-loop `for (#init; #cond; #inc) #body` is equivalent to: // A for-loop `for (#init; #cond; #inc) #body` is equivalent to:
// (block // depth X // (block // depth X
// (#init) // (#init)
// (loop $after_loop $loop_top // depth X+2 (loop) // (block $after_loop // depth X+1 (block)
// (brIf $after (eq 0 #cond)) // (loop $loop_top // depth X+2 (loop)
// (block $after_body #body) // depth X+3 // (brIf $after (eq 0 #cond))
// #inc // (block $after_body #body) // depth X+3
// (br $loop_top) // #inc
// (br $loop_top)
// )
// ) // )
// ) // )
// A break in the body should break out to $after_loop, i.e. depth + 1. // A break in the body should break out to $after_loop, i.e. depth + 1.
@ -6506,9 +6539,11 @@ CheckDoWhile(FunctionValidator& f, ParseNode* whileStmt, const NameVector* label
ParseNode* cond = BinaryRight(whileStmt); ParseNode* cond = BinaryRight(whileStmt);
// A do-while loop `do { #body } while (#cond)` is equivalent to: // A do-while loop `do { #body } while (#cond)` is equivalent to:
// (loop $after_loop $top // depth X // (block $after_loop // depth X
// (block #body) // depth X+2 // (loop $top // depth X+1
// (brIf #cond $top) // (block #body) // depth X+2
// (brIf #cond $top)
// )
// ) // )
// A break should break out of the entire loop, i.e. at depth 0. // A break should break out of the entire loop, i.e. at depth 0.
// A continue should break out to the condition, i.e. at depth 2. // A continue should break out to the condition, i.e. at depth 2.
@ -6600,9 +6635,12 @@ CheckIf(FunctionValidator& f, ParseNode* ifStmt)
if (!condType.isInt()) if (!condType.isInt())
return f.failf(cond, "%s is not a subtype of int", condType.toChars()); return f.failf(cond, "%s is not a subtype of int", condType.toChars());
if (!f.pushIf()) size_t typeAt;
if (!f.pushIf(&typeAt))
return false; return false;
f.setIfType(typeAt, ExprType::Void);
if (!CheckStatement(f, thenStmt)) if (!CheckStatement(f, thenStmt))
return false; return false;
@ -6746,8 +6784,13 @@ CheckSwitch(FunctionValidator& f, ParseNode* switchStmt)
} }
ParseNode* stmt = ListHead(switchBody); ParseNode* stmt = ListHead(switchBody);
if (!stmt) if (!stmt) {
return CheckSwitchExpr(f, switchExpr); if (!CheckSwitchExpr(f, switchExpr))
return false;
if (!f.encoder().writeExpr(Expr::Drop))
return false;
return true;
}
if (!CheckDefaultAtEnd(f, stmt)) if (!CheckDefaultAtEnd(f, stmt))
return false; return false;
@ -6810,10 +6853,6 @@ CheckSwitch(FunctionValidator& f, ParseNode* switchStmt)
if (!f.encoder().writeExpr(Expr::BrTable)) if (!f.encoder().writeExpr(Expr::BrTable))
return false; return false;
// The br_table arity.
if (!f.encoder().writeVarU32(0))
return false;
// Write the number of cases (tableLength - 1 + 1 (default)). // Write the number of cases (tableLength - 1 + 1 (default)).
// Write the number of cases (tableLength - 1 + 1 (default)). // Write the number of cases (tableLength - 1 + 1 (default)).
if (!f.encoder().writeVarU32(tableLength)) if (!f.encoder().writeVarU32(tableLength))
@ -6823,12 +6862,12 @@ CheckSwitch(FunctionValidator& f, ParseNode* switchStmt)
// a case is not explicitly defined, it goes to the default. // a case is not explicitly defined, it goes to the default.
for (size_t i = 0; i < tableLength; i++) { for (size_t i = 0; i < tableLength; i++) {
uint32_t target = caseDepths[i] == CASE_NOT_DEFINED ? defaultDepth : caseDepths[i]; uint32_t target = caseDepths[i] == CASE_NOT_DEFINED ? defaultDepth : caseDepths[i];
if (!f.encoder().writeFixedU32(target)) if (!f.encoder().writeVarU32(target))
return false; return false;
} }
// Write the default depth. // Write the default depth.
if (!f.encoder().writeFixedU32(defaultDepth)) if (!f.encoder().writeVarU32(defaultDepth))
return false; return false;
// Our br_table is done. Close its block, write the cases down in order. // Our br_table is done. Close its block, write the cases down in order.
@ -6893,9 +6932,6 @@ CheckReturn(FunctionValidator& f, ParseNode* returnStmt)
if (!f.encoder().writeExpr(Expr::Return)) if (!f.encoder().writeExpr(Expr::Return))
return false; return false;
if (!f.encoder().writeVarU32(expr ? 1 : 0))
return false;
return true; return true;
} }

Просмотреть файл

@ -195,13 +195,18 @@ enum class AstExprKind
ComparisonOperator, ComparisonOperator,
Const, Const,
ConversionOperator, ConversionOperator,
Drop,
First,
GetGlobal, GetGlobal,
GetLocal, GetLocal,
If, If,
Load, Load,
Nop,
Pop,
Return, Return,
SetGlobal, SetGlobal,
SetLocal, SetLocal,
TeeLocal,
Store, Store,
TernaryOperator, TernaryOperator,
UnaryOperator, UnaryOperator,
@ -212,15 +217,22 @@ enum class AstExprKind
class AstExpr : public AstNode class AstExpr : public AstNode
{ {
const AstExprKind kind_; const AstExprKind kind_;
ExprType type_;
protected: protected:
explicit AstExpr(AstExprKind kind) AstExpr(AstExprKind kind, ExprType type)
: kind_(kind) : kind_(kind), type_(type)
{} {}
public: public:
AstExprKind kind() const { return kind_; } AstExprKind kind() const { return kind_; }
bool isVoid() const { return IsVoid(type_); }
// Note that for nodes other than blocks and block-like things, this
// may return ExprType::Limit for nodes with non-void types.
ExprType type() const { return type_; }
template <class T> template <class T>
T& as() { T& as() {
MOZ_ASSERT(kind() == T::Kind); MOZ_ASSERT(kind() == T::Kind);
@ -228,14 +240,37 @@ class AstExpr : public AstNode
} }
}; };
struct AstNop : AstExpr
{
static const AstExprKind Kind = AstExprKind::Nop;
AstNop()
: AstExpr(AstExprKind::Nop, ExprType::Void)
{}
};
struct AstUnreachable : AstExpr struct AstUnreachable : AstExpr
{ {
static const AstExprKind Kind = AstExprKind::Unreachable; static const AstExprKind Kind = AstExprKind::Unreachable;
AstUnreachable() AstUnreachable()
: AstExpr(AstExprKind::Unreachable) : AstExpr(AstExprKind::Unreachable, ExprType::Void)
{} {}
}; };
class AstDrop : public AstExpr
{
AstExpr& value_;
public:
static const AstExprKind Kind = AstExprKind::Drop;
explicit AstDrop(AstExpr& value)
: AstExpr(AstExprKind::Drop, ExprType::Void),
value_(value)
{}
AstExpr& value() const {
return value_;
}
};
class AstConst : public AstExpr class AstConst : public AstExpr
{ {
const Val val_; const Val val_;
@ -243,7 +278,7 @@ class AstConst : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::Const; static const AstExprKind Kind = AstExprKind::Const;
explicit AstConst(Val val) explicit AstConst(Val val)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Limit),
val_(val) val_(val)
{} {}
Val val() const { return val_; } Val val() const { return val_; }
@ -256,7 +291,7 @@ class AstGetLocal : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::GetLocal; static const AstExprKind Kind = AstExprKind::GetLocal;
explicit AstGetLocal(AstRef local) explicit AstGetLocal(AstRef local)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Limit),
local_(local) local_(local)
{} {}
AstRef& local() { AstRef& local() {
@ -272,7 +307,7 @@ class AstSetLocal : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::SetLocal; static const AstExprKind Kind = AstExprKind::SetLocal;
AstSetLocal(AstRef local, AstExpr& value) AstSetLocal(AstRef local, AstExpr& value)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Void),
local_(local), local_(local),
value_(value) value_(value)
{} {}
@ -291,7 +326,7 @@ class AstGetGlobal : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::GetGlobal; static const AstExprKind Kind = AstExprKind::GetGlobal;
explicit AstGetGlobal(AstRef global) explicit AstGetGlobal(AstRef global)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Limit),
global_(global) global_(global)
{} {}
AstRef& global() { AstRef& global() {
@ -307,7 +342,7 @@ class AstSetGlobal : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::SetGlobal; static const AstExprKind Kind = AstExprKind::SetGlobal;
AstSetGlobal(AstRef global, AstExpr& value) AstSetGlobal(AstRef global, AstExpr& value)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Void),
global_(global), global_(global),
value_(value) value_(value)
{} {}
@ -319,26 +354,43 @@ class AstSetGlobal : public AstExpr
} }
}; };
class AstTeeLocal : public AstExpr
{
AstRef local_;
AstExpr& value_;
public:
static const AstExprKind Kind = AstExprKind::TeeLocal;
AstTeeLocal(AstRef local, AstExpr& value)
: AstExpr(Kind, ExprType::Limit),
local_(local),
value_(value)
{}
AstRef& local() {
return local_;
}
AstExpr& value() const {
return value_;
}
};
class AstBlock : public AstExpr class AstBlock : public AstExpr
{ {
Expr expr_; Expr expr_;
AstName breakName_; AstName name_;
AstName continueName_;
AstExprVector exprs_; AstExprVector exprs_;
public: public:
static const AstExprKind Kind = AstExprKind::Block; static const AstExprKind Kind = AstExprKind::Block;
explicit AstBlock(Expr expr, AstName breakName, AstName continueName, AstExprVector&& exprs) explicit AstBlock(Expr expr, ExprType type, AstName name, AstExprVector&& exprs)
: AstExpr(Kind), : AstExpr(Kind, type),
expr_(expr), expr_(expr),
breakName_(breakName), name_(name),
continueName_(continueName),
exprs_(Move(exprs)) exprs_(Move(exprs))
{} {}
Expr expr() const { return expr_; } Expr expr() const { return expr_; }
AstName breakName() const { return breakName_; } AstName name() const { return name_; }
AstName continueName() const { return continueName_; }
const AstExprVector& exprs() const { return exprs_; } const AstExprVector& exprs() const { return exprs_; }
}; };
@ -351,8 +403,9 @@ class AstBranch : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::Branch; static const AstExprKind Kind = AstExprKind::Branch;
explicit AstBranch(Expr expr, AstExpr* cond, AstRef target, AstExpr* value) explicit AstBranch(Expr expr, ExprType type,
: AstExpr(Kind), AstExpr* cond, AstRef target, AstExpr* value)
: AstExpr(Kind, type),
expr_(expr), expr_(expr),
cond_(cond), cond_(cond),
target_(target), target_(target),
@ -373,8 +426,8 @@ class AstCall : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::Call; static const AstExprKind Kind = AstExprKind::Call;
AstCall(Expr expr, AstRef func, AstExprVector&& args) AstCall(Expr expr, ExprType type, AstRef func, AstExprVector&& args)
: AstExpr(Kind), expr_(expr), func_(func), args_(Move(args)) : AstExpr(Kind, type), expr_(expr), func_(func), args_(Move(args))
{} {}
Expr expr() const { return expr_; } Expr expr() const { return expr_; }
@ -385,17 +438,17 @@ class AstCall : public AstExpr
class AstCallIndirect : public AstExpr class AstCallIndirect : public AstExpr
{ {
AstRef sig_; AstRef sig_;
AstExpr* index_;
AstExprVector args_; AstExprVector args_;
AstExpr* index_;
public: public:
static const AstExprKind Kind = AstExprKind::CallIndirect; static const AstExprKind Kind = AstExprKind::CallIndirect;
AstCallIndirect(AstRef sig, AstExpr* index, AstExprVector&& args) AstCallIndirect(AstRef sig, ExprType type, AstExprVector&& args, AstExpr* index)
: AstExpr(Kind), sig_(sig), index_(index), args_(Move(args)) : AstExpr(Kind, type), sig_(sig), args_(Move(args)), index_(index)
{} {}
AstRef& sig() { return sig_; } AstRef& sig() { return sig_; }
AstExpr* index() const { return index_; }
const AstExprVector& args() const { return args_; } const AstExprVector& args() const { return args_; }
AstExpr* index() const { return index_; }
}; };
class AstReturn : public AstExpr class AstReturn : public AstExpr
@ -405,7 +458,7 @@ class AstReturn : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::Return; static const AstExprKind Kind = AstExprKind::Return;
explicit AstReturn(AstExpr* maybeExpr) explicit AstReturn(AstExpr* maybeExpr)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Void),
maybeExpr_(maybeExpr) maybeExpr_(maybeExpr)
{} {}
AstExpr* maybeExpr() const { return maybeExpr_; } AstExpr* maybeExpr() const { return maybeExpr_; }
@ -414,20 +467,18 @@ class AstReturn : public AstExpr
class AstIf : public AstExpr class AstIf : public AstExpr
{ {
AstExpr* cond_; AstExpr* cond_;
AstName thenName_; AstName name_;
AstExprVector thenExprs_; AstExprVector thenExprs_;
AstName elseName_;
AstExprVector elseExprs_; AstExprVector elseExprs_;
public: public:
static const AstExprKind Kind = AstExprKind::If; static const AstExprKind Kind = AstExprKind::If;
AstIf(AstExpr* cond, AstName thenName, AstExprVector&& thenExprs, AstIf(ExprType type, AstExpr* cond, AstName name,
AstName elseName, AstExprVector&& elseExprs) AstExprVector&& thenExprs, AstExprVector&& elseExprs)
: AstExpr(Kind), : AstExpr(Kind, type),
cond_(cond), cond_(cond),
thenName_(thenName), name_(name),
thenExprs_(Move(thenExprs)), thenExprs_(Move(thenExprs)),
elseName_(elseName),
elseExprs_(Move(elseExprs)) elseExprs_(Move(elseExprs))
{} {}
@ -435,8 +486,7 @@ class AstIf : public AstExpr
const AstExprVector& thenExprs() const { return thenExprs_; } const AstExprVector& thenExprs() const { return thenExprs_; }
bool hasElse() const { return elseExprs_.length(); } bool hasElse() const { return elseExprs_.length(); }
const AstExprVector& elseExprs() const { MOZ_ASSERT(hasElse()); return elseExprs_; } const AstExprVector& elseExprs() const { MOZ_ASSERT(hasElse()); return elseExprs_; }
AstName thenName() const { return thenName_; } AstName name() const { return name_; }
AstName elseName() const { return elseName_; }
}; };
class AstLoadStoreAddress class AstLoadStoreAddress
@ -465,7 +515,7 @@ class AstLoad : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::Load; static const AstExprKind Kind = AstExprKind::Load;
explicit AstLoad(Expr expr, const AstLoadStoreAddress &address) explicit AstLoad(Expr expr, const AstLoadStoreAddress &address)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Limit),
expr_(expr), expr_(expr),
address_(address) address_(address)
{} {}
@ -484,7 +534,7 @@ class AstStore : public AstExpr
static const AstExprKind Kind = AstExprKind::Store; static const AstExprKind Kind = AstExprKind::Store;
explicit AstStore(Expr expr, const AstLoadStoreAddress &address, explicit AstStore(Expr expr, const AstLoadStoreAddress &address,
AstExpr* value) AstExpr* value)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Void),
expr_(expr), expr_(expr),
address_(address), address_(address),
value_(value) value_(value)
@ -505,8 +555,8 @@ class AstBranchTable : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::BranchTable; static const AstExprKind Kind = AstExprKind::BranchTable;
explicit AstBranchTable(AstExpr& index, AstRef def, AstRefVector&& table, explicit AstBranchTable(AstExpr& index, AstRef def, AstRefVector&& table,
AstExpr* maybeValue) AstExpr* maybeValue)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Void),
index_(index), index_(index),
default_(def), default_(def),
table_(Move(table)), table_(Move(table)),
@ -542,20 +592,6 @@ class AstFunc : public AstNode
AstName name() const { return name_; } AstName name() const { return name_; }
}; };
class AstResizable
{
uint32_t initial_;
Maybe<uint32_t> maximum_;
public:
AstResizable() : initial_(0), maximum_() {}
AstResizable(uint32_t initial, Maybe<uint32_t> maximum)
: initial_(initial), maximum_(maximum)
{}
uint32_t initial() const { return initial_; }
const Maybe<uint32_t>& maximum() const { return maximum_; }
};
class AstGlobal : public AstNode class AstGlobal : public AstNode
{ {
AstName name_; AstName name_;
@ -590,14 +626,14 @@ class AstImport : public AstNode
DefinitionKind kind_; DefinitionKind kind_;
AstRef funcSig_; AstRef funcSig_;
AstResizable resizable_; ResizableLimits resizable_;
AstGlobal global_; AstGlobal global_;
public: public:
AstImport(AstName name, AstName module, AstName field, AstRef funcSig) AstImport(AstName name, AstName module, AstName field, AstRef funcSig)
: name_(name), module_(module), field_(field), kind_(DefinitionKind::Function), funcSig_(funcSig) : name_(name), module_(module), field_(field), kind_(DefinitionKind::Function), funcSig_(funcSig)
{} {}
AstImport(AstName name, AstName module, AstName field, DefinitionKind kind, AstResizable resizable) AstImport(AstName name, AstName module, AstName field, DefinitionKind kind, ResizableLimits resizable)
: name_(name), module_(module), field_(field), kind_(kind), resizable_(resizable) : name_(name), module_(module), field_(field), kind_(kind), resizable_(resizable)
{} {}
AstImport(AstName name, AstName module, AstName field, AstGlobal global) AstImport(AstName name, AstName module, AstName field, AstGlobal global)
@ -613,7 +649,7 @@ class AstImport : public AstNode
MOZ_ASSERT(kind_ == DefinitionKind::Function); MOZ_ASSERT(kind_ == DefinitionKind::Function);
return funcSig_; return funcSig_;
} }
AstResizable resizable() const { ResizableLimits resizable() const {
MOZ_ASSERT(kind_ == DefinitionKind::Memory || kind_ == DefinitionKind::Table); MOZ_ASSERT(kind_ == DefinitionKind::Memory || kind_ == DefinitionKind::Table);
return resizable_; return resizable_;
} }
@ -698,6 +734,7 @@ class AstModule : public AstNode
typedef AstVector<AstImport*> ImportVector; typedef AstVector<AstImport*> ImportVector;
typedef AstVector<AstExport*> ExportVector; typedef AstVector<AstExport*> ExportVector;
typedef AstVector<AstSig*> SigVector; typedef AstVector<AstSig*> SigVector;
typedef AstVector<AstName> NameVector;
private: private:
typedef AstHashMap<AstSig*, uint32_t, AstSig> SigMap; typedef AstHashMap<AstSig*, uint32_t, AstSig> SigMap;
@ -706,8 +743,9 @@ class AstModule : public AstNode
SigVector sigs_; SigVector sigs_;
SigMap sigMap_; SigMap sigMap_;
ImportVector imports_; ImportVector imports_;
Maybe<AstResizable> table_; NameVector funcImportNames_;
Maybe<AstResizable> memory_; Maybe<ResizableLimits> table_;
Maybe<ResizableLimits> memory_;
ExportVector exports_; ExportVector exports_;
Maybe<AstStartFunc> startFunc_; Maybe<AstStartFunc> startFunc_;
FuncVector funcs_; FuncVector funcs_;
@ -721,6 +759,7 @@ class AstModule : public AstNode
sigs_(lifo), sigs_(lifo),
sigMap_(lifo), sigMap_(lifo),
imports_(lifo), imports_(lifo),
funcImportNames_(lifo),
exports_(lifo), exports_(lifo),
funcs_(lifo), funcs_(lifo),
dataSegments_(lifo), dataSegments_(lifo),
@ -730,7 +769,7 @@ class AstModule : public AstNode
bool init() { bool init() {
return sigMap_.init(); return sigMap_.init();
} }
bool setMemory(AstResizable memory) { bool setMemory(ResizableLimits memory) {
if (memory_) if (memory_)
return false; return false;
memory_.emplace(memory); memory_.emplace(memory);
@ -739,10 +778,10 @@ class AstModule : public AstNode
bool hasMemory() const { bool hasMemory() const {
return !!memory_; return !!memory_;
} }
const AstResizable& memory() const { const ResizableLimits& memory() const {
return *memory_; return *memory_;
} }
bool setTable(AstResizable table) { bool setTable(ResizableLimits table) {
if (table_) if (table_)
return false; return false;
table_.emplace(table); table_.emplace(table);
@ -751,7 +790,7 @@ class AstModule : public AstNode
bool hasTable() const { bool hasTable() const {
return !!table_; return !!table_;
} }
const AstResizable& table() const { const ResizableLimits& table() const {
return *table_; return *table_;
} }
bool append(AstDataSegment* seg) { bool append(AstDataSegment* seg) {
@ -807,11 +846,19 @@ class AstModule : public AstNode
return funcs_; return funcs_;
} }
bool append(AstImport* imp) { bool append(AstImport* imp) {
if (imp->kind() == DefinitionKind::Function) {
if (!funcImportNames_.append(imp->name()))
return false;
}
return imports_.append(imp); return imports_.append(imp);
} }
const ImportVector& imports() const { const ImportVector& imports() const {
return imports_; return imports_;
} }
const NameVector& funcImportNames() const {
return funcImportNames_;
}
bool append(AstExport* exp) { bool append(AstExport* exp) {
return exports_.append(exp); return exports_.append(exp);
} }
@ -833,7 +880,7 @@ class AstNullaryOperator final : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::NullaryOperator; static const AstExprKind Kind = AstExprKind::NullaryOperator;
explicit AstNullaryOperator(Expr expr) explicit AstNullaryOperator(Expr expr)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Limit),
expr_(expr) expr_(expr)
{} {}
@ -848,7 +895,7 @@ class AstUnaryOperator final : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::UnaryOperator; static const AstExprKind Kind = AstExprKind::UnaryOperator;
explicit AstUnaryOperator(Expr expr, AstExpr* op) explicit AstUnaryOperator(Expr expr, AstExpr* op)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Limit),
expr_(expr), op_(op) expr_(expr), op_(op)
{} {}
@ -865,7 +912,7 @@ class AstBinaryOperator final : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::BinaryOperator; static const AstExprKind Kind = AstExprKind::BinaryOperator;
explicit AstBinaryOperator(Expr expr, AstExpr* lhs, AstExpr* rhs) explicit AstBinaryOperator(Expr expr, AstExpr* lhs, AstExpr* rhs)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Limit),
expr_(expr), lhs_(lhs), rhs_(rhs) expr_(expr), lhs_(lhs), rhs_(rhs)
{} {}
@ -884,7 +931,7 @@ class AstTernaryOperator : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::TernaryOperator; static const AstExprKind Kind = AstExprKind::TernaryOperator;
AstTernaryOperator(Expr expr, AstExpr* op0, AstExpr* op1, AstExpr* op2) AstTernaryOperator(Expr expr, AstExpr* op0, AstExpr* op1, AstExpr* op2)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Limit),
expr_(expr), op0_(op0), op1_(op1), op2_(op2) expr_(expr), op0_(op0), op1_(op1), op2_(op2)
{} {}
@ -903,7 +950,7 @@ class AstComparisonOperator final : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::ComparisonOperator; static const AstExprKind Kind = AstExprKind::ComparisonOperator;
explicit AstComparisonOperator(Expr expr, AstExpr* lhs, AstExpr* rhs) explicit AstComparisonOperator(Expr expr, AstExpr* lhs, AstExpr* rhs)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Limit),
expr_(expr), lhs_(lhs), rhs_(rhs) expr_(expr), lhs_(lhs), rhs_(rhs)
{} {}
@ -920,7 +967,7 @@ class AstConversionOperator final : public AstExpr
public: public:
static const AstExprKind Kind = AstExprKind::ConversionOperator; static const AstExprKind Kind = AstExprKind::ConversionOperator;
explicit AstConversionOperator(Expr expr, AstExpr* op) explicit AstConversionOperator(Expr expr, AstExpr* op)
: AstExpr(Kind), : AstExpr(Kind, ExprType::Limit),
expr_(expr), op_(op) expr_(expr), op_(op)
{} {}
@ -928,6 +975,36 @@ class AstConversionOperator final : public AstExpr
AstExpr* op() const { return op_; } AstExpr* op() const { return op_; }
}; };
// 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()
: AstExpr(Kind, ExprType::Void)
{}
};
// This is an artificial AST node which can be used to represent some forms
// of stack-machine code in an AST form. It similar to Block, but returns the
// value of its first operand, rather than the last.
class AstFirst : public AstExpr
{
AstExprVector exprs_;
public:
static const AstExprKind Kind = AstExprKind::First;
explicit AstFirst(AstExprVector&& exprs)
: AstExpr(Kind, ExprType::Limit),
exprs_(Move(exprs))
{}
AstExprVector& exprs() { return exprs_; }
const AstExprVector& exprs() const { return exprs_; }
};
} // end wasm namespace } // end wasm namespace
} // end js namespace } // end js namespace

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -18,11 +18,50 @@
#include "asmjs/WasmBinary.h" #include "asmjs/WasmBinary.h"
#include <stdarg.h>
#include "jsprf.h"
#include "asmjs/WasmTypes.h" #include "asmjs/WasmTypes.h"
using namespace js; using namespace js;
using namespace js::wasm; using namespace js::wasm;
bool
Decoder::fail(const char* msg, ...) {
va_list ap;
va_start(ap, msg);
UniqueChars str(JS_vsmprintf(msg, ap));
va_end(ap);
if (!str)
return false;
return fail(Move(str));
}
bool
Decoder::fail(UniqueChars msg) {
UniqueChars strWithOffset(JS_smprintf("at offset %zu: %s", currentOffset(), msg.get()));
if (!strWithOffset)
return false;
*error_ = Move(strWithOffset);
return false;
}
bool
wasm::DecodePreamble(Decoder& d)
{
uint32_t u32;
if (!d.readFixedU32(&u32) || u32 != MagicNumber)
return d.fail("failed to match magic number");
if (!d.readFixedU32(&u32) || u32 != EncodingVersion)
return d.fail("binary version 0x%" PRIx32 " does not match expected version 0x%" PRIx32,
u32, EncodingVersion);
return true;
}
bool bool
wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals) wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals)
{ {
@ -85,3 +124,63 @@ wasm::DecodeLocalEntries(Decoder& d, ValTypeVector* locals)
return true; return true;
} }
bool
wasm::DecodeGlobalType(Decoder& d, ValType* type, uint32_t* flags)
{
if (!d.readValType(type))
return d.fail("bad global type");
if (!d.readVarU32(flags))
return d.fail("expected global flags");
if (*flags & ~uint32_t(GlobalFlags::AllowedMask))
return d.fail("unexpected bits set in global flags");
return true;
}
bool
wasm::DecodeResizable(Decoder& d, ResizableLimits* limits)
{
uint32_t flags;
if (!d.readVarU32(&flags))
return d.fail("expected flags");
if (flags & ~uint32_t(ResizableFlags::AllowedMask))
return d.fail("unexpected bits set in flags: %" PRIu32,
(flags & ~uint32_t(ResizableFlags::AllowedMask)));
if (!(flags & uint32_t(ResizableFlags::Default)))
return d.fail("currently, every memory/table must be declared default");
if (!d.readVarU32(&limits->initial))
return d.fail("expected initial length");
if (flags & uint32_t(ResizableFlags::HasMaximum)) {
uint32_t maximum;
if (!d.readVarU32(&maximum))
return d.fail("expected maximum length");
if (limits->initial > maximum) {
return d.fail("memory size minimum must not be greater than maximum; "
"maximum length %" PRIu32 " is less than initial length %" PRIu32,
maximum, limits->initial);
}
limits->maximum.emplace(maximum);
}
return true;
}
bool
wasm::DecodeUnknownSections(Decoder& d)
{
while (!d.done()) {
if (!d.skipUserDefinedSection())
return false;
}
return true;
}

Просмотреть файл

@ -68,20 +68,24 @@ enum class Telemetry {
}; };
static const uint32_t MagicNumber = 0x6d736100; // "\0asm" static const uint32_t MagicNumber = 0x6d736100; // "\0asm"
static const uint32_t EncodingVersion = 0x0b; static const uint32_t EncodingVersion = 0x0c;
static const char TypeSectionId[] = "type"; enum class SectionId {
static const char GlobalSectionId[] = "global"; UserDefined = 0,
static const char ImportSectionId[] = "import"; Type = 1,
static const char FunctionSectionId[] = "function"; Import = 2,
static const char TableSectionId[] = "table"; Function = 3,
static const char MemorySectionId[] = "memory"; Table = 4,
static const char ExportSectionId[] = "export"; Memory = 5,
static const char StartSectionId[] = "start"; Global = 6,
static const char CodeSectionId[] = "code"; Export = 7,
static const char ElemSectionId[] = "elem"; Start = 8,
static const char DataSectionId[] = "data"; Elem = 9,
static const char NameSectionId[] = "name"; Code = 10,
Data = 11
};
static const char NameSectionName[] = "name";
enum class ValType enum class ValType
{ {
@ -135,7 +139,7 @@ enum class GlobalFlags
enum class Expr enum class Expr
{ {
// Control flow operators // Control flow operators
Nop = 0x00, Unreachable = 0x00,
Block = 0x01, Block = 0x01,
Loop = 0x02, Loop = 0x02,
If = 0x03, If = 0x03,
@ -145,7 +149,8 @@ enum class Expr
BrIf = 0x07, BrIf = 0x07,
BrTable = 0x08, BrTable = 0x08,
Return = 0x09, Return = 0x09,
Unreachable = 0x0a, Nop = 0x0a,
Drop = 0x0b,
End = 0x0f, End = 0x0f,
// Basic operators // Basic operators
@ -158,6 +163,7 @@ enum class Expr
Call = 0x16, Call = 0x16,
CallIndirect = 0x17, CallIndirect = 0x17,
CallImport = 0x18, CallImport = 0x18,
TeeLocal = 0x19,
// Memory-related operators // Memory-related operators
I32Load8S = 0x20, I32Load8S = 0x20,
@ -332,13 +338,23 @@ enum class Expr
// compiling asm.js and are rejected by wasm validation. // compiling asm.js and are rejected by wasm validation.
// asm.js-specific operators // asm.js-specific operators
TeeGlobal = 0xc8,
I32Min, I32Min,
I32Max, I32Max,
I32Neg, I32Neg,
I32BitNot, I32BitNot,
I32Abs, I32Abs,
F32StoreF64, F32TeeStoreF64,
F64StoreF32, F64TeeStoreF32,
I32TeeStore8,
I32TeeStore16,
I64TeeStore8,
I64TeeStore16,
I64TeeStore32,
I32TeeStore,
I64TeeStore,
F32TeeStore,
F64TeeStore,
F64Mod, F64Mod,
F64Sin, F64Sin,
F64Cos, F64Cos,
@ -351,6 +367,9 @@ enum class Expr
F64Pow, F64Pow,
F64Atan2, F64Atan2,
// asm.js-style call_indirect with the callee evaluated first.
OldCallIndirect,
// Atomics // Atomics
I32AtomicsCompareExchange, I32AtomicsCompareExchange,
I32AtomicsExchange, I32AtomicsExchange,
@ -523,6 +542,16 @@ class Encoder
} while(assertBits != 0); } while(assertBits != 0);
} }
void patchFixedU7(size_t offset, uint8_t patchBits, uint8_t assertBits) {
MOZ_ASSERT(patchBits <= uint8_t(INT8_MAX));
patchFixedU8(offset, patchBits, assertBits);
}
void patchFixedU8(size_t offset, uint8_t patchBits, uint8_t assertBits) {
MOZ_ASSERT(bytes_[offset] == assertBits);
bytes_[offset] = patchBits;
}
uint32_t varU32ByteLength(size_t offset) const { uint32_t varU32ByteLength(size_t offset) const {
size_t start = offset; size_t start = offset;
while (bytes_[offset] & 0x80) while (bytes_[offset] & 0x80)
@ -545,6 +574,10 @@ class Encoder
// Fixed-size encoding operations simply copy the literal bytes (without // Fixed-size encoding operations simply copy the literal bytes (without
// attempting to align). // attempting to align).
MOZ_MUST_USE bool writeFixedU7(uint8_t i) {
MOZ_ASSERT(i <= uint8_t(INT8_MAX));
return writeFixedU8(i);
}
MOZ_MUST_USE bool writeFixedU8(uint8_t i) { MOZ_MUST_USE bool writeFixedU8(uint8_t i) {
return write<uint8_t>(i); return write<uint8_t>(i);
} }
@ -588,6 +621,10 @@ class Encoder
static_assert(size_t(ValType::Limit) <= INT8_MAX, "fits"); static_assert(size_t(ValType::Limit) <= INT8_MAX, "fits");
return writeFixedU8(size_t(type)); return writeFixedU8(size_t(type));
} }
MOZ_MUST_USE bool writeExprType(ExprType type) {
static_assert(size_t(ExprType::Limit) <= INT8_MAX, "fits");
return writeFixedU8(size_t(type));
}
MOZ_MUST_USE bool writeExpr(Expr expr) { MOZ_MUST_USE bool writeExpr(Expr expr) {
static_assert(size_t(Expr::Limit) <= ExprLimit, "fits"); static_assert(size_t(Expr::Limit) <= ExprLimit, "fits");
if (size_t(expr) < UINT8_MAX) if (size_t(expr) < UINT8_MAX)
@ -596,6 +633,16 @@ class Encoder
writeFixedU8(size_t(expr) - UINT8_MAX); writeFixedU8(size_t(expr) - UINT8_MAX);
} }
// Fixed-length encodings that allow back-patching.
MOZ_MUST_USE bool writePatchableFixedU7(size_t* offset) {
*offset = bytes_.length();
return writeFixedU8(UINT8_MAX);
}
void patchFixedU7(size_t offset, uint8_t patchBits) {
return patchFixedU7(offset, patchBits, UINT8_MAX);
}
// Variable-length encodings that allow back-patching. // Variable-length encodings that allow back-patching.
MOZ_MUST_USE bool writePatchableVarU32(size_t* offset) { MOZ_MUST_USE bool writePatchableVarU32(size_t* offset) {
@ -620,12 +667,10 @@ class Encoder
// end while the size's varU32 must be stored at the beginning. Immediately // end while the size's varU32 must be stored at the beginning. Immediately
// after the section length is the string id of the section. // after the section length is the string id of the section.
template <size_t IdSizeWith0> MOZ_MUST_USE bool startSection(SectionId id, size_t* offset) {
MOZ_MUST_USE bool startSection(const char (&id)[IdSizeWith0], size_t* offset) { MOZ_ASSERT(id != SectionId::UserDefined); // not supported yet
static const size_t IdSize = IdSizeWith0 - 1;
MOZ_ASSERT(id[IdSize] == '\0'); return writeVarU32(uint32_t(id)) &&
return writeVarU32(IdSize) &&
bytes_.append(reinterpret_cast<const uint8_t*>(id), IdSize) &&
writePatchableVarU32(offset); writePatchableVarU32(offset);
} }
void finishSection(size_t offset) { void finishSection(size_t offset) {
@ -740,14 +785,8 @@ class Decoder
error_(error) error_(error)
{} {}
bool fail(const char* msg) { bool fail(const char* msg, ...);
error_->reset(strdup(msg)); bool fail(UniqueChars msg);
return false;
}
bool fail(UniqueChars msg) {
*error_ = Move(msg);
return false;
}
void clearError() { void clearError() {
if (error_) if (error_)
error_->reset(); error_->reset();
@ -859,48 +898,102 @@ class Decoder
static const uint32_t NotStarted = UINT32_MAX; static const uint32_t NotStarted = UINT32_MAX;
template <size_t IdSizeWith0> MOZ_MUST_USE bool startSection(SectionId id,
MOZ_MUST_USE bool startSection(const char (&id)[IdSizeWith0],
uint32_t* startOffset, uint32_t* startOffset,
uint32_t* size) { uint32_t* size,
static const size_t IdSize = IdSizeWith0 - 1; const char* sectionName)
MOZ_ASSERT(id[IdSize] == '\0'); {
const uint8_t* before = cur_; const uint8_t* const before = cur_;
uint32_t idSize; const uint8_t* beforeId = before;
if (!readVarU32(&idSize)) uint32_t idValue;
if (!readVarU32(&idValue))
goto backup; goto backup;
if (bytesRemain() < idSize) while (idValue != uint32_t(id)) {
return false; if (idValue != uint32_t(SectionId::UserDefined))
if (idSize != IdSize || !!memcmp(cur_, id, IdSize)) goto backup;
goto backup; // Rewind to the section id since skipUserDefinedSection expects it.
cur_ += IdSize; cur_ = beforeId;
if (!skipUserDefinedSection())
return false;
beforeId = cur_;
if (!readVarU32(&idValue))
goto backup;
}
if (!readVarU32(size)) if (!readVarU32(size))
goto backup; goto fail;
if (bytesRemain() < *size) if (bytesRemain() < *size)
return false; goto fail;
*startOffset = cur_ - beg_; *startOffset = cur_ - beg_;
return true; return true;
backup: backup:
cur_ = before; cur_ = before;
*startOffset = NotStarted; *startOffset = NotStarted;
return true; return true;
fail:
return fail("failed to start %s section", sectionName);
} }
MOZ_MUST_USE bool finishSection(uint32_t startOffset, uint32_t size) { MOZ_MUST_USE bool finishSection(uint32_t startOffset, uint32_t size,
return size == (cur_ - beg_) - startOffset; const char* sectionName)
{
if (size != (cur_ - beg_) - startOffset)
return fail("byte size mismatch in %s section", sectionName);
return true;
} }
void ignoreSection(uint32_t startOffset, uint32_t size) {
cur_ = (beg_ + startOffset) + size; // "User sections" do not cause validation errors unless the error is in
// the user-defined section header itself.
MOZ_MUST_USE bool startUserDefinedSection(const char* expectedId,
size_t expectedIdSize,
uint32_t* sectionStart,
uint32_t* sectionSize)
{
const uint8_t* const before = cur_;
while (true) {
if (!startSection(SectionId::UserDefined, sectionStart, sectionSize, "user-defined"))
return false;
if (*sectionStart == NotStarted) {
cur_ = before;
return true;
}
uint32_t idSize;
if (!readVarU32(&idSize))
goto fail;
if (idSize > bytesRemain() || currentOffset() + idSize > *sectionStart + *sectionSize)
goto fail;
if (expectedId && (expectedIdSize != idSize || !!memcmp(cur_, expectedId, idSize))) {
finishUserDefinedSection(*sectionStart, *sectionSize);
continue;
}
cur_ += idSize;
return true;
}
MOZ_CRASH("unreachable");
fail:
return fail("failed to start user-defined section");
}
template <size_t IdSizeWith0>
MOZ_MUST_USE bool startUserDefinedSection(const char (&id)[IdSizeWith0],
uint32_t* sectionStart,
uint32_t* sectionSize)
{
MOZ_ASSERT(id[IdSizeWith0 - 1] == '\0');
return startUserDefinedSection(id, IdSizeWith0 - 1, sectionStart, sectionSize);
}
void finishUserDefinedSection(uint32_t sectionStart, uint32_t sectionSize) {
MOZ_ASSERT(cur_ >= beg_);
MOZ_ASSERT(cur_ <= end_); MOZ_ASSERT(cur_ <= end_);
cur_ = (beg_ + sectionStart) + sectionSize;
MOZ_ASSERT(cur_ <= end_);
clearError();
} }
MOZ_MUST_USE bool skipSection() { MOZ_MUST_USE bool skipUserDefinedSection() {
uint32_t idSize; uint32_t sectionStart, sectionSize;
if (!readVarU32(&idSize) || bytesRemain() < idSize) if (!startUserDefinedSection(nullptr, 0, &sectionStart, &sectionSize))
return false; return false;
cur_ += idSize; if (sectionStart == NotStarted)
uint32_t size; return fail("expected user-defined section");
if (!readVarU32(&size) || bytesRemain() < size) finishUserDefinedSection(sectionStart, sectionSize);
return false;
cur_ += size;
return true; return true;
} }
@ -991,12 +1084,26 @@ class Decoder
typedef Vector<ValType, 8, SystemAllocPolicy> ValTypeVector; typedef Vector<ValType, 8, SystemAllocPolicy> ValTypeVector;
MOZ_MUST_USE bool
DecodePreamble(Decoder& d);
MOZ_MUST_USE bool MOZ_MUST_USE bool
EncodeLocalEntries(Encoder& d, const ValTypeVector& locals); EncodeLocalEntries(Encoder& d, const ValTypeVector& locals);
MOZ_MUST_USE bool MOZ_MUST_USE bool
DecodeLocalEntries(Decoder& d, ValTypeVector* locals); DecodeLocalEntries(Decoder& d, ValTypeVector* locals);
MOZ_MUST_USE bool
DecodeGlobalType(Decoder& d, ValType* type, uint32_t* flags);
struct ResizableLimits;
MOZ_MUST_USE bool
DecodeResizable(Decoder& d, ResizableLimits* resizable);
MOZ_MUST_USE bool
DecodeUnknownSections(Decoder& d);
} // namespace wasm } // namespace wasm
} // namespace js } // namespace js

Просмотреть файл

@ -33,6 +33,8 @@ wasm::Classify(Expr expr)
return ExprKind::Loop; return ExprKind::Loop;
case Expr::Unreachable: case Expr::Unreachable:
return ExprKind::Unreachable; return ExprKind::Unreachable;
case Expr::Drop:
return ExprKind::Drop;
case Expr::I32Const: case Expr::I32Const:
return ExprKind::I32; return ExprKind::I32;
case Expr::I64Const: case Expr::I64Const:
@ -62,7 +64,7 @@ wasm::Classify(Expr expr)
case Expr::BrTable: case Expr::BrTable:
return ExprKind::BrTable; return ExprKind::BrTable;
case Expr::Nop: case Expr::Nop:
return ExprKind::Nullary; return ExprKind::Nop;
case Expr::I32Clz: case Expr::I32Clz:
case Expr::I32Ctz: case Expr::I32Ctz:
case Expr::I32Popcnt: case Expr::I32Popcnt:
@ -314,8 +316,18 @@ wasm::Classify(Expr expr)
case Expr::I64Store: case Expr::I64Store:
case Expr::F32Store: case Expr::F32Store:
case Expr::F64Store: case Expr::F64Store:
case Expr::F32StoreF64: return ExprKind::Store;
case Expr::F64StoreF32: case Expr::I32TeeStore8:
case Expr::I32TeeStore16:
case Expr::I64TeeStore8:
case Expr::I64TeeStore16:
case Expr::I64TeeStore32:
case Expr::I32TeeStore:
case Expr::I64TeeStore:
case Expr::F32TeeStore:
case Expr::F64TeeStore:
case Expr::F32TeeStoreF64:
case Expr::F64TeeStoreF32:
case Expr::I8x16store: case Expr::I8x16store:
case Expr::I16x8store: case Expr::I16x8store:
case Expr::I32x4store: case Expr::I32x4store:
@ -326,19 +338,27 @@ wasm::Classify(Expr expr)
case Expr::F32x4store1: case Expr::F32x4store1:
case Expr::F32x4store2: case Expr::F32x4store2:
case Expr::F32x4store3: case Expr::F32x4store3:
return ExprKind::Store; return ExprKind::TeeStore;
case Expr::Select: case Expr::Select:
return ExprKind::Select; return ExprKind::Select;
case Expr::GetLocal: case Expr::GetLocal:
case Expr::GetGlobal: return ExprKind::GetLocal;
return ExprKind::GetVar;
case Expr::SetLocal: case Expr::SetLocal:
return ExprKind::SetLocal;
case Expr::TeeLocal:
return ExprKind::TeeLocal;
case Expr::GetGlobal:
return ExprKind::GetGlobal;
case Expr::SetGlobal: case Expr::SetGlobal:
return ExprKind::SetVar; return ExprKind::SetGlobal;
case Expr::TeeGlobal:
return ExprKind::TeeGlobal;
case Expr::Call: case Expr::Call:
return ExprKind::Call; return ExprKind::Call;
case Expr::CallIndirect: case Expr::CallIndirect:
return ExprKind::CallIndirect; return ExprKind::CallIndirect;
case Expr::OldCallIndirect:
return ExprKind::OldCallIndirect;
case Expr::CallImport: case Expr::CallImport:
return ExprKind::CallImport; return ExprKind::CallImport;
case Expr::Return: case Expr::Return:

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -159,10 +159,12 @@ IsDropValueExpr(AstExpr& expr)
return !expr.as<AstBranchTable>().maybeValue(); return !expr.as<AstBranchTable>().maybeValue();
case AstExprKind::If: case AstExprKind::If:
return !expr.as<AstIf>().hasElse(); return !expr.as<AstIf>().hasElse();
case AstExprKind::NullaryOperator: case AstExprKind::Nop:
return expr.as<AstNullaryOperator>().expr() == Expr::Nop; case AstExprKind::Drop:
case AstExprKind::Unreachable: case AstExprKind::Unreachable:
case AstExprKind::Return: case AstExprKind::Return:
case AstExprKind::SetLocal:
case AstExprKind::Store:
return true; return true;
default: default:
return false; return false;
@ -377,7 +379,6 @@ PrintNullaryOperator(WasmPrintContext& c, AstNullaryOperator& op)
const char* opStr; const char* opStr;
switch (op.expr()) { switch (op.expr()) {
case Expr::Nop: opStr = "nop"; break;
case Expr::CurrentMemory: opStr = "curent_memory"; break; case Expr::CurrentMemory: opStr = "curent_memory"; break;
default: return false; default: return false;
} }
@ -385,6 +386,21 @@ PrintNullaryOperator(WasmPrintContext& c, AstNullaryOperator& op)
return c.buffer.append(opStr, strlen(opStr)); return c.buffer.append(opStr, strlen(opStr));
} }
static bool
PrintNop(WasmPrintContext& c)
{
return c.buffer.append("nop");
}
static bool
PrintDrop(WasmPrintContext& c, AstDrop& drop)
{
if (!PrintExpr(c, drop.value()))
return false;
return true;
}
static bool static bool
PrintUnreachable(WasmPrintContext& c, AstUnreachable& unreachable) PrintUnreachable(WasmPrintContext& c, AstUnreachable& unreachable)
{ {
@ -447,6 +463,12 @@ PrintCallIndirect(WasmPrintContext& c, AstCallIndirect& call)
if (!PrintRef(c, call.sig())) if (!PrintRef(c, call.sig()))
return false; return false;
if (!c.buffer.append(' '))
return false;
if (!PrintCallArgs(c, call.args()))
return false;
if (!c.buffer.append(" [")) if (!c.buffer.append(" ["))
return false; return false;
@ -458,9 +480,7 @@ PrintCallIndirect(WasmPrintContext& c, AstCallIndirect& call)
c.currentPrecedence = lastPrecedence; c.currentPrecedence = lastPrecedence;
if (!c.buffer.append("] ")) if (!c.buffer.append(']'))
return false;
if (!PrintCallArgs(c, call.args()))
return false; return false;
return true; return true;
} }
@ -530,6 +550,35 @@ PrintSetLocal(WasmPrintContext& c, AstSetLocal& sl)
return true; return true;
} }
static bool
PrintTeeLocal(WasmPrintContext& c, AstTeeLocal& sl)
{
PrintOperatorPrecedence lastPrecedence = c.currentPrecedence;
if (!c.f.reduceParens || lastPrecedence > AssignmentPrecedence) {
if (!c.buffer.append("("))
return false;
}
if (!PrintRef(c, sl.local()))
return false;
if (!c.buffer.append(" = "))
return false;
c.currentPrecedence = AssignmentPrecedence;
if (!PrintExpr(c, sl.value()))
return false;
if (!c.f.reduceParens || lastPrecedence > AssignmentPrecedence) {
if (!c.buffer.append(")"))
return false;
}
c.currentPrecedence = lastPrecedence;
return true;
}
static bool static bool
PrintExprList(WasmPrintContext& c, const AstExprVector& exprs, uint32_t startFrom = 0) PrintExprList(WasmPrintContext& c, const AstExprVector& exprs, uint32_t startFrom = 0)
{ {
@ -558,10 +607,10 @@ PrintGroupedBlock(WasmPrintContext& c, AstBlock& block)
return false; return false;
// If no br/br_if/br_table refer this block, use some non-existent label. // If no br/br_if/br_table refer this block, use some non-existent label.
if (block.breakName().empty()) if (block.name().empty())
return c.buffer.append("$label:\n"); return c.buffer.append("$label:\n");
if (!PrintName(c, block.breakName())) if (!PrintName(c, block.name()))
return false; return false;
if (!c.buffer.append(":\n")) if (!c.buffer.append(":\n"))
return false; return false;
@ -590,10 +639,10 @@ PrintBlock(WasmPrintContext& c, AstBlock& block)
} else if (block.expr() == Expr::Loop) { } else if (block.expr() == Expr::Loop) {
if (!c.buffer.append("loop")) if (!c.buffer.append("loop"))
return false; return false;
if (!block.continueName().empty()) { if (!block.name().empty()) {
if (!c.buffer.append(" ")) if (!c.buffer.append(" "))
return false; return false;
if (!PrintName(c, block.continueName())) if (!PrintName(c, block.name()))
return false; return false;
} }
if (!c.buffer.append(" {\n")) if (!c.buffer.append(" {\n"))
@ -606,15 +655,18 @@ PrintBlock(WasmPrintContext& c, AstBlock& block)
bool skip = 0; bool skip = 0;
if (c.f.groupBlocks && block.expr() == Expr::Block && if (c.f.groupBlocks && block.expr() == Expr::Block &&
block.exprs().length() > 0 && block.exprs()[0]->kind() == AstExprKind::Block) { block.exprs().length() > 0 && block.exprs()[0]->kind() == AstExprKind::Block) {
if (!PrintGroupedBlock(c, *static_cast<AstBlock*>(block.exprs()[0]))) AstBlock* innerBlock = static_cast<AstBlock*>(block.exprs()[0]);
return false; if (innerBlock->expr() == Expr::Block) {
skip = 1; if (!PrintGroupedBlock(c, *innerBlock))
if (block.exprs().length() == 1 && block.breakName().empty()) { return false;
// Special case to resolve ambiguity in parsing of optional end block label. skip = 1;
if (!PrintIndent(c)) if (block.exprs().length() == 1 && block.name().empty()) {
return false; // Special case to resolve ambiguity in parsing of optional end block label.
if (!c.buffer.append("$exit$:\n")) if (!PrintIndent(c))
return false; return false;
if (!c.buffer.append("$exit$:\n"))
return false;
}
} }
} }
@ -624,8 +676,10 @@ PrintBlock(WasmPrintContext& c, AstBlock& block)
c.indent--; c.indent--;
c.currentPrecedence = lastPrecedence; c.currentPrecedence = lastPrecedence;
if (!PrintBlockName(c, block.breakName())) if (block.expr() != Expr::Loop) {
return false; if (!PrintBlockName(c, block.name()))
return false;
}
if (!PrintIndent(c)) if (!PrintIndent(c))
return false; return false;
@ -1009,7 +1063,7 @@ PrintIf(WasmPrintContext& c, AstIf& if_)
return false; return false;
c.indent--; c.indent--;
if (!PrintBlockName(c, if_.thenName())) if (!PrintBlockName(c, if_.name()))
return false; return false;
if (if_.hasElse()) { if (if_.hasElse()) {
@ -1022,7 +1076,7 @@ PrintIf(WasmPrintContext& c, AstIf& if_)
if (!PrintExprList(c, if_.elseExprs())) if (!PrintExprList(c, if_.elseExprs()))
return false; return false;
c.indent--; c.indent--;
if (!PrintBlockName(c, if_.elseName())) if (!PrintBlockName(c, if_.name()))
return false; return false;
} }
@ -1346,6 +1400,27 @@ PrintReturn(WasmPrintContext& c, AstReturn& ret)
return true; return true;
} }
static bool
PrintFirst(WasmPrintContext& c, AstFirst& first)
{
if (!c.buffer.append("first("))
return false;
for (uint32_t i = 0; i < first.exprs().length(); i++) {
if (!PrintExpr(c, *first.exprs()[i]))
return false;
if (i + 1 == first.exprs().length())
break;
if (!c.buffer.append(", "))
return false;
}
if (!c.buffer.append(")"))
return false;
return true;
}
static bool static bool
PrintExpr(WasmPrintContext& c, AstExpr& expr) PrintExpr(WasmPrintContext& c, AstExpr& expr)
{ {
@ -1357,6 +1432,10 @@ PrintExpr(WasmPrintContext& c, AstExpr& expr)
} }
switch (expr.kind()) { switch (expr.kind()) {
case AstExprKind::Nop:
return PrintNop(c);
case AstExprKind::Drop:
return PrintDrop(c, expr.as<AstDrop>());
case AstExprKind::NullaryOperator: case AstExprKind::NullaryOperator:
return PrintNullaryOperator(c, expr.as<AstNullaryOperator>()); return PrintNullaryOperator(c, expr.as<AstNullaryOperator>());
case AstExprKind::Unreachable: case AstExprKind::Unreachable:
@ -1371,6 +1450,8 @@ PrintExpr(WasmPrintContext& c, AstExpr& expr)
return PrintGetLocal(c, expr.as<AstGetLocal>()); return PrintGetLocal(c, expr.as<AstGetLocal>());
case AstExprKind::SetLocal: case AstExprKind::SetLocal:
return PrintSetLocal(c, expr.as<AstSetLocal>()); return PrintSetLocal(c, expr.as<AstSetLocal>());
case AstExprKind::TeeLocal:
return PrintTeeLocal(c, expr.as<AstTeeLocal>());
case AstExprKind::Block: case AstExprKind::Block:
return PrintBlock(c, expr.as<AstBlock>()); return PrintBlock(c, expr.as<AstBlock>());
case AstExprKind::If: case AstExprKind::If:
@ -1395,6 +1476,8 @@ PrintExpr(WasmPrintContext& c, AstExpr& expr)
return PrintBrTable(c, expr.as<AstBranchTable>()); return PrintBrTable(c, expr.as<AstBranchTable>());
case AstExprKind::Return: case AstExprKind::Return:
return PrintReturn(c, expr.as<AstReturn>()); return PrintReturn(c, expr.as<AstReturn>());
case AstExprKind::First:
return PrintFirst(c, expr.as<AstFirst>());
default: default:
// Note: it's important not to remove this default since readExpr() // Note: it's important not to remove this default since readExpr()
// can return Expr values for which there is no enumerator. // can return Expr values for which there is no enumerator.
@ -1496,12 +1579,15 @@ PrintTableSection(WasmPrintContext& c, const AstModule& module)
for (uint32_t i = 0; i < segment.elems().length(); i++) { for (uint32_t i = 0; i < segment.elems().length(); i++) {
const AstRef& elem = segment.elems()[i]; const AstRef& elem = segment.elems()[i];
AstFunc* func = module.funcs()[elem.index()]; uint32_t index = elem.index();
if (func->name().empty()) { AstName name = index < module.funcImportNames().length()
if (!PrintInt32(c, elem.index())) ? module.funcImportNames()[index]
: module.funcs()[index - module.funcImportNames().length()]->name();
if (name.empty()) {
if (!PrintInt32(c, index))
return false; return false;
} else { } else {
if (!PrintName(c, func->name())) if (!PrintName(c, name))
return false; return false;
} }
if (i + 1 == segment.elems().length()) if (i + 1 == segment.elems().length())
@ -1575,7 +1661,9 @@ PrintImportSection(WasmPrintContext& c, const AstModule::ImportVector& imports,
} }
static bool static bool
PrintExport(WasmPrintContext& c, AstExport& export_, const AstModule::FuncVector& funcs) PrintExport(WasmPrintContext& c, AstExport& export_,
const AstModule::NameVector& funcImportNames,
const AstModule::FuncVector& funcs)
{ {
if (!PrintIndent(c)) if (!PrintIndent(c))
return false; return false;
@ -1585,12 +1673,15 @@ PrintExport(WasmPrintContext& c, AstExport& export_, const AstModule::FuncVector
if (!c.buffer.append("memory")) if (!c.buffer.append("memory"))
return false; return false;
} else { } else {
const AstFunc* func = funcs[export_.ref().index()]; uint32_t index = export_.ref().index();
if (func->name().empty()) { AstName name = index < funcImportNames.length()
if (!PrintInt32(c, export_.ref().index())) ? funcImportNames[index]
: funcs[index - funcImportNames.length()]->name();
if (name.empty()) {
if (!PrintInt32(c, index))
return false; return false;
} else { } else {
if (!PrintName(c, func->name())) if (!PrintName(c, name))
return false; return false;
} }
} }
@ -1605,11 +1696,13 @@ PrintExport(WasmPrintContext& c, AstExport& export_, const AstModule::FuncVector
} }
static bool static bool
PrintExportSection(WasmPrintContext& c, const AstModule::ExportVector& exports, const AstModule::FuncVector& funcs) PrintExportSection(WasmPrintContext& c, const AstModule::ExportVector& exports,
const AstModule::NameVector& funcImportNames,
const AstModule::FuncVector& funcs)
{ {
uint32_t numExports = exports.length(); uint32_t numExports = exports.length();
for (uint32_t i = 0; i < numExports; i++) { for (uint32_t i = 0; i < numExports; i++) {
if (!PrintExport(c, *exports[i], funcs)) if (!PrintExport(c, *exports[i], funcImportNames, funcs))
return false; return false;
} }
if (numExports) { if (numExports) {
@ -1722,12 +1815,12 @@ PrintDataSection(WasmPrintContext& c, const AstModule& module)
return false; return false;
if (!c.buffer.append("memory ")) if (!c.buffer.append("memory "))
return false; return false;
if (!PrintInt32(c, module.memory().initial())) if (!PrintInt32(c, module.memory().initial))
return false; return false;
if (module.memory().maximum()) { if (module.memory().maximum) {
if (!c.buffer.append(", ")) if (!c.buffer.append(", "))
return false; return false;
if (!PrintInt32(c, *module.memory().maximum())) if (!PrintInt32(c, *module.memory().maximum))
return false; return false;
} }
@ -1779,7 +1872,7 @@ PrintModule(WasmPrintContext& c, AstModule& module)
if (!PrintTableSection(c, module)) if (!PrintTableSection(c, module))
return false; return false;
if (!PrintExportSection(c, module.exports(), module.funcs())) if (!PrintExportSection(c, module.exports(), module.funcImportNames(), module.funcs()))
return false; return false;
if (!PrintCodeSection(c, module.funcs(), module.sigs())) if (!PrintCodeSection(c, module.funcs(), module.sigs()))

Просмотреть файл

@ -199,33 +199,66 @@ RenderRef(WasmRenderContext& c, const AstRef& ref)
} }
static bool static bool
RenderExpr(WasmRenderContext& c, AstExpr& expr); RenderBlockNameAndSignature(WasmRenderContext& c, const AstName& name, ExprType type)
{
if (!name.empty()) {
if (!c.buffer.append(' '))
return false;
if (!RenderName(c, name))
return false;
}
if (!IsVoid(type)) {
if (!c.buffer.append(' '))
return false;
if (!RenderExprType(c, type))
return false;
}
return true;
}
static bool static bool
RenderFullLine(WasmRenderContext& c, AstExpr& expr) RenderExpr(WasmRenderContext& c, AstExpr& expr);
{
if (!RenderIndent(c))
return false;
if (!RenderExpr(c, expr))
return false;
return c.buffer.append('\n');
}
/*****************************************************************************/ /*****************************************************************************/
// binary format parsing and rendering // binary format parsing and rendering
static bool static bool
RenderUnreachable(WasmRenderContext& c, AstUnreachable& unreachable) RenderNop(WasmRenderContext& c)
{ {
return c.buffer.append("(trap)"); if (!RenderIndent(c))
return false;
return c.buffer.append("nop\n");
}
static bool
RenderDrop(WasmRenderContext& c, AstDrop& drop)
{
if (!RenderExpr(c, drop.value()))
return false;
if (!RenderIndent(c))
return false;
if (!c.buffer.append("drop\n"))
return false;
return true;
}
static bool
RenderUnreachable(WasmRenderContext& c)
{
if (!RenderIndent(c))
return false;
return c.buffer.append("unreachable\n");
} }
static bool static bool
RenderCallArgs(WasmRenderContext& c, const AstExprVector& args) RenderCallArgs(WasmRenderContext& c, const AstExprVector& args)
{ {
for (uint32_t i = 0; i < args.length(); i++) { for (uint32_t i = 0; i < args.length(); i++) {
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, *args[i])) if (!RenderExpr(c, *args[i]))
return false; return false;
} }
@ -236,11 +269,17 @@ RenderCallArgs(WasmRenderContext& c, const AstExprVector& args)
static bool static bool
RenderCall(WasmRenderContext& c, AstCall& call) RenderCall(WasmRenderContext& c, AstCall& call)
{ {
if (!RenderCallArgs(c, call.args()))
return false;
if (!RenderIndent(c))
return false;
if (call.expr() == Expr::Call) { if (call.expr() == Expr::Call) {
if (!c.buffer.append("(call ")) if (!c.buffer.append("call "))
return false; return false;
} else if (call.expr() == Expr::CallImport) { } else if (call.expr() == Expr::CallImport) {
if (!c.buffer.append("(call_import ")) if (!c.buffer.append("call_import "))
return false; return false;
} else { } else {
return false; return false;
@ -249,10 +288,7 @@ RenderCall(WasmRenderContext& c, AstCall& call)
if (!RenderRef(c, call.func())) if (!RenderRef(c, call.func()))
return false; return false;
if (!RenderCallArgs(c, call.args())) if (!c.buffer.append('\n'))
return false;
if (!c.buffer.append(")"))
return false; return false;
return true; return true;
@ -261,23 +297,21 @@ RenderCall(WasmRenderContext& c, AstCall& call)
static bool static bool
RenderCallIndirect(WasmRenderContext& c, AstCallIndirect& call) RenderCallIndirect(WasmRenderContext& c, AstCallIndirect& call)
{ {
if (!c.buffer.append("(call_indirect ")) if (!RenderCallArgs(c, call.args()))
return false;
if (!RenderRef(c, call.sig()))
return false;
if (!c.buffer.append(" "))
return false; return false;
if (!RenderExpr(c, *call.index())) if (!RenderExpr(c, *call.index()))
return false; return false;
if (!c.buffer.append(" ")) if (!RenderIndent(c))
return false;
if (!RenderCallArgs(c, call.args()))
return false; return false;
if (!c.buffer.append(")")) if (!c.buffer.append("call_indirect "))
return false;
if (!RenderRef(c, call.sig()))
return false;
if (!c.buffer.append('\n'))
return false; return false;
return true; return true;
@ -286,8 +320,9 @@ RenderCallIndirect(WasmRenderContext& c, AstCallIndirect& call)
static bool static bool
RenderConst(WasmRenderContext& c, AstConst& cst) RenderConst(WasmRenderContext& c, AstConst& cst)
{ {
if (!c.buffer.append('(')) if (!RenderIndent(c))
return false; return false;
if (!RenderValType(c, cst.val().type())) if (!RenderValType(c, cst.val().type()))
return false; return false;
if (!c.buffer.append(".const ")) if (!c.buffer.append(".const "))
@ -314,7 +349,7 @@ RenderConst(WasmRenderContext& c, AstConst& cst)
return false; return false;
} }
if (!c.buffer.append(")")) if (!c.buffer.append('\n'))
return false; return false;
return true; return true;
} }
@ -322,29 +357,52 @@ RenderConst(WasmRenderContext& c, AstConst& cst)
static bool static bool
RenderGetLocal(WasmRenderContext& c, AstGetLocal& gl) RenderGetLocal(WasmRenderContext& c, AstGetLocal& gl)
{ {
if (!c.buffer.append("(get_local ")) if (!RenderIndent(c))
return false;
if (!c.buffer.append("get_local "))
return false; return false;
if (!RenderRef(c, gl.local())) if (!RenderRef(c, gl.local()))
return false; return false;
if (!c.buffer.append(")")) if (!c.buffer.append('\n'))
return false; return false;
return true; return true;
} }
static bool static bool
RenderSetLocal(WasmRenderContext& c, AstSetLocal& sl) RenderSetLocal(WasmRenderContext& c, AstSetLocal& sl)
{ {
if (!c.buffer.append("(set_local "))
return false;
if (!RenderRef(c, sl.local()))
return false;
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, sl.value())) if (!RenderExpr(c, sl.value()))
return false; return false;
if (!c.buffer.append(")")) if (!RenderIndent(c))
return false;
if (!c.buffer.append("set_local "))
return false;
if (!RenderRef(c, sl.local()))
return false;
if (!c.buffer.append('\n'))
return false;
return true;
}
static bool
RenderTeeLocal(WasmRenderContext& c, AstTeeLocal& tl)
{
if (!RenderExpr(c, tl.value()))
return false;
if (!RenderIndent(c))
return false;
if (!c.buffer.append("tee_local "))
return false;
if (!RenderRef(c, tl.local()))
return false;
if (!c.buffer.append('\n'))
return false; return false;
return true; return true;
} }
@ -353,8 +411,6 @@ static bool
RenderExprList(WasmRenderContext& c, const AstExprVector& exprs) RenderExprList(WasmRenderContext& c, const AstExprVector& exprs)
{ {
for (uint32_t i = 0; i < exprs.length(); i++) { for (uint32_t i = 0; i < exprs.length(); i++) {
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, *exprs[i])) if (!RenderExpr(c, *exprs[i]))
return false; return false;
} }
@ -364,48 +420,52 @@ RenderExprList(WasmRenderContext& c, const AstExprVector& exprs)
static bool static bool
RenderBlock(WasmRenderContext& c, AstBlock& block) RenderBlock(WasmRenderContext& c, AstBlock& block)
{ {
if (!RenderIndent(c))
return false;
if (block.expr() == Expr::Block) { if (block.expr() == Expr::Block) {
if (!c.buffer.append("(block ")) if (!c.buffer.append("block"))
return false;
if (!RenderName(c, block.breakName()))
return false; return false;
} else if (block.expr() == Expr::Loop) { } else if (block.expr() == Expr::Loop) {
if (!c.buffer.append("(loop ")) if (!c.buffer.append("loop"))
return false; return false;
if (block.breakName().empty() && !block.continueName().empty()) {
// Giving auto label if continue label is present.
if (!c.buffer.append("$exit$"))
return false;
} else {
if (!RenderName(c, block.breakName()))
return false;
}
if (!block.continueName().empty()) {
if (!c.buffer.append(" "))
return false;
if (!RenderName(c, block.continueName()))
return false;
}
} else } else
return false; return false;
if (!RenderBlockNameAndSignature(c, block.name(), block.type()))
return false;
if (!c.buffer.append('\n'))
return false;
c.indent++; c.indent++;
if (!RenderExprList(c, block.exprs())) if (!RenderExprList(c, block.exprs()))
return false; return false;
c.indent--; c.indent--;
return c.buffer.append(")"); if (!RenderIndent(c))
return false;
return c.buffer.append("end\n");
}
static bool
RenderFirst(WasmRenderContext& c, AstFirst& first)
{
if (!RenderExprList(c, first.exprs()))
return false;
return true;
} }
static bool static bool
RenderNullaryOperator(WasmRenderContext& c, AstNullaryOperator& op) RenderNullaryOperator(WasmRenderContext& c, AstNullaryOperator& op)
{ {
if (!c.buffer.append("(")) if (!RenderIndent(c))
return false; return false;
const char* opStr; const char* opStr;
switch (op.expr()) { switch (op.expr()) {
case Expr::Nop: opStr = "nop"; break;
case Expr::CurrentMemory: opStr = "current_memory"; break; case Expr::CurrentMemory: opStr = "current_memory"; break;
default: return false; default: return false;
} }
@ -413,14 +473,17 @@ RenderNullaryOperator(WasmRenderContext& c, AstNullaryOperator& op)
if (!c.buffer.append(opStr, strlen(opStr))) if (!c.buffer.append(opStr, strlen(opStr)))
return false; return false;
return c.buffer.append(")"); return c.buffer.append('\n');
} }
static bool static bool
RenderUnaryOperator(WasmRenderContext& c, AstUnaryOperator& op) RenderUnaryOperator(WasmRenderContext& c, AstUnaryOperator& op)
{ {
if (!c.buffer.append("(")) if (!RenderExpr(c, *op.op()))
return false; return false;
if (!RenderIndent(c))
return false;
const char* opStr; const char* opStr;
switch (op.expr()) { switch (op.expr()) {
@ -449,20 +512,19 @@ RenderUnaryOperator(WasmRenderContext& c, AstUnaryOperator& op)
if (!c.buffer.append(opStr, strlen(opStr))) if (!c.buffer.append(opStr, strlen(opStr)))
return false; return false;
if (!c.buffer.append(" ")) return c.buffer.append('\n');
return false;
if (!RenderExpr(c, *op.op()))
return false;
return c.buffer.append(")");
} }
static bool static bool
RenderBinaryOperator(WasmRenderContext& c, AstBinaryOperator& op) RenderBinaryOperator(WasmRenderContext& c, AstBinaryOperator& op)
{ {
if (!c.buffer.append("(")) if (!RenderExpr(c, *op.lhs()))
return false; return false;
if (!RenderExpr(c, *op.rhs()))
return false;
if (!RenderIndent(c))
return false;
const char* opStr; const char* opStr;
switch (op.expr()) { switch (op.expr()) {
@ -510,15 +572,7 @@ RenderBinaryOperator(WasmRenderContext& c, AstBinaryOperator& op)
if (!c.buffer.append(opStr, strlen(opStr))) if (!c.buffer.append(opStr, strlen(opStr)))
return false; return false;
if (!c.buffer.append(" ")) if (!c.buffer.append('\n'))
return false;
if (!RenderExpr(c, *op.lhs()))
return false;
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, *op.rhs()))
return false;
if (!c.buffer.append(")"))
return false; return false;
return true; return true;
@ -527,7 +581,14 @@ RenderBinaryOperator(WasmRenderContext& c, AstBinaryOperator& op)
static bool static bool
RenderTernaryOperator(WasmRenderContext& c, AstTernaryOperator& op) RenderTernaryOperator(WasmRenderContext& c, AstTernaryOperator& op)
{ {
if (!c.buffer.append("(")) if (!RenderExpr(c, *op.op0()))
return false;
if (!RenderExpr(c, *op.op1()))
return false;
if (!RenderExpr(c, *op.op2()))
return false;
if (!RenderIndent(c))
return false; return false;
const char* opStr; const char* opStr;
@ -538,19 +599,7 @@ RenderTernaryOperator(WasmRenderContext& c, AstTernaryOperator& op)
if (!c.buffer.append(opStr, strlen(opStr))) if (!c.buffer.append(opStr, strlen(opStr)))
return false; return false;
if (!c.buffer.append(" ")) if (!c.buffer.append('\n'))
return false;
if (!RenderExpr(c, *op.op0()))
return false;
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, *op.op1()))
return false;
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, *op.op2()))
return false;
if (!c.buffer.append(")"))
return false; return false;
return true; return true;
@ -559,8 +608,13 @@ RenderTernaryOperator(WasmRenderContext& c, AstTernaryOperator& op)
static bool static bool
RenderComparisonOperator(WasmRenderContext& c, AstComparisonOperator& op) RenderComparisonOperator(WasmRenderContext& c, AstComparisonOperator& op)
{ {
if (!c.buffer.append("(")) if (!RenderExpr(c, *op.lhs()))
return false; return false;
if (!RenderExpr(c, *op.rhs()))
return false;
if (!RenderIndent(c))
return false;
const char* opStr; const char* opStr;
switch (op.expr()) { switch (op.expr()) {
@ -601,15 +655,7 @@ RenderComparisonOperator(WasmRenderContext& c, AstComparisonOperator& op)
if (!c.buffer.append(opStr, strlen(opStr))) if (!c.buffer.append(opStr, strlen(opStr)))
return false; return false;
if (!c.buffer.append(" ")) if (!c.buffer.append('\n'))
return false;
if (!RenderExpr(c, *op.lhs()))
return false;
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, *op.rhs()))
return false;
if (!c.buffer.append(")"))
return false; return false;
return true; return true;
@ -618,8 +664,11 @@ RenderComparisonOperator(WasmRenderContext& c, AstComparisonOperator& op)
static bool static bool
RenderConversionOperator(WasmRenderContext& c, AstConversionOperator& op) RenderConversionOperator(WasmRenderContext& c, AstConversionOperator& op)
{ {
if (!c.buffer.append("(")) if (!RenderExpr(c, *op.op()))
return false; return false;
if (!RenderIndent(c))
return false;
const char* opStr; const char* opStr;
switch (op.expr()) { switch (op.expr()) {
@ -648,32 +697,40 @@ RenderConversionOperator(WasmRenderContext& c, AstConversionOperator& op)
case Expr::F64ConvertUI64: opStr = "f64.convert_u/i64"; break; case Expr::F64ConvertUI64: opStr = "f64.convert_u/i64"; break;
case Expr::F64ReinterpretI64: opStr = "f64.reinterpret/i64"; break; case Expr::F64ReinterpretI64: opStr = "f64.reinterpret/i64"; break;
case Expr::F64PromoteF32: opStr = "f64.promote/f32"; break; case Expr::F64PromoteF32: opStr = "f64.promote/f32"; break;
case Expr::I32Eqz: opStr = "i32.eqz"; break;
case Expr::I64Eqz: opStr = "i64.eqz"; break;
default: return false; default: return false;
} }
if (!c.buffer.append(opStr, strlen(opStr))) if (!c.buffer.append(opStr, strlen(opStr)))
return false; return false;
if (!c.buffer.append(" ")) return c.buffer.append('\n');
return false;
if (!RenderExpr(c, *op.op()))
return false;
return c.buffer.append(")");
} }
static bool static bool
RenderIf(WasmRenderContext& c, AstIf& if_) RenderIf(WasmRenderContext& c, AstIf& if_)
{ {
if (!c.buffer.append("(if "))
return false;
if (!RenderExpr(c, if_.cond())) if (!RenderExpr(c, if_.cond()))
return false; return false;
if (!c.buffer.append(" (then ")) if (!RenderIndent(c))
return false; return false;
if (!RenderName(c, if_.thenName())) if (!c.buffer.append("if"))
return false;
if (!RenderBlockNameAndSignature(c, if_.name(), if_.type()))
return false;
if (!if_.name().empty()) {
if (!c.buffer.append(' '))
return false;
if (!RenderName(c, if_.name()))
return false;
}
if (!c.buffer.append('\n'))
return false; return false;
c.indent++; c.indent++;
@ -682,10 +739,10 @@ RenderIf(WasmRenderContext& c, AstIf& if_)
c.indent--; c.indent--;
if (if_.hasElse()) { if (if_.hasElse()) {
if (!c.buffer.append(") (else ")) if (!RenderIndent(c))
return false; return false;
if (!RenderName(c, if_.elseName())) if (!c.buffer.append("else\n"))
return false; return false;
c.indent++; c.indent++;
@ -694,7 +751,19 @@ RenderIf(WasmRenderContext& c, AstIf& if_)
c.indent--; c.indent--;
} }
return c.buffer.append("))"); if (!RenderIndent(c))
return false;
return c.buffer.append("end\n");
}
static bool
RenderLoadStoreBase(WasmRenderContext& c, const AstLoadStoreAddress& lsa)
{
if (!RenderExpr(c, lsa.base()))
return false;
return true;
} }
static bool static bool
@ -715,87 +784,87 @@ RenderLoadStoreAddress(WasmRenderContext& c, const AstLoadStoreAddress& lsa, uin
return false; return false;
} }
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, lsa.base()))
return false;
return true; return true;
} }
static bool static bool
RenderLoad(WasmRenderContext& c, AstLoad& load) RenderLoad(WasmRenderContext& c, AstLoad& load)
{ {
if (!RenderLoadStoreBase(c, load.address()))
return false;
if (!RenderIndent(c))
return false;
uint32_t defaultAlignLog2; uint32_t defaultAlignLog2;
switch (load.expr()) { switch (load.expr()) {
case Expr::I32Load8S: case Expr::I32Load8S:
if (!c.buffer.append("(i32.load8_s")) if (!c.buffer.append("i32.load8_s"))
return false; return false;
defaultAlignLog2 = 0; defaultAlignLog2 = 0;
break; break;
case Expr::I64Load8S: case Expr::I64Load8S:
if (!c.buffer.append("(i64.load8_s")) if (!c.buffer.append("i64.load8_s"))
return false; return false;
defaultAlignLog2 = 0; defaultAlignLog2 = 0;
break; break;
case Expr::I32Load8U: case Expr::I32Load8U:
if (!c.buffer.append("(i32.load8_u")) if (!c.buffer.append("i32.load8_u"))
return false; return false;
defaultAlignLog2 = 0; defaultAlignLog2 = 0;
break; break;
case Expr::I64Load8U: case Expr::I64Load8U:
if (!c.buffer.append("(i64.load8_u")) if (!c.buffer.append("i64.load8_u"))
return false; return false;
defaultAlignLog2 = 0; defaultAlignLog2 = 0;
break; break;
case Expr::I32Load16S: case Expr::I32Load16S:
if (!c.buffer.append("(i32.load16_s")) if (!c.buffer.append("i32.load16_s"))
return false; return false;
defaultAlignLog2 = 1; defaultAlignLog2 = 1;
break; break;
case Expr::I64Load16S: case Expr::I64Load16S:
if (!c.buffer.append("(i64.load16_s")) if (!c.buffer.append("i64.load16_s"))
return false; return false;
defaultAlignLog2 = 1; defaultAlignLog2 = 1;
break; break;
case Expr::I32Load16U: case Expr::I32Load16U:
if (!c.buffer.append("(i32.load16_u")) if (!c.buffer.append("i32.load16_u"))
return false; return false;
defaultAlignLog2 = 1; defaultAlignLog2 = 1;
break; break;
case Expr::I64Load16U: case Expr::I64Load16U:
if (!c.buffer.append("(i64.load16_u")) if (!c.buffer.append("i64.load16_u"))
return false; return false;
defaultAlignLog2 = 1; defaultAlignLog2 = 1;
break; break;
case Expr::I64Load32S: case Expr::I64Load32S:
if (!c.buffer.append("(i64.load32_s")) if (!c.buffer.append("i64.load32_s"))
return false; return false;
defaultAlignLog2 = 2; defaultAlignLog2 = 2;
break; break;
case Expr::I64Load32U: case Expr::I64Load32U:
if (!c.buffer.append("(i64.load32_u")) if (!c.buffer.append("i64.load32_u"))
return false; return false;
defaultAlignLog2 = 2; defaultAlignLog2 = 2;
break; break;
case Expr::I32Load: case Expr::I32Load:
if (!c.buffer.append("(i32.load")) if (!c.buffer.append("i32.load"))
return false; return false;
defaultAlignLog2 = 2; defaultAlignLog2 = 2;
break; break;
case Expr::I64Load: case Expr::I64Load:
if (!c.buffer.append("(i64.load")) if (!c.buffer.append("i64.load"))
return false; return false;
defaultAlignLog2 = 3; defaultAlignLog2 = 3;
break; break;
case Expr::F32Load: case Expr::F32Load:
if (!c.buffer.append("(f32.load")) if (!c.buffer.append("f32.load"))
return false; return false;
defaultAlignLog2 = 2; defaultAlignLog2 = 2;
break; break;
case Expr::F64Load: case Expr::F64Load:
if (!c.buffer.append("(f64.load")) if (!c.buffer.append("f64.load"))
return false; return false;
defaultAlignLog2 = 3; defaultAlignLog2 = 3;
break; break;
@ -803,60 +872,68 @@ RenderLoad(WasmRenderContext& c, AstLoad& load)
return false; return false;
} }
if (!RenderLoadStoreAddress(c, load.address(), defaultAlignLog2)) if (!RenderLoadStoreAddress(c, load.address(), defaultAlignLog2))
return false; return false;
return c.buffer.append(")"); return c.buffer.append('\n');
} }
static bool static bool
RenderStore(WasmRenderContext& c, AstStore& store) RenderStore(WasmRenderContext& c, AstStore& store)
{ {
if (!RenderLoadStoreBase(c, store.address()))
return false;
if (!RenderExpr(c, store.value()))
return false;
if (!RenderIndent(c))
return false;
uint32_t defaultAlignLog2; uint32_t defaultAlignLog2;
switch (store.expr()) { switch (store.expr()) {
case Expr::I32Store8: case Expr::I32Store8:
if (!c.buffer.append("(i32.store8")) if (!c.buffer.append("i32.store8"))
return false; return false;
defaultAlignLog2 = 0; defaultAlignLog2 = 0;
break; break;
case Expr::I64Store8: case Expr::I64Store8:
if (!c.buffer.append("(i64.store8")) if (!c.buffer.append("i64.store8"))
return false; return false;
defaultAlignLog2 = 0; defaultAlignLog2 = 0;
break; break;
case Expr::I32Store16: case Expr::I32Store16:
if (!c.buffer.append("(i32.store16")) if (!c.buffer.append("i32.store16"))
return false; return false;
defaultAlignLog2 = 1; defaultAlignLog2 = 1;
break; break;
case Expr::I64Store16: case Expr::I64Store16:
if (!c.buffer.append("(i64.store16")) if (!c.buffer.append("i64.store16"))
return false; return false;
defaultAlignLog2 = 1; defaultAlignLog2 = 1;
break; break;
case Expr::I64Store32: case Expr::I64Store32:
if (!c.buffer.append("(i64.store32")) if (!c.buffer.append("i64.store32"))
return false; return false;
defaultAlignLog2 = 2; defaultAlignLog2 = 2;
break; break;
case Expr::I32Store: case Expr::I32Store:
if (!c.buffer.append("(i32.store")) if (!c.buffer.append("i32.store"))
return false; return false;
defaultAlignLog2 = 2; defaultAlignLog2 = 2;
break; break;
case Expr::I64Store: case Expr::I64Store:
if (!c.buffer.append("(i64.store")) if (!c.buffer.append("i64.store"))
return false; return false;
defaultAlignLog2 = 3; defaultAlignLog2 = 3;
break; break;
case Expr::F32Store: case Expr::F32Store:
if (!c.buffer.append("(f32.store")) if (!c.buffer.append("f32.store"))
return false; return false;
defaultAlignLog2 = 2; defaultAlignLog2 = 2;
break; break;
case Expr::F64Store: case Expr::F64Store:
if (!c.buffer.append("(f64.store")) if (!c.buffer.append("f64.store"))
return false; return false;
defaultAlignLog2 = 3; defaultAlignLog2 = 3;
break; break;
@ -867,13 +944,7 @@ RenderStore(WasmRenderContext& c, AstStore& store)
if (!RenderLoadStoreAddress(c, store.address(), defaultAlignLog2)) if (!RenderLoadStoreAddress(c, store.address(), defaultAlignLog2))
return false; return false;
if (!c.buffer.append(" ")) return c.buffer.append('\n');
return false;
if (!RenderExpr(c, store.value()))
return false;
return c.buffer.append(")");
} }
static bool static bool
@ -882,34 +953,44 @@ RenderBranch(WasmRenderContext& c, AstBranch& branch)
Expr expr = branch.expr(); Expr expr = branch.expr();
MOZ_ASSERT(expr == Expr::BrIf || expr == Expr::Br); MOZ_ASSERT(expr == Expr::BrIf || expr == Expr::Br);
if (expr == Expr::BrIf ? !c.buffer.append("(br_if ") : !c.buffer.append("(br "))
return false;
if (!RenderRef(c, branch.target()))
return false;
if (expr == Expr::BrIf) { if (expr == Expr::BrIf) {
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, branch.cond())) if (!RenderExpr(c, branch.cond()))
return false; return false;
} }
if (branch.maybeValue()) { if (branch.maybeValue()) {
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, *(branch.maybeValue()))) if (!RenderExpr(c, *(branch.maybeValue())))
return false; return false;
} }
return c.buffer.append(")"); if (!RenderIndent(c))
return false;
if (expr == Expr::BrIf ? !c.buffer.append("br_if ") : !c.buffer.append("br "))
return false;
if (!RenderRef(c, branch.target()))
return false;
return c.buffer.append('\n');
} }
static bool static bool
RenderBrTable(WasmRenderContext& c, AstBranchTable& table) RenderBrTable(WasmRenderContext& c, AstBranchTable& table)
{ {
if (!c.buffer.append("(br_table ")) if (table.maybeValue()) {
if (!RenderExpr(c, *(table.maybeValue())))
return false;
}
// Index
if (!RenderExpr(c, table.index()))
return false;
if (!RenderIndent(c))
return false;
if (!c.buffer.append("br_table "))
return false; return false;
uint32_t tableLength = table.table().length(); uint32_t tableLength = table.table().length();
@ -924,48 +1005,36 @@ RenderBrTable(WasmRenderContext& c, AstBranchTable& table)
if (!RenderRef(c, table.def())) if (!RenderRef(c, table.def()))
return false; return false;
if (!c.buffer.append(" ")) return c.buffer.append('\n');
return false;
if (table.maybeValue()) {
if (!RenderExpr(c, *(table.maybeValue())))
return false;
if (!c.buffer.append(" "))
return false;
}
// Index
if (!RenderExpr(c, table.index()))
return false;
return c.buffer.append(")");
} }
static bool static bool
RenderReturn(WasmRenderContext& c, AstReturn& ret) RenderReturn(WasmRenderContext& c, AstReturn& ret)
{ {
if (!c.buffer.append("(return"))
return false;
if (ret.maybeExpr()) { if (ret.maybeExpr()) {
if (!c.buffer.append(" "))
return false;
if (!RenderExpr(c, *(ret.maybeExpr()))) if (!RenderExpr(c, *(ret.maybeExpr())))
return false; return false;
} }
return c.buffer.append(")"); if (!RenderIndent(c))
return false;
if (!c.buffer.append("return"))
return false;
return c.buffer.append('\n');
} }
static bool static bool
RenderExpr(WasmRenderContext& c, AstExpr& expr) RenderExpr(WasmRenderContext& c, AstExpr& expr)
{ {
switch (expr.kind()) { switch (expr.kind()) {
case AstExprKind::NullaryOperator: case AstExprKind::Drop:
return RenderNullaryOperator(c, expr.as<AstNullaryOperator>()); return RenderDrop(c, expr.as<AstDrop>());
case AstExprKind::Nop:
return RenderNop(c);
case AstExprKind::Unreachable: case AstExprKind::Unreachable:
return RenderUnreachable(c, expr.as<AstUnreachable>()); return RenderUnreachable(c);
case AstExprKind::Call: case AstExprKind::Call:
return RenderCall(c, expr.as<AstCall>()); return RenderCall(c, expr.as<AstCall>());
case AstExprKind::CallIndirect: case AstExprKind::CallIndirect:
@ -976,10 +1045,14 @@ RenderExpr(WasmRenderContext& c, AstExpr& expr)
return RenderGetLocal(c, expr.as<AstGetLocal>()); return RenderGetLocal(c, expr.as<AstGetLocal>());
case AstExprKind::SetLocal: case AstExprKind::SetLocal:
return RenderSetLocal(c, expr.as<AstSetLocal>()); return RenderSetLocal(c, expr.as<AstSetLocal>());
case AstExprKind::TeeLocal:
return RenderTeeLocal(c, expr.as<AstTeeLocal>());
case AstExprKind::Block: case AstExprKind::Block:
return RenderBlock(c, expr.as<AstBlock>()); return RenderBlock(c, expr.as<AstBlock>());
case AstExprKind::If: case AstExprKind::If:
return RenderIf(c, expr.as<AstIf>()); return RenderIf(c, expr.as<AstIf>());
case AstExprKind::NullaryOperator:
return RenderNullaryOperator(c, expr.as<AstNullaryOperator>());
case AstExprKind::UnaryOperator: case AstExprKind::UnaryOperator:
return RenderUnaryOperator(c, expr.as<AstUnaryOperator>()); return RenderUnaryOperator(c, expr.as<AstUnaryOperator>());
case AstExprKind::BinaryOperator: case AstExprKind::BinaryOperator:
@ -1000,6 +1073,8 @@ RenderExpr(WasmRenderContext& c, AstExpr& expr)
return RenderBrTable(c, expr.as<AstBranchTable>()); return RenderBrTable(c, expr.as<AstBranchTable>());
case AstExprKind::Return: case AstExprKind::Return:
return RenderReturn(c, expr.as<AstReturn>()); return RenderReturn(c, expr.as<AstReturn>());
case AstExprKind::First:
return RenderFirst(c, expr.as<AstFirst>());
default: default:
// Note: it's important not to remove this default since readExpr() // Note: it's important not to remove this default since readExpr()
// can return Expr values for which there is no enumerator. // can return Expr values for which there is no enumerator.
@ -1101,12 +1176,15 @@ RenderTableSection(WasmRenderContext& c, const AstModule& module)
for (const AstRef& elem : segment.elems()) { for (const AstRef& elem : segment.elems()) {
if (!c.buffer.append(" ")) if (!c.buffer.append(" "))
return false; return false;
AstFunc* func = module.funcs()[elem.index()]; uint32_t index = elem.index();
if (func->name().empty()) { AstName name = index < module.funcImportNames().length()
if (!RenderInt32(c, elem.index())) ? module.funcImportNames()[index]
: module.funcs()[index - module.funcImportNames().length()]->name();
if (name.empty()) {
if (!RenderInt32(c, index))
return false; return false;
} else { } else {
if (!RenderName(c, func->name())) if (!RenderName(c, name))
return false; return false;
} }
} }
@ -1167,7 +1245,9 @@ RenderImportSection(WasmRenderContext& c, const AstModule::ImportVector& imports
} }
static bool static bool
RenderExport(WasmRenderContext& c, AstExport& export_, const AstModule::FuncVector& funcs) RenderExport(WasmRenderContext& c, AstExport& export_,
const AstModule::NameVector& funcImportNames,
const AstModule::FuncVector& funcs)
{ {
if (!RenderIndent(c)) if (!RenderIndent(c))
return false; return false;
@ -1181,12 +1261,15 @@ RenderExport(WasmRenderContext& c, AstExport& export_, const AstModule::FuncVect
if (!c.buffer.append("memory")) if (!c.buffer.append("memory"))
return false; return false;
} else { } else {
const AstFunc* func = funcs[export_.ref().index()]; uint32_t index = export_.ref().index();
if (func->name().empty()) { AstName name = index < funcImportNames.length()
if (!RenderInt32(c, export_.ref().index())) ? funcImportNames[index]
: funcs[index - funcImportNames.length()]->name();
if (name.empty()) {
if (!RenderInt32(c, index))
return false; return false;
} else { } else {
if (!RenderName(c, func->name())) if (!RenderName(c, name))
return false; return false;
} }
} }
@ -1197,11 +1280,13 @@ RenderExport(WasmRenderContext& c, AstExport& export_, const AstModule::FuncVect
} }
static bool static bool
RenderExportSection(WasmRenderContext& c, const AstModule::ExportVector& exports, const AstModule::FuncVector& funcs) RenderExportSection(WasmRenderContext& c, const AstModule::ExportVector& exports,
const AstModule::NameVector& funcImportNames,
const AstModule::FuncVector& funcs)
{ {
uint32_t numExports = exports.length(); uint32_t numExports = exports.length();
for (uint32_t i = 0; i < numExports; i++) { for (uint32_t i = 0; i < numExports; i++) {
if (!RenderExport(c, *exports[i], funcs)) if (!RenderExport(c, *exports[i], funcImportNames, funcs))
return false; return false;
} }
return true; return true;
@ -1211,7 +1296,6 @@ static bool
RenderFunctionBody(WasmRenderContext& c, AstFunc& func, const AstModule::SigVector& sigs) RenderFunctionBody(WasmRenderContext& c, AstFunc& func, const AstModule::SigVector& sigs)
{ {
const AstSig* sig = sigs[func.sig().index()]; const AstSig* sig = sigs[func.sig().index()];
c.indent++;
uint32_t argsNum = sig->args().length(); uint32_t argsNum = sig->args().length();
uint32_t localsNum = func.vars().length(); uint32_t localsNum = func.vars().length();
@ -1241,12 +1325,10 @@ RenderFunctionBody(WasmRenderContext& c, AstFunc& func, const AstModule::SigVect
uint32_t exprsNum = func.body().length(); uint32_t exprsNum = func.body().length();
for (uint32_t i = 0; i < exprsNum; i++) { for (uint32_t i = 0; i < exprsNum; i++) {
if (!RenderFullLine(c, *func.body()[i])) if (!RenderExpr(c, *func.body()[i]))
return false; return false;
} }
c.indent--;
return true; return true;
} }
@ -1299,9 +1381,9 @@ RenderDataSection(WasmRenderContext& c, const AstModule& module)
return false; return false;
if (!c.buffer.append("(memory ")) if (!c.buffer.append("(memory "))
return false; return false;
if (!RenderInt32(c, module.memory().initial())) if (!RenderInt32(c, module.memory().initial))
return false; return false;
Maybe<uint32_t> memMax = module.memory().maximum(); Maybe<uint32_t> memMax = module.memory().maximum;
if (memMax) { if (memMax) {
if (!c.buffer.append(" ")) if (!c.buffer.append(" "))
return false; return false;
@ -1362,7 +1444,7 @@ RenderModule(WasmRenderContext& c, AstModule& module)
if (!RenderTableSection(c, module)) if (!RenderTableSection(c, module))
return false; return false;
if (!RenderExportSection(c, module.exports(), module.funcs())) if (!RenderExportSection(c, module.exports(), module.funcImportNames(), module.funcs()))
return false; return false;
if (!RenderCodeSection(c, module.funcs(), module.sigs())) if (!RenderCodeSection(c, module.funcs(), module.sigs()))

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -137,8 +137,7 @@ ModuleGenerator::init(UniqueModuleGeneratorData shared, const CompileArgs& args,
numSigs_ = shared_->sigs.length(); numSigs_ = shared_->sigs.length();
numTables_ = shared_->tables.length(); numTables_ = shared_->tables.length();
if (args.assumptions.newFormat) shared_->firstFuncDefIndex = shared_->funcImports.length();
shared_->firstFuncDefIndex = shared_->funcImports.length();
for (FuncImportGenDesc& funcImport : shared_->funcImports) { for (FuncImportGenDesc& funcImport : shared_->funcImports) {
MOZ_ASSERT(!funcImport.globalDataOffset); MOZ_ASSERT(!funcImport.globalDataOffset);

Просмотреть файл

@ -1313,7 +1313,7 @@ class FunctionCompiler
{ {
*loopHeader = nullptr; *loopHeader = nullptr;
blockDepth_ += 2; blockDepth_++;
loopDepth_++; loopDepth_++;
if (inDeadCode()) if (inDeadCode())
@ -1389,19 +1389,17 @@ class FunctionCompiler
public: public:
bool closeLoop(MBasicBlock* loopHeader, MDefinition** loopResult) bool closeLoop(MBasicBlock* loopHeader, MDefinition** loopResult)
{ {
MOZ_ASSERT(blockDepth_ >= 2); MOZ_ASSERT(blockDepth_ >= 1);
MOZ_ASSERT(loopDepth_); MOZ_ASSERT(loopDepth_);
uint32_t headerLabel = blockDepth_ - 1; uint32_t headerLabel = blockDepth_ - 1;
uint32_t afterLabel = blockDepth_ - 2;
if (!loopHeader) { if (!loopHeader) {
MOZ_ASSERT(inDeadCode()); MOZ_ASSERT(inDeadCode());
MOZ_ASSERT(afterLabel >= blockPatches_.length() || blockPatches_[afterLabel].empty());
MOZ_ASSERT(headerLabel >= blockPatches_.length() || blockPatches_[headerLabel].empty()); MOZ_ASSERT(headerLabel >= blockPatches_.length() || blockPatches_[headerLabel].empty());
*loopResult = nullptr; blockDepth_--;
blockDepth_ -= 2;
loopDepth_--; loopDepth_--;
*loopResult = nullptr;
return true; return true;
} }
@ -1410,9 +1408,12 @@ class FunctionCompiler
MBasicBlock* loopBody = curBlock_; MBasicBlock* loopBody = curBlock_;
curBlock_ = nullptr; curBlock_ = nullptr;
// TODO (bug 1253544): blocks branching to the top join to a single // As explained in bug 1253544, Ion apparently has an invariant that
// backedge block. Could they directly be set as backedges of the loop // there is only one backedge to loop headers. To handle wasm's ability
// instead? // to have multiple backedges to the same loop header, we bind all those
// branches as forward jumps to a single backward jump. This is
// unfortunate but the optimizer is able to fold these into single jumps
// to backedges.
MDefinition* _; MDefinition* _;
if (!bindBranches(headerLabel, &_)) if (!bindBranches(headerLabel, &_))
return false; return false;
@ -1433,11 +1434,8 @@ class FunctionCompiler
curBlock_ = loopBody; curBlock_ = loopBody;
loopDepth_--; loopDepth_--;
if (!bindBranches(afterLabel, loopResult))
return false;
// If we have not created a new block in bindBranches, we're still on // If the loop depth still at the inner loop body, correct it.
// the inner loop body, which loop depth is incorrect.
if (curBlock_ && curBlock_->loopDepth() != loopDepth_) { if (curBlock_ && curBlock_->loopDepth() != loopDepth_) {
MBasicBlock* out; MBasicBlock* out;
if (!goToNewBlock(curBlock_, &out)) if (!goToNewBlock(curBlock_, &out))
@ -1445,7 +1443,8 @@ class FunctionCompiler
curBlock_ = out; curBlock_ = out;
} }
blockDepth_ -= 2; blockDepth_ -= 1;
*loopResult = inDeadCode() ? nullptr : popDefIfPushed();
return true; return true;
} }
@ -1735,6 +1734,7 @@ EmitEnd(FunctionCompiler& f)
return false; return false;
break; break;
case LabelKind::Then: case LabelKind::Then:
case LabelKind::UnreachableThen:
// If we didn't see an Else, create a trivial else block so that we create // If we didn't see an Else, create a trivial else block so that we create
// a diamond anyway, to preserve Ion invariants. // a diamond anyway, to preserve Ion invariants.
if (!f.switchToElse(block, &block)) if (!f.switchToElse(block, &block))
@ -1749,7 +1749,9 @@ EmitEnd(FunctionCompiler& f)
break; break;
} }
f.iter().setResult(def); if (!IsVoid(type))
f.iter().setResult(def);
return true; return true;
} }
@ -1810,13 +1812,13 @@ EmitBrTable(FunctionCompiler& f)
uint32_t depth; uint32_t depth;
for (size_t i = 0; i < tableLength; ++i) { for (size_t i = 0; i < tableLength; ++i) {
if (!f.iter().readBrTableEntry(type, &depth)) if (!f.iter().readBrTableEntry(&type, &value, &depth))
return false; return false;
depths.infallibleAppend(depth); depths.infallibleAppend(depth);
} }
// Read the default label. // Read the default label.
if (!f.iter().readBrTableEntry(type, &depth)) if (!f.iter().readBrTableDefault(&type, &value, &depth))
return false; return false;
MDefinition* maybeValue = IsVoid(type) ? nullptr : value; MDefinition* maybeValue = IsVoid(type) ? nullptr : value;
@ -1834,6 +1836,9 @@ EmitReturn(FunctionCompiler& f)
if (!f.iter().readReturn(&value)) if (!f.iter().readReturn(&value))
return false; return false;
if (f.inDeadCode())
return true;
if (IsVoid(f.sig().ret())) { if (IsVoid(f.sig().ret())) {
f.returnVoid(); f.returnVoid();
return true; return true;
@ -1896,13 +1901,15 @@ EmitCall(FunctionCompiler& f, uint32_t callOffset)
uint32_t lineOrBytecode = f.readCallSiteLineOrBytecode(callOffset); uint32_t lineOrBytecode = f.readCallSiteLineOrBytecode(callOffset);
uint32_t calleeIndex; uint32_t calleeIndex;
uint32_t arity; if (!f.iter().readCall(&calleeIndex))
if (!f.iter().readCall(&calleeIndex, &arity))
return false; return false;
// For asm.js and old-format wasm code, imports are not part of the function if (f.inDeadCode())
// index space so in these cases firstFuncDefIndex is fixed to 0, even if return true;
// there are function imports.
// For asm.js, imports are not part of the function index space so in
// these cases firstFuncDefIndex is fixed to 0, even if there are
// function imports.
if (calleeIndex < f.mg().firstFuncDefIndex) if (calleeIndex < f.mg().firstFuncDefIndex)
return EmitCallImportCommon(f, lineOrBytecode, calleeIndex); return EmitCallImportCommon(f, lineOrBytecode, calleeIndex);
@ -1935,22 +1942,32 @@ EmitCallImport(FunctionCompiler& f, uint32_t callOffset)
uint32_t lineOrBytecode = f.readCallSiteLineOrBytecode(callOffset); uint32_t lineOrBytecode = f.readCallSiteLineOrBytecode(callOffset);
uint32_t funcImportIndex; uint32_t funcImportIndex;
uint32_t arity; if (!f.iter().readCallImport(&funcImportIndex))
if (!f.iter().readCallImport(&funcImportIndex, &arity))
return false; return false;
if (f.inDeadCode())
return true;
return EmitCallImportCommon(f, lineOrBytecode, funcImportIndex); return EmitCallImportCommon(f, lineOrBytecode, funcImportIndex);
} }
static bool static bool
EmitCallIndirect(FunctionCompiler& f, uint32_t callOffset) EmitCallIndirect(FunctionCompiler& f, uint32_t callOffset, bool oldStyle)
{ {
uint32_t lineOrBytecode = f.readCallSiteLineOrBytecode(callOffset); uint32_t lineOrBytecode = f.readCallSiteLineOrBytecode(callOffset);
uint32_t sigIndex; uint32_t sigIndex;
uint32_t arity; MDefinition* callee;
if (!f.iter().readCallIndirect(&sigIndex, &arity)) if (oldStyle) {
return false; if (!f.iter().readOldCallIndirect(&sigIndex))
return false;
} else {
if (!f.iter().readCallIndirect(&sigIndex, &callee))
return false;
}
if (f.inDeadCode())
return true;
const Sig& sig = f.mg().sigs[sigIndex]; const Sig& sig = f.mg().sigs[sigIndex];
@ -1960,9 +1977,10 @@ EmitCallIndirect(FunctionCompiler& f, uint32_t callOffset)
if (!EmitCallArgs(f, sig, interModule, &call)) if (!EmitCallArgs(f, sig, interModule, &call))
return false; return false;
MDefinition* callee; if (oldStyle) {
if (!f.iter().readCallIndirectCallee(&callee)) if (!f.iter().readOldCallIndirectCallee(&callee))
return false; return false;
}
if (!f.iter().readCallReturn(sig.ret())) if (!f.iter().readCallReturn(sig.ret()))
return false; return false;
@ -2001,6 +2019,18 @@ EmitSetLocal(FunctionCompiler& f)
return true; return true;
} }
static bool
EmitTeeLocal(FunctionCompiler& f)
{
uint32_t id;
MDefinition* value;
if (!f.iter().readTeeLocal(f.locals(), &id, &value))
return false;
f.assign(id, value);
return true;
}
static bool static bool
EmitGetGlobal(FunctionCompiler& f) EmitGetGlobal(FunctionCompiler& f)
{ {
@ -2067,6 +2097,21 @@ EmitSetGlobal(FunctionCompiler& f)
return true; return true;
} }
static bool
EmitTeeGlobal(FunctionCompiler& f)
{
uint32_t id;
MDefinition* value;
if (!f.iter().readTeeGlobal(f.mg().globals, &id, &value))
return false;
const GlobalDesc& global = f.mg().globals[id];
MOZ_ASSERT(global.isMutable());
f.storeGlobalVar(global.offset(), value);
return true;
}
template <typename MIRClass> template <typename MIRClass>
static bool static bool
EmitUnary(FunctionCompiler& f, ValType operandType) EmitUnary(FunctionCompiler& f, ValType operandType)
@ -2312,16 +2357,14 @@ EmitComparison(FunctionCompiler& f,
static bool static bool
EmitSelect(FunctionCompiler& f) EmitSelect(FunctionCompiler& f)
{ {
ExprType type; ValType type;
MDefinition* trueValue; MDefinition* trueValue;
MDefinition* falseValue; MDefinition* falseValue;
MDefinition* condition; MDefinition* condition;
if (!f.iter().readSelect(&type, &trueValue, &falseValue, &condition)) if (!f.iter().readSelect(&type, &trueValue, &falseValue, &condition))
return false; return false;
if (!IsVoid(type)) f.iter().setResult(f.select(trueValue, falseValue, condition));
f.iter().setResult(f.select(trueValue, falseValue, condition));
return true; return true;
} }
@ -2351,11 +2394,24 @@ EmitStore(FunctionCompiler& f, ValType resultType, Scalar::Type viewType)
} }
static bool static bool
EmitStoreWithCoercion(FunctionCompiler& f, ValType resultType, Scalar::Type viewType) EmitTeeStore(FunctionCompiler& f, ValType resultType, Scalar::Type viewType)
{ {
LinearMemoryAddress<MDefinition*> addr; LinearMemoryAddress<MDefinition*> addr;
MDefinition* value; MDefinition* value;
if (!f.iter().readStore(resultType, Scalar::byteSize(viewType), &addr, &value)) if (!f.iter().readTeeStore(resultType, Scalar::byteSize(viewType), &addr, &value))
return false;
MWasmMemoryAccess access(viewType, addr.align, addr.offset);
f.store(addr.base, access, value);
return true;
}
static bool
EmitTeeStoreWithCoercion(FunctionCompiler& f, ValType resultType, Scalar::Type viewType)
{
LinearMemoryAddress<MDefinition*> addr;
MDefinition* value;
if (!f.iter().readTeeStore(resultType, Scalar::byteSize(viewType), &addr, &value))
return false; return false;
if (resultType == ValType::F32 && viewType == Scalar::Float64) if (resultType == ValType::F32 && viewType == Scalar::Float64)
@ -2737,7 +2793,7 @@ EmitSimdStore(FunctionCompiler& f, ValType resultType, unsigned numElems)
LinearMemoryAddress<MDefinition*> addr; LinearMemoryAddress<MDefinition*> addr;
MDefinition* value; MDefinition* value;
if (!f.iter().readStore(resultType, Scalar::byteSize(viewType), &addr, &value)) if (!f.iter().readTeeStore(resultType, Scalar::byteSize(viewType), &addr, &value))
return false; return false;
MWasmMemoryAccess access(viewType, addr.align, addr.offset, numElems); MWasmMemoryAccess access(viewType, addr.align, addr.offset, numElems);
@ -3027,7 +3083,7 @@ EmitCurrentMemory(FunctionCompiler& f, uint32_t callOffset)
CallCompileState args(f, lineOrBytecode); CallCompileState args(f, lineOrBytecode);
if (!f.iter().readNullary(ExprType::I32)) if (!f.iter().readNullary(ValType::I32))
return false; return false;
if (!f.startCall(&args)) if (!f.startCall(&args))
@ -3061,7 +3117,9 @@ EmitExpr(FunctionCompiler& f)
switch (expr) { switch (expr) {
// Control opcodes // Control opcodes
case Expr::Nop: case Expr::Nop:
return f.iter().readNullary(ExprType::Void); return f.iter().readNop();
case Expr::Drop:
return f.iter().readDrop();
case Expr::Block: case Expr::Block:
return EmitBlock(f); return EmitBlock(f);
case Expr::Loop: case Expr::Loop:
@ -3090,7 +3148,9 @@ EmitExpr(FunctionCompiler& f)
case Expr::Call: case Expr::Call:
return EmitCall(f, exprOffset); return EmitCall(f, exprOffset);
case Expr::CallIndirect: case Expr::CallIndirect:
return EmitCallIndirect(f, exprOffset); return EmitCallIndirect(f, exprOffset, /* oldStyle = */ false);
case Expr::OldCallIndirect:
return EmitCallIndirect(f, exprOffset, /* oldStyle = */ true);
case Expr::CallImport: case Expr::CallImport:
return EmitCallImport(f, exprOffset); return EmitCallImport(f, exprOffset);
@ -3099,10 +3159,14 @@ EmitExpr(FunctionCompiler& f)
return EmitGetLocal(f); return EmitGetLocal(f);
case Expr::SetLocal: case Expr::SetLocal:
return EmitSetLocal(f); return EmitSetLocal(f);
case Expr::TeeLocal:
return EmitTeeLocal(f);
case Expr::GetGlobal: case Expr::GetGlobal:
return EmitGetGlobal(f); return EmitGetGlobal(f);
case Expr::SetGlobal: case Expr::SetGlobal:
return EmitSetGlobal(f); return EmitSetGlobal(f);
case Expr::TeeGlobal:
return EmitTeeGlobal(f);
// Select // Select
case Expr::Select: case Expr::Select:
@ -3180,10 +3244,16 @@ EmitExpr(FunctionCompiler& f)
return EmitLoad(f, ValType::I32, Scalar::Int32); return EmitLoad(f, ValType::I32, Scalar::Int32);
case Expr::I32Store8: case Expr::I32Store8:
return EmitStore(f, ValType::I32, Scalar::Int8); return EmitStore(f, ValType::I32, Scalar::Int8);
case Expr::I32TeeStore8:
return EmitTeeStore(f, ValType::I32, Scalar::Int8);
case Expr::I32Store16: case Expr::I32Store16:
return EmitStore(f, ValType::I32, Scalar::Int16); return EmitStore(f, ValType::I32, Scalar::Int16);
case Expr::I32TeeStore16:
return EmitTeeStore(f, ValType::I32, Scalar::Int16);
case Expr::I32Store: case Expr::I32Store:
return EmitStore(f, ValType::I32, Scalar::Int32); return EmitStore(f, ValType::I32, Scalar::Int32);
case Expr::I32TeeStore:
return EmitTeeStore(f, ValType::I32, Scalar::Int32);
case Expr::I32Rotr: case Expr::I32Rotr:
case Expr::I32Rotl: case Expr::I32Rotl:
return EmitRotate(f, ValType::I32, expr == Expr::I32Rotl); return EmitRotate(f, ValType::I32, expr == Expr::I32Rotl);
@ -3259,12 +3329,20 @@ EmitExpr(FunctionCompiler& f)
return EmitLoad(f, ValType::I64, Scalar::Int64); return EmitLoad(f, ValType::I64, Scalar::Int64);
case Expr::I64Store8: case Expr::I64Store8:
return EmitStore(f, ValType::I64, Scalar::Int8); return EmitStore(f, ValType::I64, Scalar::Int8);
case Expr::I64TeeStore8:
return EmitTeeStore(f, ValType::I64, Scalar::Int8);
case Expr::I64Store16: case Expr::I64Store16:
return EmitStore(f, ValType::I64, Scalar::Int16); return EmitStore(f, ValType::I64, Scalar::Int16);
case Expr::I64TeeStore16:
return EmitTeeStore(f, ValType::I64, Scalar::Int16);
case Expr::I64Store32: case Expr::I64Store32:
return EmitStore(f, ValType::I64, Scalar::Int32); return EmitStore(f, ValType::I64, Scalar::Int32);
case Expr::I64TeeStore32:
return EmitTeeStore(f, ValType::I64, Scalar::Int32);
case Expr::I64Store: case Expr::I64Store:
return EmitStore(f, ValType::I64, Scalar::Int64); return EmitStore(f, ValType::I64, Scalar::Int64);
case Expr::I64TeeStore:
return EmitTeeStore(f, ValType::I64, Scalar::Int64);
// F32 // F32
case Expr::F32Const: { case Expr::F32Const: {
@ -3319,8 +3397,10 @@ EmitExpr(FunctionCompiler& f)
return EmitLoad(f, ValType::F32, Scalar::Float32); return EmitLoad(f, ValType::F32, Scalar::Float32);
case Expr::F32Store: case Expr::F32Store:
return EmitStore(f, ValType::F32, Scalar::Float32); return EmitStore(f, ValType::F32, Scalar::Float32);
case Expr::F32StoreF64: case Expr::F32TeeStore:
return EmitStoreWithCoercion(f, ValType::F32, Scalar::Float64); return EmitTeeStore(f, ValType::F32, Scalar::Float32);
case Expr::F32TeeStoreF64:
return EmitTeeStoreWithCoercion(f, ValType::F32, Scalar::Float64);
// F64 // F64
case Expr::F64Const: { case Expr::F64Const: {
@ -3395,8 +3475,10 @@ EmitExpr(FunctionCompiler& f)
return EmitLoad(f, ValType::F64, Scalar::Float64); return EmitLoad(f, ValType::F64, Scalar::Float64);
case Expr::F64Store: case Expr::F64Store:
return EmitStore(f, ValType::F64, Scalar::Float64); return EmitStore(f, ValType::F64, Scalar::Float64);
case Expr::F64StoreF32: case Expr::F64TeeStore:
return EmitStoreWithCoercion(f, ValType::F64, Scalar::Float32); return EmitTeeStore(f, ValType::F64, Scalar::Float64);
case Expr::F64TeeStoreF32:
return EmitTeeStoreWithCoercion(f, ValType::F64, Scalar::Float32);
case Expr::F64ReinterpretI64: case Expr::F64ReinterpretI64:
return EmitReinterpret(f, ValType::F64, ValType::I64, MIRType::Double); return EmitReinterpret(f, ValType::F64, ValType::I64, MIRType::Double);
@ -3661,7 +3743,10 @@ wasm::IonCompileFunction(IonCompileTask* task)
if (!f.init()) if (!f.init())
return false; return false;
if (!f.iter().readFunctionStart()) if (!f.startBlock())
return false;
if (!f.iter().readFunctionStart(f.sig().ret()))
return false; return false;
while (!f.done()) { while (!f.done()) {
@ -3669,13 +3754,13 @@ wasm::IonCompileFunction(IonCompileTask* task)
return false; return false;
} }
MDefinition* value; if (f.inDeadCode() || IsVoid(f.sig().ret()))
if (!f.iter().readFunctionEnd(f.sig().ret(), &value))
return false;
if (IsVoid(f.sig().ret()))
f.returnVoid(); f.returnVoid();
else else
f.returnExpr(value); f.returnExpr(f.iter().getResult());
if (!f.iter().readFunctionEnd())
return false;
f.finish(); f.finish();
} }

Просмотреть файл

@ -21,6 +21,8 @@
#include "mozilla/CheckedInt.h" #include "mozilla/CheckedInt.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "jsprf.h"
#include "asmjs/WasmCompile.h" #include "asmjs/WasmCompile.h"
#include "asmjs/WasmInstance.h" #include "asmjs/WasmInstance.h"
#include "asmjs/WasmModule.h" #include "asmjs/WasmModule.h"
@ -336,6 +338,9 @@ bool
wasm::Eval(JSContext* cx, Handle<TypedArrayObject*> code, HandleObject importObj, wasm::Eval(JSContext* cx, Handle<TypedArrayObject*> code, HandleObject importObj,
MutableHandleWasmInstanceObject instanceObj) MutableHandleWasmInstanceObject instanceObj)
{ {
if (!GlobalObject::ensureConstructor(cx, cx->global(), JSProto_WebAssembly))
return false;
MutableBytes bytecode = cx->new_<ShareableBytes>(); MutableBytes bytecode = cx->new_<ShareableBytes>();
if (!bytecode) if (!bytecode)
return false; return false;
@ -356,10 +361,12 @@ wasm::Eval(JSContext* cx, Handle<TypedArrayObject*> code, HandleObject importObj
UniqueChars error; UniqueChars error;
SharedModule module = Compile(*bytecode, compileArgs, &error); SharedModule module = Compile(*bytecode, compileArgs, &error);
if (!module) { if (!module) {
if (error) if (error) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_FAIL, error.get()); JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_DECODE_FAIL,
else error.get());
ReportOutOfMemory(cx); return false;
}
ReportOutOfMemory(cx);
return false; return false;
} }
@ -373,35 +380,6 @@ wasm::Eval(JSContext* cx, Handle<TypedArrayObject*> code, HandleObject importObj
return module->instantiate(cx, funcs, table, memory, globals, nullptr, instanceObj); return module->instantiate(cx, funcs, table, memory, globals, nullptr, instanceObj);
} }
static bool
InstantiateModule(JSContext* cx, unsigned argc, Value* vp)
{
MOZ_ASSERT(cx->options().wasm());
CallArgs args = CallArgsFromVp(argc, vp);
if (!args.get(0).isObject() || !args.get(0).toObject().is<TypedArrayObject>()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_BUF_ARG);
return false;
}
RootedObject importObj(cx);
if (!args.get(1).isUndefined()) {
if (!args.get(1).isObject()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMPORT_ARG);
return false;
}
importObj = &args[1].toObject();
}
Rooted<TypedArrayObject*> code(cx, &args[0].toObject().as<TypedArrayObject>());
RootedWasmInstanceObject instanceObj(cx);
if (!Eval(cx, code, importObj, &instanceObj))
return false;
args.rval().setObject(*instanceObj);
return true;
}
#if JS_HAS_TOSOURCE #if JS_HAS_TOSOURCE
static bool static bool
wasm_toSource(JSContext* cx, unsigned argc, Value* vp) wasm_toSource(JSContext* cx, unsigned argc, Value* vp)
@ -416,7 +394,6 @@ static const JSFunctionSpec wasm_static_methods[] = {
#if JS_HAS_TOSOURCE #if JS_HAS_TOSOURCE
JS_FN(js_toSource_str, wasm_toSource, 0, 0), JS_FN(js_toSource_str, wasm_toSource, 0, 0),
#endif #endif
JS_FN("instantiateModule", InstantiateModule, 1, 0),
JS_FS_END JS_FS_END
}; };
@ -601,7 +578,6 @@ GetCompileArgs(JSContext* cx, CallArgs callArgs, const char* name, MutableBytes*
if (!compileArgs->initFromContext(cx, Move(scriptedCaller))) if (!compileArgs->initFromContext(cx, Move(scriptedCaller)))
return false; return false;
compileArgs->assumptions.newFormat = true;
return true; return true;
} }
@ -621,10 +597,12 @@ WasmModuleObject::construct(JSContext* cx, unsigned argc, Value* vp)
UniqueChars error; UniqueChars error;
SharedModule module = Compile(*bytecode, compileArgs, &error); SharedModule module = Compile(*bytecode, compileArgs, &error);
if (!module) { if (!module) {
if (error) if (error) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_FAIL, error.get()); JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_DECODE_FAIL,
else error.get());
ReportOutOfMemory(cx); return false;
}
ReportOutOfMemory(cx);
return false; return false;
} }
@ -1478,7 +1456,14 @@ Reject(JSContext* cx, const CompileArgs& args, UniqueChars error, Handle<Promise
unsigned line = args.scriptedCaller.line; unsigned line = args.scriptedCaller.line;
unsigned column = args.scriptedCaller.column; unsigned column = args.scriptedCaller.column;
RootedString message(cx, NewLatin1StringZ(cx, Move(error))); // Ideally we'd report a JSMSG_WASM_DECODE_FAIL here, but there's no easy
// way to create an ErrorObject for an arbitrary error code with multiple
// replacements.
UniqueChars str(JS_smprintf("wasm validation error: %s", error.get()));
if (!str)
return false;
RootedString message(cx, NewLatin1StringZ(cx, Move(str)));
if (!message) if (!message)
return false; return false;
@ -1598,7 +1583,7 @@ WebAssembly_validate(JSContext* cx, unsigned argc, Value* vp)
if (error) { if (error) {
JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING, GetErrorMessage, nullptr, JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING, GetErrorMessage, nullptr,
JSMSG_WASM_DECODE_FAIL, "?", error.get()); JSMSG_WASM_DECODE_FAIL, error.get());
} }
callArgs.rval().setBoolean(validated); callArgs.rval().setBoolean(validated);

Просмотреть файл

@ -101,7 +101,7 @@ ExportedFunctionToDefinitionIndex(JSFunction* fun);
} // namespace wasm } // namespace wasm
// 'Wasm' and its one function 'instantiateModule' are transitional APIs and // 'Wasm' and its one field 'experimentalVersion' are transitional APIs and
// will be removed (replaced by 'WebAssembly') before release. // will be removed (replaced by 'WebAssembly') before release.
extern const Class WasmClass; extern const Class WasmClass;

Просмотреть файл

@ -559,9 +559,7 @@ Module::instantiateMemory(JSContext* cx, MutableHandleWasmMemoryObject memory) c
if (!buffer) if (!buffer)
return false; return false;
RootedObject proto(cx); RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmMemory).toObject());
if (metadata_->assumptions.newFormat)
proto = &cx->global()->getPrototype(JSProto_WasmMemory).toObject();
memory.set(WasmMemoryObject::create(cx, buffer, proto)); memory.set(WasmMemoryObject::create(cx, buffer, proto));
if (!memory) if (!memory)
@ -744,10 +742,7 @@ CreateExportObject(JSContext* cx,
val = ObjectValue(*tableObj); val = ObjectValue(*tableObj);
break; break;
case DefinitionKind::Memory: case DefinitionKind::Memory:
if (metadata.assumptions.newFormat) val = ObjectValue(*memoryObj);
val = ObjectValue(*memoryObj);
else
val = ObjectValue(memoryObj->buffer());
break; break;
case DefinitionKind::Global: case DefinitionKind::Global:
if (!GetGlobalExport(cx, metadata.globals, exp.globalIndex(), globalImports, &val)) if (!GetGlobalExport(cx, metadata.globals, exp.globalIndex(), globalImports, &val))

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -28,12 +28,9 @@ namespace wasm {
// Translate the textual representation of a wasm module (given by a // Translate the textual representation of a wasm module (given by a
// null-terminated char16_t array) into serialized bytes. If there is an error // null-terminated char16_t array) into serialized bytes. If there is an error
// other than out-of-memory an error message string will be stored in 'error'. // other than out-of-memory an error message string will be stored in 'error'.
// The 'newFormat' argument is transitional and enables the new binary
// format for memory and table imports and exports so that tests can be written
// before the transition is complete.
extern MOZ_MUST_USE bool extern MOZ_MUST_USE bool
TextToBinary(const char16_t* text, bool newFormat, Bytes* bytes, UniqueChars* error); TextToBinary(const char16_t* text, Bytes* bytes, UniqueChars* error);
} // namespace wasm } // namespace wasm
} // namespace js } // namespace js

Просмотреть файл

@ -552,14 +552,12 @@ SigWithId::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
Assumptions::Assumptions(JS::BuildIdCharVector&& buildId) Assumptions::Assumptions(JS::BuildIdCharVector&& buildId)
: cpuId(GetCPUID()), : cpuId(GetCPUID()),
buildId(Move(buildId)), buildId(Move(buildId))
newFormat(false)
{} {}
Assumptions::Assumptions() Assumptions::Assumptions()
: cpuId(GetCPUID()), : cpuId(GetCPUID()),
buildId(), buildId()
newFormat(false)
{} {}
bool bool
@ -576,7 +574,6 @@ bool
Assumptions::clone(const Assumptions& other) Assumptions::clone(const Assumptions& other)
{ {
cpuId = other.cpuId; cpuId = other.cpuId;
newFormat = other.newFormat;
return buildId.appendAll(other.buildId); return buildId.appendAll(other.buildId);
} }
@ -585,16 +582,14 @@ Assumptions::operator==(const Assumptions& rhs) const
{ {
return cpuId == rhs.cpuId && return cpuId == rhs.cpuId &&
buildId.length() == rhs.buildId.length() && buildId.length() == rhs.buildId.length() &&
PodEqual(buildId.begin(), rhs.buildId.begin(), buildId.length()) && PodEqual(buildId.begin(), rhs.buildId.begin(), buildId.length());
newFormat == rhs.newFormat;
} }
size_t size_t
Assumptions::serializedSize() const Assumptions::serializedSize() const
{ {
return sizeof(uint32_t) + return sizeof(uint32_t) +
SerializedPodVectorSize(buildId) + SerializedPodVectorSize(buildId);
sizeof(bool);
} }
uint8_t* uint8_t*
@ -602,7 +597,6 @@ Assumptions::serialize(uint8_t* cursor) const
{ {
cursor = WriteScalar<uint32_t>(cursor, cpuId); cursor = WriteScalar<uint32_t>(cursor, cpuId);
cursor = SerializePodVector(cursor, buildId); cursor = SerializePodVector(cursor, buildId);
cursor = WriteScalar<bool>(cursor, newFormat);
return cursor; return cursor;
} }
@ -610,8 +604,7 @@ const uint8_t*
Assumptions::deserialize(const uint8_t* cursor) Assumptions::deserialize(const uint8_t* cursor)
{ {
(cursor = ReadScalar<uint32_t>(cursor, &cpuId)) && (cursor = ReadScalar<uint32_t>(cursor, &cpuId)) &&
(cursor = DeserializePodVector(cursor, &buildId)) && (cursor = DeserializePodVector(cursor, &buildId));
(cursor = ReadScalar<bool>(cursor, &newFormat));
return cursor; return cursor;
} }

Просмотреть файл

@ -146,24 +146,6 @@ struct ShareableBase : RefCounted<T>
// ValType/ExprType utilities // ValType/ExprType utilities
// ExprType::Limit is an out-of-band value and has no wasm-semantic meaning. For
// the purpose of recursive validation, we use this value to represent the type
// of branch/return instructions that don't actually return to the parent
// expression and can thus be used in any context.
const ExprType AnyType = ExprType::Limit;
inline ExprType
Unify(ExprType a, ExprType b)
{
if (a == AnyType)
return b;
if (b == AnyType)
return a;
if (a == b)
return a;
return ExprType::Void;
}
static inline bool static inline bool
IsVoid(ExprType et) IsVoid(ExprType et)
{ {
@ -927,7 +909,6 @@ struct Assumptions
{ {
uint32_t cpuId; uint32_t cpuId;
JS::BuildIdCharVector buildId; JS::BuildIdCharVector buildId;
bool newFormat;
explicit Assumptions(JS::BuildIdCharVector&& buildId); explicit Assumptions(JS::BuildIdCharVector&& buildId);

Просмотреть файл

@ -532,28 +532,16 @@ WasmTextToBinary(JSContext* cx, unsigned argc, Value* vp)
if (!twoByteChars.initTwoByte(cx, args[0].toString())) if (!twoByteChars.initTwoByte(cx, args[0].toString()))
return false; return false;
bool newFormat = false;
if (args.hasDefined(1)) { if (args.hasDefined(1)) {
if (!args[1].isString()) { if (!args[1].isString()) {
ReportUsageError(cx, callee, "Second argument, if present, must be a String"); ReportUsageError(cx, callee, "Second argument, if present, must be a String");
return false; return false;
} }
JSLinearString* str = args[1].toString()->ensureLinear(cx);
if (!str)
return false;
if (!StringEqualsAscii(str, "new-format")) {
ReportUsageError(cx, callee, "Unknown string value for second argument");
return false;
}
newFormat = true;
} }
wasm::Bytes bytes; wasm::Bytes bytes;
UniqueChars error; UniqueChars error;
if (!wasm::TextToBinary(twoByteChars.twoByteChars(), newFormat, &bytes, &error)) { if (!wasm::TextToBinary(twoByteChars.twoByteChars(), &bytes, &error)) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_TEXT_FAIL, JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_TEXT_FAIL,
error.get() ? error.get() : "out of memory"); error.get() ? error.get() : "out of memory");
return false; return false;

Просмотреть файл

@ -55,7 +55,7 @@ evaluated in the same lexical environment.
For `Debugger.Script` instances referring to a block of WebAssembly code, they For `Debugger.Script` instances referring to a block of WebAssembly code, they
are distinguished by their `format` property being `"wasm"`. are distinguished by their `format` property being `"wasm"`.
Currently only entire modules evaluated via `Wasm.instantiateModule` are Currently only entire modules evaluated via `new WebAssembly.Module` are
represented. represented.
`Debugger.Script` objects for WebAssembly are uncovered via `onNewScript` when `Debugger.Script` objects for WebAssembly are uncovered via `onNewScript` when

Просмотреть файл

@ -46,7 +46,7 @@ instance to represent each presentation, or it may use a single
For a `Debugger.Source` instance representing the serialized text of a block For a `Debugger.Source` instance representing the serialized text of a block
of WebAssembly code, its properties provide the serialized text as a string. of WebAssembly code, its properties provide the serialized text as a string.
Currently only entire modules evaluated via `Wasm.instantiateModule` are Currently only entire modules evaluated via `new WebAssembly.Module` are
represented. SpiderMonkey constructs exactly one `Debugger.Source` for each represented. SpiderMonkey constructs exactly one `Debugger.Source` for each
underlying WebAssembly module per [`Debugger`][debugger-object] instance. underlying WebAssembly module per [`Debugger`][debugger-object] instance.
@ -107,7 +107,7 @@ from its prototype:
return `undefined`.) return `undefined`.)
**If the instance refers to WebAssembly code**, the URL of the script that **If the instance refers to WebAssembly code**, the URL of the script that
called `Wasm.instantiateModule` with the string `"> wasm"` appended. called `new WebAssembly.Module` with the string `"> wasm"` appended.
`sourceMapURL` `sourceMapURL`
: **If the instance refers to JavaScript source**, if this source was : **If the instance refers to JavaScript source**, if this source was

Просмотреть файл

@ -3,17 +3,8 @@ if (!wasmIsSupported())
load(libdir + "asserts.js"); load(libdir + "asserts.js");
function textToBinary(str) { function wasmEvalText(str, imports) {
// TODO when mass-switching to the new-format, just rename let binary = wasmTextToBinary(str);
// textToBinary to wasmTextToBinary and remove this function.
return wasmTextToBinary(str, 'new-format');
}
function evalText(str, imports) {
// TODO when mass-switching to the new-format, just rename
// evalText to wasmEvalText and remove the function wasmEvalText
// below.
let binary = wasmTextToBinary(str, 'new-format');
let valid = WebAssembly.validate(binary); let valid = WebAssembly.validate(binary);
let m; let m;
@ -29,22 +20,15 @@ function evalText(str, imports) {
} }
function wasmValidateText(str) { function wasmValidateText(str) {
assertEq(WebAssembly.validate(wasmTextToBinary(str, 'new-format')), true); assertEq(WebAssembly.validate(wasmTextToBinary(str)), true);
} }
function wasmFailValidateText(str, errorType, pattern) { function wasmFailValidateText(str, errorType, pattern) {
let binary = wasmTextToBinary(str, 'new-format'); let binary = wasmTextToBinary(str);
assertEq(WebAssembly.validate(binary), false); assertEq(WebAssembly.validate(binary), false);
assertErrorMessage(() => new WebAssembly.Module(binary), errorType, pattern); assertErrorMessage(() => new WebAssembly.Module(binary), errorType, pattern);
} }
function wasmEvalText(str, imports) {
var exports = Wasm.instantiateModule(wasmTextToBinary(str), imports).exports;
if (Object.keys(exports).length == 1 && exports[""])
return exports[""];
return exports;
}
function mismatchError(actual, expect) { function mismatchError(actual, expect) {
var str = `type mismatch: expression has type ${actual} but expected ${expect}`; var str = `type mismatch: expression has type ${actual} but expected ${expect}`;
return RegExp(str); return RegExp(str);

Просмотреть файл

@ -10,7 +10,7 @@ var asmJS = asmCompile('stdlib', 'ffis', 'buf', USE_ASM + 'var i32 = new stdlib.
var asmJSBuf = new ArrayBuffer(BUF_MIN); var asmJSBuf = new ArrayBuffer(BUF_MIN);
asmLink(asmJS, this, null, asmJSBuf); asmLink(asmJS, this, null, asmJSBuf);
var wasmMem = evalText('(module (memory 1 1) (export "mem" memory))').exports.mem; var wasmMem = wasmEvalText('(module (memory 1 1) (export "mem" memory))').exports.mem;
assertAsmLinkFail(asmJS, this, null, wasmMem.buffer); assertAsmLinkFail(asmJS, this, null, wasmMem.buffer);
if (!getBuildConfiguration().x64 && isSimdAvailable() && this["SIMD"]) { if (!getBuildConfiguration().x64 && isSimdAvailable() && this["SIMD"]) {

Просмотреть файл

@ -164,14 +164,14 @@ var g = asmLink(asmCompile('glob', 'ffis', USE_ASM + 'var f = ffis.f; function g
assertEq(g(), 0); assertEq(g(), 0);
if (wasmIsSupported()) { if (wasmIsSupported()) {
var h = Wasm.instantiateModule(wasmTextToBinary(`(module var h = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`(module
(import $f "imp" "f" (param i32) (result i32)) (import $f "imp" "f" (param i32) (result i32))
(func $h (result i32) (call_import $f (i32.const 1))) (func $h (result i32) (call_import $f (i32.const 1)))
(export "h" $h) (export "h" $h)
)`), {imp:{f}}).exports.h; )`)), {imp:{f}}).exports.h;
assertEq(h(), 0); assertEq(h(), 0);
var i = Wasm.instantiateModule(wasmTextToBinary(`(module (func $i) (export "i" $i))`)).exports.i var i = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`(module (func $i) (export "i" $i))`))).exports.i
var j = asmLink(asmCompile('glob', 'ffis', USE_ASM + 'var i = ffis.i; function j() { return i(1)|0; } return j'), null, {i}); var j = asmLink(asmCompile('glob', 'ffis', USE_ASM + 'var i = ffis.i; function j() { return i(1)|0; } return j'), null, {i});
assertEq(j(), 0); assertEq(j(), 0);
} }

Просмотреть файл

@ -7,5 +7,5 @@ var dbg = new Debugger(g);
dbg.onNewScript = (function(script) { dbg.onNewScript = (function(script) {
s = script; s = script;
}) })
g.eval(`Wasm.instantiateModule(wasmTextToBinary('(module (func) (export "" 0))'));`); g.eval(`new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func) (export "" 0))')));`);
s.source; s.source;

Просмотреть файл

@ -4,7 +4,7 @@ if (!wasmIsSupported())
quit(); quit();
var g = newGlobal(); var g = newGlobal();
g.eval(`o = Wasm.instantiateModule(wasmTextToBinary('(module (func) (export "" 0))'));`); g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func) (export "" 0))')));`);
function isWasm(script) { return script.format === "wasm"; } function isWasm(script) { return script.format === "wasm"; }
@ -14,7 +14,7 @@ assertEq(foundScripts1.length, 1);
var found = foundScripts1[0]; var found = foundScripts1[0];
// Add another module, we should be able to find it via findScripts. // Add another module, we should be able to find it via findScripts.
g.eval(`o2 = Wasm.instantiateModule(wasmTextToBinary('(module (func) (export "a" 0))'));`); g.eval(`o2 = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func) (export "a" 0))')));`);
var foundScripts2 = dbg.findScripts().filter(isWasm); var foundScripts2 = dbg.findScripts().filter(isWasm);
assertEq(foundScripts2.length, 2); assertEq(foundScripts2.length, 2);

Просмотреть файл

@ -11,11 +11,11 @@ dbg.onNewScript = (script) => {
gotScript = script; gotScript = script;
} }
g.eval(`o = Wasm.instantiateModule(wasmTextToBinary('(module (func) (export "" 0))'));`); g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func) (export "" 0))')));`);
assertEq(gotScript.format, "wasm"); assertEq(gotScript.format, "wasm");
var gotScript2 = gotScript; var gotScript2 = gotScript;
g.eval(`o = Wasm.instantiateModule(wasmTextToBinary('(module (func) (export "a" 0))'));`); g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func) (export "a" 0))')));`);
assertEq(gotScript.format, "wasm"); assertEq(gotScript.format, "wasm");
// The two wasm Debugger.Scripts are distinct. // The two wasm Debugger.Scripts are distinct.

Просмотреть файл

@ -13,7 +13,7 @@ dbg.onNewScript = (script) => {
s = script; s = script;
} }
g.eval(`o = Wasm.instantiateModule(wasmTextToBinary('(module (func) (export "" 0))'));`); g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func) (export "" 0))')));`);
assertEq(s.format, "wasm"); assertEq(s.format, "wasm");
var source = s.source; var source = s.source;

Просмотреть файл

@ -13,7 +13,7 @@ dbg.onNewScript = (script) => {
s = script; s = script;
} }
g.eval(`o = Wasm.instantiateModule(wasmTextToBinary('(module (func) (export "" 0))'));`); g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module (func) (export "" 0))')));`);
assertEq(s.format, "wasm"); assertEq(s.format, "wasm");
assertThrowsInstanceOf(() => s.displayName, Error); assertThrowsInstanceOf(() => s.displayName, Error);

Просмотреть файл

@ -15,7 +15,7 @@ function getAllOffsets(wast) {
dbg.addDebuggee(sandbox); dbg.addDebuggee(sandbox);
sandbox.eval(` sandbox.eval(`
var wasm = wasmTextToBinary('${wast}'); var wasm = wasmTextToBinary('${wast}');
var m = Wasm.instantiateModule(wasm); var m = new WebAssembly.Instance(new WebAssembly.Module(wasm));
`); `);
var wasmScript = dbg.findScripts().filter(s => s.format == 'wasm')[0]; var wasmScript = dbg.findScripts().filter(s => s.format == 'wasm')[0];
var lines = wasmScript.source.text.split('\n'); var lines = wasmScript.source.text.split('\n');
@ -24,7 +24,7 @@ function getAllOffsets(wast) {
var result1 = getAllOffsets('(module \ var result1 = getAllOffsets('(module \
(func (nop)) \ (func (nop)) \
(func (f32.sqrt (f32.add (f32.const 1.0) (f32.const 2.0)))) \ (func (drop (f32.sqrt (f32.add (f32.const 1.0) (f32.const 2.0))))) \
)'); )');
var nopLine = result1.filter(i => i.str.indexOf('nop') >= 0); var nopLine = result1.filter(i => i.str.indexOf('nop') >= 0);
@ -35,11 +35,12 @@ assertEq(nopLine[0].offsets[0] > 0, true);
var sqrtLine = result1.filter(i => i.str.indexOf('sqrt') >= 0); var sqrtLine = result1.filter(i => i.str.indexOf('sqrt') >= 0);
assertEq(sqrtLine.length, 1); assertEq(sqrtLine.length, 1);
// The sqrtLine shall have 4 offsets but they were produced from AST postorder decoding: // The sqrtLine shall have 5 offsets but they were produced from AST postorder decoding:
// f32.sqrt(1.0 + 2.0) ~~> 74,73,63,68 // drop(f32.sqrt(1.0 + 2.0)) ~~> 88,87,86,76,81
assertEq(sqrtLine[0].offsets.length, 4); assertEq(sqrtLine[0].offsets.length, 5);
assertEq(sqrtLine[0].offsets[2] > 0, true); assertEq(sqrtLine[0].offsets[3] > 0, true);
assertEq(sqrtLine[0].offsets[2] < sqrtLine[0].offsets[3], true); assertEq(sqrtLine[0].offsets[3] < sqrtLine[0].offsets[4], true);
assertEq(sqrtLine[0].offsets[2] > sqrtLine[0].offsets[3], true);
assertEq(sqrtLine[0].offsets[1] > sqrtLine[0].offsets[2], true); assertEq(sqrtLine[0].offsets[1] > sqrtLine[0].offsets[2], true);
assertEq(sqrtLine[0].offsets[0] > sqrtLine[0].offsets[1], true); assertEq(sqrtLine[0].offsets[0] > sqrtLine[0].offsets[1], true);

Просмотреть файл

@ -19,5 +19,5 @@ var mod = wasmEvalText(code, {
backtrace(); backtrace();
} }
} }
}); }).exports;
mod.test(); mod.test();

Просмотреть файл

@ -4,13 +4,13 @@ load(libdir + "wasm.js");
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// exports // exports
var o = wasmEvalText('(module)'); var o = wasmEvalText('(module)').exports;
assertEq(Object.getOwnPropertyNames(o).length, 0); assertEq(Object.getOwnPropertyNames(o).length, 0);
var o = wasmEvalText('(module (func))'); var o = wasmEvalText('(module (func))').exports;
assertEq(Object.getOwnPropertyNames(o).length, 0); assertEq(Object.getOwnPropertyNames(o).length, 0);
var o = wasmEvalText('(module (func) (export "a" 0))'); var o = wasmEvalText('(module (func) (export "a" 0))').exports;
var names = Object.getOwnPropertyNames(o); var names = Object.getOwnPropertyNames(o);
assertEq(names.length, 1); assertEq(names.length, 1);
assertEq(names[0], 'a'); assertEq(names[0], 'a');
@ -32,22 +32,22 @@ wasmValidateText('(module (func $a) (func $b) (export "a" $a) (export "b" $b))')
wasmFailValidateText('(module (func) (export "a" 1))', TypeError, /exported function index out of bounds/); wasmFailValidateText('(module (func) (export "a" 1))', TypeError, /exported function index out of bounds/);
wasmFailValidateText('(module (func) (func) (export "a" 2))', TypeError, /exported function index out of bounds/); wasmFailValidateText('(module (func) (func) (export "a" 2))', TypeError, /exported function index out of bounds/);
var o = wasmEvalText('(module (func) (export "a" 0) (export "b" 0))'); var o = wasmEvalText('(module (func) (export "a" 0) (export "b" 0))').exports;
assertEq(Object.getOwnPropertyNames(o).sort().toString(), "a,b"); assertEq(Object.getOwnPropertyNames(o).sort().toString(), "a,b");
assertEq(o.a.name, "wasm-function[0]"); assertEq(o.a.name, "wasm-function[0]");
assertEq(o.b.name, "wasm-function[0]"); assertEq(o.b.name, "wasm-function[0]");
assertEq(o.a === o.b, true); assertEq(o.a === o.b, true);
var o = wasmEvalText('(module (func) (func) (export "a" 0) (export "b" 1))'); var o = wasmEvalText('(module (func) (func) (export "a" 0) (export "b" 1))').exports;
assertEq(Object.getOwnPropertyNames(o).sort().toString(), "a,b"); assertEq(Object.getOwnPropertyNames(o).sort().toString(), "a,b");
assertEq(o.a.name, "wasm-function[0]"); assertEq(o.a.name, "wasm-function[0]");
assertEq(o.b.name, "wasm-function[1]"); assertEq(o.b.name, "wasm-function[1]");
assertEq(o.a === o.b, false); assertEq(o.a === o.b, false);
var o = wasmEvalText('(module (func (result i32) (i32.const 1)) (func (result i32) (i32.const 2)) (export "a" 0) (export "b" 1))'); var o = wasmEvalText('(module (func (result i32) (i32.const 1)) (func (result i32) (i32.const 2)) (export "a" 0) (export "b" 1))').exports;
assertEq(o.a(), 1); assertEq(o.a(), 1);
assertEq(o.b(), 2); assertEq(o.b(), 2);
var o = wasmEvalText('(module (func (result i32) (i32.const 1)) (func (result i32) (i32.const 2)) (export "a" 1) (export "b" 0))'); var o = wasmEvalText('(module (func (result i32) (i32.const 1)) (func (result i32) (i32.const 2)) (export "a" 1) (export "b" 0))').exports;
assertEq(o.a(), 2); assertEq(o.a(), 2);
assertEq(o.b(), 1); assertEq(o.b(), 1);
@ -68,21 +68,21 @@ wasmValidateText('(module (func (result i32) (param i32) (i32.const 42)))');
wasmValidateText('(module (func (param f32)))'); wasmValidateText('(module (func (param f32)))');
wasmValidateText('(module (func (param f64)))'); wasmValidateText('(module (func (param f64)))');
var f = wasmEvalText('(module (func (param i64) (result i32) (i32.const 123)) (export "" 0))'); var f = wasmEvalText('(module (func (param i64) (result i32) (i32.const 123)) (export "" 0))').exports[""];
assertErrorMessage(f, TypeError, /i64/); assertErrorMessage(f, TypeError, /i64/);
var f = wasmEvalText('(module (func (param i32) (result i64) (i64.const 123)) (export "" 0))'); var f = wasmEvalText('(module (func (param i32) (result i64) (i64.const 123)) (export "" 0))').exports[""];
assertErrorMessage(f, TypeError, /i64/); assertErrorMessage(f, TypeError, /i64/);
var f = wasmEvalText('(module (import $imp "a" "b" (param i64) (result i32)) (func $f (call_import $imp (i64.const 0))) (export "" $f))', {a:{b:()=>{}}}); var f = wasmEvalText('(module (import $imp "a" "b" (param i64) (result i32)) (func $f (result i32) (call_import $imp (i64.const 0))) (export "" $f))', {a:{b:()=>{}}}).exports[""];
assertErrorMessage(f, TypeError, /i64/); assertErrorMessage(f, TypeError, /i64/);
var f = wasmEvalText('(module (import $imp "a" "b" (result i64)) (func $f (call_import $imp)) (export "" $f))', {a:{b:()=>{}}}); var f = wasmEvalText('(module (import $imp "a" "b" (result i64)) (func $f (result i64) (call_import $imp)) (export "" $f))', {a:{b:()=>{}}}).exports[""];
assertErrorMessage(f, TypeError, /i64/); assertErrorMessage(f, TypeError, /i64/);
setJitCompilerOption('wasm.test-mode', 1); setJitCompilerOption('wasm.test-mode', 1);
assertEqI64(wasmEvalText('(module (func (result i64) (i64.const 123)) (export "" 0))')(), {low: 123, high: 0}); assertEqI64(wasmEvalText('(module (func (result i64) (i64.const 123)) (export "" 0))').exports[""](), {low: 123, high: 0});
assertEqI64(wasmEvalText('(module (func (param i64) (result i64) (get_local 0)) (export "" 0))')({ low: 0x7fffffff, high: 0x12340000}), assertEqI64(wasmEvalText('(module (func (param i64) (result i64) (get_local 0)) (export "" 0))').exports[""]({ low: 0x7fffffff, high: 0x12340000}),
{low: 0x7fffffff, high: 0x12340000}); {low: 0x7fffffff, high: 0x12340000});
assertEqI64(wasmEvalText('(module (func (param i64) (result i64) (i64.add (get_local 0) (i64.const 1))) (export "" 0))')({ low: 0xffffffff, high: 0x12340000}), {low: 0x0, high: 0x12340001}); assertEqI64(wasmEvalText('(module (func (param i64) (result i64) (i64.add (get_local 0) (i64.const 1))) (export "" 0))').exports[""]({ low: 0xffffffff, high: 0x12340000}), {low: 0x0, high: 0x12340001});
setJitCompilerOption('wasm.test-mode', 0); setJitCompilerOption('wasm.test-mode', 0);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -132,126 +132,127 @@ wasmFailValidateText('(module (memory 65536))', TypeError, /initial memory size
try { try {
wasmEvalText('(module (memory 65535))'); wasmEvalText('(module (memory 65535))');
} catch (e) { } catch (e) {
assertEq(String(e).indexOf("out of memory") != -1, true); assertEq(String(e).indexOf("out of memory") != -1 ||
String(e).indexOf("memory size too big") != -1, true);
} }
var buf = wasmEvalText('(module (memory 1) (export "memory" memory))').memory; var buf = wasmEvalText('(module (memory 1) (export "memory" memory))').exports.memory.buffer;
assertEq(buf instanceof ArrayBuffer, true); assertEq(buf instanceof ArrayBuffer, true);
assertEq(buf.byteLength, 65536); assertEq(buf.byteLength, 65536);
var obj = wasmEvalText('(module (memory 1) (func (result i32) (i32.const 42)) (func (nop)) (export "memory" memory) (export "b" 0) (export "c" 1))'); var obj = wasmEvalText('(module (memory 1) (func (result i32) (i32.const 42)) (func (nop)) (export "memory" memory) (export "b" 0) (export "c" 1))').exports;
assertEq(obj.memory instanceof ArrayBuffer, true); assertEq(obj.memory.buffer instanceof ArrayBuffer, true);
assertEq(obj.b instanceof Function, true); assertEq(obj.b instanceof Function, true);
assertEq(obj.c instanceof Function, true); assertEq(obj.c instanceof Function, true);
assertEq(obj.memory.byteLength, 65536); assertEq(obj.memory.buffer.byteLength, 65536);
assertEq(obj.b(), 42); assertEq(obj.b(), 42);
assertEq(obj.c(), undefined); assertEq(obj.c(), undefined);
var buf = wasmEvalText('(module (memory 1 (segment 0 "")) (export "memory" memory))').memory; var buf = wasmEvalText('(module (memory 1) (data 0 "") (export "memory" memory))').exports.memory.buffer;
assertEq(new Uint8Array(buf)[0], 0); assertEq(new Uint8Array(buf)[0], 0);
var buf = wasmEvalText('(module (memory 1 (segment 65536 "")) (export "memory" memory))').memory; var buf = wasmEvalText('(module (memory 1) (data 65536 "") (export "memory" memory))').exports.memory.buffer;
assertEq(new Uint8Array(buf)[0], 0); assertEq(new Uint8Array(buf)[0], 0);
var buf = wasmEvalText('(module (memory 1 (segment 0 "a")) (export "memory" memory))').memory; var buf = wasmEvalText('(module (memory 1) (data 0 "a") (export "memory" memory))').exports.memory.buffer;
assertEq(new Uint8Array(buf)[0], 'a'.charCodeAt(0)); assertEq(new Uint8Array(buf)[0], 'a'.charCodeAt(0));
var buf = wasmEvalText('(module (memory 1 (segment 0 "a") (segment 2 "b")) (export "memory" memory))').memory; var buf = wasmEvalText('(module (memory 1) (data 0 "a") (data 2 "b") (export "memory" memory))').exports.memory.buffer;
assertEq(new Uint8Array(buf)[0], 'a'.charCodeAt(0)); assertEq(new Uint8Array(buf)[0], 'a'.charCodeAt(0));
assertEq(new Uint8Array(buf)[1], 0); assertEq(new Uint8Array(buf)[1], 0);
assertEq(new Uint8Array(buf)[2], 'b'.charCodeAt(0)); assertEq(new Uint8Array(buf)[2], 'b'.charCodeAt(0));
var buf = wasmEvalText('(module (memory 1 (segment 65535 "c")) (export "memory" memory))').memory; var buf = wasmEvalText('(module (memory 1) (data 65535 "c") (export "memory" memory))').exports.memory.buffer;
assertEq(new Uint8Array(buf)[0], 0); assertEq(new Uint8Array(buf)[0], 0);
assertEq(new Uint8Array(buf)[65535], 'c'.charCodeAt(0)); assertEq(new Uint8Array(buf)[65535], 'c'.charCodeAt(0));
wasmFailValidateText('(module (memory 1 (segment 65536 "a")) (export "memory" memory))', TypeError, /data segment does not fit/); wasmFailValidateText('(module (memory 1) (data 65536 "a") (export "memory" memory))', TypeError, /data segment does not fit/);
wasmFailValidateText('(module (memory 1 (segment 65535 "ab")) (export "memory" memory))', TypeError, /data segment does not fit/); wasmFailValidateText('(module (memory 1) (data 65535 "ab") (export "memory" memory))', TypeError, /data segment does not fit/);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// locals // locals
assertEq(wasmEvalText('(module (func (param i32) (result i32) (get_local 0)) (export "" 0))')(), 0); assertEq(wasmEvalText('(module (func (param i32) (result i32) (get_local 0)) (export "" 0))').exports[""](), 0);
assertEq(wasmEvalText('(module (func (param i32) (result i32) (get_local 0)) (export "" 0))')(42), 42); assertEq(wasmEvalText('(module (func (param i32) (result i32) (get_local 0)) (export "" 0))').exports[""](42), 42);
assertEq(wasmEvalText('(module (func (param i32) (param i32) (result i32) (get_local 0)) (export "" 0))')(42, 43), 42); assertEq(wasmEvalText('(module (func (param i32) (param i32) (result i32) (get_local 0)) (export "" 0))').exports[""](42, 43), 42);
assertEq(wasmEvalText('(module (func (param i32) (param i32) (result i32) (get_local 1)) (export "" 0))')(42, 43), 43); assertEq(wasmEvalText('(module (func (param i32) (param i32) (result i32) (get_local 1)) (export "" 0))').exports[""](42, 43), 43);
wasmFailValidateText('(module (func (get_local 0)))', TypeError, /get_local index out of range/); wasmFailValidateText('(module (func (get_local 0)))', TypeError, /get_local index out of range/);
wasmValidateText('(module (func (local i32)))'); wasmValidateText('(module (func (local i32)))');
wasmValidateText('(module (func (local i32) (local f32)))'); wasmValidateText('(module (func (local i32) (local f32)))');
assertEq(wasmEvalText('(module (func (result i32) (local i32) (get_local 0)) (export "" 0))')(), 0); assertEq(wasmEvalText('(module (func (result i32) (local i32) (get_local 0)) (export "" 0))').exports[""](), 0);
wasmFailValidateText('(module (func (result f32) (local i32) (get_local 0)))', TypeError, mismatchError("i32", "f32")); wasmFailValidateText('(module (func (result f32) (local i32) (get_local 0)))', TypeError, mismatchError("i32", "f32"));
wasmFailValidateText('(module (func (result i32) (local f32) (get_local 0)))', TypeError, mismatchError("f32", "i32")); wasmFailValidateText('(module (func (result i32) (local f32) (get_local 0)))', TypeError, mismatchError("f32", "i32"));
assertEq(wasmEvalText('(module (func (result i32) (param i32) (local f32) (get_local 0)) (export "" 0))')(), 0); assertEq(wasmEvalText('(module (func (result i32) (param i32) (local f32) (get_local 0)) (export "" 0))').exports[""](), 0);
assertEq(wasmEvalText('(module (func (result f32) (param i32) (local f32) (get_local 1)) (export "" 0))')(), 0); assertEq(wasmEvalText('(module (func (result f32) (param i32) (local f32) (get_local 1)) (export "" 0))').exports[""](), 0);
wasmFailValidateText('(module (func (result f32) (param i32) (local f32) (get_local 0)))', TypeError, mismatchError("i32", "f32")); wasmFailValidateText('(module (func (result f32) (param i32) (local f32) (get_local 0)))', TypeError, mismatchError("i32", "f32"));
wasmFailValidateText('(module (func (result i32) (param i32) (local f32) (get_local 1)))', TypeError, mismatchError("f32", "i32")); wasmFailValidateText('(module (func (result i32) (param i32) (local f32) (get_local 1)))', TypeError, mismatchError("f32", "i32"));
wasmFailValidateText('(module (func (set_local 0 (i32.const 0))))', TypeError, /set_local index out of range/); wasmFailValidateText('(module (func (set_local 0 (i32.const 0))))', TypeError, /set_local index out of range/);
wasmValidateText('(module (func (local i32) (set_local 0 (i32.const 0))))'); wasmValidateText('(module (func (local i32) (set_local 0 (i32.const 0))))');
wasmFailValidateText('(module (func (local f32) (set_local 0 (i32.const 0))))', TypeError, mismatchError("i32", "f32")); wasmFailValidateText('(module (func (local f32) (set_local 0 (i32.const 0))))', TypeError, mismatchError("i32", "f32"));
wasmFailValidateText('(module (func (local f32) (set_local 0 (nop))))', TypeError, mismatchError("void", "f32")); wasmFailValidateText('(module (func (local f32) (set_local 0 (nop))))', TypeError, /popping value from empty stack/);
wasmFailValidateText('(module (func (local i32) (local f32) (set_local 0 (get_local 1))))', TypeError, mismatchError("f32", "i32")); wasmFailValidateText('(module (func (local i32) (local f32) (set_local 0 (get_local 1))))', TypeError, mismatchError("f32", "i32"));
wasmFailValidateText('(module (func (local i32) (local f32) (set_local 1 (get_local 0))))', TypeError, mismatchError("i32", "f32")); wasmFailValidateText('(module (func (local i32) (local f32) (set_local 1 (get_local 0))))', TypeError, mismatchError("i32", "f32"));
wasmValidateText('(module (func (local i32) (local f32) (set_local 0 (get_local 0))))'); wasmValidateText('(module (func (local i32) (local f32) (set_local 0 (get_local 0))))');
wasmValidateText('(module (func (local i32) (local f32) (set_local 1 (get_local 1))))'); wasmValidateText('(module (func (local i32) (local f32) (set_local 1 (get_local 1))))');
assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (i32.const 42))) (export "" 0))')(), 42); assertEq(wasmEvalText('(module (func (result i32) (local i32) (tee_local 0 (i32.const 42))) (export "" 0))').exports[""](), 42);
assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (get_local 0))) (export "" 0))')(), 0); assertEq(wasmEvalText('(module (func (result i32) (local i32) (tee_local 0 (get_local 0))) (export "" 0))').exports[""](), 0);
assertEq(wasmEvalText('(module (func (param $a i32) (result i32) (get_local $a)) (export "" 0))')(), 0); assertEq(wasmEvalText('(module (func (param $a i32) (result i32) (get_local $a)) (export "" 0))').exports[""](), 0);
assertEq(wasmEvalText('(module (func (param $a i32) (local $b i32) (result i32) (block (set_local $b (get_local $a)) (get_local $b))) (export "" 0))')(42), 42); assertEq(wasmEvalText('(module (func (param $a i32) (local $b i32) (result i32) (block i32 (set_local $b (get_local $a)) (get_local $b))) (export "" 0))').exports[""](42), 42);
wasmValidateText('(module (func (local i32) (local $a f32) (set_local 0 (i32.const 1)) (set_local $a (f32.const nan))))'); wasmValidateText('(module (func (local i32) (local $a f32) (set_local 0 (i32.const 1)) (set_local $a (f32.const nan))))');
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// blocks // blocks
assertEq(wasmEvalText('(module (func (block)) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (block )) (export "" 0))').exports[""](), undefined);
wasmFailValidateText('(module (func (result i32) (block)))', TypeError, mismatchError("void", "i32")); wasmFailValidateText('(module (func (result i32) (block )))', TypeError, mismatchError("void", "i32"));
wasmFailValidateText('(module (func (result i32) (block (block))))', TypeError, mismatchError("void", "i32")); wasmFailValidateText('(module (func (result i32) (block (block ))))', TypeError, mismatchError("void", "i32"));
wasmFailValidateText('(module (func (local i32) (set_local 0 (block))))', TypeError, mismatchError("void", "i32")); wasmFailValidateText('(module (func (local i32) (set_local 0 (block ))))', TypeError, /popping value from empty stack/);
assertEq(wasmEvalText('(module (func (block (block))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (block (block ))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (result i32) (block (i32.const 42))) (export "" 0))')(), 42); assertEq(wasmEvalText('(module (func (result i32) (block i32 (i32.const 42))) (export "" 0))').exports[""](), 42);
assertEq(wasmEvalText('(module (func (result i32) (block (block (i32.const 42)))) (export "" 0))')(), 42); assertEq(wasmEvalText('(module (func (result i32) (block i32 (block i32 (i32.const 42)))) (export "" 0))').exports[""](), 42);
wasmFailValidateText('(module (func (result f32) (block (i32.const 0))))', TypeError, mismatchError("i32", "f32")); wasmFailValidateText('(module (func (result f32) (block i32 (i32.const 0))))', TypeError, mismatchError("i32", "f32"));
assertEq(wasmEvalText('(module (func (result i32) (block (i32.const 13) (block (i32.const 42)))) (export "" 0))')(), 42); assertEq(wasmEvalText('(module (func (result i32) (block i32 (drop (i32.const 13)) (block i32 (i32.const 42)))) (export "" 0))').exports[""](), 42);
wasmFailValidateText('(module (func (result f32) (param f32) (block (get_local 0) (i32.const 0))))', TypeError, mismatchError("i32", "f32")); wasmFailValidateText('(module (func (result f32) (param f32) (block i32 (drop (get_local 0)) (i32.const 0))))', TypeError, mismatchError("i32", "f32"));
assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (i32.const 42)) (get_local 0)) (export "" 0))')(), 42); assertEq(wasmEvalText('(module (func (result i32) (local i32) (set_local 0 (i32.const 42)) (get_local 0)) (export "" 0))').exports[""](), 42);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// calls // calls
wasmFailValidateText('(module (func (nop)) (func (call 0 (i32.const 0))))', TypeError, /call arity out of range/); wasmFailValidateText('(module (func (nop)) (func (call 0 (i32.const 0))))', TypeError, /unused values not explicitly dropped by end of block/);
wasmFailValidateText('(module (func (param i32) (nop)) (func (call 0)))', TypeError, /call arity out of range/); wasmFailValidateText('(module (func (param i32) (nop)) (func (call 0)))', TypeError, /peeking at value from outside block/);
wasmFailValidateText('(module (func (param f32) (nop)) (func (call 0 (i32.const 0))))', TypeError, mismatchError("i32", "f32")); wasmFailValidateText('(module (func (param f32) (nop)) (func (call 0 (i32.const 0))))', TypeError, mismatchError("i32", "f32"));
wasmFailValidateText('(module (func (nop)) (func (call 3)))', TypeError, /callee index out of range/); wasmFailValidateText('(module (func (nop)) (func (call 3)))', TypeError, /callee index out of range/);
wasmValidateText('(module (func (nop)) (func (call 0)))'); wasmValidateText('(module (func (nop)) (func (call 0)))');
wasmValidateText('(module (func (param i32) (nop)) (func (call 0 (i32.const 0))))'); wasmValidateText('(module (func (param i32) (nop)) (func (call 0 (i32.const 0))))');
assertEq(wasmEvalText('(module (func (result i32) (i32.const 42)) (func (result i32) (call 0)) (export "" 1))')(), 42); assertEq(wasmEvalText('(module (func (result i32) (i32.const 42)) (func (result i32) (call 0)) (export "" 1))').exports[""](), 42);
assertThrowsInstanceOf(() => wasmEvalText('(module (func (call 0)) (export "" 0))')(), InternalError); assertThrowsInstanceOf(() => wasmEvalText('(module (func (call 0)) (export "" 0))').exports[""](), InternalError);
assertThrowsInstanceOf(() => wasmEvalText('(module (func (call 1)) (func (call 0)) (export "" 0))')(), InternalError); assertThrowsInstanceOf(() => wasmEvalText('(module (func (call 1)) (func (call 0)) (export "" 0))').exports[""](), InternalError);
wasmValidateText('(module (func (param i32 f32)) (func (call 0 (i32.const 0) (f32.const nan))))'); wasmValidateText('(module (func (param i32 f32)) (func (call 0 (i32.const 0) (f32.const nan))))');
wasmFailValidateText('(module (func (param i32 f32)) (func (call 0 (i32.const 0) (i32.const 0))))', TypeError, mismatchError("i32", "f32")); wasmFailValidateText('(module (func (param i32 f32)) (func (call 0 (i32.const 0) (i32.const 0))))', TypeError, mismatchError("i32", "f32"));
wasmFailValidateText('(module (import "a" "") (func (call_import 0 (i32.const 0))))', TypeError, /call arity out of range/); wasmFailValidateText('(module (import "a" "") (func (call_import 0 (i32.const 0))))', TypeError, /unused values not explicitly dropped by end of block/);
wasmFailValidateText('(module (import "a" "" (param i32)) (func (call_import 0)))', TypeError, /call arity out of range/); wasmFailValidateText('(module (import "a" "" (param i32)) (func (call_import 0)))', TypeError, /peeking at value from outside block/);
wasmFailValidateText('(module (import "a" "" (param f32)) (func (call_import 0 (i32.const 0))))', TypeError, mismatchError("i32", "f32")); wasmFailValidateText('(module (import "a" "" (param f32)) (func (call_import 0 (i32.const 0))))', TypeError, mismatchError("i32", "f32"));
assertErrorMessage(() => wasmEvalText('(module (import "a" "") (func (call_import 1)))'), TypeError, /import index out of range/); assertErrorMessage(() => wasmEvalText('(module (import "a" "") (func (call_import 1)))'), TypeError, /no import object given/);
wasmEvalText('(module (import "" "a") (func (call_import 0)))', {"":{a:()=>{}}}); wasmEvalText('(module (import "" "a") (func (call_import 0)))', {"":{a:()=>{}}});
wasmEvalText('(module (import "" "a" (param i32)) (func (call_import 0 (i32.const 0))))', {"":{a:()=>{}}}); wasmEvalText('(module (import "" "a" (param i32)) (func (call_import 0 (i32.const 0))))', {"":{a:()=>{}}});
function checkF32CallImport(v) { function checkF32CallImport(v) {
assertEq(wasmEvalText('(module (import "" "a" (result f32)) (func (result f32) (call_import 0)) (export "" 0))', {"":{a:()=>{ return v; }}})(), Math.fround(v)); assertEq(wasmEvalText('(module (import "" "a" (result f32)) (func (result f32) (call_import 0)) (export "" 1))', {"":{a:()=>{ return v; }}}).exports[""](), Math.fround(v));
wasmEvalText('(module (import "" "a" (param f32)) (func (param f32) (call_import 0 (get_local 0))) (export "" 0))', {"":{a:x=>{ assertEq(Math.fround(v), x); }}})(v); wasmEvalText('(module (import "" "a" (param f32)) (func (param f32) (call_import 0 (get_local 0))) (export "" 1))', {"":{a:x=>{ assertEq(Math.fround(v), x); }}}).exports[""](v);
} }
checkF32CallImport(13.37); checkF32CallImport(13.37);
checkF32CallImport(NaN); checkF32CallImport(NaN);
@ -260,31 +261,31 @@ checkF32CallImport(-0);
checkF32CallImport(Math.pow(2, 32) - 1); checkF32CallImport(Math.pow(2, 32) - 1);
var counter = 0; var counter = 0;
var f = wasmEvalText('(module (import "" "inc") (func (call_import 0)) (export "" 0))', {"":{inc:()=>counter++}}); var f = wasmEvalText('(module (import "" "inc") (func (call_import 0)) (export "" 1))', {"":{inc:()=>counter++}}).exports[""];
var g = wasmEvalText('(module (import "" "f") (func (block (call_import 0) (call_import 0))) (export "" 0))', {"":{f}}); var g = wasmEvalText('(module (import "" "f") (func (block (call_import 0) (call_import 0))) (export "" 1))', {"":{f}}).exports[""];
f(); f();
assertEq(counter, 1); assertEq(counter, 1);
g(); g();
assertEq(counter, 3); assertEq(counter, 3);
var f = wasmEvalText('(module (import "" "callf") (func (call_import 0)) (export "" 0))', {"":{callf:()=>f()}}); var f = wasmEvalText('(module (import "" "callf") (func (call_import 0)) (export "" 1))', {"":{callf:()=>f()}}).exports[""];
assertThrowsInstanceOf(() => f(), InternalError); assertThrowsInstanceOf(() => f(), InternalError);
var f = wasmEvalText('(module (import "" "callg") (func (call_import 0)) (export "" 0))', {"":{callg:()=>g()}}); var f = wasmEvalText('(module (import "" "callg") (func (call_import 0)) (export "" 1))', {"":{callg:()=>g()}}).exports[""];
var g = wasmEvalText('(module (import "" "callf") (func (call_import 0)) (export "" 0))', {"":{callf:()=>f()}}); var g = wasmEvalText('(module (import "" "callf") (func (call_import 0)) (export "" 1))', {"":{callf:()=>f()}}).exports[""];
assertThrowsInstanceOf(() => f(), InternalError); assertThrowsInstanceOf(() => f(), InternalError);
var code = '(module (import "" "one" (result i32)) (import "" "two" (result i32)) (func (result i32) (i32.const 3)) (func (result i32) (i32.const 4)) (func (result i32) BODY) (export "" 2))'; var code = '(module (import "" "one" (result i32)) (import "" "two" (result i32)) (func (result i32) (i32.const 3)) (func (result i32) (i32.const 4)) (func (result i32) BODY) (export "" 4))';
var imports = {"":{one:()=>1, two:()=>2}}; var imports = {"":{one:()=>1, two:()=>2}};
assertEq(wasmEvalText(code.replace('BODY', '(call_import 0)'), imports)(), 1); assertEq(wasmEvalText(code.replace('BODY', '(call_import 0)'), imports).exports[""](), 1);
assertEq(wasmEvalText(code.replace('BODY', '(call_import 1)'), imports)(), 2); assertEq(wasmEvalText(code.replace('BODY', '(call_import 1)'), imports).exports[""](), 2);
assertEq(wasmEvalText(code.replace('BODY', '(call 0)'), imports)(), 3); assertEq(wasmEvalText(code.replace('BODY', '(call 2)'), imports).exports[""](), 3);
assertEq(wasmEvalText(code.replace('BODY', '(call 1)'), imports)(), 4); assertEq(wasmEvalText(code.replace('BODY', '(call 3)'), imports).exports[""](), 4);
assertEq(wasmEvalText(`(module (import "" "evalcx" (param i32) (result i32)) (func (result i32) (call_import 0 (i32.const 0))) (export "" 0))`, {"":{evalcx}})(), 0); assertEq(wasmEvalText(`(module (import "" "evalcx" (param i32) (result i32)) (func (result i32) (call_import 0 (i32.const 0))) (export "" 1))`, {"":{evalcx}}).exports[""](), 0);
if (typeof evaluate === 'function') if (typeof evaluate === 'function')
evaluate(`Wasm.instantiateModule(wasmTextToBinary('(module)')) `, { fileName: null }); evaluate(`new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module)'))) `, { fileName: null });
{ {
setJitCompilerOption('wasm.test-mode', 1); setJitCompilerOption('wasm.test-mode', 1);
@ -316,17 +317,17 @@ if (typeof evaluate === 'function')
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
(import "" "param" (param i64) (result i32)) (import "" "param" (param i64) (result i32))
(func (result i32) (call_import 0 (i64.const 0x123456789abcdef0))) (func (result i32) (call_import 0 (i64.const 0x123456789abcdef0)))
(export "" 0))`, imp)(), 42); (export "" 1))`, imp).exports[""](), 42);
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
(import "" "param" (param i64)(param i64)(param i64)(param i64)(param i64)(param i64)(param i64) (param i64) (result i32)) (import "" "param" (param i64)(param i64)(param i64)(param i64)(param i64)(param i64)(param i64) (param i64) (result i32))
(func (result i32) (call_import 0 (i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0))) (func (result i32) (call_import 0 (i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)(i64.const 0x123456789abcdef0)))
(export "" 0))`, imp)(), 42); (export "" 1))`, imp).exports[""](), 42);
assertEqI64(wasmEvalText(`(module assertEqI64(wasmEvalText(`(module
(import "" "result" (param i32) (result i64)) (import "" "result" (param i32) (result i64))
(func (result i64) (call_import 0 (i32.const 3))) (func (result i64) (call_import 0 (i32.const 3)))
(export "" 0))`, imp)(), { low: 0xabcdef01, high: 0x1234567b }); (export "" 1))`, imp).exports[""](), { low: 0xabcdef01, high: 0x1234567b });
// Ensure the ion exit is never taken. // Ensure the ion exit is never taken.
let ionThreshold = 2 * getJitCompilerOptions()['ion.warmup.trigger']; let ionThreshold = 2 * getJitCompilerOptions()['ion.warmup.trigger'];
@ -341,7 +342,22 @@ if (typeof evaluate === 'function')
) )
(get_local 1) (get_local 1)
) )
(export "" 0))`, imp)(), { low: 1337, high: 0x12345678 }); (export "" 1))`, imp).exports[""](), { low: 1337, high: 0x12345678 });
assertEqI64(wasmEvalText(`(module
(import "" "paramAndResult" (param i64) (result i64))
(func (result i64) (local i32) (local i64)
(set_local 0 (i32.const 0))
(block $out
(loop $in
(set_local 1 (call_import 0 (i64.const 0x123456789abcdef0)))
(set_local 0 (i32.add (get_local 0) (i32.const 1)))
(if (i32.le_s (get_local 0) (i32.const ${ionThreshold})) (br $in))
)
)
(get_local 1)
)
(export "" 1))`, imp).exports[""](), { low: 1337, high: 0x12345678 });
setJitCompilerOption('wasm.test-mode', 0); setJitCompilerOption('wasm.test-mode', 0);
} }
@ -360,12 +376,12 @@ var {v2i, i2i, i2v} = wasmEvalText(`(module
(func (type 1) (i32.add (get_local 0) (i32.const 4))) (func (type 1) (i32.add (get_local 0) (i32.const 4)))
(table 0 1 2 3 4 5) (table 0 1 2 3 4 5)
(func (param i32) (result i32) (call_indirect 0 (get_local 0))) (func (param i32) (result i32) (call_indirect 0 (get_local 0)))
(func (param i32) (param i32) (result i32) (call_indirect 1 (get_local 0) (get_local 1))) (func (param i32) (param i32) (result i32) (call_indirect 1 (get_local 1) (get_local 0)))
(func (param i32) (call_indirect 2 (get_local 0) (i32.const 0))) (func (param i32) (call_indirect 2 (i32.const 0) (get_local 0)))
(export "v2i" 6) (export "v2i" 6)
(export "i2i" 7) (export "i2i" 7)
(export "i2v" 8) (export "i2v" 8)
)`); )`).exports;
const signatureMismatch = /indirect call signature mismatch/; const signatureMismatch = /indirect call signature mismatch/;
@ -405,7 +421,7 @@ assertErrorMessage(() => i2v(5), Error, signatureMismatch);
(export "" $bar) (export "" $bar)
)`, )`,
{"":{f:() => { stack = new Error().stack }}} {"":{f:() => { stack = new Error().stack }}}
)(), undefined); ).exports[""](), undefined);
disableSPSProfiling(); disableSPSProfiling();
@ -431,12 +447,12 @@ wasmValidateText('(module (import $bar "" "a") (func (call_import $bar)) (func $
wasmFailValidateText('(module (func (select (i32.const 0) (i32.const 0) (f32.const 0))))', TypeError, mismatchError("f32", "i32")); wasmFailValidateText('(module (func (select (i32.const 0) (i32.const 0) (f32.const 0))))', TypeError, mismatchError("f32", "i32"));
assertEq(wasmEvalText('(module (func (select (i32.const 0) (f32.const 0) (i32.const 0))) (export "" 0))')(), undefined); wasmFailValidateText('(module (func (select (i32.const 0) (f32.const 0) (i32.const 0))) (export "" 0))', TypeError, /select operand types must match/);
assertEq(wasmEvalText('(module (func (select (block) (i32.const 0) (i32.const 0))) (export "" 0))')(), undefined); wasmFailValidateText('(module (func (select (block ) (i32.const 0) (i32.const 0))) (export "" 0))', TypeError, /popping value from empty stack/);
assertEq(wasmEvalText('(module (func (select (return) (i32.const 0) (i32.const 0))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (select (return) (i32.const 0) (i32.const 0))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (i32.add (i32.const 0) (select (return) (i32.const 0) (i32.const 0)))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (i32.add (i32.const 0) (select (return) (i32.const 0) (i32.const 0)))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (select (if (i32.const 1) (i32.const 0) (f32.const 0)) (i32.const 0) (i32.const 0))) (export "" 0))')(), undefined); wasmFailValidateText('(module (func (select (if i32 (i32.const 1) (i32.const 0) (f32.const 0)) (i32.const 0) (i32.const 0))) (export "" 0))', TypeError, mismatchError("f32", "i32"));
assertEq(wasmEvalText('(module (func) (func (select (call 0) (call 0) (i32.const 0))) (export "" 0))')(), undefined); wasmFailValidateText('(module (func) (func (select (call 0) (call 0) (i32.const 0))) (export "" 0))', TypeError, /popping value from empty stack/);
(function testSideEffects() { (function testSideEffects() {
@ -460,9 +476,9 @@ var f = wasmEvalText(`
(get_local 0) (get_local 0)
) )
) )
(export "" 0) (export "" 2)
) )
`, imports); `, imports).exports[""];
assertEq(f(-1), numT); assertEq(f(-1), numT);
assertEq(numT, 1); assertEq(numT, 1);
@ -507,7 +523,7 @@ function testSelect(type, trueVal, falseVal) {
) )
(export "" 0) (export "" 0)
) )
`, imports); `, imports).exports[""];
assertEq(alwaysTrue(0), trueJS); assertEq(alwaysTrue(0), trueJS);
assertEq(alwaysTrue(1), trueJS); assertEq(alwaysTrue(1), trueJS);
@ -525,7 +541,7 @@ function testSelect(type, trueVal, falseVal) {
) )
(export "" 0) (export "" 0)
) )
`, imports); `, imports).exports[""];
assertEq(alwaysFalse(0), falseJS); assertEq(alwaysFalse(0), falseJS);
assertEq(alwaysFalse(1), falseJS); assertEq(alwaysFalse(1), falseJS);
@ -543,7 +559,7 @@ function testSelect(type, trueVal, falseVal) {
) )
(export "" 0) (export "" 0)
) )
`, imports); `, imports).exports[""];
assertEq(f(0), falseJS); assertEq(f(0), falseJS);
assertEq(f(1), trueJS); assertEq(f(1), trueJS);
@ -574,7 +590,7 @@ testSelect('f64', 'nan', Math.pow(2, -31));
) )
) )
(export "" 0) (export "" 0)
)`, imports); )`, imports).exports[""];
assertEqI64(f(0), { low: 0xdeadc0de, high: 0x12345678}); assertEqI64(f(0), { low: 0xdeadc0de, high: 0x12345678});
assertEqI64(f(1), { low: 0x8badf00d, high: 0xc0010ff0}); assertEqI64(f(1), { low: 0x8badf00d, high: 0xc0010ff0});

Просмотреть файл

@ -64,70 +64,67 @@ function loadTwiceModule(type, ext, offset, align) {
// TODO: Generate memory from byte string // TODO: Generate memory from byte string
return wasmEvalText( return wasmEvalText(
`(module `(module
(memory 1 (memory 1)
(segment 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f") (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(segment 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff") (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
(segment 65520 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff") (data 65520 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
)
(func (param i32) (param i32) (result ${type}) (func (param i32) (param i32) (result ${type})
(${type}.load${ext} (drop (${type}.load${ext}
offset=${offset} offset=${offset}
${align != 0 ? 'align=' + align : ''} ${align != 0 ? 'align=' + align : ''}
(get_local 0) (get_local 0)
) ))
(${type}.load${ext} (${type}.load${ext}
offset=${offset} offset=${offset}
${align != 0 ? 'align=' + align : ''} ${align != 0 ? 'align=' + align : ''}
(get_local 1) (get_local 1)
) )
) (export "" 0))` ) (export "" 0))`
); ).exports[""];
} }
function loadTwiceSameBasePlusConstModule(type, ext, offset, align, addConst) { function loadTwiceSameBasePlusConstModule(type, ext, offset, align, addConst) {
return wasmEvalText( return wasmEvalText(
`(module `(module
(memory 1 (memory 1)
(segment 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f") (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(segment 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff") (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
(segment 65520 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff") (data 65520 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
)
(func (param i32) (result ${type}) (func (param i32) (result ${type})
(${type}.load${ext} (drop (${type}.load${ext}
offset=${offset} offset=${offset}
${align != 0 ? 'align=' + align : ''} ${align != 0 ? 'align=' + align : ''}
(get_local 0) (get_local 0)
) ))
(${type}.load${ext} (${type}.load${ext}
offset=${offset} offset=${offset}
${align != 0 ? 'align=' + align : ''} ${align != 0 ? 'align=' + align : ''}
(i32.add (get_local 0) (i32.const ${addConst})) (i32.add (get_local 0) (i32.const ${addConst}))
) )
) (export "" 0))` ) (export "" 0))`
); ).exports[""];
} }
function loadTwiceSameBasePlusNonConstModule(type, ext, offset, align) { function loadTwiceSameBasePlusNonConstModule(type, ext, offset, align) {
return wasmEvalText( return wasmEvalText(
`(module `(module
(memory 1 (memory 1)
(segment 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f") (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(segment 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff") (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
(segment 65520 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff") (data 65520 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
)
(func (param i32) (param i32) (result ${type}) (func (param i32) (param i32) (result ${type})
(${type}.load${ext} (drop (${type}.load${ext}
offset=${offset} offset=${offset}
${align != 0 ? 'align=' + align : ''} ${align != 0 ? 'align=' + align : ''}
(get_local 0) (get_local 0)
) ))
(${type}.load${ext} (${type}.load${ext}
offset=${offset} offset=${offset}
${align != 0 ? 'align=' + align : ''} ${align != 0 ? 'align=' + align : ''}
(i32.add (get_local 0) (get_local 1)) (i32.add (get_local 0) (get_local 1))
) )
) (export "" 0))` ) (export "" 0))`
); ).exports[""];
} }
/* /*

Просмотреть файл

@ -1,6 +1,6 @@
load(libdir + "wasm.js"); load(libdir + "wasm.js");
assertEq(new WebAssembly.Instance(new WebAssembly.Module(textToBinary(`(module assertEq(new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`(module
(memory 1 32768) (memory 1 32768)
(func $test (result i32) (func $test (result i32)
(if (i32.eq (grow_memory (i32.const 16384)) (i32.const -1)) (return (i32.const 42))) (if (i32.eq (grow_memory (i32.const 16384)) (i32.const -1)) (return (i32.const 42)))

Просмотреть файл

@ -13,20 +13,34 @@ const ver1 = (Wasm.experimentalVersion >>> 8) & 0xff;
const ver2 = (Wasm.experimentalVersion >>> 16) & 0xff; const ver2 = (Wasm.experimentalVersion >>> 16) & 0xff;
const ver3 = (Wasm.experimentalVersion >>> 24) & 0xff; const ver3 = (Wasm.experimentalVersion >>> 24) & 0xff;
// Section names // Section opcodes
const sigId = "type"; const userDefinedId = 0;
const importId = "import"; const typeId = 1;
const functionSignaturesId = "function"; const importId = 2;
const functionTableId = "table"; const functionId = 3;
const exportTableId = "export"; const tableId = 4;
const functionBodiesId = "code"; const memoryId = 5;
const dataSegmentsId = "data"; const globalId = 6;
const nameId = "name"; const exportId = 7;
const startId = 8;
const elemId = 9;
const codeId = 10;
const dataId = 11;
const nameName = "name";
const magicError = /failed to match magic number/; const magicError = /failed to match magic number/;
const versionError = /failed to match binary version/; const unknownSection = /expected user-defined section/;
const unknownSectionError = /failed to skip unknown section at end/;
const sectionError = /failed to start section/; function sectionError(section) {
return RegExp(`failed to start ${section} section`);
}
function versionError(actual) {
var expect = Wasm.experimentalVersion;
var str = `binary version 0x${actual.toString(16)} does not match expected version 0x${expect.toString(16)}`;
return RegExp(str);
}
const VoidCode = 0; const VoidCode = 0;
const I32Code = 1; const I32Code = 1;
@ -34,11 +48,27 @@ const I64Code = 2;
const F32Code = 3; const F32Code = 3;
const F64Code = 4; const F64Code = 4;
const AnyFuncCode = 0x20;
const FunctionConstructorCode = 0x40; const FunctionConstructorCode = 0x40;
const Block = 0x01; const Unreachable = 0x00;
const End = 0x0f; const Block = 0x01;
const CallImport = 0x18; const End = 0x0f;
const I32Const = 0x10;
const I64Const = 0x11;
const F64Const = 0x12;
const F32Const = 0x13;
const Call = 0x16;
// DefinitionKind
const FunctionCode = 0x00;
const TableCode = 0x01;
const MemoryCode = 0x02;
const GlobalCode = 0x03;
// ResizableFlags
const DefaultFlag = 0x1;
const HasMaximumFlag = 0x2;
function toU8(array) { function toU8(array) {
for (let b of array) for (let b of array)
@ -60,18 +90,32 @@ function varU32(u32) {
return bytes; return bytes;
} }
function varS32(s32) {
assertEq(s32 >= -Math.pow(2,31), true);
assertEq(s32 < Math.pow(2,31), true);
var bytes = [];
do {
var byte = s32 & 0x7f;
s32 >>= 7;
if (s32 != 0 && s32 != -1)
byte |= 0x80;
bytes.push(byte);
} while (s32 != 0 && s32 != -1);
return bytes;
}
const U32MAX_LEB = [255, 255, 255, 255, 15]; const U32MAX_LEB = [255, 255, 255, 255, 15];
const wasmEval = (code, imports) => Wasm.instantiateModule(code, imports).exports; const wasmEval = (code, imports) => new WebAssembly.Instance(new WebAssembly.Module(code), imports).exports;
assertErrorMessage(() => wasmEval(toU8([])), TypeError, magicError); assertErrorMessage(() => wasmEval(toU8([])), TypeError, magicError);
assertErrorMessage(() => wasmEval(toU8([42])), TypeError, magicError); assertErrorMessage(() => wasmEval(toU8([42])), TypeError, magicError);
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2])), TypeError, magicError); assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2])), TypeError, magicError);
assertErrorMessage(() => wasmEval(toU8([1,2,3,4])), TypeError, magicError); assertErrorMessage(() => wasmEval(toU8([1,2,3,4])), TypeError, magicError);
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3])), TypeError, versionError); assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3])), TypeError, versionError(0x6d736100));
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, 1])), TypeError, versionError); assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, 1])), TypeError, versionError(0x6d736100));
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0])), TypeError, versionError); assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0])), TypeError, versionError(0x6d736100));
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0, ver1, ver2])), TypeError, versionError); assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0, ver1, ver2])), TypeError, versionError(0x6d736100));
function moduleHeaderThen(...rest) { function moduleHeaderThen(...rest) {
return [magic0, magic1, magic2, magic3, ver0, ver1, ver2, ver3, ...rest]; return [magic0, magic1, magic2, magic3, ver0, ver1, ver2, ver3, ...rest];
@ -80,19 +124,34 @@ function moduleHeaderThen(...rest) {
var o = wasmEval(toU8(moduleHeaderThen())); var o = wasmEval(toU8(moduleHeaderThen()));
assertEq(Object.getOwnPropertyNames(o).length, 0); assertEq(Object.getOwnPropertyNames(o).length, 0);
wasmEval(toU8(moduleHeaderThen(0, 0))); // unknown section containing 0-length string // unfinished known sections
wasmEval(toU8(moduleHeaderThen(1, 0, 0))); // unknown section containing 1-length string ("\0") assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(typeId))), TypeError, sectionError("type"));
wasmEval(toU8(moduleHeaderThen(0, 0, 0, 0))); assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(importId))), TypeError, sectionError("import"));
wasmEval(toU8(moduleHeaderThen(0, 0, 1, 0, 0))); assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(functionId))), TypeError, sectionError("function"));
wasmEval(toU8(moduleHeaderThen(1, 0, 0, 1, 0, 0))); assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(tableId))), TypeError, sectionError("table"));
wasmEval(toU8(moduleHeaderThen(1, 0, 0, 0, 0))); assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(memoryId))), TypeError, sectionError("memory"));
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(globalId))), TypeError, sectionError("global"));
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(exportId))), TypeError, sectionError("export"));
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(startId))), TypeError, sectionError("start"));
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(elemId))), TypeError, sectionError("elem"));
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(codeId))), TypeError, sectionError("code"));
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(dataId))), TypeError, sectionError("data"));
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(1))), TypeError, sectionError); // unknown sections are unconditionally rejected
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 1))), TypeError, unknownSectionError); assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42))), TypeError, unknownSection);
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42, 0))), TypeError, unknownSection);
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(42, 1, 0))), TypeError, unknownSection);
function cstring(name) { // user sections have special rules
return (name + '\0').split('').map(c => c.charCodeAt(0)); assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0))), TypeError, sectionError("user-defined")); // no length
} assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 0))), TypeError, sectionError("user-defined")); // no id
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 0, 0))), TypeError, sectionError("user-defined")); // payload too small to have id length
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 1, 1))), TypeError, sectionError("user-defined")); // id not present
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 1, 1, 65))), TypeError, sectionError("user-defined")); // id length doesn't fit in section
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 1, 0, 0))), TypeError, sectionError("user-defined")); // second, unfinished user-defined section
wasmEval(toU8(moduleHeaderThen(0, 1, 0))); // empty id
wasmEval(toU8(moduleHeaderThen(0, 1, 0, 0, 1, 0))); // 2x empty id
wasmEval(toU8(moduleHeaderThen(0, 2, 1, 65))); // id = "A"
function string(name) { function string(name) {
var nameBytes = name.split('').map(c => { var nameBytes = name.split('').map(c => {
@ -112,7 +171,7 @@ function encodedString(name, len) {
function moduleWithSections(sectionArray) { function moduleWithSections(sectionArray) {
var bytes = moduleHeaderThen(); var bytes = moduleHeaderThen();
for (let section of sectionArray) { for (let section of sectionArray) {
bytes.push(...string(section.name)); bytes.push(section.name);
bytes.push(...varU32(section.body.length)); bytes.push(...varU32(section.body.length));
bytes.push(...section.body); bytes.push(...section.body);
} }
@ -131,7 +190,7 @@ function sigSection(sigs) {
if (sig.ret != VoidCode) if (sig.ret != VoidCode)
body.push(...varU32(sig.ret)); body.push(...varU32(sig.ret));
} }
return { name: sigId, body }; return { name: typeId, body };
} }
function declSection(decls) { function declSection(decls) {
@ -139,7 +198,7 @@ function declSection(decls) {
body.push(...varU32(decls.length)); body.push(...varU32(decls.length));
for (let decl of decls) for (let decl of decls)
body.push(...varU32(decl)); body.push(...varU32(decl));
return { name: functionSignaturesId, body }; return { name: functionId, body };
} }
function funcBody(func) { function funcBody(func) {
@ -147,22 +206,24 @@ function funcBody(func) {
for (let local of func.locals) for (let local of func.locals)
body.push(...varU32(local)); body.push(...varU32(local));
body = body.concat(...func.body); body = body.concat(...func.body);
body.push(End);
body.splice(0, 0, ...varU32(body.length)); body.splice(0, 0, ...varU32(body.length));
return body; return body;
} }
function bodySection(bodies) { function bodySection(bodies) {
var body = varU32(bodies.length).concat(...bodies); var body = varU32(bodies.length).concat(...bodies);
return { name: functionBodiesId, body }; return { name: codeId, body };
} }
function importSection(imports) { function importSection(imports) {
var body = []; var body = [];
body.push(...varU32(imports.length)); body.push(...varU32(imports.length));
for (let imp of imports) { for (let imp of imports) {
body.push(...varU32(imp.sigIndex));
body.push(...string(imp.module)); body.push(...string(imp.module));
body.push(...string(imp.func)); body.push(...string(imp.func));
body.push(...varU32(FunctionCode));
body.push(...varU32(imp.sigIndex));
} }
return { name: importId, body }; return { name: importId, body };
} }
@ -171,22 +232,50 @@ function exportSection(exports) {
var body = []; var body = [];
body.push(...varU32(exports.length)); body.push(...varU32(exports.length));
for (let exp of exports) { for (let exp of exports) {
body.push(...varU32(exp.funcIndex));
body.push(...string(exp.name)); body.push(...string(exp.name));
body.push(...varU32(FunctionCode));
body.push(...varU32(exp.funcIndex));
} }
return { name: exportTableId, body }; return { name: exportId, body };
} }
function tableSection(elems) { function tableSection(initialSize) {
var body = []; var body = [];
body.push(...varU32(elems.length)); body.push(...varU32(1)); // number of tables
for (let i of elems) body.push(...varU32(AnyFuncCode));
body.push(...varU32(i)); body.push(...varU32(DefaultFlag)); // for now, no maximum
return { name: functionTableId, body }; body.push(...varU32(initialSize));
// for now, no maximum
return { name: tableId, body };
}
function memorySection(initialSize) {
var body = [];
body.push(...varU32(1)); // number of memories
body.push(...varU32(DefaultFlag)); // for now, no maximum
body.push(...varU32(initialSize));
// for now, no maximum
return { name: memoryId, body };
}
function elemSection(elemArrays) {
var body = [];
body.push(...varU32(elemArrays.length));
for (let array of elemArrays) {
body.push(...varU32(0)); // table index
body.push(...varU32(I32Const));
body.push(...varS32(array.offset));
body.push(...varU32(End));
body.push(...varU32(array.elems.length));
for (let elem of array.elems)
body.push(...varU32(elem));
}
return { name: elemId, body };
} }
function nameSection(elems) { function nameSection(elems) {
var body = []; var body = [];
body.push(...string(nameName));
body.push(...varU32(elems.length)); body.push(...varU32(elems.length));
for (let fn of elems) { for (let fn of elems) {
body.push(...encodedString(fn.name, fn.nameLen)); body.push(...encodedString(fn.name, fn.nameLen));
@ -198,19 +287,23 @@ function nameSection(elems) {
for (let local of fn.locals) for (let local of fn.locals)
body.push(...encodedString(local.name, local.nameLen)); body.push(...encodedString(local.name, local.nameLen));
} }
return { name: nameId, body }; return { name: userDefinedId, body };
}
function userDefinedSection(name, ...body) {
return { name: userDefinedId, body: [...string(name), ...body] };
} }
const v2vSig = {args:[], ret:VoidCode}; const v2vSig = {args:[], ret:VoidCode};
const i2vSig = {args:[I32Code], ret:VoidCode}; const i2vSig = {args:[I32Code], ret:VoidCode};
const v2vBody = funcBody({locals:[], body:[]}); const v2vBody = funcBody({locals:[], body:[]});
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: sigId, body: U32MAX_LEB } ])), TypeError, /too many signatures/); assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: U32MAX_LEB } ])), TypeError, /too many signatures/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: sigId, body: [1, 0], } ])), TypeError, /expected function form/); assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, 0], } ])), TypeError, /expected function form/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: sigId, body: [1, FunctionConstructorCode, ...U32MAX_LEB], } ])), TypeError, /too many arguments in signature/); assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, FunctionConstructorCode, ...U32MAX_LEB], } ])), TypeError, /too many arguments in signature/);
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: sigId, body: [1]}])), TypeError); assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1]}])), TypeError);
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: sigId, body: [1, 1, 0]}])), TypeError); assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1, 1, 0]}])), TypeError);
wasmEval(moduleWithSections([sigSection([])])); wasmEval(moduleWithSections([sigSection([])]));
wasmEval(moduleWithSections([sigSection([v2vSig])])); wasmEval(moduleWithSections([sigSection([v2vSig])]));
@ -225,6 +318,8 @@ assertThrowsInstanceOf(() => wasmEval(moduleWithSections([sigSection([v2vSig]),
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0])])), TypeError, /expected function bodies/); assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0])])), TypeError, /expected function bodies/);
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([v2vBody])])); wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([v2vBody])]));
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([v2vBody.concat(v2vBody)])])), TypeError, /byte size mismatch in code section/);
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([sigSection([v2vSig]), {name: importId, body:[]}])), TypeError); assertThrowsInstanceOf(() => wasmEval(moduleWithSections([sigSection([v2vSig]), {name: importId, body:[]}])), TypeError);
assertErrorMessage(() => wasmEval(moduleWithSections([importSection([{sigIndex:0, module:"a", func:"b"}])])), TypeError, /signature index out of range/); assertErrorMessage(() => wasmEval(moduleWithSections([importSection([{sigIndex:0, module:"a", func:"b"}])])), TypeError, /signature index out of range/);
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), importSection([{sigIndex:1, module:"a", func:"b"}])])), TypeError, /signature index out of range/); assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), importSection([{sigIndex:1, module:"a", func:"b"}])])), TypeError, /signature index out of range/);
@ -238,40 +333,91 @@ wasmEval(moduleWithSections([
bodySection([v2vBody]) bodySection([v2vBody])
]), {a:{"":()=>{}}}); ]), {a:{"":()=>{}}});
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: dataSegmentsId, body: [], } ])), TypeError, /data section requires a memory section/); assertErrorMessage(() => wasmEval(moduleWithSections([ {name: dataId, body: [], } ])), TypeError, /data section requires a memory section/);
wasmEval(moduleWithSections([tableSection([])])); wasmEval(moduleWithSections([tableSection(0)]));
assertErrorMessage(() => wasmEval(moduleWithSections([tableSection([0])])), TypeError, /table element out of range/); wasmEval(moduleWithSections([elemSection([])]));
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0]), bodySection([v2vBody])])); wasmEval(moduleWithSections([tableSection(0), elemSection([])]));
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,0]), bodySection([v2vBody])])); wasmEval(moduleWithSections([tableSection(1), elemSection([{offset:1, elems:[]}])]));
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,1]), bodySection([v2vBody])])), TypeError, /table element out of range/); assertErrorMessage(() => wasmEval(moduleWithSections([tableSection(1), elemSection([{offset:0, elems:[0]}])])), TypeError, /table element out of range/);
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0,0,0]), tableSection([0,1,0,2]), bodySection([v2vBody, v2vBody, v2vBody])])); assertErrorMessage(() => wasmEval(moduleWithSections([tableSection(0), elemSection([{offset:0, elems:[0]}])])), TypeError, /element segment does not fit/);
wasmEval(moduleWithSections([sigSection([v2vSig,i2vSig]), declSection([0,0,1]), tableSection([0,1,2]), bodySection([v2vBody, v2vBody, v2vBody])])); assertErrorMessage(() => wasmEval(moduleWithSections([tableSection(1), elemSection([{offset:1, elems:[0]}])])), TypeError, /element segment does not fit/);
assertErrorMessage(() => wasmEval(moduleWithSections([tableSection(1), elemSection([{offset:0, elems:[0,0]}])])), TypeError, /element segment does not fit/);
assertErrorMessage(() => wasmEval(moduleWithSections([tableSection(0), elemSection([{offset:1, elems:[]}])])), TypeError, /element segment does not fit/);
assertErrorMessage(() => wasmEval(moduleWithSections([tableSection(0), elemSection([{offset:-1, elems:[]}])])), TypeError, /element segment does not fit/);
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection(1), elemSection([{offset:0, elems:[0]}]), bodySection([v2vBody])]));
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection(2), elemSection([{offset:0, elems:[0,0]}]), bodySection([v2vBody])]));
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection(2), elemSection([{offset:0, elems:[0,1]}]), bodySection([v2vBody])])), TypeError, /table element out of range/);
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0,0,0]), tableSection(4), elemSection([{offset:0, elems:[0,1,0,2]}]), bodySection([v2vBody, v2vBody, v2vBody])]));
wasmEval(moduleWithSections([sigSection([v2vSig,i2vSig]), declSection([0,0,1]), tableSection(3), elemSection([{offset:0,elems:[0,1,2]}]), bodySection([v2vBody, v2vBody, v2vBody])]));
function invalidTableSection0() {
var body = [];
body.push(...varU32(0)); // number of tables
return { name: tableId, body };
}
assertErrorMessage(() => wasmEval(moduleWithSections([invalidTableSection0()])), TypeError, /number of tables must be exactly one/);
wasmEval(moduleWithSections([memorySection(0)]));
function invalidMemorySection0() {
var body = [];
body.push(...varU32(0)); // number of memories
return { name: memoryId, body };
}
assertErrorMessage(() => wasmEval(moduleWithSections([invalidMemorySection0()])), TypeError, /number of memories must be exactly one/);
// Test early 'end'
const bodyMismatch = /function body length mismatch/;
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:[End]})])])), TypeError, bodyMismatch);
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:[Unreachable,End]})])])), TypeError, bodyMismatch);
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:[End,Unreachable]})])])), TypeError, bodyMismatch);
// Deep nesting shouldn't crash or even throw. // Deep nesting shouldn't crash or even throw.
var manyBlocks = []; var manyBlocks = [];
for (var i = 0; i < 20000; i++) for (var i = 0; i < 20000; i++)
manyBlocks.push(Block, End); manyBlocks.push(Block, VoidCode, End);
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:manyBlocks})])])); wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:manyBlocks})])]));
// Ignore errors in name section. // Ignore errors in name section.
var tooBigNameSection = { var tooBigNameSection = {
name: nameId, name: userDefinedId,
body: [...varU32(Math.pow(2, 31))] // declare 2**31 functions. body: [...string(nameName), ...varU32(Math.pow(2, 31))] // declare 2**31 functions.
}; };
wasmEval(moduleWithSections([tooBigNameSection])); wasmEval(moduleWithSections([tooBigNameSection]));
// Skip user-defined sections before any expected section
var userDefSec = userDefinedSection("wee", 42, 13);
var sigSec = sigSection([v2vSig]);
var declSec = declSection([0]);
var bodySec = bodySection([v2vBody]);
wasmEval(moduleWithSections([userDefSec, sigSec, declSec, bodySec]));
wasmEval(moduleWithSections([sigSec, userDefSec, declSec, bodySec]));
wasmEval(moduleWithSections([sigSec, declSec, userDefSec, bodySec]));
wasmEval(moduleWithSections([sigSec, declSec, bodySec, userDefSec]));
wasmEval(moduleWithSections([userDefSec, userDefSec, sigSec, declSec, bodySec]));
wasmEval(moduleWithSections([userDefSec, userDefSec, sigSec, userDefSec, declSec, userDefSec, bodySec]));
// Diagnose nonstandard block signature types.
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:[Block, F64Code + 1, End]})])])), TypeError, /unknown block signature type/);
// Checking stack trace. // Checking stack trace.
function runStackTraceTest(namesContent, expectedName) { function runStackTraceTest(namesContent, expectedName) {
var sections = [ var sections = [
sigSection([v2vSig]), sigSection([v2vSig]),
importSection([{sigIndex:0, module:"env", func:"callback"}]), importSection([{sigIndex:0, module:"env", func:"callback"}]),
declSection([0]), declSection([0]),
exportSection([{funcIndex:0, name: "run"}]), exportSection([{funcIndex:1, name: "run"}]),
bodySection([funcBody({locals: [], body: [CallImport, varU32(0), varU32(0)]})]) bodySection([funcBody({locals: [], body: [Call, varU32(0)]})]),
userDefinedSection("whoa"),
userDefinedSection("wee", 42),
]; ];
if (namesContent) if (namesContent)
sections.push(nameSection(namesContent)); sections.push(nameSection(namesContent));
sections.push(userDefinedSection("yay", 13));
var result = ""; var result = "";
var callback = () => { var callback = () => {
var prevFrameEntry = new Error().stack.split('\n')[1]; var prevFrameEntry = new Error().stack.split('\n')[1];

Просмотреть файл

@ -11,7 +11,7 @@ var o = wasmEvalText('(module (func))\n;; end');
var o = wasmEvalText('(module (func))\n;; end'); var o = wasmEvalText('(module (func))\n;; end');
var o = wasmEvalText(';;start\n(module (func))'); var o = wasmEvalText(';;start\n(module (func))');
var o = wasmEvalText('(module (func ;; middle\n))'); var o = wasmEvalText('(module (func ;; middle\n))');
var o = wasmEvalText('(module (func) ;; middle\n (export "a" 0))'); var o = wasmEvalText('(module (func) ;; middle\n (export "a" 0))').exports;
assertEq(Object.getOwnPropertyNames(o)[0], "a"); assertEq(Object.getOwnPropertyNames(o)[0], "a");
// multi-line comments // multi-line comments
@ -21,7 +21,7 @@ var o = wasmEvalText('(module (func))\n(;;)');
var o = wasmEvalText('(;start;)(module (func))'); var o = wasmEvalText('(;start;)(module (func))');
var o = wasmEvalText('(;start;)\n(module (func))'); var o = wasmEvalText('(;start;)\n(module (func))');
var o = wasmEvalText('(module (func (; middle\n multi\n;)))'); var o = wasmEvalText('(module (func (; middle\n multi\n;)))');
var o = wasmEvalText('(module (func)(;middle;)(export "a" 0))'); var o = wasmEvalText('(module (func)(;middle;)(export "a" 0))').exports;
assertEq(Object.getOwnPropertyNames(o)[0], "a"); assertEq(Object.getOwnPropertyNames(o)[0], "a");
// nested comments // nested comments

Просмотреть файл

@ -18,4 +18,4 @@ var module = `(module
(export "" 0) (export "" 0)
)`; )`;
assertEq(wasmEvalText(module)(13.37), Math.fround(13.37)); assertEq(wasmEvalText(module).exports[""](13.37), Math.fround(13.37));

Просмотреть файл

@ -3,14 +3,14 @@ load(libdir + "wasm.js");
function testConst(type, str, expect) { function testConst(type, str, expect) {
if (type === 'i64') if (type === 'i64')
assertEqI64(wasmEvalText('(module (func (result i64) (i64.const ' + str + ')) (export "" 0))')(), expect); assertEqI64(wasmEvalText('(module (func (result i64) (i64.const ' + str + ')) (export "" 0))').exports[""](), expect);
else else
assertEq(wasmEvalText('(module (func (result ' + type + ') (' + type + '.const ' + str + ')) (export "" 0))')(), expect); assertEq(wasmEvalText('(module (func (result ' + type + ') (' + type + '.const ' + str + ')) (export "" 0))').exports[""](), expect);
} }
function testConstError(type, str) { function testConstError(type, str) {
// For now at least, we don't distinguish between parse errors and OOMs. // For now at least, we don't distinguish between parse errors and OOMs.
assertErrorMessage(() => wasmEvalText('(module (func (result ' + type + ') (' + type + '.const ' + str + ')) (export "" 0))')(), Error, /parsing wasm text/); assertErrorMessage(() => wasmEvalText('(module (func (result ' + type + ') (' + type + '.const ' + str + ')) (export "" 0))').exports[""](), Error, /parsing wasm text/);
} }
testConst('i32', '0', 0); testConst('i32', '0', 0);

Просмотреть файл

@ -12,27 +12,29 @@ wasmEvalText('(module (func (local i32) (if (get_local 0) (nop))) (export "" 0))
wasmEvalText('(module (func (local i32) (if (get_local 0) (nop) (nop))) (export "" 0))'); wasmEvalText('(module (func (local i32) (if (get_local 0) (nop) (nop))) (export "" 0))');
// Expression values types are consistent // Expression values types are consistent
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (local f32) (if (i32.const 42) (get_local 0) (i32.const 0))))'), TypeError, mismatchError("void", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (local f32) (if f32 (i32.const 42) (get_local 0) (i32.const 0))))'), TypeError, mismatchError("i32", "f32"));
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (local f64) (if (i32.const 42) (i32.const 0) (get_local 0))))'), TypeError, mismatchError("void", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (local f64) (if i32 (i32.const 42) (i32.const 0) (get_local 0))))'), TypeError, mismatchError("f64", "i32"));
assertEq(wasmEvalText('(module (func (result i32) (if (i32.const 42) (i32.const 1) (i32.const 2))) (export "" 0))')(), 1); assertEq(wasmEvalText('(module (func (result i32) (if i32 (i32.const 42) (i32.const 1) (i32.const 2))) (export "" 0))').exports[""](), 1);
assertEq(wasmEvalText('(module (func (result i32) (if (i32.const 0) (i32.const 1) (i32.const 2))) (export "" 0))')(), 2); assertEq(wasmEvalText('(module (func (result i32) (if i32 (i32.const 0) (i32.const 1) (i32.const 2))) (export "" 0))').exports[""](), 2);
// If we don't yield, sub expressions types don't have to match // Even if we don't yield, sub expressions types still have to match.
assertEq(wasmEvalText('(module (func (if (i32.const 42) (i32.const 1) (i32.const 0))) (export "" 0))')(), undefined); assertErrorMessage(() => wasmEvalText('(module (func (param f32) (if i32 (i32.const 42) (i32.const 1) (get_local 0))) (export "" 0))'), TypeError, mismatchError('f32', 'i32'));
assertEq(wasmEvalText('(module (func (param f32) (if (i32.const 42) (i32.const 1) (get_local 0))) (export "" 0))')(13.37), undefined); assertErrorMessage(() => wasmEvalText('(module (func (if i32 (i32.const 42) (i32.const 1) (i32.const 0))) (export "" 0))'), TypeError, /unused values not explicitly dropped by end of block/);
assertEq(wasmEvalText('(module (func (drop (if i32 (i32.const 42) (i32.const 1) (i32.const 0)))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (param f32) (if (i32.const 42) (drop (i32.const 1)) (drop (get_local 0)))) (export "" 0))').exports[""](13.37), undefined);
// Sub-expression values are returned // Sub-expression values are returned
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
(func (func
(result i32) (result i32)
(if (if i32
(i32.const 42) (i32.const 42)
(block (block i32
( (
if if i32
(block (block i32
(i32.const 3) (drop (i32.const 3))
(i32.const 5) (drop (i32.const 5))
(i32.const 0) (i32.const 0)
) )
(i32.const 1) (i32.const 1)
@ -43,7 +45,7 @@ assertEq(wasmEvalText(`(module
) )
) )
(export "" 0) (export "" 0)
)`)(), 2); )`).exports[""](), 2);
// The if (resp. else) branch is taken iff the condition is true (resp. false) // The if (resp. else) branch is taken iff the condition is true (resp. false)
counter = 0; counter = 0;
@ -52,28 +54,28 @@ assertEq(wasmEvalText(`(module
(import "" "inc" (result i32)) (import "" "inc" (result i32))
(func (func
(result i32) (result i32)
(if (if i32
(i32.const 42) (i32.const 42)
(i32.const 1) (i32.const 1)
(call_import 0) (call_import 0)
) )
) )
(export "" 0) (export "" 1)
)`, imports)(), 1); )`, imports).exports[""](), 1);
assertEq(counter, 0); assertEq(counter, 0);
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
(import "" "inc" (result i32)) (import "" "inc" (result i32))
(func (func
(result i32) (result i32)
(if (if i32
(i32.const 0) (i32.const 0)
(call_import 0) (call_import 0)
(i32.const 1) (i32.const 1)
) )
) )
(export "" 0) (export "" 1)
)`, imports)(), 1); )`, imports).exports[""](), 1);
assertEq(counter, 0); assertEq(counter, 0);
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
@ -81,11 +83,11 @@ assertEq(wasmEvalText(`(module
(func (func
(if (if
(i32.const 0) (i32.const 0)
(call_import 0) (drop (call_import 0))
) )
) )
(export "" 0) (export "" 1)
)`, imports)(), undefined); )`, imports).exports[""](), undefined);
assertEq(counter, 0); assertEq(counter, 0);
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
@ -93,11 +95,35 @@ assertEq(wasmEvalText(`(module
(func (func
(if (if
(i32.const 1) (i32.const 1)
(call_import 0) (drop (call_import 0))
)
)
(export "" 1)
)`, imports).exports[""](), undefined);
assertEq(counter, 1);
assertEq(wasmEvalText(`(module
(func
(result i32)
(if i32
(i32.const 0)
(br 0 (i32.const 0))
(br 0 (i32.const 1))
) )
) )
(export "" 0) (export "" 0)
)`, imports)(), undefined); )`).exports[""](), 1);
assertEq(counter, 1);
assertEq(wasmEvalText(`(module
(func
(if
(i32.const 1)
(br 0)
)
)
(export "" 0)
)`).exports[""](), undefined);
assertEq(counter, 1); assertEq(counter, 1);
// One can chain if with if/if // One can chain if with if/if
@ -106,13 +132,13 @@ assertEq(wasmEvalText(`(module
(import "" "inc" (result i32)) (import "" "inc" (result i32))
(func (func
(result i32) (result i32)
(if (if i32
(i32.const 1) (i32.const 1)
(if (if i32
(i32.const 2) (i32.const 2)
(if (if i32
(i32.const 3) (i32.const 3)
(if (if i32
(i32.const 0) (i32.const 0)
(call_import 0) (call_import 0)
(i32.const 42) (i32.const 42)
@ -124,22 +150,28 @@ assertEq(wasmEvalText(`(module
(call_import 0) (call_import 0)
) )
) )
(export "" 0) (export "" 1)
)`, imports)(), 42); )`, imports).exports[""](), 42);
assertEq(counter, 0); assertEq(counter, 0);
// "if" doesn't return an expression value // "if" doesn't return an expression value
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (if (i32.const 42) (i32.const 0))))'), TypeError, mismatchError("void", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (if i32 (i32.const 42) (i32.const 0))))'), TypeError, /if without else with a result value/);
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (if (i32.const 1) (i32.const 0) (if (i32.const 1) (i32.const 1)))))'), TypeError, mismatchError("void", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (if i32 (i32.const 42) (drop (i32.const 0)))))'), TypeError, mismatchError("void", "i32"));
wasmEvalText('(module (func (if (i32.const 1) (i32.const 0) (if (i32.const 1) (i32.const 1)))))'); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (if i32 (i32.const 1) (i32.const 0) (if i32 (i32.const 1) (i32.const 1)))))'), TypeError, /if without else with a result value/);
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (if i32 (i32.const 1) (drop (i32.const 0)) (if (i32.const 1) (drop (i32.const 1))))))'), TypeError, mismatchError("void", "i32"));
assertErrorMessage(() => wasmEvalText('(module (func (if i32 (i32.const 1) (i32.const 0) (if i32 (i32.const 1) (i32.const 1)))))'), TypeError, /if without else with a result value/);
assertErrorMessage(() => wasmEvalText('(module (func (if i32 (i32.const 1) (i32.const 0) (if (i32.const 1) (drop (i32.const 1))))))'), TypeError, mismatchError("void", "i32"));
assertErrorMessage(() => wasmEvalText('(module (func (if (i32.const 1) (drop (i32.const 0)) (if i32 (i32.const 1) (i32.const 1)))))'), TypeError, /if without else with a result value/);
wasmEvalText('(module (func (if (i32.const 1) (drop (i32.const 0)) (if (i32.const 1) (drop (i32.const 1))))))');
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// return // return
assertEq(wasmEvalText('(module (func (return)) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (return)) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (result i32) (return (i32.const 1))) (export "" 0))')(), 1); assertEq(wasmEvalText('(module (func (result i32) (return (i32.const 1))) (export "" 0))').exports[""](), 1);
assertEq(wasmEvalText('(module (func (if (return) (i32.const 0))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (if (return) (i32.const 0))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (return (i32.const 1))) (export "" 0))')(), undefined); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (return)) (export "" 0))'), TypeError, /popping value from empty stack/);
assertEq(wasmEvalText('(module (func (return (i32.const 1))) (export "" 0))').exports[""](), undefined);
assertErrorMessage(() => wasmEvalText('(module (func (result f32) (return (i32.const 1))) (export "" 0))'), TypeError, mismatchError("i32", "f32")); assertErrorMessage(() => wasmEvalText('(module (func (result f32) (return (i32.const 1))) (export "" 0))'), TypeError, mismatchError("i32", "f32"));
assertThrowsInstanceOf(() => wasmEvalText('(module (func (result i32) (return)) (export "" 0))'), TypeError); assertThrowsInstanceOf(() => wasmEvalText('(module (func (result i32) (return)) (export "" 0))'), TypeError);
@ -147,16 +179,20 @@ assertThrowsInstanceOf(() => wasmEvalText('(module (func (result i32) (return))
// br / br_if // br / br_if
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block (br 0))) (export "" 0))'), TypeError, mismatchError("void", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block (br 0))) (export "" 0))'), TypeError, mismatchError("void", "i32"));
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (br 0)) (export "" 0))'), TypeError, /popping value from empty stack/);
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block (br_if 0 (i32.const 0)))) (export "" 0))'), TypeError, mismatchError("void", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block (br_if 0 (i32.const 0)))) (export "" 0))'), TypeError, mismatchError("void", "i32"));
const DEPTH_OUT_OF_BOUNDS = /branch depth exceeds current nesting level/; const DEPTH_OUT_OF_BOUNDS = /branch depth exceeds current nesting level/;
assertErrorMessage(() => wasmEvalText('(module (func (br 0)))'), TypeError, DEPTH_OUT_OF_BOUNDS); assertErrorMessage(() => wasmEvalText('(module (func (br 1)))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (block (br 1))))'), TypeError, DEPTH_OUT_OF_BOUNDS); assertErrorMessage(() => wasmEvalText('(module (func (block (br 2))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (loop (br 2))))'), TypeError, DEPTH_OUT_OF_BOUNDS); assertErrorMessage(() => wasmEvalText('(module (func (loop (br 2))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (if (i32.const 0) (br 2))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (if (i32.const 0) (br 1) (br 2))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (if (i32.const 0) (br 2) (br 1))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (br_if 0 (i32.const 0))))'), TypeError, DEPTH_OUT_OF_BOUNDS); assertErrorMessage(() => wasmEvalText('(module (func (br_if 1 (i32.const 0))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (block (br_if 1 (i32.const 0)))))'), TypeError, DEPTH_OUT_OF_BOUNDS); assertErrorMessage(() => wasmEvalText('(module (func (block (br_if 2 (i32.const 0)))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (loop (br_if 2 (i32.const 0)))))'), TypeError, DEPTH_OUT_OF_BOUNDS); assertErrorMessage(() => wasmEvalText('(module (func (loop (br_if 2 (i32.const 0)))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText(`(module (func (result i32) assertErrorMessage(() => wasmEvalText(`(module (func (result i32)
@ -169,16 +205,17 @@ assertErrorMessage(() => wasmEvalText(`(module (func (result i32)
) )
) (export "" 0))`), TypeError, mismatchError("void", "i32")); ) (export "" 0))`), TypeError, mismatchError("void", "i32"));
assertEq(wasmEvalText(`(module (func (block $out (br_if $out (br 0)))) (export "" 0))`)(), undefined); assertEq(wasmEvalText(`(module (func (block $out (br_if $out (br 0)))) (export "" 0))`).exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block (br 0))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (br 0)) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block $l (br $l))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (block (br 0))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block $l (br $l))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block (block (br 1)))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (block (block (br 1)))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block $l (block (br $l)))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (block $l (block (br $l)))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block $l (block $m (br $l)))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (block $l (block $m (br $l)))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block $l (block $m (br $m)))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (block $l (block $m (br $m)))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText(`(module (func (result i32) assertEq(wasmEvalText(`(module (func (result i32)
(block (block
@ -186,7 +223,7 @@ assertEq(wasmEvalText(`(module (func (result i32)
(return (i32.const 0)) (return (i32.const 0))
) )
(return (i32.const 1)) (return (i32.const 1))
) (export "" 0))`)(), 1); ) (export "" 0))`).exports[""](), 1);
assertEq(wasmEvalText(`(module (func (result i32) assertEq(wasmEvalText(`(module (func (result i32)
(block (block
@ -197,7 +234,7 @@ assertEq(wasmEvalText(`(module (func (result i32)
(return (i32.const 1)) (return (i32.const 1))
) )
(return (i32.const 2)) (return (i32.const 2))
) (export "" 0))`)(), 1); ) (export "" 0))`).exports[""](), 1);
assertEq(wasmEvalText(`(module (func (result i32) assertEq(wasmEvalText(`(module (func (result i32)
(block $outer (block $outer
@ -208,7 +245,7 @@ assertEq(wasmEvalText(`(module (func (result i32)
(return (i32.const 1)) (return (i32.const 1))
) )
(return (i32.const 2)) (return (i32.const 2))
) (export "" 0))`)(), 1); ) (export "" 0))`).exports[""](), 1);
var notcalled = false; var notcalled = false;
var called = false; var called = false;
@ -225,7 +262,7 @@ assertEq(wasmEvalText(`(module
(call_import 0) (call_import 0)
) )
(call_import 1) (call_import 1)
) (export "" 0))`, imports)(), undefined); ) (export "" 2))`, imports).exports[""](), undefined);
assertEq(notcalled, false); assertEq(notcalled, false);
assertEq(called, true); assertEq(called, true);
@ -237,7 +274,7 @@ assertEq(wasmEvalText(`(module (func
) )
) )
(return) (return)
) (export "" 0))`)(), undefined); ) (export "" 0))`).exports[""](), undefined);
assertEq(wasmEvalText(`(module (func (result i32) assertEq(wasmEvalText(`(module (func (result i32)
(block (block
@ -248,11 +285,13 @@ assertEq(wasmEvalText(`(module (func (result i32)
) )
) )
(return (i32.const 1)) (return (i32.const 1))
) (export "" 0))`)(), 1); ) (export "" 0))`).exports[""](), 1);
assertEq(wasmEvalText('(module (func (block (br_if 0 (i32.const 1)))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (br_if 0 (i32.const 1))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block (br_if 0 (i32.const 0)))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (br_if 0 (i32.const 0))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block $l (br_if $l (i32.const 1)))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (block (br_if 0 (i32.const 1)))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block (br_if 0 (i32.const 0)))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block $l (br_if $l (i32.const 1)))) (export "" 0))').exports[""](), undefined);
var isNonZero = wasmEvalText(`(module (func (result i32) (param i32) var isNonZero = wasmEvalText(`(module (func (result i32) (param i32)
(block (block
@ -260,7 +299,7 @@ var isNonZero = wasmEvalText(`(module (func (result i32) (param i32)
(return (i32.const 0)) (return (i32.const 0))
) )
(return (i32.const 1)) (return (i32.const 1))
) (export "" 0))`); ) (export "" 0))`).exports[""];
assertEq(isNonZero(0), 0); assertEq(isNonZero(0), 0);
assertEq(isNonZero(1), 1); assertEq(isNonZero(1), 1);
@ -268,58 +307,79 @@ assertEq(isNonZero(-1), 1);
// branches with values // branches with values
// br/br_if and block // br/br_if and block
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (br 0)))'), TypeError, /popping value from empty stack/);
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (br 0 (f32.const 42))))'), TypeError, mismatchError("f32", "i32"));
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block (br 0))))'), TypeError, mismatchError("void", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block (br 0))))'), TypeError, mismatchError("void", "i32"));
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block (br 0 (f32.const 42)))))'), TypeError, mismatchError("f32", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block f32 (br 0 (f32.const 42)))))'), TypeError, mismatchError("f32", "i32"));
assertErrorMessage(() => wasmEvalText(`(module (func (result i32) (param i32) (block (if (get_local 0) (br 0 (i32.const 42))))) (export "" 0))`), TypeError, mismatchError("void", "i32")); assertErrorMessage(() => wasmEvalText(`(module (func (result i32) (param i32) (block (if i32 (get_local 0) (br 0 (i32.const 42))))) (export "" 0))`), TypeError, /if without else with a result value/);
assertErrorMessage(() => wasmEvalText(`(module (func (result i32) (param i32) (block (if (get_local 0) (br 0 (i32.const 42))) (br 0 (f32.const 42)))) (export "" 0))`), TypeError, mismatchError("f32", "i32")); assertErrorMessage(() => wasmEvalText(`(module (func (result i32) (param i32) (block i32 (if (get_local 0) (drop (i32.const 42))) (br 0 (f32.const 42)))) (export "" 0))`), TypeError, mismatchError("f32", "i32"));
assertEq(wasmEvalText('(module (func (result i32) (block (br 0 (i32.const 42)) (i32.const 13))) (export "" 0))')(), 42); assertEq(wasmEvalText('(module (func (result i32) (br 0 (i32.const 42)) (i32.const 13)) (export "" 0))').exports[""](), 42);
assertEq(wasmEvalText('(module (func (result i32) (block i32 (br 0 (i32.const 42)) (i32.const 13))) (export "" 0))').exports[""](), 42);
assertEq(wasmEvalText('(module (func) (func (block (br 0 (call 0)) (i32.const 13))) (export "" 0))')(), undefined); assertErrorMessage(() => wasmEvalText('(module (func) (func (block i32 (br 0 (call 0)) (i32.const 13))) (export "" 0))'), TypeError, /popping value from empty stack/);
assertEq(wasmEvalText('(module (func) (func (block (br_if 0 (call 0) (i32.const 1)) (i32.const 13))) (export "" 0))')(), undefined); assertErrorMessage(() => wasmEvalText('(module (func) (func (block i32 (br_if 0 (call 0) (i32.const 1)) (i32.const 13))) (export "" 0))'), TypeError, /popping value from empty stack/);
var f = wasmEvalText(`(module (func (result i32) (param i32) (block (if (get_local 0) (br 0 (i32.const 42))) (i32.const 43))) (export "" 0))`); var f = wasmEvalText(`(module (func (result i32) (param i32) (block i32 (if (get_local 0) (drop (i32.const 42))) (i32.const 43))) (export "" 0))`).exports[""];
assertEq(f(0), 43); assertEq(f(0), 43);
assertEq(f(1), 43); assertEq(f(1), 43);
var f = wasmEvalText(`(module (func (result i32) (param i32) (block (if (get_local 0) (br 1 (i32.const 42))) (i32.const 43))) (export "" 0))`); assertErrorMessage(() => wasmEvalText(`(module (func (result i32) (param i32) (block i32 (if i32 (get_local 0) (br 0 (i32.const 42))) (i32.const 43))) (export "" 0))`), TypeError, /if without else with a result value/);
var f = wasmEvalText(`(module (func (result i32) (param i32) (block i32 (if (get_local 0) (br 1 (i32.const 42))) (i32.const 43))) (export "" 0))`).exports[""];
assertEq(f(0), 43); assertEq(f(0), 43);
assertEq(f(1), 42); assertEq(f(1), 42);
var f = wasmEvalText(`(module (func (result i32) (param i32) (block (br_if 0 (i32.const 42) (get_local 0)) (i32.const 43))) (export "" 0))`); assertErrorMessage(() => wasmEvalText(`(module (func (result i32) (param i32) (block (br_if 0 (i32.const 42) (get_local 0)) (i32.const 43))) (export "" 0))`), TypeError, /unused values not explicitly dropped by end of block/);
var f = wasmEvalText(`(module (func (result i32) (param i32) (block i32 (drop (br_if 0 (i32.const 42) (get_local 0))) (i32.const 43))) (export "" 0))`).exports[""];
assertEq(f(0), 43); assertEq(f(0), 43);
assertEq(f(1), 42); assertEq(f(1), 42);
var f = wasmEvalText(`(module (func (result i32) (param i32) (block (if (get_local 0) (br 0 (i32.const 42))) (br 0 (i32.const 43)))) (export "" 0))`); var f = wasmEvalText(`(module (func (result i32) (param i32) (block i32 (if (get_local 0) (drop (i32.const 42))) (br 0 (i32.const 43)))) (export "" 0))`).exports[""];
assertEq(f(0), 43); assertEq(f(0), 43);
assertEq(f(1), 43); assertEq(f(1), 43);
var f = wasmEvalText(`(module (func (result i32) (param i32) (block (if (get_local 0) (br 1 (i32.const 42))) (br 0 (i32.const 43)))) (export "" 0))`); assertErrorMessage(() => wasmEvalText(`(module (func (result i32) (param i32) (block i32 (if i32 (get_local 0) (br 0 (i32.const 42))) (br 0 (i32.const 43)))) (export "" 0))`), TypeError, /if without else with a result value/);
var f = wasmEvalText(`(module (func (result i32) (param i32) (if (get_local 0) (br 1 (i32.const 42))) (br 0 (i32.const 43))) (export "" 0))`).exports[""];
assertEq(f(0), 43); assertEq(f(0), 43);
assertEq(f(1), 42); assertEq(f(1), 42);
var f = wasmEvalText(`(module (func (result i32) (param i32) (block (br_if 0 (i32.const 42) (get_local 0)) (br 0 (i32.const 43)))) (export "" 0))`); var f = wasmEvalText(`(module (func (result i32) (param i32) (block i32 (if (get_local 0) (br 1 (i32.const 42))) (br 0 (i32.const 43)))) (export "" 0))`).exports[""];
assertEq(f(0), 43); assertEq(f(0), 43);
assertEq(f(1), 42); assertEq(f(1), 42);
var f = wasmEvalText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block (if (get_local 0) (br 0 (i32.const 99))) (i32.const -1)))) (export "" 0))`); var f = wasmEvalText(`(module (func (result i32) (param i32) (br_if 0 (i32.const 42) (get_local 0)) (br 0 (i32.const 43))) (export "" 0))`).exports[""];
assertEq(f(0), 43);
assertEq(f(1), 42);
var f = wasmEvalText(`(module (func (result i32) (param i32) (block i32 (br_if 0 (i32.const 42) (get_local 0)) (br 0 (i32.const 43)))) (export "" 0))`).exports[""];
assertEq(f(0), 43);
assertEq(f(1), 42);
var f = wasmEvalText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block i32 (if (get_local 0) (drop (i32.const 99))) (i32.const -1)))) (export "" 0))`).exports[""];
assertEq(f(0), 0); assertEq(f(0), 0);
assertEq(f(1), 0); assertEq(f(1), 0);
var f = wasmEvalText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block (if (get_local 0) (br 1 (i32.const 99))) (i32.const -1)))) (export "" 0))`); assertErrorMessage(() => wasmEvalText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block i32 (if i32 (get_local 0) (br 0 (i32.const 99))) (i32.const -1)))) (export "" 0))`), TypeError, /if without else with a result value/);
var f = wasmEvalText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block i32 (if (get_local 0) (br 1 (i32.const 99))) (i32.const -1)))) (export "" 0))`).exports[""];
assertEq(f(0), 0); assertEq(f(0), 0);
assertEq(f(1), 100); assertEq(f(1), 100);
var f = wasmEvalText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block (br_if 0 (i32.const 99) (get_local 0)) (i32.const -1)))) (export "" 0))`); assertErrorMessage(() => wasmEvalText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block (br_if 0 (i32.const 99) (get_local 0)) (i32.const -1)))) (export "" 0))`), TypeError, /unused values not explicitly dropped by end of block/);
var f = wasmEvalText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block i32 (drop (br_if 0 (i32.const 99) (get_local 0))) (i32.const -1)))) (export "" 0))`).exports[""];
assertEq(f(0), 0); assertEq(f(0), 0);
assertEq(f(1), 100); assertEq(f(1), 100);
assertEq(wasmEvalText(`(module (func (result i32) (block (br 0 (return (i32.const 42))) (i32.const 0))) (export "" 0))`)(), 42); assertEq(wasmEvalText(`(module (func (result i32) (block i32 (br 0 (return (i32.const 42))) (i32.const 0))) (export "" 0))`).exports[""](), 42);
assertEq(wasmEvalText(`(module (func (result i32) (block (return (br 0 (i32.const 42))))) (export "" 0))`)(), 42); assertEq(wasmEvalText(`(module (func (result i32) (block i32 (return (br 0 (i32.const 42))))) (export "" 0))`).exports[""](), 42);
assertEq(wasmEvalText(`(module (func (result i32) (block (return (br 0 (i32.const 42))) (i32.const 0))) (export "" 0))`)(), 42); assertEq(wasmEvalText(`(module (func (result i32) (block i32 (return (br 0 (i32.const 42))) (i32.const 0))) (export "" 0))`).exports[""](), 42);
assertEq(wasmEvalText(`(module (func (result f32) (block (br 0 (i32.const 0))) (block (br 0 (f32.const 42)))) (export "" 0))`)(), 42); assertEq(wasmEvalText(`(module (func (result f32) (drop (block i32 (br 0 (i32.const 0)))) (block f32 (br 0 (f32.const 42)))) (export "" 0))`).exports[""](), 42);
var called = 0; var called = 0;
var imports = { var imports = {
@ -336,25 +396,27 @@ var f = wasmEvalText(`(module
(block $outer (block $outer
(if (if
(get_local 0) (get_local 0)
(br $outer (call_import 0 (i32.const 13))) (block (call_import 0 (i32.const 13)) (br $outer))
) )
(if (if
(i32.eqz (get_local 0)) (i32.eqz (get_local 0))
(br $outer (call_import 1 (i32.const 37))) (block (call_import 1 (i32.const 37)) (br $outer))
) )
) )
(i32.const 42) (i32.const 42)
) )
(export "" 0))`, imports); (export "" 2))`, imports).exports[""];
assertEq(f(0), 42); assertEq(f(0), 42);
assertEq(called, -1); assertEq(called, -1);
assertEq(f(1), 42); assertEq(f(1), 42);
assertEq(called, 0); assertEq(called, 0);
// br/br_if and loop // br/br_if and loop
assertEq(wasmEvalText(`(module (func (param i32) (result i32) (loop $out $in (br $out (get_local 0)))) (export "" 0))`)(1), 1); assertEq(wasmEvalText(`(module (func (param i32) (result i32) (loop $out $in i32 (br $out (get_local 0)))) (export "" 0))`).exports[""](1), 1);
assertEq(wasmEvalText(`(module (func (param i32) (result i32) (loop $in (br 1 (get_local 0)))) (export "" 0))`).exports[""](1), 1);
assertEq(wasmEvalText(`(module (func (param i32) (result i32) (block $out i32 (loop $in i32 (br $out (get_local 0))))) (export "" 0))`).exports[""](1), 1);
assertEq(wasmEvalText(`(module (func (param i32) (result i32) assertErrorMessage(() => wasmEvalText(`(module (func (param i32) (result i32)
(loop $out $in (loop $out $in
(if (get_local 0) (br $in (i32.const 1))) (if (get_local 0) (br $in (i32.const 1)))
(if (get_local 0) (br $in (f32.const 2))) (if (get_local 0) (br $in (f32.const 2)))
@ -362,43 +424,51 @@ assertEq(wasmEvalText(`(module (func (param i32) (result i32)
(if (get_local 0) (br $in)) (if (get_local 0) (br $in))
(i32.const 7) (i32.const 7)
) )
) (export "" 0))`)(0), 7); ) (export "" 0))`), TypeError, /unused values not explicitly dropped by end of block/);
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
(func (func
(result i32) (result i32)
(local i32) (local i32)
(loop $out $in (block $out i32
(loop $in
(set_local 0 (i32.add (get_local 0) (i32.const 1))) (set_local 0 (i32.add (get_local 0) (i32.const 1)))
(if (i32.ge_s (get_local 0) (i32.const 7)) (br $out (get_local 0))) (if (i32.ge_s (get_local 0) (i32.const 7)) (br $out (get_local 0)))
(br $in) (br $in)
) )
)
) )
(export "" 0))`)(), 7); (export "" 0))`).exports[""](), 7);
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
(func (func
(result i32) (result i32)
(local i32) (local i32)
(loop $out $in (block $out i32
(set_local 0 (i32.add (get_local 0) (i32.const 1))) (loop $in
(br_if $out (get_local 0) (i32.ge_s (get_local 0) (i32.const 7))) (set_local 0 (i32.add (get_local 0) (i32.const 1)))
(br $in) (br_if $out (get_local 0) (i32.ge_s (get_local 0) (i32.const 7)))
(br $in)
)
) )
) )
(export "" 0))`)(), 7); (export "" 0))`).exports[""](), 7);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// loop // loop
assertErrorMessage(() => wasmEvalText('(module (func (loop (br 2))))'), TypeError, DEPTH_OUT_OF_BOUNDS); assertErrorMessage(() => wasmEvalText('(module (func (loop (br 2))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertEq(wasmEvalText('(module (func (loop)) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (loop )) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (result i32) (loop (i32.const 2)) (i32.const 1)) (export "" 0))')(), 1); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (drop (loop (i32.const 2))) (i32.const 1)) (export "" 0))'), TypeError, /unused values not explicitly dropped by end of block/);
assertEq(wasmEvalText('(module (func (result i32) (loop (drop (i32.const 2))) (i32.const 1)) (export "" 0))').exports[""](), 1);
assertEq(wasmEvalText('(module (func (loop (br 1))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (loop (br 1))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (loop $a (br $a))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (loop $a (br 1))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (loop $a $b (br $a))) (export "" 0))')(), undefined); assertEq(wasmEvalText('(module (func (loop $a (br_if $a (i32.const 0)))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (loop $a $b (br $a))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (block $a (loop $b (br $a)))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (result i32) (loop i32 (i32.const 1))) (export "" 0))').exports[""](), 1);
assertEq(wasmEvalText(`(module (func (result i32) (local i32) assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(loop (loop
@ -411,7 +481,23 @@ assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(br $continue) (br $continue)
) )
(return (get_local 0)) (return (get_local 0))
) (export "" 0))`)(), 6); ) (export "" 0))`).exports[""](), 6);
assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(block
$break
(loop
$continue
(if
(i32.gt_u (get_local 0) (i32.const 5))
(br $break)
)
(set_local 0 (i32.add (get_local 0) (i32.const 1)))
(br $continue)
)
)
(return (get_local 0))
) (export "" 0))`).exports[""](), 6);
assertEq(wasmEvalText(`(module (func (result i32) (local i32) assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(loop (loop
@ -424,7 +510,23 @@ assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(br $continue) (br $continue)
) )
(return (get_local 0)) (return (get_local 0))
) (export "" 0))`)(), 6); ) (export "" 0))`).exports[""](), 6);
assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(block
$break
(loop
$continue
(br_if
$break
(i32.gt_u (get_local 0) (i32.const 5))
)
(set_local 0 (i32.add (get_local 0) (i32.const 1)))
(br $continue)
)
)
(return (get_local 0))
) (export "" 0))`).exports[""](), 6);
assertEq(wasmEvalText(`(module (func (result i32) (local i32) assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(loop (loop
@ -436,7 +538,22 @@ assertEq(wasmEvalText(`(module (func (result i32) (local i32)
) )
) )
(return (get_local 0)) (return (get_local 0))
) (export "" 0))`)(), 6); ) (export "" 0))`).exports[""](), 6);
assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(block
$break
(loop
$continue
(set_local 0 (i32.add (get_local 0) (i32.const 1)))
(br_if
$continue
(i32.le_u (get_local 0) (i32.const 5))
)
)
)
(return (get_local 0))
) (export "" 0))`).exports[""](), 6);
assertEq(wasmEvalText(`(module (func (result i32) (local i32) assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(loop (loop
@ -452,7 +569,26 @@ assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(return (i32.const 42)) (return (i32.const 42))
) )
(return (get_local 0)) (return (get_local 0))
) (export "" 0))`)(), 6); ) (export "" 0))`).exports[""](), 6);
assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(block
$break
(loop
$continue
(br_if
$break
(i32.gt_u (get_local 0) (i32.const 5))
)
(set_local 0 (i32.add (get_local 0) (i32.const 1)))
(loop
(br $continue)
)
(return (i32.const 42))
)
)
(return (get_local 0))
) (export "" 0))`).exports[""](), 6);
assertEq(wasmEvalText(`(module (func (result i32) (local i32) assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(loop (loop
@ -467,14 +603,38 @@ assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(br $break) (br $break)
) )
(return (get_local 0)) (return (get_local 0))
) (export "" 0))`)(), 6); ) (export "" 0))`).exports[""](), 6);
assertEq(wasmEvalText(`(module (func (result i32) (local i32)
(block
$break
(loop
$continue
(set_local 0 (i32.add (get_local 0) (i32.const 1)))
(loop
(br_if
$continue
(i32.le_u (get_local 0) (i32.const 5))
)
)
(br $break)
)
)
(return (get_local 0))
) (export "" 0))`).exports[""](), 6);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// br_table // br_table
assertErrorMessage(() => wasmEvalText('(module (func (br_table 0 (i32.const 0))))'), TypeError, DEPTH_OUT_OF_BOUNDS); assertErrorMessage(() => wasmEvalText('(module (func (br_table 1 (i32.const 0))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (br_table 1 0 (i32.const 0))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (br_table 0 1 (i32.const 0))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (block (br_table 2 0 (i32.const 0)))))'), TypeError, DEPTH_OUT_OF_BOUNDS); assertErrorMessage(() => wasmEvalText('(module (func (block (br_table 2 0 (i32.const 0)))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (block (br_table 0 2 (i32.const 0)))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (block (br_table 0 (f32.const 0)))))'), TypeError, mismatchError("f32", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (block (br_table 0 (f32.const 0)))))'), TypeError, mismatchError("f32", "i32"));
assertErrorMessage(() => wasmEvalText('(module (func (loop (br_table 2 0 (i32.const 0)))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (loop (br_table 0 2 (i32.const 0)))))'), TypeError, DEPTH_OUT_OF_BOUNDS);
assertErrorMessage(() => wasmEvalText('(module (func (loop (br_table 0 (f32.const 0)))))'), TypeError, mismatchError("f32", "i32"));
assertEq(wasmEvalText(`(module (func (result i32) (param i32) assertEq(wasmEvalText(`(module (func (result i32) (param i32)
(block $default (block $default
@ -482,7 +642,7 @@ assertEq(wasmEvalText(`(module (func (result i32) (param i32)
(return (i32.const 0)) (return (i32.const 0))
) )
(return (i32.const 1)) (return (i32.const 1))
) (export "" 0))`)(), 1); ) (export "" 0))`).exports[""](), 1);
assertEq(wasmEvalText(`(module (func (result i32) (param i32) assertEq(wasmEvalText(`(module (func (result i32) (param i32)
(block $default (block $default
@ -490,7 +650,7 @@ assertEq(wasmEvalText(`(module (func (result i32) (param i32)
(return (i32.const 0)) (return (i32.const 0))
) )
(return (i32.const 2)) (return (i32.const 2))
) (export "" 0))`)(), 1); ) (export "" 0))`).exports[""](), 1);
assertEq(wasmEvalText(`(module (func (result i32) (param i32) assertEq(wasmEvalText(`(module (func (result i32) (param i32)
(block $outer (block $outer
@ -501,7 +661,7 @@ assertEq(wasmEvalText(`(module (func (result i32) (param i32)
(return (i32.const 1)) (return (i32.const 1))
) )
(return (i32.const 2)) (return (i32.const 2))
) (export "" 0))`)(), 1); ) (export "" 0))`).exports[""](), 1);
var f = wasmEvalText(`(module (func (result i32) (param i32) var f = wasmEvalText(`(module (func (result i32) (param i32)
(block $0 (block $0
@ -516,7 +676,7 @@ var f = wasmEvalText(`(module (func (result i32) (param i32)
) )
) )
(return (i32.const 0)) (return (i32.const 0))
) (export "" 0))`); ) (export "" 0))`).exports[""];
assertEq(f(-2), -1); assertEq(f(-2), -1);
assertEq(f(-1), -1); assertEq(f(-1), -1);
@ -527,36 +687,36 @@ assertEq(f(3), -1);
// br_table with values // br_table with values
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block (br_table 0 (i32.const 0)))))'), TypeError, mismatchError("void", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block (br_table 0 (i32.const 0)))))'), TypeError, mismatchError("void", "i32"));
assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block (br_table 0 (f32.const 0) (i32.const 0)))))'), TypeError, mismatchError("f32", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (result i32) (block i32 (br_table 0 (f32.const 0) (i32.const 0)))))'), TypeError, mismatchError("f32", "i32"));
assertErrorMessage(() => wasmEvalText(`(module assertErrorMessage(() => wasmEvalText(`(module
(func (func
(result i32) (result i32)
(block $outer (block $outer f32
(block $inner (block $inner f32
(br_table $outer $inner (f32.const 13.37) (i32.const 1)) (br_table $outer $inner (f32.const 13.37) (i32.const 1))
) )
(br $outer (i32.const 42)) (br $outer (i32.const 42))
) )
) )
(export "" 0))`), TypeError, mismatchError("void", "i32")); (export "" 0))`), TypeError, mismatchError("i32", "f32"));
assertEq(wasmEvalText(`(module (func (result i32) (block $default (br_table $default (i32.const 42) (i32.const 1)))) (export "" 0))`)(), 42); assertEq(wasmEvalText(`(module (func (result i32) (block $default i32 (br_table $default (i32.const 42) (i32.const 1)))) (export "" 0))`).exports[""](), 42);
var f = wasmEvalText(`(module (func (param i32) (result i32) var f = wasmEvalText(`(module (func (param i32) (result i32)
(i32.add (i32.add
(block $1 (block $1 i32
(block $0 (drop (block $0 i32
(block $default (drop (block $default i32
(br_table $0 $1 $default (get_local 0) (get_local 0)) (br_table $0 $1 $default (get_local 0) (get_local 0))
) ))
(set_local 0 (i32.mul (i32.const 2) (get_local 0))) (tee_local 0 (i32.mul (i32.const 2) (get_local 0)))
) ))
(set_local 0 (i32.add (i32.const 4) (get_local 0))) (tee_local 0 (i32.add (i32.const 4) (get_local 0)))
) )
(i32.const 1) (i32.const 1)
) )
) (export "" 0))`); ) (export "" 0))`).exports[""];
assertEq(f(0), 5); assertEq(f(0), 5);
assertEq(f(1), 2); assertEq(f(1), 2);
@ -568,8 +728,8 @@ assertEq(f(4), 13);
// unreachable // unreachable
const UNREACHABLE = /unreachable/; const UNREACHABLE = /unreachable/;
assertErrorMessage(wasmEvalText(`(module (func (unreachable)) (export "" 0))`), Error, UNREACHABLE); assertErrorMessage(wasmEvalText(`(module (func (unreachable)) (export "" 0))`).exports[""], Error, UNREACHABLE);
assertErrorMessage(wasmEvalText(`(module (func (if (unreachable) (i32.const 0))) (export "" 0))`), Error, UNREACHABLE); assertErrorMessage(wasmEvalText(`(module (func (if (unreachable) (i32.const 0))) (export "" 0))`).exports[""], Error, UNREACHABLE);
assertErrorMessage(wasmEvalText(`(module (func (block (br_if 0 (unreachable)))) (export "" 0))`), Error, UNREACHABLE); assertErrorMessage(wasmEvalText(`(module (func (block (br_if 0 (unreachable)))) (export "" 0))`).exports[""], Error, UNREACHABLE);
assertErrorMessage(wasmEvalText(`(module (func (block (br_table 0 (unreachable)))) (export "" 0))`), Error, UNREACHABLE); assertErrorMessage(wasmEvalText(`(module (func (block (br_table 0 (unreachable)))) (export "" 0))`).exports[""], Error, UNREACHABLE);
assertErrorMessage(wasmEvalText(`(module (func (result i32) (i32.add (i32.const 0) (unreachable))) (export "" 0))`), Error, UNREACHABLE); assertErrorMessage(wasmEvalText(`(module (func (result i32) (i32.add (i32.const 0) (unreachable))) (export "" 0))`).exports[""], Error, UNREACHABLE);

Просмотреть файл

@ -6,21 +6,21 @@ function testConversion(resultType, opcode, paramType, op, expect) {
// i64 cannot be imported, so we use a wrapper function. // i64 cannot be imported, so we use a wrapper function.
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
(func (param i64) (result ${resultType}) (${resultType}.${opcode}/i64 (get_local 0))) (func (param i64) (result ${resultType}) (${resultType}.${opcode}/i64 (get_local 0)))
(export "" 0))`)(createI64(op)), expect); (export "" 0))`).exports[""](createI64(op)), expect);
// The same, but now the input is a constant. // The same, but now the input is a constant.
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
(func (result ${resultType}) (${resultType}.${opcode}/i64 (i64.const ${op}))) (func (result ${resultType}) (${resultType}.${opcode}/i64 (i64.const ${op})))
(export "" 0))`)(), expect); (export "" 0))`).exports[""](), expect);
} else if (resultType === 'i64') { } else if (resultType === 'i64') {
assertEqI64(wasmEvalText(`(module assertEqI64(wasmEvalText(`(module
(func (param ${paramType}) (result i64) (i64.${opcode}/${paramType} (get_local 0))) (func (param ${paramType}) (result i64) (i64.${opcode}/${paramType} (get_local 0)))
(export "" 0))`)(op), createI64(expect)); (export "" 0))`).exports[""](op), createI64(expect));
// The same, but now the input is a constant. // The same, but now the input is a constant.
assertEqI64(wasmEvalText(`(module assertEqI64(wasmEvalText(`(module
(func (result i64) (i64.${opcode}/${paramType} (${paramType}.const ${op}))) (func (result i64) (i64.${opcode}/${paramType} (${paramType}.const ${op})))
(export "" 0))`)(), createI64(expect)); (export "" 0))`).exports[""](), createI64(expect));
} else { } else {
assertEq(wasmEvalText('(module (func (param ' + paramType + ') (result ' + resultType + ') (' + resultType + '.' + opcode + '/' + paramType + ' (get_local 0))) (export "" 0))')(op), expect); assertEq(wasmEvalText('(module (func (param ' + paramType + ') (result ' + resultType + ') (' + resultType + '.' + opcode + '/' + paramType + ' (get_local 0))) (export "" 0))').exports[""](op), expect);
} }
let formerTestMode = getJitCompilerOptions()['wasm.test-mode']; let formerTestMode = getJitCompilerOptions()['wasm.test-mode'];
@ -53,7 +53,7 @@ function testTrap(resultType, opcode, paramType, op, expect) {
(${resultType}.${opcode}/${paramType} (get_local 0)) (${resultType}.${opcode}/${paramType} (get_local 0))
) )
(export "" 0) (export "" 0)
)`); )`).exports[""];
let expectedError = op === 'nan' ? /invalid conversion to integer/ : /integer overflow/; let expectedError = op === 'nan' ? /invalid conversion to integer/ : /integer overflow/;
@ -271,5 +271,5 @@ testConversion('f32', 'demote', 'f64', 40.1, 40.099998474121094);
testConversion('f64', 'promote', 'f32', 40.1, 40.099998474121094); testConversion('f64', 'promote', 'f32', 40.1, 40.099998474121094);
// Non-canonical NaNs. // Non-canonical NaNs.
assertEq(wasmEvalText('(module (func (result i32) (i32.reinterpret/f32 (f32.demote/f64 (f64.const -nan:0x4444444444444)))) (export "" 0))')(), -0x1dddde); assertEq(wasmEvalText('(module (func (result i32) (i32.reinterpret/f32 (f32.demote/f64 (f64.const -nan:0x4444444444444)))) (export "" 0))').exports[""](), -0x1dddde);
assertEq(wasmEvalText('(module (func (result i32) (local i64) (set_local 0 (i64.reinterpret/f64 (f64.promote/f32 (f32.const -nan:0x222222)))) (i32.xor (i32.wrap/i64 (get_local 0)) (i32.wrap/i64 (i64.shr_u (get_local 0) (i64.const 32))))) (export "" 0))')(), -0x4003bbbc); assertEq(wasmEvalText('(module (func (result i32) (local i64) (set_local 0 (i64.reinterpret/f64 (f64.promote/f32 (f32.const -nan:0x222222)))) (i32.xor (i32.wrap/i64 (get_local 0)) (i32.wrap/i64 (i64.shr_u (get_local 0) (i64.const 32))))) (export "" 0))').exports[""](), -0x4003bbbc);

Просмотреть файл

@ -4,8 +4,8 @@ const Module = WebAssembly.Module;
// Create cross-compartment wrappers to typed arrays and array buffers. // Create cross-compartment wrappers to typed arrays and array buffers.
var g = newGlobal(); var g = newGlobal();
var code1 = g.eval("wasmTextToBinary('(module)', 'new-format')"); var code1 = g.eval("wasmTextToBinary('(module)')");
var code2 = g.eval("wasmTextToBinary('(module)', 'new-format').buffer"); var code2 = g.eval("wasmTextToBinary('(module)').buffer");
// Should get unwrapped. // Should get unwrapped.
assertEq(new Module(code1) instanceof Module, true); assertEq(new Module(code1) instanceof Module, true);

Просмотреть файл

@ -19,4 +19,4 @@ assertEq(wasmEvalText(`(module
) )
(export "" 0) (export "" 0)
)`)(10), 3628800); )`).exports[""](10), 3628800);

Просмотреть файл

@ -1,29 +1,29 @@
// |jit-test| test-also-wasm-baseline // |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js"); load(libdir + "wasm.js");
assertEq(wasmEvalText('(module (func (result f32) (f32.const -1)) (export "" 0))')(), -1); assertEq(wasmEvalText('(module (func (result f32) (f32.const -1)) (export "" 0))').exports[""](), -1);
assertEq(wasmEvalText('(module (func (result f32) (f32.const 1)) (export "" 0))')(), 1); assertEq(wasmEvalText('(module (func (result f32) (f32.const 1)) (export "" 0))').exports[""](), 1);
assertEq(wasmEvalText('(module (func (result f64) (f64.const -2)) (export "" 0))')(), -2); assertEq(wasmEvalText('(module (func (result f64) (f64.const -2)) (export "" 0))').exports[""](), -2);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 2)) (export "" 0))')(), 2); assertEq(wasmEvalText('(module (func (result f64) (f64.const 2)) (export "" 0))').exports[""](), 2);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 4294967296)) (export "" 0))')(), 4294967296); assertEq(wasmEvalText('(module (func (result f64) (f64.const 4294967296)) (export "" 0))').exports[""](), 4294967296);
assertEq(wasmEvalText('(module (func (result f32) (f32.const 1.5)) (export "" 0))')(), 1.5); assertEq(wasmEvalText('(module (func (result f32) (f32.const 1.5)) (export "" 0))').exports[""](), 1.5);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 2.5)) (export "" 0))')(), 2.5); assertEq(wasmEvalText('(module (func (result f64) (f64.const 2.5)) (export "" 0))').exports[""](), 2.5);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 10e2)) (export "" 0))')(), 10e2); assertEq(wasmEvalText('(module (func (result f64) (f64.const 10e2)) (export "" 0))').exports[""](), 10e2);
assertEq(wasmEvalText('(module (func (result f32) (f32.const 10e2)) (export "" 0))')(), 10e2); assertEq(wasmEvalText('(module (func (result f32) (f32.const 10e2)) (export "" 0))').exports[""](), 10e2);
assertEq(wasmEvalText('(module (func (result f64) (f64.const -0x8000000000000000)) (export "" 0))')(), -0x8000000000000000); assertEq(wasmEvalText('(module (func (result f64) (f64.const -0x8000000000000000)) (export "" 0))').exports[""](), -0x8000000000000000);
assertEq(wasmEvalText('(module (func (result f64) (f64.const -9223372036854775808)) (export "" 0))')(), -9223372036854775808); assertEq(wasmEvalText('(module (func (result f64) (f64.const -9223372036854775808)) (export "" 0))').exports[""](), -9223372036854775808);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 1797693134862315708145274e284)) (export "" 0))')(), 1797693134862315708145274e284); assertEq(wasmEvalText('(module (func (result f64) (f64.const 1797693134862315708145274e284)) (export "" 0))').exports[""](), 1797693134862315708145274e284);
function testUnary(type, opcode, op, expect) { function testUnary(type, opcode, op, expect) {
assertEq(wasmEvalText('(module (func (param ' + type + ') (result ' + type + ') (' + type + '.' + opcode + ' (get_local 0))) (export "" 0))')(op), expect); assertEq(wasmEvalText('(module (func (param ' + type + ') (result ' + type + ') (' + type + '.' + opcode + ' (get_local 0))) (export "" 0))').exports[""](op), expect);
} }
function testBinary(type, opcode, lhs, rhs, expect) { function testBinary(type, opcode, lhs, rhs, expect) {
assertEq(wasmEvalText('(module (func (param ' + type + ') (param ' + type + ') (result ' + type + ') (' + type + '.' + opcode + ' (get_local 0) (get_local 1))) (export "" 0))')(lhs, rhs), expect); assertEq(wasmEvalText('(module (func (param ' + type + ') (param ' + type + ') (result ' + type + ') (' + type + '.' + opcode + ' (get_local 0) (get_local 1))) (export "" 0))').exports[""](lhs, rhs), expect);
} }
function testComparison(type, opcode, lhs, rhs, expect) { function testComparison(type, opcode, lhs, rhs, expect) {
assertEq(wasmEvalText('(module (func (param ' + type + ') (param ' + type + ') (result i32) (' + type + '.' + opcode + ' (get_local 0) (get_local 1))) (export "" 0))')(lhs, rhs), expect); assertEq(wasmEvalText('(module (func (param ' + type + ') (param ' + type + ') (result i32) (' + type + '.' + opcode + ' (get_local 0) (get_local 1))) (export "" 0))').exports[""](lhs, rhs), expect);
} }
testUnary('f32', 'abs', -40, 40); testUnary('f32', 'abs', -40, 40);
@ -78,7 +78,7 @@ assertErrorMessage(() => wasmEvalText('(module (func (param i32) (result i32) (f
assertErrorMessage(() => wasmEvalText('(module (func (param i32) (result f64) (f64.sqrt (get_local 0))))'), TypeError, mismatchError("i32", "f64")); assertErrorMessage(() => wasmEvalText('(module (func (param i32) (result f64) (f64.sqrt (get_local 0))))'), TypeError, mismatchError("i32", "f64"));
assertErrorMessage(() => wasmEvalText('(module (func (param f64) (result i32) (f64.sqrt (get_local 0))))'), TypeError, mismatchError("f64", "i32")); assertErrorMessage(() => wasmEvalText('(module (func (param f64) (result i32) (f64.sqrt (get_local 0))))'), TypeError, mismatchError("f64", "i32"));
assertErrorMessage(() => wasmEvalText('(module (func (param i32) (result i32) (f64.sqrt (get_local 0))))'), TypeError, mismatchError("i32", "f64")); assertErrorMessage(() => wasmEvalText('(module (func (param i32) (result i32) (f64.sqrt (get_local 0))))'), TypeError, mismatchError("i32", "f64"));
assertErrorMessage(() => wasmEvalText('(module (func (f32.sqrt (nop))))'), TypeError, mismatchError("void", "f32")); assertErrorMessage(() => wasmEvalText('(module (func (f32.sqrt (nop))))'), TypeError, /popping value from empty stack/);
assertErrorMessage(() => wasmEvalText('(module (func (param i32) (param f32) (result f32) (f32.add (get_local 0) (get_local 1))))'), TypeError, mismatchError("i32", "f32")); assertErrorMessage(() => wasmEvalText('(module (func (param i32) (param f32) (result f32) (f32.add (get_local 0) (get_local 1))))'), TypeError, mismatchError("i32", "f32"));
assertErrorMessage(() => wasmEvalText('(module (func (param f32) (param i32) (result f32) (f32.add (get_local 0) (get_local 1))))'), TypeError, mismatchError("i32", "f32")); assertErrorMessage(() => wasmEvalText('(module (func (param f32) (param i32) (result f32) (f32.add (get_local 0) (get_local 1))))'), TypeError, mismatchError("i32", "f32"));
@ -97,9 +97,9 @@ assertErrorMessage(() => wasmEvalText('(module (func (param f64) (param i32) (re
assertErrorMessage(() => wasmEvalText('(module (func (param f64) (param f64) (result f64) (f64.eq (get_local 0) (get_local 1))))'), TypeError, mismatchError("i32", "f64")); assertErrorMessage(() => wasmEvalText('(module (func (param f64) (param f64) (result f64) (f64.eq (get_local 0) (get_local 1))))'), TypeError, mismatchError("i32", "f64"));
// Non-canonical NaNs. // Non-canonical NaNs.
assertEq(wasmEvalText('(module (func (result i32) (i32.reinterpret/f32 (f32.mul (f32.const 0.0) (f32.const -nan:0x222222)))) (export "" 0))')(), -0x1dddde); assertEq(wasmEvalText('(module (func (result i32) (i32.reinterpret/f32 (f32.mul (f32.const 0.0) (f32.const -nan:0x222222)))) (export "" 0))').exports[""](), -0x1dddde);
assertEq(wasmEvalText('(module (func (result i32) (i32.reinterpret/f32 (f32.min (f32.const 0.0) (f32.const -nan:0x222222)))) (export "" 0))')(), -0x1dddde); assertEq(wasmEvalText('(module (func (result i32) (i32.reinterpret/f32 (f32.min (f32.const 0.0) (f32.const -nan:0x222222)))) (export "" 0))').exports[""](), -0x1dddde);
assertEq(wasmEvalText('(module (func (result i32) (i32.reinterpret/f32 (f32.max (f32.const 0.0) (f32.const -nan:0x222222)))) (export "" 0))')(), -0x1dddde); assertEq(wasmEvalText('(module (func (result i32) (i32.reinterpret/f32 (f32.max (f32.const 0.0) (f32.const -nan:0x222222)))) (export "" 0))').exports[""](), -0x1dddde);
assertEq(wasmEvalText('(module (func (result i32) (local i64) (set_local 0 (i64.reinterpret/f64 (f64.mul (f64.const 0.0) (f64.const -nan:0x4444444444444)))) (i32.xor (i32.wrap/i64 (get_local 0)) (i32.wrap/i64 (i64.shr_u (get_local 0) (i64.const 32))))) (export "" 0))')(), -0x44480000); assertEq(wasmEvalText('(module (func (result i32) (local i64) (set_local 0 (i64.reinterpret/f64 (f64.mul (f64.const 0.0) (f64.const -nan:0x4444444444444)))) (i32.xor (i32.wrap/i64 (get_local 0)) (i32.wrap/i64 (i64.shr_u (get_local 0) (i64.const 32))))) (export "" 0))').exports[""](), -0x44480000);
assertEq(wasmEvalText('(module (func (result i32) (local i64) (set_local 0 (i64.reinterpret/f64 (f64.min (f64.const 0.0) (f64.const -nan:0x4444444444444)))) (i32.xor (i32.wrap/i64 (get_local 0)) (i32.wrap/i64 (i64.shr_u (get_local 0) (i64.const 32))))) (export "" 0))')(), -0x44480000); assertEq(wasmEvalText('(module (func (result i32) (local i64) (set_local 0 (i64.reinterpret/f64 (f64.min (f64.const 0.0) (f64.const -nan:0x4444444444444)))) (i32.xor (i32.wrap/i64 (get_local 0)) (i32.wrap/i64 (i64.shr_u (get_local 0) (i64.const 32))))) (export "" 0))').exports[""](), -0x44480000);
assertEq(wasmEvalText('(module (func (result i32) (local i64) (set_local 0 (i64.reinterpret/f64 (f64.max (f64.const 0.0) (f64.const -nan:0x4444444444444)))) (i32.xor (i32.wrap/i64 (get_local 0)) (i32.wrap/i64 (i64.shr_u (get_local 0) (i64.const 32))))) (export "" 0))')(), -0x44480000); assertEq(wasmEvalText('(module (func (result i32) (local i64) (set_local 0 (i64.reinterpret/f64 (f64.max (f64.const 0.0) (f64.const -nan:0x4444444444444)))) (i32.xor (i32.wrap/i64 (get_local 0)) (i32.wrap/i64 (i64.shr_u (get_local 0) (i64.const 32))))) (export "" 0))').exports[""](), -0x44480000);

Просмотреть файл

@ -4,22 +4,22 @@ load(libdir + "wasm.js");
const { Instance, Module } = WebAssembly; const { Instance, Module } = WebAssembly;
// Locally-defined globals // Locally-defined globals
assertErrorMessage(() => evalText(`(module (global))`), SyntaxError, /parsing/); assertErrorMessage(() => wasmEvalText(`(module (global))`), SyntaxError, /parsing/);
assertErrorMessage(() => evalText(`(module (global i32))`), SyntaxError, /parsing/); assertErrorMessage(() => wasmEvalText(`(module (global i32))`), SyntaxError, /parsing/);
assertErrorMessage(() => evalText(`(module (global i32 immutable))`), SyntaxError, /parsing/); assertErrorMessage(() => wasmEvalText(`(module (global i32 immutable))`), SyntaxError, /parsing/);
// Initializer expressions. // Initializer expressions.
assertErrorMessage(() => evalText(`(module (global i32 (f32.const 13.37)))`), TypeError, /type mismatch/); assertErrorMessage(() => wasmEvalText(`(module (global i32 (f32.const 13.37)))`), TypeError, /type mismatch/);
assertErrorMessage(() => evalText(`(module (global f64 (f32.const 13.37)))`), TypeError, /type mismatch/); assertErrorMessage(() => wasmEvalText(`(module (global f64 (f32.const 13.37)))`), TypeError, /type mismatch/);
assertErrorMessage(() => evalText(`(module (global i32 (i32.add (i32.const 13) (i32.const 37))))`), TypeError, /failed to read end/); assertErrorMessage(() => wasmEvalText(`(module (global i32 (i32.add (i32.const 13) (i32.const 37))))`), TypeError, /failed to read end/);
assertErrorMessage(() => evalText(`(module (global i32 (get_global 0)))`), TypeError, /out of range/); assertErrorMessage(() => wasmEvalText(`(module (global i32 (get_global 0)))`), TypeError, /out of range/);
assertErrorMessage(() => evalText(`(module (global i32 (get_global 1)) (global i32 immutable (i32.const 1)))`), TypeError, /out of range/); assertErrorMessage(() => wasmEvalText(`(module (global i32 (get_global 1)) (global i32 immutable (i32.const 1)))`), TypeError, /out of range/);
// Test a well-defined global section. // Test a well-defined global section.
function testInner(type, initialValue, nextValue, coercion, assertFunc = assertEq) function testInner(type, initialValue, nextValue, coercion, assertFunc = assertEq)
{ {
var module = evalText(`(module var module = wasmEvalText(`(module
(global ${type} (${type}.const ${initialValue})) (global ${type} (${type}.const ${initialValue}))
(global ${type} immutable (${type}.const ${initialValue})) (global ${type} immutable (${type}.const ${initialValue}))
@ -46,8 +46,8 @@ testInner('f32', 13.37, 0.1989, Math.fround);
testInner('f64', 13.37, 0.1989, x => +x); testInner('f64', 13.37, 0.1989, x => +x);
// Semantic errors. // Semantic errors.
assertErrorMessage(() => evalText(`(module (global i32 (i32.const 1337)) (func (set_global 1 (i32.const 0))))`), TypeError, /out of range/); assertErrorMessage(() => wasmEvalText(`(module (global i32 (i32.const 1337)) (func (set_global 1 (i32.const 0))))`), TypeError, /out of range/);
assertErrorMessage(() => evalText(`(module (global i32 immutable (i32.const 1337)) (func (set_global 0 (i32.const 0))))`), TypeError, /can't write an immutable global/); assertErrorMessage(() => wasmEvalText(`(module (global i32 immutable (i32.const 1337)) (func (set_global 0 (i32.const 0))))`), TypeError, /can't write an immutable global/);
// Big module with many variables: test that setting one doesn't overwrite the // Big module with many variables: test that setting one doesn't overwrite the
// other ones. // other ones.
@ -57,7 +57,7 @@ function get_set(i, type) { return `
` `
} }
var module = evalText(`(module var module = wasmEvalText(`(module
(global i32 (i32.const 42)) (global i32 (i32.const 42))
(global i32 (i32.const 10)) (global i32 (i32.const 10))
(global f32 (f32.const 13.37)) (global f32 (f32.const 13.37))
@ -93,9 +93,9 @@ for (let i = 0; i < 5; i++) {
} }
// Initializer expressions can also be used in elem section initializers. // Initializer expressions can also be used in elem section initializers.
assertErrorMessage(() => evalText(`(module (import "globals" "a" (global f32 immutable)) (table (resizable 4)) (elem (get_global 0) $f) (func $f))`), TypeError, /type mismatch/); assertErrorMessage(() => wasmEvalText(`(module (import "globals" "a" (global f32 immutable)) (table (resizable 4)) (elem (get_global 0) $f) (func $f))`), TypeError, /type mismatch/);
module = evalText(`(module module = wasmEvalText(`(module
(import "globals" "a" (global i32 immutable)) (import "globals" "a" (global i32 immutable))
(table (resizable 4)) (table (resizable 4))
(elem (get_global 0) $f) (elem (get_global 0) $f)
@ -110,11 +110,11 @@ module = evalText(`(module
assertEq(module.f, module.tbl.get(1)); assertEq(module.f, module.tbl.get(1));
// Import/export rules. // Import/export rules.
assertErrorMessage(() => evalText(`(module (import "globals" "x" (global i32)))`), TypeError, /can't import.* mutable globals in the MVP/); assertErrorMessage(() => wasmEvalText(`(module (import "globals" "x" (global i32)))`), TypeError, /can't import.* mutable globals in the MVP/);
assertErrorMessage(() => evalText(`(module (global i32 (i32.const 42)) (export "" global 0))`), TypeError, /can't .*export mutable globals in the MVP/); assertErrorMessage(() => wasmEvalText(`(module (global i32 (i32.const 42)) (export "" global 0))`), TypeError, /can't .*export mutable globals in the MVP/);
// Import/export semantics. // Import/export semantics.
module = evalText(`(module module = wasmEvalText(`(module
(import $g "globals" "x" (global i32 immutable)) (import $g "globals" "x" (global i32 immutable))
(func $get (result i32) (get_global $g)) (func $get (result i32) (get_global $g))
(export "getter" $get) (export "getter" $get)
@ -125,7 +125,7 @@ assertEq(module.getter(), 42);
assertEq(module.value, 42); assertEq(module.value, 42);
// Imported globals and locally defined globals use the same index space. // Imported globals and locally defined globals use the same index space.
module = evalText(`(module module = wasmEvalText(`(module
(import "globals" "x" (global i32 immutable)) (import "globals" "x" (global i32 immutable))
(global i32 immutable (i32.const 1337)) (global i32 immutable (i32.const 1337))
(export "imported" global 0) (export "imported" global 0)
@ -136,14 +136,14 @@ assertEq(module.imported, 42);
assertEq(module.defined, 1337); assertEq(module.defined, 1337);
// Initializer expressions can reference an imported immutable global. // Initializer expressions can reference an imported immutable global.
assertErrorMessage(() => evalText(`(module (global f32 immutable (f32.const 13.37)) (global i32 (get_global 0)))`), TypeError, /must reference a global immutable import/); assertErrorMessage(() => wasmEvalText(`(module (global f32 immutable (f32.const 13.37)) (global i32 (get_global 0)))`), TypeError, /must reference a global immutable import/);
assertErrorMessage(() => evalText(`(module (global f32 (f32.const 13.37)) (global i32 (get_global 0)))`), TypeError, /must reference a global immutable import/); assertErrorMessage(() => wasmEvalText(`(module (global f32 (f32.const 13.37)) (global i32 (get_global 0)))`), TypeError, /must reference a global immutable import/);
assertErrorMessage(() => evalText(`(module (global i32 (i32.const 0)) (global i32 (get_global 0)))`), TypeError, /must reference a global immutable import/); assertErrorMessage(() => wasmEvalText(`(module (global i32 (i32.const 0)) (global i32 (get_global 0)))`), TypeError, /must reference a global immutable import/);
assertErrorMessage(() => evalText(`(module (import "globals" "a" (global f32 immutable)) (global i32 (get_global 0)))`), TypeError, /type mismatch/); assertErrorMessage(() => wasmEvalText(`(module (import "globals" "a" (global f32 immutable)) (global i32 (get_global 0)))`), TypeError, /type mismatch/);
function testInitExpr(type, initialValue, nextValue, coercion, assertFunc = assertEq) { function testInitExpr(type, initialValue, nextValue, coercion, assertFunc = assertEq) {
var module = evalText(`(module var module = wasmEvalText(`(module
(import "globals" "a" (global ${type} immutable)) (import "globals" "a" (global ${type} immutable))
(global ${type} (get_global 0)) (global ${type} (get_global 0))
@ -183,14 +183,14 @@ testInitExpr('f64', 13.37, 0.1989, x => +x);
// Int64. // Int64.
{ {
assertErrorMessage(() => evalText(`(module (import "globals" "x" (global i64 immutable)))`), TypeError, /can't import.* an Int64 global/); assertErrorMessage(() => wasmEvalText(`(module (import "globals" "x" (global i64 immutable)))`), TypeError, /can't import.* an Int64 global/);
assertErrorMessage(() => evalText(`(module (global i64 immutable (i64.const 42)) (export "" global 0))`), TypeError, /can't .*export an Int64 global/); assertErrorMessage(() => wasmEvalText(`(module (global i64 immutable (i64.const 42)) (export "" global 0))`), TypeError, /can't .*export an Int64 global/);
setJitCompilerOption('wasm.test-mode', 1); setJitCompilerOption('wasm.test-mode', 1);
testInner('i64', '0x531642753864975F', '0x123456789abcdef0', createI64, assertEqI64); testInner('i64', '0x531642753864975F', '0x123456789abcdef0', createI64, assertEqI64);
testInitExpr('i64', '0x531642753864975F', '0x123456789abcdef0', createI64, assertEqI64); testInitExpr('i64', '0x531642753864975F', '0x123456789abcdef0', createI64, assertEqI64);
module = evalText(`(module module = wasmEvalText(`(module
(import "globals" "x" (global i64 immutable)) (import "globals" "x" (global i64 immutable))
(global i64 immutable (i64.const 0xFAFADADABABA)) (global i64 immutable (i64.const 0xFAFADADABABA))
(export "imported" global 0) (export "imported" global 0)

Просмотреть файл

@ -4,11 +4,11 @@ load(libdir + "wasm.js");
function linearModule(min, max, ops) { function linearModule(min, max, ops) {
var opsText = ops.map(function (op) { var opsText = ops.map(function (op) {
if (op[0] == "CM") { if (op[0] == "CM") {
res = `(if (i32.ne (current_memory) (i32.const ${op[1]})) res = `(if i32 (i32.ne (current_memory) (i32.const ${op[1]}))
(i32.load offset=10 (i32.const 4294967295)) (i32.load offset=10 (i32.const 4294967295))
(i32.const 0))` (i32.const 0))`
} else if (op[0] == "GM") { } else if (op[0] == "GM") {
res = `(if (i32.ne (grow_memory (i32.const ${op[1]})) (i32.const ${op[2]})) res = `(if i32 (i32.ne (grow_memory (i32.const ${op[1]})) (i32.const ${op[2]}))
(i32.load offset=10 (i32.const 4294967295)) (i32.load offset=10 (i32.const 4294967295))
(i32.const 0))` (i32.const 0))`
} else if (op[0] == "L") { } else if (op[0] == "L") {
@ -31,15 +31,15 @@ function linearModule(min, max, ops) {
text = text =
`(module `(module
(memory ${min} ${max}` + (memory ${min} ${max})
(min != 0 ? `(segment 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f") ` + (min != 0 ? `(data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(segment 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")` (data (i32.const 16) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")`
: "") + : "") +
`) `
(func (result i32) (func (result i32)
` + opsText + ` (drop ` + opsText + `)
(current_memory) (current_memory)
) (export "" 0))` ) (export "" 0))`;
return wasmEvalText(text); return wasmEvalText(text);
} }
@ -49,4 +49,4 @@ function assertOOB(lambda) {
} }
// Just grow some memory // Just grow some memory
assertEq(linearModule(3,5, [["CM", 3]])(), 3); assertEq(linearModule(3,5, [["CM", 3]]).exports[""](), 3);

Просмотреть файл

@ -1,6 +1,5 @@
// |jit-test| test-also-wasm-baseline // |jit-test| test-also-wasm-baseline
load(libdir + 'wasm.js'); load(libdir + 'wasm.js');
load(libdir + 'asserts.js');
const Module = WebAssembly.Module; const Module = WebAssembly.Module;
const Instance = WebAssembly.Instance; const Instance = WebAssembly.Instance;
@ -24,7 +23,7 @@ const tab4Elem = new Table({initial:4, element:"anyfunc"});
assertErrorMessage(() => new Memory({initial:2, maximum:1}), RangeError, /bad Memory maximum size/); assertErrorMessage(() => new Memory({initial:2, maximum:1}), RangeError, /bad Memory maximum size/);
const m1 = new Module(textToBinary('(module (import "foo" "bar") (import "baz" "quux"))')); const m1 = new Module(wasmTextToBinary('(module (import "foo" "bar") (import "baz" "quux"))'));
assertErrorMessage(() => new Instance(m1), TypeError, /no import object given/); assertErrorMessage(() => new Instance(m1), TypeError, /no import object given/);
assertErrorMessage(() => new Instance(m1, {foo:null}), TypeError, /import object field is not an Object/); assertErrorMessage(() => new Instance(m1, {foo:null}), TypeError, /import object field is not an Object/);
assertErrorMessage(() => new Instance(m1, {foo:{bar:{}}}), TypeError, /import object field is not a Function/); assertErrorMessage(() => new Instance(m1, {foo:{bar:{}}}), TypeError, /import object field is not a Function/);
@ -32,7 +31,7 @@ assertErrorMessage(() => new Instance(m1, {foo:{bar:()=>{}}, baz:null}), TypeErr
assertErrorMessage(() => new Instance(m1, {foo:{bar:()=>{}}, baz:{}}), TypeError, /import object field is not a Function/); assertErrorMessage(() => new Instance(m1, {foo:{bar:()=>{}}, baz:{}}), TypeError, /import object field is not a Function/);
assertEq(new Instance(m1, {foo:{bar:()=>{}}, baz:{quux:()=>{}}}) instanceof Instance, true); assertEq(new Instance(m1, {foo:{bar:()=>{}}, baz:{quux:()=>{}}}) instanceof Instance, true);
const m2 = new Module(textToBinary('(module (import "x" "y" (memory 2 3)))')); const m2 = new Module(wasmTextToBinary('(module (import "x" "y" (memory 2 3)))'));
assertErrorMessage(() => new Instance(m2), TypeError, /no import object given/); assertErrorMessage(() => new Instance(m2), TypeError, /no import object given/);
assertErrorMessage(() => new Instance(m2, {x:null}), TypeError, /import object field is not an Object/); assertErrorMessage(() => new Instance(m2, {x:null}), TypeError, /import object field is not an Object/);
assertErrorMessage(() => new Instance(m2, {x:{y:{}}}), TypeError, /import object field is not a Memory/); assertErrorMessage(() => new Instance(m2, {x:{y:{}}}), TypeError, /import object field is not a Memory/);
@ -47,7 +46,7 @@ assertEq(new Instance(m2, {x:{y:mem3PageMax3}}) instanceof Instance, true);
assertEq(new Instance(m2, {x:{y:mem2PageMax3}}) instanceof Instance, true); assertEq(new Instance(m2, {x:{y:mem2PageMax3}}) instanceof Instance, true);
assertErrorMessage(() => new Instance(m2, {x:{y:mem2PageMax4}}), TypeError, /imported Memory with incompatible maximum size/); assertErrorMessage(() => new Instance(m2, {x:{y:mem2PageMax4}}), TypeError, /imported Memory with incompatible maximum size/);
const m3 = new Module(textToBinary('(module (import "foo" "bar" (memory 1 1)) (import "baz" "quux"))')); const m3 = new Module(wasmTextToBinary('(module (import "foo" "bar" (memory 1 1)) (import "baz" "quux"))'));
assertErrorMessage(() => new Instance(m3), TypeError, /no import object given/); assertErrorMessage(() => new Instance(m3), TypeError, /no import object given/);
assertErrorMessage(() => new Instance(m3, {foo:null}), TypeError, /import object field is not an Object/); assertErrorMessage(() => new Instance(m3, {foo:null}), TypeError, /import object field is not an Object/);
assertErrorMessage(() => new Instance(m3, {foo:{bar:{}}}), TypeError, /import object field is not a Memory/); assertErrorMessage(() => new Instance(m3, {foo:{bar:{}}}), TypeError, /import object field is not a Memory/);
@ -56,7 +55,7 @@ assertErrorMessage(() => new Instance(m3, {foo:{bar:mem1Page}, baz:{quux:mem1Pag
assertErrorMessage(() => new Instance(m3, {foo:{bar:mem1Page}, baz:{quux:()=>{}}}), TypeError, /imported Memory with incompatible maximum size/); assertErrorMessage(() => new Instance(m3, {foo:{bar:mem1Page}, baz:{quux:()=>{}}}), TypeError, /imported Memory with incompatible maximum size/);
assertEq(new Instance(m3, {foo:{bar:mem1PageMax1}, baz:{quux:()=>{}}}) instanceof Instance, true); assertEq(new Instance(m3, {foo:{bar:mem1PageMax1}, baz:{quux:()=>{}}}) instanceof Instance, true);
const m4 = new Module(textToBinary('(module (import "baz" "quux") (import "foo" "bar" (memory 1 1)))')); const m4 = new Module(wasmTextToBinary('(module (import "baz" "quux") (import "foo" "bar" (memory 1 1)))'));
assertErrorMessage(() => new Instance(m4), TypeError, /no import object given/); assertErrorMessage(() => new Instance(m4), TypeError, /no import object given/);
assertErrorMessage(() => new Instance(m4, {baz:null}), TypeError, /import object field is not an Object/); assertErrorMessage(() => new Instance(m4, {baz:null}), TypeError, /import object field is not an Object/);
assertErrorMessage(() => new Instance(m4, {baz:{quux:{}}}), TypeError, /import object field is not a Function/); assertErrorMessage(() => new Instance(m4, {baz:{quux:{}}}), TypeError, /import object field is not a Function/);
@ -65,34 +64,34 @@ assertErrorMessage(() => new Instance(m4, {baz:{quux:()=>{}}, foo:{bar:()=>{}}})
assertErrorMessage(() => new Instance(m4, {baz:{quux:()=>{}}, foo:{bar:mem1Page}}), TypeError, /imported Memory with incompatible maximum size/); assertErrorMessage(() => new Instance(m4, {baz:{quux:()=>{}}, foo:{bar:mem1Page}}), TypeError, /imported Memory with incompatible maximum size/);
assertEq(new Instance(m3, {baz:{quux:()=>{}}, foo:{bar:mem1PageMax1}}) instanceof Instance, true); assertEq(new Instance(m3, {baz:{quux:()=>{}}, foo:{bar:mem1PageMax1}}) instanceof Instance, true);
const m5 = new Module(textToBinary('(module (import "a" "b" (memory 2)))')); const m5 = new Module(wasmTextToBinary('(module (import "a" "b" (memory 2)))'));
assertErrorMessage(() => new Instance(m5, {a:{b:mem1Page}}), TypeError, /imported Memory with incompatible size/); assertErrorMessage(() => new Instance(m5, {a:{b:mem1Page}}), TypeError, /imported Memory with incompatible size/);
assertEq(new Instance(m5, {a:{b:mem2Page}}) instanceof Instance, true); assertEq(new Instance(m5, {a:{b:mem2Page}}) instanceof Instance, true);
assertEq(new Instance(m5, {a:{b:mem3Page}}) instanceof Instance, true); assertEq(new Instance(m5, {a:{b:mem3Page}}) instanceof Instance, true);
assertEq(new Instance(m5, {a:{b:mem4Page}}) instanceof Instance, true); assertEq(new Instance(m5, {a:{b:mem4Page}}) instanceof Instance, true);
const m6 = new Module(textToBinary('(module (import "a" "b" (table 2)))')); const m6 = new Module(wasmTextToBinary('(module (import "a" "b" (table 2)))'));
assertErrorMessage(() => new Instance(m6, {a:{b:tab1Elem}}), TypeError, /imported Table with incompatible size/); assertErrorMessage(() => new Instance(m6, {a:{b:tab1Elem}}), TypeError, /imported Table with incompatible size/);
assertEq(new Instance(m6, {a:{b:tab2Elem}}) instanceof Instance, true); assertEq(new Instance(m6, {a:{b:tab2Elem}}) instanceof Instance, true);
assertEq(new Instance(m6, {a:{b:tab3Elem}}) instanceof Instance, true); assertEq(new Instance(m6, {a:{b:tab3Elem}}) instanceof Instance, true);
assertEq(new Instance(m6, {a:{b:tab4Elem}}) instanceof Instance, true); assertEq(new Instance(m6, {a:{b:tab4Elem}}) instanceof Instance, true);
const m7 = new Module(textToBinary('(module (import "a" "b" (table 2 3)))')); const m7 = new Module(wasmTextToBinary('(module (import "a" "b" (table 2 3)))'));
assertErrorMessage(() => new Instance(m7, {a:{b:tab1Elem}}), TypeError, /imported Table with incompatible size/); assertErrorMessage(() => new Instance(m7, {a:{b:tab1Elem}}), TypeError, /imported Table with incompatible size/);
assertErrorMessage(() => new Instance(m7, {a:{b:tab2Elem}}), TypeError, /imported Table with incompatible maximum size/); assertErrorMessage(() => new Instance(m7, {a:{b:tab2Elem}}), TypeError, /imported Table with incompatible maximum size/);
assertErrorMessage(() => new Instance(m7, {a:{b:tab3Elem}}), TypeError, /imported Table with incompatible maximum size/); assertErrorMessage(() => new Instance(m7, {a:{b:tab3Elem}}), TypeError, /imported Table with incompatible maximum size/);
assertErrorMessage(() => new Instance(m7, {a:{b:tab4Elem}}), TypeError, /imported Table with incompatible size/); assertErrorMessage(() => new Instance(m7, {a:{b:tab4Elem}}), TypeError, /imported Table with incompatible size/);
assertErrorMessage(() => new Module(textToBinary('(module (memory 2 1))')), TypeError, /maximum length less than initial length/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (memory 2 1))')), TypeError, /maximum length 1 is less than initial length 2/);
assertErrorMessage(() => new Module(textToBinary('(module (import "a" "b" (memory 2 1)))')), TypeError, /maximum length less than initial length/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (import "a" "b" (memory 2 1)))')), TypeError, /maximum length 1 is less than initial length 2/);
assertErrorMessage(() => new Module(textToBinary('(module (table (resizable 2 1)))')), TypeError, /maximum length less than initial length/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (table (resizable 2 1)))')), TypeError, /maximum length 1 is less than initial length 2/);
assertErrorMessage(() => new Module(textToBinary('(module (import "a" "b" (table 2 1)))')), TypeError, /maximum length less than initial length/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (import "a" "b" (table 2 1)))')), TypeError, /maximum length 1 is less than initial length 2/);
// Import wasm-wasm type mismatch // Import wasm-wasm type mismatch
var e = evalText('(module (func $i2v (param i32)) (export "i2v" $i2v) (func $f2v (param f32)) (export "f2v" $f2v))').exports; var e = wasmEvalText('(module (func $i2v (param i32)) (export "i2v" $i2v) (func $f2v (param f32)) (export "f2v" $f2v))').exports;
var i2vm = new Module(textToBinary('(module (import "a" "b" (param i32)))')); var i2vm = new Module(wasmTextToBinary('(module (import "a" "b" (param i32)))'));
var f2vm = new Module(textToBinary('(module (import "a" "b" (param f32)))')); var f2vm = new Module(wasmTextToBinary('(module (import "a" "b" (param f32)))'));
assertEq(new Instance(i2vm, {a:{b:e.i2v}}) instanceof Instance, true); assertEq(new Instance(i2vm, {a:{b:e.i2v}}) instanceof Instance, true);
assertErrorMessage(() => new Instance(i2vm, {a:{b:e.f2v}}), TypeError, /imported function signature mismatch/); assertErrorMessage(() => new Instance(i2vm, {a:{b:e.f2v}}), TypeError, /imported function signature mismatch/);
assertErrorMessage(() => new Instance(f2vm, {a:{b:e.i2v}}), TypeError, /imported function signature mismatch/); assertErrorMessage(() => new Instance(f2vm, {a:{b:e.i2v}}), TypeError, /imported function signature mismatch/);
@ -152,34 +151,34 @@ assertEq(arr.join(), "baz,quux,foo,bar");
// Export key order: // Export key order:
var code = textToBinary('(module)'); var code = wasmTextToBinary('(module)');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).length, 0); assertEq(Object.keys(e).length, 0);
var code = textToBinary('(module (func) (export "foo" 0))'); var code = wasmTextToBinary('(module (func) (export "foo" 0))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).join(), "foo"); assertEq(Object.keys(e).join(), "foo");
assertEq(e.foo(), undefined); assertEq(e.foo(), undefined);
var code = textToBinary('(module (func) (export "foo" 0) (export "bar" 0))'); var code = wasmTextToBinary('(module (func) (export "foo" 0) (export "bar" 0))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).join(), "foo,bar"); assertEq(Object.keys(e).join(), "foo,bar");
assertEq(e.foo(), undefined); assertEq(e.foo(), undefined);
assertEq(e.bar(), undefined); assertEq(e.bar(), undefined);
assertEq(e.foo, e.bar); assertEq(e.foo, e.bar);
var code = textToBinary('(module (memory 1 1) (export "memory" memory))'); var code = wasmTextToBinary('(module (memory 1 1) (export "memory" memory))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).join(), "memory"); assertEq(Object.keys(e).join(), "memory");
var code = textToBinary('(module (memory 1 1) (export "foo" memory) (export "bar" memory))'); var code = wasmTextToBinary('(module (memory 1 1) (export "foo" memory) (export "bar" memory))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).join(), "foo,bar"); assertEq(Object.keys(e).join(), "foo,bar");
assertEq(e.foo, e.bar); assertEq(e.foo, e.bar);
assertEq(e.foo instanceof Memory, true); assertEq(e.foo instanceof Memory, true);
assertEq(e.foo.buffer.byteLength, 64*1024); assertEq(e.foo.buffer.byteLength, 64*1024);
var code = textToBinary('(module (memory 1 1) (func) (export "foo" 0) (export "bar" memory))'); var code = wasmTextToBinary('(module (memory 1 1) (func) (export "foo" 0) (export "bar" memory))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).join(), "foo,bar"); assertEq(Object.keys(e).join(), "foo,bar");
assertEq(e.foo(), undefined); assertEq(e.foo(), undefined);
@ -187,25 +186,25 @@ assertEq(e.bar instanceof Memory, true);
assertEq(e.bar instanceof Memory, true); assertEq(e.bar instanceof Memory, true);
assertEq(e.bar.buffer.byteLength, 64*1024); assertEq(e.bar.buffer.byteLength, 64*1024);
var code = textToBinary('(module (memory 1 1) (func) (export "bar" memory) (export "foo" 0))'); var code = wasmTextToBinary('(module (memory 1 1) (func) (export "bar" memory) (export "foo" 0))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).join(), "bar,foo"); assertEq(Object.keys(e).join(), "bar,foo");
assertEq(e.foo(), undefined); assertEq(e.foo(), undefined);
assertEq(e.bar.buffer.byteLength, 64*1024); assertEq(e.bar.buffer.byteLength, 64*1024);
var code = textToBinary('(module (memory 1 1) (export "" memory))'); var code = wasmTextToBinary('(module (memory 1 1) (export "" memory))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).length, 1); assertEq(Object.keys(e).length, 1);
assertEq(String(Object.keys(e)), ""); assertEq(String(Object.keys(e)), "");
assertEq(e[""] instanceof Memory, true); assertEq(e[""] instanceof Memory, true);
var code = textToBinary('(module (table) (export "tbl" table))'); var code = wasmTextToBinary('(module (table) (export "tbl" table))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).join(), "tbl"); assertEq(Object.keys(e).join(), "tbl");
assertEq(e.tbl instanceof Table, true); assertEq(e.tbl instanceof Table, true);
assertEq(e.tbl.length, 0); assertEq(e.tbl.length, 0);
var code = textToBinary('(module (table (resizable 2)) (export "t1" table) (export "t2" table))'); var code = wasmTextToBinary('(module (table (resizable 2)) (export "t1" table) (export "t2" table))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).join(), "t1,t2"); assertEq(Object.keys(e).join(), "t1,t2");
assertEq(e.t1 instanceof Table, true); assertEq(e.t1 instanceof Table, true);
@ -213,7 +212,7 @@ assertEq(e.t2 instanceof Table, true);
assertEq(e.t1, e.t2); assertEq(e.t1, e.t2);
assertEq(e.t1.length, 2); assertEq(e.t1.length, 2);
var code = textToBinary('(module (table (resizable 2)) (memory 1 1) (func) (export "t" table) (export "m" memory) (export "f" 0))'); var code = wasmTextToBinary('(module (table (resizable 2)) (memory 1 1) (func) (export "t" table) (export "m" memory) (export "f" 0))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).join(), "t,m,f"); assertEq(Object.keys(e).join(), "t,m,f");
assertEq(e.f(), undefined); assertEq(e.f(), undefined);
@ -221,7 +220,7 @@ assertEq(e.t instanceof Table, true);
assertEq(e.m instanceof Memory, true); assertEq(e.m instanceof Memory, true);
assertEq(e.t.length, 2); assertEq(e.t.length, 2);
var code = textToBinary('(module (table (resizable 1)) (memory 1 1) (func) (export "m" memory) (export "f" 0) (export "t" table))'); var code = wasmTextToBinary('(module (table (resizable 1)) (memory 1 1) (func) (export "m" memory) (export "f" 0) (export "t" table))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).join(), "m,f,t"); assertEq(Object.keys(e).join(), "m,f,t");
assertEq(e.f(), undefined); assertEq(e.f(), undefined);
@ -229,7 +228,7 @@ assertEq(e.t instanceof Table, true);
assertEq(e.m instanceof Memory, true); assertEq(e.m instanceof Memory, true);
+assertEq(e.t.length, 1); +assertEq(e.t.length, 1);
var code = textToBinary('(module (table) (export "" table))'); var code = wasmTextToBinary('(module (table) (export "" table))');
var e = new Instance(new Module(code)).exports; var e = new Instance(new Module(code)).exports;
assertEq(Object.keys(e).length, 1); assertEq(Object.keys(e).length, 1);
assertEq(String(Object.keys(e)), ""); assertEq(String(Object.keys(e)), "");
@ -238,7 +237,7 @@ assertEq(e[""] instanceof Table, true);
// Table export function identity // Table export function identity
var code = textToBinary(`(module var code = wasmTextToBinary(`(module
(func $f (result i32) (i32.const 1)) (func $f (result i32) (i32.const 1))
(func $g (result i32) (i32.const 2)) (func $g (result i32) (i32.const 2))
(func $h (result i32) (i32.const 3)) (func $h (result i32) (i32.const 3))
@ -275,19 +274,19 @@ assertEq(e.tbl1.get(0), e.tbl1.get(3));
// Re-exports and Identity: // Re-exports and Identity:
var code = textToBinary('(module (import "a" "b" (memory 1 1)) (export "foo" memory) (export "bar" memory))'); var code = wasmTextToBinary('(module (import "a" "b" (memory 1 1)) (export "foo" memory) (export "bar" memory))');
var mem = new Memory({initial:1, maximum:1}); var mem = new Memory({initial:1, maximum:1});
var e = new Instance(new Module(code), {a:{b:mem}}).exports; var e = new Instance(new Module(code), {a:{b:mem}}).exports;
assertEq(mem, e.foo); assertEq(mem, e.foo);
assertEq(mem, e.bar); assertEq(mem, e.bar);
var code = textToBinary('(module (import "a" "b" (table 1 1)) (export "foo" table) (export "bar" table))'); var code = wasmTextToBinary('(module (import "a" "b" (table 1 1)) (export "foo" table) (export "bar" table))');
var tbl = new Table({initial:1, maximum:1, element:"anyfunc"}); var tbl = new Table({initial:1, maximum:1, element:"anyfunc"});
var e = new Instance(new Module(code), {a:{b:tbl}}).exports; var e = new Instance(new Module(code), {a:{b:tbl}}).exports;
assertEq(tbl, e.foo); assertEq(tbl, e.foo);
assertEq(tbl, e.bar); assertEq(tbl, e.bar);
var code = textToBinary('(module (import "a" "b" (table 2 2)) (func $foo) (elem (i32.const 0) $foo) (export "foo" $foo))'); var code = wasmTextToBinary('(module (import "a" "b" (table 2 2)) (func $foo) (elem (i32.const 0) $foo) (export "foo" $foo))');
var tbl = new Table({initial:2, maximum:2, element:"anyfunc"}); var tbl = new Table({initial:2, maximum:2, element:"anyfunc"});
var e1 = new Instance(new Module(code), {a:{b:tbl}}).exports; var e1 = new Instance(new Module(code), {a:{b:tbl}}).exports;
assertEq(e1.foo, tbl.get(0)); assertEq(e1.foo, tbl.get(0));
@ -299,8 +298,8 @@ assertEq(e1.foo, tbl.get(1));
assertEq(tbl.get(0) === e1.foo, false); assertEq(tbl.get(0) === e1.foo, false);
assertEq(e1.foo === e2.foo, false); assertEq(e1.foo === e2.foo, false);
var code = textToBinary('(module (table (resizable 2 2)) (import $foo "a" "b" (result i32)) (func $bar (result i32) (i32.const 13)) (elem (i32.const 0) $foo $bar) (export "foo" $foo) (export "bar" $bar) (export "tbl" table))'); var code = wasmTextToBinary('(module (table (resizable 2 2)) (import $foo "a" "b" (result i32)) (func $bar (result i32) (i32.const 13)) (elem (i32.const 0) $foo $bar) (export "foo" $foo) (export "bar" $bar) (export "tbl" table))');
var foo = new Instance(new Module(textToBinary('(module (func (result i32) (i32.const 42)) (export "foo" 0))'))).exports.foo; var foo = new Instance(new Module(wasmTextToBinary('(module (func (result i32) (i32.const 42)) (export "foo" 0))'))).exports.foo;
var e1 = new Instance(new Module(code), {a:{b:foo}}).exports; var e1 = new Instance(new Module(code), {a:{b:foo}}).exports;
assertEq(foo, e1.foo); assertEq(foo, e1.foo);
assertEq(foo, e1.tbl.get(0)); assertEq(foo, e1.tbl.get(0));
@ -316,29 +315,29 @@ assertEq(e1.tbl.get(1) === e2.tbl.get(1), false);
// i64 is fully allowed for imported wasm functions // i64 is fully allowed for imported wasm functions
var code1 = textToBinary('(module (func $exp (param i64) (result i64) (i64.add (get_local 0) (i64.const 10))) (export "exp" $exp))'); var code1 = wasmTextToBinary('(module (func $exp (param i64) (result i64) (i64.add (get_local 0) (i64.const 10))) (export "exp" $exp))');
var e1 = new Instance(new Module(code1)).exports; var e1 = new Instance(new Module(code1)).exports;
var code2 = textToBinary('(module (import $i "a" "b" (param i64) (result i64)) (func $f (result i32) (i32.wrap/i64 (call_import $i (i64.const 42)))) (export "f" $f))'); var code2 = wasmTextToBinary('(module (import $i "a" "b" (param i64) (result i64)) (func $f (result i32) (i32.wrap/i64 (call_import $i (i64.const 42)))) (export "f" $f))');
var e2 = new Instance(new Module(code2), {a:{b:e1.exp}}).exports; var e2 = new Instance(new Module(code2), {a:{b:e1.exp}}).exports;
assertEq(e2.f(), 52); assertEq(e2.f(), 52);
// Non-existent export errors // Non-existent export errors
assertErrorMessage(() => new Module(textToBinary('(module (export "a" 0))')), TypeError, /exported function index out of bounds/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (export "a" 0))')), TypeError, /exported function index out of bounds/);
assertErrorMessage(() => new Module(textToBinary('(module (export "a" global 0))')), TypeError, /exported global index out of bounds/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (export "a" global 0))')), TypeError, /exported global index out of bounds/);
assertErrorMessage(() => new Module(textToBinary('(module (export "a" memory))')), TypeError, /exported memory index out of bounds/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (export "a" memory))')), TypeError, /exported memory index out of bounds/);
assertErrorMessage(() => new Module(textToBinary('(module (export "a" table))')), TypeError, /exported table index out of bounds/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (export "a" table))')), TypeError, /exported table index out of bounds/);
// Default memory/table rules // Default memory/table rules
assertErrorMessage(() => new Module(textToBinary('(module (import "a" "b" (memory 1 1)) (memory 1 1))')), TypeError, /already have default memory/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (import "a" "b" (memory 1 1)) (memory 1 1))')), TypeError, /already have default memory/);
assertErrorMessage(() => new Module(textToBinary('(module (import "a" "b" (memory 1 1)) (import "x" "y" (memory 2 2)))')), TypeError, /already have default memory/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (import "a" "b" (memory 1 1)) (import "x" "y" (memory 2 2)))')), TypeError, /already have default memory/);
assertErrorMessage(() => new Module(textToBinary('(module (import "a" "b" (table 1 1)) (table 1 1))')), TypeError, /already have default table/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (import "a" "b" (table 1 1)) (table 1 1))')), TypeError, /already have default table/);
assertErrorMessage(() => new Module(textToBinary('(module (import "a" "b" (table 1 1)) (import "x" "y" (table 2 2)))')), TypeError, /already have default table/); assertErrorMessage(() => new Module(wasmTextToBinary('(module (import "a" "b" (table 1 1)) (import "x" "y" (table 2 2)))')), TypeError, /already have default table/);
// Data segments on imports // Data segments on imports
var m = new Module(textToBinary(` var m = new Module(wasmTextToBinary(`
(module (module
(import "a" "b" (memory 1 1)) (import "a" "b" (memory 1 1))
(data 0 "\\0a\\0b") (data 0 "\\0a\\0b")
@ -365,7 +364,7 @@ assertEq(i8[102], 0x0);
// Data segments with imported offsets // Data segments with imported offsets
var m = new Module(textToBinary(` var m = new Module(wasmTextToBinary(`
(module (module
(import "glob" "a" (global i32 immutable)) (import "glob" "a" (global i32 immutable))
(memory 1) (memory 1)
@ -380,7 +379,7 @@ assertErrorMessage(() => new Instance(m, {glob:{a:64*1024}}), RangeError, /data
// and are checked against the actual memory/table length, not the declared // and are checked against the actual memory/table length, not the declared
// initial length. // initial length.
var m = new Module(textToBinary(` var m = new Module(wasmTextToBinary(`
(module (module
(import "a" "mem" (memory 1)) (import "a" "mem" (memory 1))
(import "a" "tbl" (table 1)) (import "a" "tbl" (table 1))
@ -419,7 +418,7 @@ assertEq(tbl.get(1), i.exports.g);
// Elem segments on imports // Elem segments on imports
var m = new Module(textToBinary(` var m = new Module(wasmTextToBinary(`
(module (module
(import "a" "b" (table 10)) (import "a" "b" (table 10))
(elem (i32.const 0) $one $two) (elem (i32.const 0) $one $two)
@ -441,17 +440,17 @@ for (var i = 5; i < 10; i++)
// Cross-instance calls // Cross-instance calls
var i1 = new Instance(new Module(textToBinary(`(module (func) (func (param i32) (result i32) (i32.add (get_local 0) (i32.const 1))) (func) (export "f" 1))`))); var i1 = new Instance(new Module(wasmTextToBinary(`(module (func) (func (param i32) (result i32) (i32.add (get_local 0) (i32.const 1))) (func) (export "f" 1))`)));
var i2 = new Instance(new Module(textToBinary(`(module (import $imp "a" "b" (param i32) (result i32)) (func $g (result i32) (call $imp (i32.const 13))) (export "g" $g))`)), {a:{b:i1.exports.f}}); var i2 = new Instance(new Module(wasmTextToBinary(`(module (import $imp "a" "b" (param i32) (result i32)) (func $g (result i32) (call $imp (i32.const 13))) (export "g" $g))`)), {a:{b:i1.exports.f}});
assertEq(i2.exports.g(), 14); assertEq(i2.exports.g(), 14);
var i1 = new Instance(new Module(textToBinary(`(module var i1 = new Instance(new Module(wasmTextToBinary(`(module
(memory 1 1) (memory 1 1)
(data (i32.const 0) "\\42") (data (i32.const 0) "\\42")
(func $f (result i32) (i32.load (i32.const 0))) (func $f (result i32) (i32.load (i32.const 0)))
(export "f" $f) (export "f" $f)
)`))); )`)));
var i2 = new Instance(new Module(textToBinary(`(module var i2 = new Instance(new Module(wasmTextToBinary(`(module
(import $imp "a" "b" (result i32)) (import $imp "a" "b" (result i32))
(memory 1 1) (memory 1 1)
(data (i32.const 0) "\\13") (data (i32.const 0) "\\13")
@ -465,7 +464,7 @@ var i2 = new Instance(new Module(textToBinary(`(module
assertEq(i2.exports.call(0), 0x42); assertEq(i2.exports.call(0), 0x42);
assertEq(i2.exports.call(1), 0x13); assertEq(i2.exports.call(1), 0x13);
var m = new Module(textToBinary(`(module var m = new Module(wasmTextToBinary(`(module
(import $val "a" "val" (global i32 immutable)) (import $val "a" "val" (global i32 immutable))
(import $next "a" "next" (result i32)) (import $next "a" "next" (result i32))
(memory 1) (memory 1)

Просмотреть файл

@ -3,13 +3,12 @@
// adding spurious edges to the GC graph. // adding spurious edges to the GC graph.
load(libdir + 'wasm.js'); load(libdir + 'wasm.js');
load(libdir + 'asserts.js');
const Module = WebAssembly.Module; const Module = WebAssembly.Module;
const Instance = WebAssembly.Instance; const Instance = WebAssembly.Instance;
const m1 = new Module(textToBinary(`(module (func $f) (export "f" $f))`)); const m1 = new Module(wasmTextToBinary(`(module (func $f) (export "f" $f))`));
const m2 = new Module(textToBinary(`(module (import "a" "f") (func $f) (export "g" $f))`)); const m2 = new Module(wasmTextToBinary(`(module (import "a" "f") (func $f) (export "g" $f))`));
// Imported instance objects should stay alive as long as any importer is alive. // Imported instance objects should stay alive as long as any importer is alive.
resetFinalizeCount(); resetFinalizeCount();

Просмотреть файл

@ -1,9 +1,9 @@
// |jit-test| test-also-wasm-baseline // |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js"); load(libdir + "wasm.js");
assertEq(wasmEvalText('(module (func (result i32) (i32.const -1)) (export "" 0))')(), -1); assertEq(wasmEvalText('(module (func (result i32) (i32.const -1)) (export "" 0))').exports[""](), -1);
assertEq(wasmEvalText('(module (func (result i32) (i32.const -2147483648)) (export "" 0))')(), -2147483648); assertEq(wasmEvalText('(module (func (result i32) (i32.const -2147483648)) (export "" 0))').exports[""](), -2147483648);
assertEq(wasmEvalText('(module (func (result i32) (i32.const 4294967295)) (export "" 0))')(), -1); assertEq(wasmEvalText('(module (func (result i32) (i32.const 4294967295)) (export "" 0))').exports[""](), -1);
function testUnary(type, opcode, op, expect) { function testUnary(type, opcode, op, expect) {
var assertFunc = assertEq; var assertFunc = assertEq;
@ -13,14 +13,14 @@ function testUnary(type, opcode, op, expect) {
} }
// Test with constant // Test with constant
assertFunc(wasmEvalText(`(module (func (result ${type}) (${type}.${opcode} (${type}.const ${op}))) (export "" 0))`)(), expect); assertFunc(wasmEvalText(`(module (func (result ${type}) (${type}.${opcode} (${type}.const ${op}))) (export "" 0))`).exports[""](), expect);
if (type === 'i64') { if (type === 'i64') {
op = createI64(op); op = createI64(op);
} }
// Test with param // Test with param
assertFunc(wasmEvalText(`(module (func (param ${type}) (result ${type}) (${type}.${opcode} (get_local 0))) (export "" 0))`)(op), expect); assertFunc(wasmEvalText(`(module (func (param ${type}) (result ${type}) (${type}.${opcode} (get_local 0))) (export "" 0))`).exports[""](op), expect);
} }
function testBinary64(opcode, lhs, rhs, expect) { function testBinary64(opcode, lhs, rhs, expect) {
@ -28,23 +28,23 @@ function testBinary64(opcode, lhs, rhs, expect) {
let robj = createI64(rhs); let robj = createI64(rhs);
expect = createI64(expect); expect = createI64(expect);
assertEqI64(wasmEvalText(`(module (func (param i64) (param i64) (result i64) (i64.${opcode} (get_local 0) (get_local 1))) (export "" 0))`)(lobj, robj), expect); assertEqI64(wasmEvalText(`(module (func (param i64) (param i64) (result i64) (i64.${opcode} (get_local 0) (get_local 1))) (export "" 0))`).exports[""](lobj, robj), expect);
// The same, but now the RHS is a constant. // The same, but now the RHS is a constant.
assertEqI64(wasmEvalText(`(module (func (param i64) (result i64) (i64.${opcode} (get_local 0) (i64.const ${rhs}))) (export "" 0))`)(lobj), expect); assertEqI64(wasmEvalText(`(module (func (param i64) (result i64) (i64.${opcode} (get_local 0) (i64.const ${rhs}))) (export "" 0))`).exports[""](lobj), expect);
// LHS and RHS are constants. // LHS and RHS are constants.
assertEqI64(wasmEvalText(`(module (func (result i64) (i64.${opcode} (i64.const ${lhs}) (i64.const ${rhs}))) (export "" 0))`)(), expect); assertEqI64(wasmEvalText(`(module (func (result i64) (i64.${opcode} (i64.const ${lhs}) (i64.const ${rhs}))) (export "" 0))`).exports[""](), expect);
} }
function testBinary32(opcode, lhs, rhs, expect) { function testBinary32(opcode, lhs, rhs, expect) {
assertEq(wasmEvalText(`(module (func (param i32) (param i32) (result i32) (i32.${opcode} (get_local 0) (get_local 1))) (export "" 0))`)(lhs, rhs), expect); assertEq(wasmEvalText(`(module (func (param i32) (param i32) (result i32) (i32.${opcode} (get_local 0) (get_local 1))) (export "" 0))`).exports[""](lhs, rhs), expect);
// The same, but now the RHS is a constant. // The same, but now the RHS is a constant.
assertEq(wasmEvalText(`(module (func (param i32) (result i32) (i32.${opcode} (get_local 0) (i32.const ${rhs}))) (export "" 0))`)(lhs), expect); assertEq(wasmEvalText(`(module (func (param i32) (result i32) (i32.${opcode} (get_local 0) (i32.const ${rhs}))) (export "" 0))`).exports[""](lhs), expect);
// LHS and RHS are constants. // LHS and RHS are constants.
assertEq(wasmEvalText(`(module (func (result i32) (i32.${opcode} (i32.const ${lhs}) (i32.const ${rhs}))) (export "" 0))`)(), expect); assertEq(wasmEvalText(`(module (func (result i32) (i32.${opcode} (i32.const ${lhs}) (i32.const ${rhs}))) (export "" 0))`).exports[""](), expect);
} }
function testComparison32(opcode, lhs, rhs, expect) { function testComparison32(opcode, lhs, rhs, expect) {
assertEq(wasmEvalText(`(module (func (param i32) (param i32) (result i32) (i32.${opcode} (get_local 0) (get_local 1))) (export "" 0))`)(lhs, rhs), expect); assertEq(wasmEvalText(`(module (func (param i32) (param i32) (result i32) (i32.${opcode} (get_local 0) (get_local 1))) (export "" 0))`).exports[""](lhs, rhs), expect);
} }
function testComparison64(opcode, lhs, rhs, expect) { function testComparison64(opcode, lhs, rhs, expect) {
let lobj = createI64(lhs); let lobj = createI64(lhs);
@ -52,39 +52,39 @@ function testComparison64(opcode, lhs, rhs, expect) {
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
(func (param i64) (param i64) (result i32) (i64.${opcode} (get_local 0) (get_local 1))) (func (param i64) (param i64) (result i32) (i64.${opcode} (get_local 0) (get_local 1)))
(export "" 0))`)(lobj, robj), expect); (export "" 0))`).exports[""](lobj, robj), expect);
// Also test if, for the compare-and-branch path. // Also test if, for the compare-and-branch path.
assertEq(wasmEvalText(`(module assertEq(wasmEvalText(`(module
(func (param i64) (param i64) (result i32) (func (param i64) (param i64) (result i32)
(if (i64.${opcode} (get_local 0) (get_local 1)) (if i32 (i64.${opcode} (get_local 0) (get_local 1))
(i32.const 1) (i32.const 1)
(i32.const 0))) (i32.const 0)))
(export "" 0))`)(lobj, robj), expect); (export "" 0))`).exports[""](lobj, robj), expect);
} }
function testI64Eqz(input, expect) { function testI64Eqz(input, expect) {
assertEq(wasmEvalText(`(module (func (result i32) (i64.eqz (i64.const ${input}))) (export "" 0))`)(input), expect); assertEq(wasmEvalText(`(module (func (result i32) (i64.eqz (i64.const ${input}))) (export "" 0))`).exports[""](input), expect);
input = createI64(input); input = createI64(input);
assertEq(wasmEvalText(`(module (func (param i64) (result i32) (i64.eqz (get_local 0))) (export "" 0))`)(input), expect); assertEq(wasmEvalText(`(module (func (param i64) (result i32) (i64.eqz (get_local 0))) (export "" 0))`).exports[""](input), expect);
} }
function testTrap32(opcode, lhs, rhs, expect) { function testTrap32(opcode, lhs, rhs, expect) {
assertErrorMessage(() => wasmEvalText(`(module (func (param i32) (param i32) (result i32) (i32.${opcode} (get_local 0) (get_local 1))) (export "" 0))`)(lhs, rhs), Error, expect); assertErrorMessage(() => wasmEvalText(`(module (func (param i32) (param i32) (result i32) (i32.${opcode} (get_local 0) (get_local 1))) (export "" 0))`).exports[""](lhs, rhs), Error, expect);
// The same, but now the RHS is a constant. // The same, but now the RHS is a constant.
assertErrorMessage(() => wasmEvalText(`(module (func (param i32) (result i32) (i32.${opcode} (get_local 0) (i32.const ${rhs}))) (export "" 0))`)(lhs), Error, expect); assertErrorMessage(() => wasmEvalText(`(module (func (param i32) (result i32) (i32.${opcode} (get_local 0) (i32.const ${rhs}))) (export "" 0))`).exports[""](lhs), Error, expect);
// LHS and RHS are constants. // LHS and RHS are constants.
assertErrorMessage(wasmEvalText(`(module (func (result i32) (i32.${opcode} (i32.const ${lhs}) (i32.const ${rhs}))) (export "" 0))`), Error, expect); assertErrorMessage(wasmEvalText(`(module (func (result i32) (i32.${opcode} (i32.const ${lhs}) (i32.const ${rhs}))) (export "" 0))`).exports[""], Error, expect);
} }
function testTrap64(opcode, lhs, rhs, expect) { function testTrap64(opcode, lhs, rhs, expect) {
let lobj = createI64(lhs); let lobj = createI64(lhs);
let robj = createI64(rhs); let robj = createI64(rhs);
assertErrorMessage(() => wasmEvalText(`(module (func (param i64) (param i64) (result i64) (i64.${opcode} (get_local 0) (get_local 1))) (export "" 0))`)(lobj, robj), Error, expect); assertErrorMessage(() => wasmEvalText(`(module (func (param i64) (param i64) (result i64) (i64.${opcode} (get_local 0) (get_local 1))) (export "" 0))`).exports[""](lobj, robj), Error, expect);
// The same, but now the RHS is a constant. // The same, but now the RHS is a constant.
assertErrorMessage(() => wasmEvalText(`(module (func (param i64) (result i64) (i64.${opcode} (get_local 0) (i64.const ${rhs}))) (export "" 0))`)(lobj), Error, expect); assertErrorMessage(() => wasmEvalText(`(module (func (param i64) (result i64) (i64.${opcode} (get_local 0) (i64.const ${rhs}))) (export "" 0))`).exports[""](lobj), Error, expect);
// LHS and RHS are constants. // LHS and RHS are constants.
assertErrorMessage(wasmEvalText(`(module (func (result i64) (i64.${opcode} (i64.const ${lhs}) (i64.const ${rhs}))) (export "" 0))`), Error, expect); assertErrorMessage(wasmEvalText(`(module (func (result i64) (i64.${opcode} (i64.const ${lhs}) (i64.const ${rhs}))) (export "" 0))`).exports[""], Error, expect);
} }
testUnary('i32', 'clz', 40, 26); testUnary('i32', 'clz', 40, 26);
@ -143,7 +143,7 @@ testComparison32('ge_s', 40, 40, 1);
testComparison32('ge_u', 40, 40, 1); testComparison32('ge_u', 40, 40, 1);
// Test MTest's GVN branch inversion. // Test MTest's GVN branch inversion.
var testTrunc = wasmEvalText(`(module (func (param f32) (result i32) (if (i32.eqz (i32.trunc_s/f32 (get_local 0))) (i32.const 0) (i32.const 1))) (export "" 0))`); var testTrunc = wasmEvalText(`(module (func (param f32) (result i32) (if i32 (i32.eqz (i32.trunc_s/f32 (get_local 0))) (i32.const 0) (i32.const 1))) (export "" 0))`).exports[""];
assertEq(testTrunc(0), 0); assertEq(testTrunc(0), 0);
assertEq(testTrunc(13.37), 1); assertEq(testTrunc(13.37), 1);
@ -278,14 +278,14 @@ assertEq(testTrunc(13.37), 1);
testI64Eqz(40, 0); testI64Eqz(40, 0);
testI64Eqz(0, 1); testI64Eqz(0, 1);
assertEqI64(wasmEvalText(`(module (func (param i64) (result i64) (local i64) (set_local 1 (i64.shl (get_local 0) (get_local 0))) (i64.shl (get_local 1) (get_local 1))) (export "" 0))`)(createI64(2)), 2048); assertEqI64(wasmEvalText(`(module (func (param i64) (result i64) (local i64) (set_local 1 (i64.shl (get_local 0) (get_local 0))) (i64.shl (get_local 1) (get_local 1))) (export "" 0))`).exports[""](createI64(2)), 2048);
// Test MTest's GVN branch inversion. // Test MTest's GVN branch inversion.
var testTrunc = wasmEvalText(`(module (func (param f32) (result i32) (if (i64.eqz (i64.trunc_s/f32 (get_local 0))) (i32.const 0) (i32.const 1))) (export "" 0))`); var testTrunc = wasmEvalText(`(module (func (param f32) (result i32) (if i32 (i64.eqz (i64.trunc_s/f32 (get_local 0))) (i32.const 0) (i32.const 1))) (export "" 0))`).exports[""];
assertEq(testTrunc(0), 0); assertEq(testTrunc(0), 0);
assertEq(testTrunc(13.37), 1); assertEq(testTrunc(13.37), 1);
assertEqI64(wasmEvalText(`(module (func (result i64) (local i64) (set_local 0 (i64.rem_s (i64.const 1) (i64.const 0xf))) (i64.rem_s (get_local 0) (get_local 0))) (export "" 0))`)(), 0); assertEqI64(wasmEvalText(`(module (func (result i64) (local i64) (set_local 0 (i64.rem_s (i64.const 1) (i64.const 0xf))) (i64.rem_s (get_local 0) (get_local 0))) (export "" 0))`).exports[""](), 0);
setJitCompilerOption('wasm.test-mode', 0); setJitCompilerOption('wasm.test-mode', 0);
} }

Просмотреть файл

@ -1,9 +1,8 @@
load(libdir + 'wasm.js'); load(libdir + 'wasm.js');
load(libdir + 'asserts.js');
const WasmPage = 64 * 1024; const WasmPage = 64 * 1024;
const emptyModule = textToBinary('(module)'); const emptyModule = wasmTextToBinary('(module)');
// 'WebAssembly' data property on global object // 'WebAssembly' data property on global object
const wasmDesc = Object.getOwnPropertyDescriptor(this, 'WebAssembly'); const wasmDesc = Object.getOwnPropertyDescriptor(this, 'WebAssembly');
@ -33,8 +32,8 @@ assertErrorMessage(() => new Module(), TypeError, /requires more than 0 argument
assertErrorMessage(() => new Module(undefined), TypeError, "first argument must be an ArrayBuffer or typed array object"); assertErrorMessage(() => new Module(undefined), TypeError, "first argument must be an ArrayBuffer or typed array object");
assertErrorMessage(() => new Module(1), TypeError, "first argument must be an ArrayBuffer or typed array object"); assertErrorMessage(() => new Module(1), TypeError, "first argument must be an ArrayBuffer or typed array object");
assertErrorMessage(() => new Module({}), TypeError, "first argument must be an ArrayBuffer or typed array object"); assertErrorMessage(() => new Module({}), TypeError, "first argument must be an ArrayBuffer or typed array object");
assertErrorMessage(() => new Module(new Uint8Array()), /* TODO: WebAssembly.CompileError */ TypeError, /compile error/); assertErrorMessage(() => new Module(new Uint8Array()), /* TODO: WebAssembly.CompileError */ TypeError, /failed to match magic number/);
assertErrorMessage(() => new Module(new ArrayBuffer()), /* TODO: WebAssembly.CompileError */ TypeError, /compile error/); assertErrorMessage(() => new Module(new ArrayBuffer()), /* TODO: WebAssembly.CompileError */ TypeError, /failed to match magic number/);
assertEq(new Module(emptyModule) instanceof Module, true); assertEq(new Module(emptyModule) instanceof Module, true);
assertEq(new Module(emptyModule.buffer) instanceof Module, true); assertEq(new Module(emptyModule.buffer) instanceof Module, true);
@ -336,8 +335,8 @@ assertCompileError([], /requires more than 0 arguments/);
assertCompileError([undefined], /first argument must be an ArrayBuffer or typed array object/); assertCompileError([undefined], /first argument must be an ArrayBuffer or typed array object/);
assertCompileError([1], /first argument must be an ArrayBuffer or typed array object/); assertCompileError([1], /first argument must be an ArrayBuffer or typed array object/);
assertCompileError([{}], /first argument must be an ArrayBuffer or typed array object/); assertCompileError([{}], /first argument must be an ArrayBuffer or typed array object/);
assertCompileError([new Uint8Array()], /compile error/); assertCompileError([new Uint8Array()], /failed to match magic number/);
assertCompileError([new ArrayBuffer()], /compile error/); assertCompileError([new ArrayBuffer()], /failed to match magic number/);
function assertCompileSuccess(bytes) { function assertCompileSuccess(bytes) {
var module = null; var module = null;
compile(bytes).then(m => module = m); compile(bytes).then(m => module = m);

Просмотреть файл

@ -3,7 +3,7 @@ load(libdir + "wasm.js");
var i = wasmEvalText( var i = wasmEvalText(
`(module `(module
(memory 1 (segment 0 "\\01\\02\\03\\04\\05\\06\\07\\08")) (memory 1) (data 0 "\\01\\02\\03\\04\\05\\06\\07\\08")
(func $off1 (param $base i32) (result i32) (func $off1 (param $base i32) (result i32)
(i32.add (i32.add
(i32.load8_u (get_local $base)) (i32.load8_u (get_local $base))
@ -16,7 +16,7 @@ var i = wasmEvalText(
(i32.load8_u offset=2 (get_local $base))) (i32.load8_u offset=2 (get_local $base)))
) )
(export "off2" $off2) (export "off2" $off2)
)`); )`).exports;
assertEq(i.off1(0), 3); assertEq(i.off1(0), 3);
assertEq(i.off1(1), 5); assertEq(i.off1(1), 5);
assertEq(i.off1(2), 7); assertEq(i.off1(2), 7);

Просмотреть файл

@ -4,10 +4,9 @@ load(libdir + "wasm.js");
function loadModule(type, ext, offset, align) { function loadModule(type, ext, offset, align) {
return wasmEvalText( return wasmEvalText(
`(module `(module
(memory 1 (memory 1)
(segment 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f") (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(segment 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff") (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
)
(func (param i32) (result ${type}) (func (param i32) (result ${type})
(${type}.load${ext} (${type}.load${ext}
offset=${offset} offset=${offset}
@ -15,18 +14,17 @@ function loadModule(type, ext, offset, align) {
(get_local 0) (get_local 0)
) )
) (export "" 0))` ) (export "" 0))`
); ).exports[""];
} }
function storeModule(type, ext, offset, align) { function storeModule(type, ext, offset, align) {
var load_ext = ext === '' ? '' : ext + '_s'; var load_ext = ext === '' ? '' : ext + '_s';
return wasmEvalText( return wasmEvalText(
`(module `(module
(memory 1 (memory 1)
(segment 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f") (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(segment 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff") (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
) (func (param i32) (param ${type})
(func (param i32) (param ${type}) (result ${type})
(${type}.store${ext} (${type}.store${ext}
offset=${offset} offset=${offset}
${align != 0 ? 'align=' + align : ''} ${align != 0 ? 'align=' + align : ''}
@ -41,18 +39,17 @@ function storeModule(type, ext, offset, align) {
(get_local 0) (get_local 0)
) )
) (export "load" 1))` ) (export "load" 1))`
); ).exports;
} }
function storeModuleCst(type, ext, offset, align, value) { function storeModuleCst(type, ext, offset, align, value) {
var load_ext = ext === '' ? '' : ext + '_s'; var load_ext = ext === '' ? '' : ext + '_s';
return wasmEvalText( return wasmEvalText(
`(module `(module
(memory 1 (memory 1)
(segment 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f") (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(segment 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff") (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
) (func (param i32)
(func (param i32) (result ${type})
(${type}.store${ext} (${type}.store${ext}
offset=${offset} offset=${offset}
${align != 0 ? 'align=' + align : ''} ${align != 0 ? 'align=' + align : ''}
@ -67,7 +64,7 @@ function storeModuleCst(type, ext, offset, align, value) {
(get_local 0) (get_local 0)
) )
) (export "load" 1))` ) (export "load" 1))`
); ).exports;
} }
function testLoad(type, ext, base, offset, align, expect) { function testLoad(type, ext, base, offset, align, expect) {
@ -86,14 +83,14 @@ function testStore(type, ext, base, offset, align, value) {
let moduleCst = storeModuleCst(type, ext, offset, align, value); let moduleCst = storeModuleCst(type, ext, offset, align, value);
if (type === 'i64') { if (type === 'i64') {
var i64 = createI64(value); var i64 = createI64(value);
assertEqI64(module.store(base, i64), i64); module.store(base, i64);
assertEqI64(module.load(base), i64); assertEqI64(module.load(base), i64);
assertEqI64(moduleCst.store(base), i64); moduleCst.store(base);
assertEqI64(moduleCst.load(base), i64); assertEqI64(moduleCst.load(base), i64);
} else { } else {
assertEq(module.store(base, value), value); module.store(base, value);
assertEq(module.load(base), value); assertEq(module.load(base), value);
assertEq(moduleCst.store(base), value); moduleCst.store(base);
assertEq(moduleCst.load(base), value); assertEq(moduleCst.load(base), value);
} }
} }
@ -188,7 +185,7 @@ for (var foldOffsets = 0; foldOffsets <= 1; foldOffsets++) {
testStore('i32', '8', 0, 0, 0, 0x23); testStore('i32', '8', 0, 0, 0, 0x23);
testStore('i32', '16', 0, 0, 0, 0x2345); testStore('i32', '16', 0, 0, 0, 0x2345);
assertErrorMessage(() => wasmEvalText('(module (memory 2 1))'), TypeError, /maximum memory size less than initial memory size/); assertErrorMessage(() => wasmEvalText('(module (memory 2 1))'), TypeError, /maximum length 1 is less than initial length 2/);
// Test bounds checks and edge cases. // Test bounds checks and edge cases.
const align = 0; const align = 0;
@ -283,10 +280,9 @@ for (var foldOffsets = 0; foldOffsets <= 1; foldOffsets++) {
function testRegisters() { function testRegisters() {
assertEq(wasmEvalText( assertEq(wasmEvalText(
`(module `(module
(memory 1 (memory 1)
(segment 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f") (data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(segment 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff") (data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
)
(func (param i32) (local i32 i32 i32 i32 f32 f64) (result i32) (func (param i32) (local i32 i32 i32 i32 f32 f64) (result i32)
(set_local 1 (i32.load8_s offset=4 (get_local 0))) (set_local 1 (i32.load8_s offset=4 (get_local 0)))
(set_local 2 (i32.load16_s (get_local 1))) (set_local 2 (i32.load16_s (get_local 1)))
@ -316,7 +312,7 @@ for (var foldOffsets = 0; foldOffsets <= 1; foldOffsets++) {
) )
) )
) (export "" 0))` ) (export "" 0))`
)(1), 50464523); ).exports[""](1), 50464523);
} }
testRegisters(); testRegisters();

Просмотреть файл

@ -13,7 +13,7 @@ function assertSameBitPattern(from, to, offset) {
f32[0] = NaN; f32[0] = NaN;
f32[0] = f32[0]; // Force canonicalization. f32[0] = f32[0]; // Force canonicalization.
f32[1] = wasmEvalText('(module (func (result f32) (f32.const nan:0x123456)) (export "" 0))')(); f32[1] = wasmEvalText('(module (func (result f32) (f32.const nan:0x123456)) (export "" 0))').exports[""]();
assertSameBitPattern(0, 4, 4); assertSameBitPattern(0, 4, 4);
var checkBitPatterns = { var checkBitPatterns = {
@ -29,14 +29,14 @@ var checkBitPatterns = {
} }
} }
wasmEvalText('(module (import "" "float32" (param f32)) (func (call_import 0 (f32.const nan:0x123456))) (export "" 0))', checkBitPatterns)(); wasmEvalText('(module (import "" "float32" (param f32)) (func (call_import 0 (f32.const nan:0x123456))) (export "" 0))', checkBitPatterns).exports[""]();
f64[0] = NaN; f64[0] = NaN;
f64[0] = f64[0]; // Force canonicalization. f64[0] = f64[0]; // Force canonicalization.
f64[1] = wasmEvalText('(module (func (result f64) (f64.const nan:0x123456)) (export "" 0))')(); f64[1] = wasmEvalText('(module (func (result f64) (f64.const nan:0x123456)) (export "" 0))').exports[""]();
assertSameBitPattern(0, 8, 8); assertSameBitPattern(0, 8, 8);
wasmEvalText('(module (import "" "float64" (param f64)) (func (call_import 0 (f64.const nan:0x123456))) (export "" 0))', checkBitPatterns)(); wasmEvalText('(module (import "" "float64" (param f64)) (func (call_import 0 (f64.const nan:0x123456))) (export "" 0))', checkBitPatterns).exports[""]();
// Enable test mode. // Enable test mode.
setJitCompilerOption('wasm.test-mode', 1); setJitCompilerOption('wasm.test-mode', 1);
@ -53,11 +53,11 @@ setJitCompilerOption('wasm.test-mode', 1);
var f32_nan_base = 0x7f800000; var f32_nan_base = 0x7f800000;
var f32_snan_code = '(f32.const nan:0x200000)'; var f32_snan_code = '(f32.const nan:0x200000)';
var f32_snan = wasmEvalText(`(module (func (result f32) ${f32_snan_code}) (export "" 0))`)(); var f32_snan = wasmEvalText(`(module (func (result f32) ${f32_snan_code}) (export "" 0))`).exports[""]();
assertEqNaN(f32_snan, { nan_low: f32_nan_base | 0x200000 }); assertEqNaN(f32_snan, { nan_low: f32_nan_base | 0x200000 });
var f32_qnan_code = '(f32.const nan:0x600000)'; var f32_qnan_code = '(f32.const nan:0x600000)';
var f32_qnan = wasmEvalText(`(module (func (result f32) ${f32_qnan_code}) (export "" 0))`)(); var f32_qnan = wasmEvalText(`(module (func (result f32) ${f32_qnan_code}) (export "" 0))`).exports[""]();
assertEqNaN(f32_qnan, { nan_low: f32_nan_base | 0x600000 }); assertEqNaN(f32_qnan, { nan_low: f32_nan_base | 0x600000 });
// A float64 has 64 bits, 1 for the sign, 11 for the exponent, the rest for the // A float64 has 64 bits, 1 for the sign, 11 for the exponent, the rest for the
@ -65,22 +65,22 @@ assertEqNaN(f32_qnan, { nan_low: f32_nan_base | 0x600000 });
var f64_nan_base_high = 0x7ff00000; var f64_nan_base_high = 0x7ff00000;
var f64_snan_code = '(f64.const nan:0x4000000000000)'; var f64_snan_code = '(f64.const nan:0x4000000000000)';
var f64_snan = wasmEvalText(`(module (func (result f64) ${f64_snan_code}) (export "" 0))`)(); var f64_snan = wasmEvalText(`(module (func (result f64) ${f64_snan_code}) (export "" 0))`).exports[""]();
assertEqNaN(f64_snan, { nan_low: 0x0, nan_high: f64_nan_base_high | 0x40000 }); assertEqNaN(f64_snan, { nan_low: 0x0, nan_high: f64_nan_base_high | 0x40000 });
var f64_qnan_code = '(f64.const nan:0xc000000000000)'; var f64_qnan_code = '(f64.const nan:0xc000000000000)';
var f64_qnan = wasmEvalText(`(module (func (result f64) ${f64_qnan_code}) (export "" 0))`)(); var f64_qnan = wasmEvalText(`(module (func (result f64) ${f64_qnan_code}) (export "" 0))`).exports[""]();
assertEqNaN(f64_qnan, { nan_low: 0x0, nan_high: f64_nan_base_high | 0xc0000 }); assertEqNaN(f64_qnan, { nan_low: 0x0, nan_high: f64_nan_base_high | 0xc0000 });
// Actual tests. // Actual tests.
// An example where a signaling nan gets transformed into a quiet nan: // An example where a signaling nan gets transformed into a quiet nan:
// snan + 0.0 = qnan // snan + 0.0 = qnan
var nan = wasmEvalText(`(module (func (result f32) (f32.add ${f32_snan_code} (f32.const 0))) (export "" 0))`)(); var nan = wasmEvalText(`(module (func (result f32) (f32.add ${f32_snan_code} (f32.const 0))) (export "" 0))`).exports[""]();
assertEqNaN(nan, f32_qnan); assertEqNaN(nan, f32_qnan);
// Globals. // Globals.
var m = evalText(`(module var m = wasmEvalText(`(module
(import "globals" "x" (global f32 immutable)) (import "globals" "x" (global f32 immutable))
(func (result f32) (get_global 0)) (func (result f32) (get_global 0))
(export "global" global 0) (export "global" global 0)
@ -90,7 +90,7 @@ var m = evalText(`(module
assertEqNaN(m.test(), f32_snan); assertEqNaN(m.test(), f32_snan);
assertEqNaN(m.global, f32_snan); assertEqNaN(m.global, f32_snan);
var m = evalText(`(module var m = wasmEvalText(`(module
(import "globals" "x" (global f64 immutable)) (import "globals" "x" (global f64 immutable))
(func (result f64) (get_global 0)) (func (result f64) (get_global 0))
(export "global" global 0) (export "global" global 0)
@ -109,7 +109,7 @@ function getConstant(code) {
return constantCache.get(code); return constantCache.get(code);
} }
let type = code.indexOf('f32') >= 0 ? 'f32' : 'f64'; let type = code.indexOf('f32') >= 0 ? 'f32' : 'f64';
let val = wasmEvalText(`(module (func (result ${type}) ${code}) (export "" 0))`)(); let val = wasmEvalText(`(module (func (result ${type}) ${code}) (export "" 0))`).exports[""]();
constantCache.set(code, val); constantCache.set(code, val);
return val; return val;
} }
@ -123,10 +123,10 @@ function test(type, opcode, snan_code, rhs_code, qnan_val) {
// - (constant, variable), // - (constant, variable),
// - (variable, constant), // - (variable, constant),
// - (variable, variable) // - (variable, variable)
assertEqNaN(wasmEvalText(`(module (func (result ${type}) (${type}.${opcode} ${snan_code} ${rhs_code})) (export "" 0))`)(), qnan_val); assertEqNaN(wasmEvalText(`(module (func (result ${type}) (${type}.${opcode} ${snan_code} ${rhs_code})) (export "" 0))`).exports[""](), qnan_val);
assertEqNaN(wasmEvalText(`(module (func (param ${type}) (result ${type}) (${type}.${opcode} (get_local 0) ${rhs_code})) (export "" 0))`)(snan_val), qnan_val); assertEqNaN(wasmEvalText(`(module (func (param ${type}) (result ${type}) (${type}.${opcode} (get_local 0) ${rhs_code})) (export "" 0))`).exports[""](snan_val), qnan_val);
assertEqNaN(wasmEvalText(`(module (func (param ${type}) (result ${type}) (${type}.${opcode} ${snan_code} (get_local 0))) (export "" 0))`)(rhs), qnan_val); assertEqNaN(wasmEvalText(`(module (func (param ${type}) (result ${type}) (${type}.${opcode} ${snan_code} (get_local 0))) (export "" 0))`).exports[""](rhs), qnan_val);
assertEqNaN(wasmEvalText(`(module (func (param ${type}) (param ${type}) (result ${type}) (${type}.${opcode} (get_local 0) (get_local 1))) (export "" 0))`)(snan_val, rhs), qnan_val); assertEqNaN(wasmEvalText(`(module (func (param ${type}) (param ${type}) (result ${type}) (${type}.${opcode} (get_local 0) (get_local 1))) (export "" 0))`).exports[""](snan_val, rhs), qnan_val);
} }
var f32_zero = '(f32.const 0)'; var f32_zero = '(f32.const 0)';

Просмотреть файл

@ -1,5 +1,4 @@
load(libdir + "wasm.js"); load(libdir + "wasm.js");
load(libdir + "asserts.js");
// Single-step profiling currently only works in the ARM simulator // Single-step profiling currently only works in the ARM simulator
if (!getBuildConfiguration()["arm-simulator"]) if (!getBuildConfiguration()["arm-simulator"])
@ -54,7 +53,7 @@ function test(code, expect)
{ {
enableSPSProfiling(); enableSPSProfiling();
var f = evalText(code).exports[""]; var f = wasmEvalText(code).exports[""];
enableSingleStepProfiling(); enableSingleStepProfiling();
f(); f();
assertEqStacks(disableSingleStepProfiling(), expect); assertEqStacks(disableSingleStepProfiling(), expect);
@ -100,7 +99,7 @@ testError(
`(module `(module
(type $good (func)) (type $good (func))
(type $bad (func (param i32))) (type $bad (func (param i32)))
(func $foo (call_indirect $bad (i32.const 0) (i32.const 1))) (func $foo (call_indirect $bad (i32.const 1) (i32.const 0)))
(func $bar (type $good)) (func $bar (type $good))
(table $bar) (table $bar)
(export "" $foo) (export "" $foo)
@ -108,7 +107,7 @@ testError(
Error); Error);
(function() { (function() {
var e = evalText(` var e = wasmEvalText(`
(module (module
(func $foo (result i32) (i32.const 42)) (func $foo (result i32) (i32.const 42))
(export "foo" $foo) (export "foo" $foo)
@ -148,7 +147,7 @@ Error);
assertEqStacks(disableSingleStepProfiling(), ["", ">", "0,>", ">", "", ">", "1,>", ">", ""]); assertEqStacks(disableSingleStepProfiling(), ["", ">", "0,>", ">", "", ">", "1,>", ">", ""]);
disableSPSProfiling(); disableSPSProfiling();
var e2 = evalText(` var e2 = wasmEvalText(`
(module (module
(type $v2i (func (result i32))) (type $v2i (func (result i32)))
(import "a" "b" (table 10)) (import "a" "b" (table 10))
@ -178,11 +177,11 @@ Error);
})(); })();
(function() { (function() {
var m1 = new Module(textToBinary(`(module var m1 = new Module(wasmTextToBinary(`(module
(func $foo (result i32) (i32.const 42)) (func $foo (result i32) (i32.const 42))
(export "foo" $foo) (export "foo" $foo)
)`)); )`));
var m2 = new Module(textToBinary(`(module var m2 = new Module(wasmTextToBinary(`(module
(import $foo "a" "foo" (result i32)) (import $foo "a" "foo" (result i32))
(func $bar (result i32) (call $foo)) (func $bar (result i32) (call $foo))
(export "bar" $bar) (export "bar" $bar)

Просмотреть файл

@ -1,11 +1,29 @@
// |jit-test| test-also-wasm-baseline // |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js"); load(libdir + "wasm.js");
assertEq(wasmEvalText(`(module assertErrorMessage(() => wasmEvalText(`(module
(func (result i32) (param i32) (func (result i32) (param i32)
(loop (if (i32.const 0) (br 0)) (get_local 0))) (loop (if (i32.const 0) (br 0)) (get_local 0)))
(export "" 0) (export "" 0)
)`)(42), 42); )`), TypeError, /unused values not explicitly dropped by end of block/);
assertErrorMessage(() => wasmEvalText(`(module
(func (param i32)
(loop (if (i32.const 0) (br 0)) (get_local 0)))
(export "" 0)
)`), TypeError, /unused values not explicitly dropped by end of block/);
assertErrorMessage(() => wasmEvalText(`(module
(func (result i32) (param i32)
(loop (if (i32.const 0) (br 0)) (drop (get_local 0))))
(export "" 0)
)`), TypeError, mismatchError("void", "i32"));
assertEq(wasmEvalText(`(module
(func (result i32) (param i32)
(loop (if (i32.const 0) (br 0))) (get_local 0))
(export "" 0)
)`).exports[""](42), 42);
wasmEvalText(`(module (func $func$0 wasmEvalText(`(module (func $func$0
(block (if (i32.const 1) (loop (br_table 0 (br 0))))) (block (if (i32.const 1) (loop (br_table 0 (br 0)))))
@ -17,16 +35,17 @@ wasmEvalText(`(module (func
) )
)`); )`);
wasmEvalText(`(module (func wasmEvalText(`(module (func (result i32)
(select (select
(block (block i32
(block (drop (block i32
(br_table (br_table
1 1
0 0
(i32.const 1) (i32.const 1)
(i32.const 0)
) )
) ))
(i32.const 2) (i32.const 2)
) )
(i32.const 3) (i32.const 3)
@ -63,7 +82,7 @@ wasmEvalText(`
(export "" 1) (export "" 1)
) )
`)(); `).exports[""]();
wasmEvalText(` wasmEvalText(`
(module (module
@ -74,14 +93,14 @@ wasmEvalText(`
(func (func
(call 1 (call 1
(i32.const 43) (i32.const 43)
(block $b (block $b i32
(if (i32.const 1) (if (i32.const 1)
(call 0 (call 0
(block (block i32
(call 0 (i32.const 42)) (call 0 (i32.const 42))
(br $b (i32.const 10))))) (br $b (i32.const 10)))))
(i32.const 44)))) (i32.const 44))))
(export "foo" 2)) (export "foo" 4))
`, { `, {
check: { check: {
one(x) { one(x) {
@ -92,9 +111,18 @@ wasmEvalText(`
assertEq(y, 10); assertEq(y, 10);
} }
} }
}).foo(); }).exports.foo();
wasmEvalText(`(module (func assertEq(wasmEvalText(`(module (func
(return)
(select
(loop (i32.const 1))
(loop (i32.const 2))
(i32.const 3)
)
) (export "" 0))`).exports[""](), undefined);
wasmEvalText(`(module (func (result i32)
(return (i32.const 0)) (return (i32.const 0))
(select (select
(loop (i32.const 1)) (loop (i32.const 1))
@ -130,16 +158,16 @@ wasmEvalText(`(module (func
) )
))`); ))`);
wasmEvalText(` assertErrorMessage(() => wasmEvalText(`
(module (module
(func $func$0 (func $func$0
(select (select
(if (if f32
(i32.const 0) (i32.const 0)
(f32.const 0) (f32.const 0)
(i32.const 0) (i32.const 0)
) )
(if (if f32
(i32.const 0) (i32.const 0)
(f32.const 0) (f32.const 0)
(i32.const 0) (i32.const 0)
@ -148,19 +176,19 @@ wasmEvalText(`
) )
) )
) )
`); `), TypeError, mismatchError("i32", "f32"));
wasmEvalText(` wasmEvalText(`
(module (module
(func (func (result i32)
(i32.add (i32.add
(block $outer (block $outer i32
(block $middle (drop (block $middle i32
(block $inner (block $inner i32
(br_table $middle $outer $inner (i32.const 42) (i32.const 1)) (br_table $middle $outer $inner (i32.const 42) (i32.const 1))
) )
(nop) (nop)
) ))
(i32.const 0) (i32.const 0)
) )
(i32.const 13) (i32.const 13)

Просмотреть файл

@ -7,6 +7,6 @@ if (typeof oomTest !== 'function' || !wasmIsSupported()) {
function foo() { function foo() {
var g = newGlobal(); var g = newGlobal();
g.eval(`o = Wasm.instantiateModule(wasmTextToBinary('(module (func) (export "" 0))'));`); g.eval(`o = new WebAssembly.Instance(new WebAssemby.Module(wasmTextToBinary('(module (func) (export "" 0))')));`);
} }
oomTest(foo); oomTest(foo);

Просмотреть файл

@ -14,4 +14,4 @@ assertEq(wasmEvalText(`(module
) )
) )
(export "" 0) (export "" 0)
)`)(), 121); )`).exports[""](), 121);

Просмотреть файл

@ -5,13 +5,15 @@ load(libdir + "wasm.js");
wasmEvalText( wasmEvalText(
`(module `(module
(func $func0 (param $var0 i32) (result i32) (func $func0 (param $arg0 i32) (result i32) (local $var0 i64)
(i32.add (set_local $var0 (i64.extend_u/i32 (get_local $arg0)))
(block (i32.wrap/i64
(loop $label1 $label0 (i64.add
(block $label2 (block i64
(br_table $label0 $label1 $label2 (i64.const 0) (get_local $var0))) (loop $label1 $label0
(set_local $var0 (i32.mul (i32.const 2) (get_local $var0)))) (drop (block $label2 i64
(set_local $var0 (i32.add (i32.const 4) (get_local $var0)))) (br_table $label2 (i64.const 0) (get_local $arg0))))
(i32.const 1))) (set_local $var0 (i64.mul (i64.const 2) (get_local $var0))))
(tee_local $var0 (i64.add (i64.const 4) (get_local $var0))))
(i64.const 1))))
(export "" 0))`); (export "" 0))`);

Просмотреть файл

@ -8,7 +8,7 @@ var m1 = wasmEvalText(
(type $type0 (func)) (type $type0 (func))
(func $func0 (func $func0
(select (unreachable) (return (nop)) (loop (i32.const 1)))) (select (unreachable) (return (nop)) (loop (i32.const 1))))
(export "" 0))`); (export "" 0))`).exports[""];
try { try {
m1(); m1();
@ -22,7 +22,7 @@ var m2 = wasmEvalText(
(type $type0 (func)) (type $type0 (func))
(func $func0 (func $func0
(select (i32.const 26) (unreachable) (i32.const 3))) (select (i32.const 26) (unreachable) (i32.const 3)))
(export "" 0))`); (export "" 0))`).exports[""];
try { try {
m2(); m2();

Просмотреть файл

@ -4,13 +4,13 @@ load(libdir + "wasm.js");
// Register allocation issue with LCompareI64AndBranch. // Register allocation issue with LCompareI64AndBranch.
let params = ''; let params = '';
let locals = ''; let locals = '';
let tests = ''; let tests = '(i64.const 0)';
for (let i = 15; i --> 0;) { for (let i = 15; i --> 0;) {
params += `\n(param i64)`; params += `\n(param i64)`;
locals += `\n(local i64)`; locals += `\n(local i64)`;
tests = ` tests = `
(if (if i64
(i64.eq (i64.eq
(get_local ${i + 8}) (get_local ${i + 8})
(get_local ${i}) (get_local ${i})
@ -21,16 +21,16 @@ for (let i = 15; i --> 0;) {
} }
let code = `(module let code = `(module
(func $i64 (func $i64 (result i64)
${params} ${locals} ${params} ${locals}
${tests} ${tests}
) )
)` )`
evalText(code); wasmEvalText(code);
// Bounds check elimination. // Bounds check elimination.
assertEq(evalText(`(module assertEq(wasmEvalText(`(module
(memory 1) (memory 1)
(func (param $p i32) (local $l i32) (result i32) (func (param $p i32) (local $l i32) (result i32)
(set_local $l (i32.const 0)) (set_local $l (i32.const 0))

Просмотреть файл

@ -13,12 +13,12 @@ const Memory = WebAssembly.Memory;
// Test for stale heap pointers after resize // Test for stale heap pointers after resize
// Grow directly from builtin call: // Grow directly from builtin call:
assertEq(evalText(`(module assertEq(wasmEvalText(`(module
(memory 1) (memory 1)
(func $test (result i32) (func $test (result i32)
(i32.store (i32.const 0) (i32.const 1)) (i32.store (i32.const 0) (i32.const 1))
(i32.store (i32.const 65532) (i32.const 10)) (i32.store (i32.const 65532) (i32.const 10))
(grow_memory (i32.const 99)) (drop (grow_memory (i32.const 99)))
(i32.store (i32.const 6553596) (i32.const 100)) (i32.store (i32.const 6553596) (i32.const 100))
(i32.add (i32.add
(i32.load (i32.const 0)) (i32.load (i32.const 0))
@ -29,10 +29,10 @@ assertEq(evalText(`(module
)`).exports.test(), 111); )`).exports.test(), 111);
// Grow during call_import: // Grow during call_import:
var exports = evalText(`(module var exports = wasmEvalText(`(module
(import $imp "" "imp") (import $imp "" "imp")
(memory 1) (memory 1)
(func $grow (grow_memory (i32.const 99))) (func $grow (drop (grow_memory (i32.const 99))))
(export "grow" $grow) (export "grow" $grow)
(func $test (result i32) (func $test (result i32)
(i32.store (i32.const 0) (i32.const 1)) (i32.store (i32.const 0) (i32.const 1))
@ -55,15 +55,15 @@ for (var i = 0; i < 10; i++)
// Grow during call_indirect: // Grow during call_indirect:
var mem = new Memory({initial:1}); var mem = new Memory({initial:1});
var tbl = new Table({initial:1, element:"anyfunc"}); var tbl = new Table({initial:1, element:"anyfunc"});
var exports1 = evalText(`(module var exports1 = wasmEvalText(`(module
(import "" "mem" (memory 1)) (import "" "mem" (memory 1))
(func $grow (func $grow
(i32.store (i32.const 65532) (i32.const 10)) (i32.store (i32.const 65532) (i32.const 10))
(grow_memory (i32.const 99)) (drop (grow_memory (i32.const 99)))
(i32.store (i32.const 6553596) (i32.const 100))) (i32.store (i32.const 6553596) (i32.const 100)))
(export "grow" $grow) (export "grow" $grow)
)`, {"":{mem}}).exports; )`, {"":{mem}}).exports;
var exports2 = evalText(`(module var exports2 = wasmEvalText(`(module
(import "" "tbl" (table 1)) (import "" "tbl" (table 1))
(import "" "mem" (memory 1)) (import "" "mem" (memory 1))
(type $v2v (func)) (type $v2v (func))
@ -84,9 +84,9 @@ assertEq(exports2.test(), 111);
var mem = new Memory({initial:1}); var mem = new Memory({initial:1});
new Int32Array(mem.buffer)[0] = 42; new Int32Array(mem.buffer)[0] = 42;
var mod = new Module(textToBinary(`(module var mod = new Module(wasmTextToBinary(`(module
(import "" "mem" (memory 1)) (import "" "mem" (memory 1))
(func $gm (param i32) (grow_memory (get_local 0))) (func $gm (param i32) (result i32) (grow_memory (get_local 0)))
(export "grow_memory" $gm) (export "grow_memory" $gm)
(func $cm (result i32) (current_memory)) (func $cm (result i32) (current_memory))
(export "current_memory" $cm) (export "current_memory" $cm)
@ -125,14 +125,14 @@ assertEq(new Int32Array(mem.buffer)[3*64*1024/4], 99);
// Test for stale table base pointers after resize // Test for stale table base pointers after resize
// Grow during call_import: // Grow during call_import:
var exports = evalText(`(module var exports = wasmEvalText(`(module
(type $v2i (func (result i32))) (type $v2i (func (result i32)))
(import $grow "" "grow") (import $grow "" "grow")
(table (resizable 1)) (table (resizable 1))
(func $test (result i32) (func $test (result i32)
(i32.add (i32.add
(call_indirect $v2i (i32.const 0)) (call_indirect $v2i (i32.const 0))
(block (block i32
(call $grow) (call $grow)
(call_indirect $v2i (i32.const 1))))) (call_indirect $v2i (i32.const 1)))))
(func $one (result i32) (i32.const 1)) (func $one (result i32) (i32.const 1))
@ -150,12 +150,12 @@ for (var i = 0; i < 10; i++)
assertEq(exports.tbl.length, 11); assertEq(exports.tbl.length, 11);
// Grow during call_indirect: // Grow during call_indirect:
var exports1 = evalText(`(module var exports1 = wasmEvalText(`(module
(import $grow "" "grow") (import $grow "" "grow")
(func $exp (call $grow)) (func $exp (call $grow))
(export "exp" $exp) (export "exp" $exp)
)`, {"":{grow() { exports2.tbl.grow(1); exports2.tbl.set(2, exports2.eleven) }}}).exports; )`, {"":{grow() { exports2.tbl.grow(1); exports2.tbl.set(2, exports2.eleven) }}}).exports;
var exports2 = evalText(`(module var exports2 = wasmEvalText(`(module
(type $v2v (func)) (type $v2v (func))
(type $v2i (func (result i32))) (type $v2i (func (result i32)))
(import $imp "" "imp") (import $imp "" "imp")
@ -164,7 +164,7 @@ var exports2 = evalText(`(module
(func $test (result i32) (func $test (result i32)
(i32.add (i32.add
(call_indirect $v2i (i32.const 1)) (call_indirect $v2i (i32.const 1))
(block (block i32
(call_indirect $v2v (i32.const 0)) (call_indirect $v2v (i32.const 0))
(call_indirect $v2i (i32.const 2))))) (call_indirect $v2i (i32.const 2)))))
(func $ten (result i32) (i32.const 10)) (func $ten (result i32) (i32.const 10))
@ -178,7 +178,7 @@ assertEq(exports2.test(), 21);
// Test for coherent length/contents // Test for coherent length/contents
var src = evalText(`(module var src = wasmEvalText(`(module
(func $one (result i32) (i32.const 1)) (func $one (result i32) (i32.const 1))
(export "one" $one) (export "one" $one)
(func $two (result i32) (i32.const 2)) (func $two (result i32) (i32.const 2))
@ -189,7 +189,7 @@ var src = evalText(`(module
var tbl = new Table({element:"anyfunc", initial:1}); var tbl = new Table({element:"anyfunc", initial:1});
tbl.set(0, src.one); tbl.set(0, src.one);
var mod = new Module(textToBinary(`(module var mod = new Module(wasmTextToBinary(`(module
(type $v2i (func (result i32))) (type $v2i (func (result i32)))
(import "" "tbl" (table 1)) (import "" "tbl" (table 1))
(func $ci (param i32) (result i32) (call_indirect $v2i (get_local 0))) (func $ci (param i32) (result i32) (call_indirect $v2i (get_local 0)))

Просмотреть файл

@ -220,7 +220,7 @@ function testNaNEqualityFunction() {
let f32 = new Float32Array(u8.buffer); let f32 = new Float32Array(u8.buffer);
// F64 NaN // F64 NaN
let someNaN = wasmEvalText('(module (func (result f64) (f64.const -nan:0x12345678)) (export "" 0))')(); let someNaN = wasmEvalText('(module (func (result f64) (f64.const -nan:0x12345678)) (export "" 0))').exports[""]();
i32[0] = someNaN.nan_low; i32[0] = someNaN.nan_low;
i32[1] = someNaN.nan_high; i32[1] = someNaN.nan_high;
assert(Number.isNaN(f64[0]), "we've stored a f64 NaN"); assert(Number.isNaN(f64[0]), "we've stored a f64 NaN");
@ -233,7 +233,7 @@ function testNaNEqualityFunction() {
assertEqNaN(someNaN, someNaN); assertEqNaN(someNaN, someNaN);
// F32 NaN // F32 NaN
someNaN = wasmEvalText('(module (func (result f32) (f32.const -nan:0x123456)) (export "" 0))')(); someNaN = wasmEvalText('(module (func (result f32) (f32.const -nan:0x123456)) (export "" 0))').exports[""]();
i32[0] = someNaN.nan_low; i32[0] = someNaN.nan_low;
assert(Number.isNaN(f32[0]), "we've stored a f32 NaN"); assert(Number.isNaN(f32[0]), "we've stored a f32 NaN");
@ -244,8 +244,8 @@ function testNaNEqualityFunction() {
assertEqNaN(someNaN, someNaN); assertEqNaN(someNaN, someNaN);
// Compare a NaN value against another one. // Compare a NaN value against another one.
let pNaN = wasmEvalText('(module (func (result f64) (f64.const nan)) (export "" 0))')(); let pNaN = wasmEvalText('(module (func (result f64) (f64.const nan)) (export "" 0))').exports[""]();
let nNaN = wasmEvalText('(module (func (result f64) (f64.const -nan)) (export "" 0))')(); let nNaN = wasmEvalText('(module (func (result f64) (f64.const -nan)) (export "" 0))').exports[""]();
i32[0] = pNaN.nan_low; i32[0] = pNaN.nan_low;
i32[1] = pNaN.nan_high; i32[1] = pNaN.nan_high;
@ -266,7 +266,7 @@ function exec(e) {
if (exprName === "module") { if (exprName === "module") {
let moduleText = e.toString(); let moduleText = e.toString();
module = evalText(moduleText, imports).exports; module = wasmEvalText(moduleText, imports).exports;
return; return;
} }
@ -296,7 +296,7 @@ function exec(e) {
return constantCache.get(key); return constantCache.get(key);
} }
var val = wasmEvalText(`(module (func (result ${type}) ${e}) (export "" 0))`)(); var val = wasmEvalText(`(module (func (result ${type}) ${e}) (export "" 0))`).exports[""]();
constantCache.set(key, val); constantCache.set(key, val);
return val; return val;
} }
@ -350,7 +350,7 @@ function exec(e) {
} }
// assert_invalid tests both the decoder *and* the parser itself. // assert_invalid tests both the decoder *and* the parser itself.
try { try {
assertEq(WebAssembly.validate(textToBinary(moduleText)), false); assertEq(WebAssembly.validate(wasmTextToBinary(moduleText)), false);
} catch(e) { } catch(e) {
if (/wasm text error/.test(e.toString())) if (/wasm text error/.test(e.toString()))
return; return;

Просмотреть файл

@ -1,34 +1,34 @@
(module (module
(memory 1 (segment 0 "abcdefghijklmnopqrstuvwxyz")) (import "spectest" "print" (func $print (param i32)))
(import $print "spectest" "print" (param i32))
(func $good (param $i i32) (memory 1)
(call_import $print (i32.load8_u offset=0 (get_local $i))) ;; 97 'a' (data (i32.const 0) "abcdefghijklmnopqrstuvwxyz")
(call_import $print (i32.load8_u offset=1 (get_local $i))) ;; 98 'b'
(call_import $print (i32.load8_u offset=2 (get_local $i))) ;; 99 'c'
(call_import $print (i32.load8_u offset=25 (get_local $i))) ;; 122 'z'
(call_import $print (i32.load16_u offset=0 (get_local $i))) ;; 25185 'ab' (func (export "good") (param $i i32)
(call_import $print (i32.load16_u align=1 (get_local $i))) ;; 25185 'ab' (call $print (i32.load8_u offset=0 (get_local $i))) ;; 97 'a'
(call_import $print (i32.load16_u offset=1 align=1 (get_local $i))) ;; 25442 'bc' (call $print (i32.load8_u offset=1 (get_local $i))) ;; 98 'b'
(call_import $print (i32.load16_u offset=2 (get_local $i))) ;; 25699 'cd' (call $print (i32.load8_u offset=2 (get_local $i))) ;; 99 'c'
(call_import $print (i32.load16_u offset=25 align=1 (get_local $i))) ;; 122 'z\0' (call $print (i32.load8_u offset=25 (get_local $i))) ;; 122 'z'
(call_import $print (i32.load offset=0 (get_local $i))) ;; 1684234849 'abcd' (call $print (i32.load16_u offset=0 (get_local $i))) ;; 25185 'ab'
(call_import $print (i32.load offset=1 align=1 (get_local $i))) ;; 1701077858 'bcde' (call $print (i32.load16_u align=1 (get_local $i))) ;; 25185 'ab'
(call_import $print (i32.load offset=2 align=2 (get_local $i))) ;; 1717920867 'cdef' (call $print (i32.load16_u offset=1 align=1 (get_local $i))) ;; 25442 'bc'
(call_import $print (i32.load offset=25 align=1 (get_local $i))) ;; 122 'z\0\0\0' (call $print (i32.load16_u offset=2 (get_local $i))) ;; 25699 'cd'
(call $print (i32.load16_u offset=25 align=1 (get_local $i))) ;; 122 'z\0'
(call $print (i32.load offset=0 (get_local $i))) ;; 1684234849 'abcd'
(call $print (i32.load offset=1 align=1 (get_local $i))) ;; 1701077858 'bcde'
(call $print (i32.load offset=2 align=2 (get_local $i))) ;; 1717920867 'cdef'
(call $print (i32.load offset=25 align=1 (get_local $i))) ;; 122 'z\0\0\0'
) )
(export "good" $good)
(func $bad2 (param $i i32) (i32.load offset=4294967295 (get_local $i))) (func (export "bad") (param $i i32) (drop (i32.load offset=4294967295 (get_local $i))))
(export "bad2" $bad2)
) )
(invoke "good" (i32.const 0)) (invoke "good" (i32.const 0))
(invoke "good" (i32.const 65507)) (invoke "good" (i32.const 65507))
(assert_trap (invoke "good" (i32.const 65508)) "out of bounds memory access") (assert_trap (invoke "good" (i32.const 65508)) "out of bounds memory access")
(assert_trap (invoke "bad2" (i32.const 0)) "out of bounds memory access") (assert_trap (invoke "bad" (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "bad2" (i32.const 1)) "out of bounds memory access") (assert_trap (invoke "bad" (i32.const 1)) "out of bounds memory access")
(assert_invalid (module (memory 1) (func $bad1 (param $i i32) (i32.load offset=4294967296 (get_local $i))) ) "offset too large") (assert_invalid (module (memory 1) (func $bad (param $i i32) (drop (i32.load offset=4294967296 (get_local $i))))) "offset too large")

Просмотреть файл

@ -1,5 +1,7 @@
(module "\00asm\0b\00\00\00") (module "\00asm\0c\00\00\00")
(module "\00asm" "\0b\00\00\00") (module "\00asm" "\0c\00\00\00")
(module $M "\00asm\0c\00\00\00")
(module $M "\00asm" "\0c\00\00\00")
(assert_invalid (module "") "unexpected end") (assert_invalid (module "") "unexpected end")
(assert_invalid (module "\01") "unexpected end") (assert_invalid (module "\01") "unexpected end")
@ -8,7 +10,7 @@
(assert_invalid (module "asm\00") "magic header not detected") (assert_invalid (module "asm\00") "magic header not detected")
(assert_invalid (module "\00asm") "unexpected end") (assert_invalid (module "\00asm") "unexpected end")
(assert_invalid (module "\00asm\0b") "unexpected end") (assert_invalid (module "\00asm\0c") "unexpected end")
(assert_invalid (module "\00asm\0b\00\00") "unexpected end") (assert_invalid (module "\00asm\0c\00\00") "unexpected end")
(assert_invalid (module "\00asm\10\00\00\00") "unknown binary version") (assert_invalid (module "\00asm\10\00\00\00") "unknown binary version")

Просмотреть файл

@ -1,35 +1,302 @@
;; Test `block` operator
(module (module
(func $empty ;; Auxiliary definition
(func $dummy)
(func (export "empty")
(block) (block)
(block $l) (block $l)
) )
(func $singular (result i32) (func (export "singular") (result i32)
(block (i32.const 7)) (block (nop))
(block i32 (i32.const 7))
) )
(func $multi (result i32) (func (export "multi") (result i32)
(block (i32.const 5) (i32.const 6) (i32.const 7) (i32.const 8)) (block (call $dummy) (call $dummy) (call $dummy) (call $dummy))
(block i32 (call $dummy) (call $dummy) (call $dummy) (i32.const 8))
) )
(func $effects (result i32) (func (export "nested") (result i32)
(block i32
(block (call $dummy) (block) (nop))
(block i32 (call $dummy) (i32.const 9))
)
)
(func (export "deep") (result i32)
(block i32 (block i32 (block i32 (block i32 (block i32 (block i32
(block i32 (block i32 (block i32 (block i32 (block i32 (block i32
(block i32 (block i32 (block i32 (block i32 (block i32 (block i32
(block i32 (block i32 (block i32 (block i32 (block i32 (block i32
(block i32 (block i32 (block i32 (block i32 (block i32 (block i32
(block i32 (block i32 (block i32 (block i32 (block i32 (block i32
(block i32 (block i32 (call $dummy) (i32.const 150)))
))))))
))))))
))))))
))))))
))))))
))))))
)
(func (export "as-unary-operand") (result i32)
(i32.ctz (block i32 (call $dummy) (i32.const 13)))
)
(func (export "as-binary-operand") (result i32)
(i32.mul
(block i32 (call $dummy) (i32.const 3))
(block i32 (call $dummy) (i32.const 4))
)
)
(func (export "as-test-operand") (result i32)
(i32.eqz (block i32 (call $dummy) (i32.const 13)))
)
(func (export "as-compare-operand") (result i32)
(f32.gt
(block f32 (call $dummy) (f32.const 3))
(block f32 (call $dummy) (f32.const 3))
)
)
(func (export "break-bare") (result i32)
(block (br 0) (unreachable))
(block (br_if 0 (i32.const 1)) (unreachable))
(block (br_table 0 (i32.const 0)) (unreachable))
(block (br_table 0 0 0 (i32.const 1)) (unreachable))
(i32.const 19)
)
(func (export "break-value") (result i32)
(block i32 (br 0 (i32.const 18)) (i32.const 19))
)
(func (export "break-repeated") (result i32)
(block i32
(br 0 (i32.const 18))
(br 0 (i32.const 19))
(br_if 0 (i32.const 20) (i32.const 0))
(br_if 0 (i32.const 20) (i32.const 1))
(br 0 (i32.const 21))
(br_table 0 (i32.const 22) (i32.const 4))
(br_table 0 0 0 (i32.const 23) (i32.const 1))
(i32.const 21)
)
)
(func (export "break-inner") (result i32)
(local i32)
(set_local 0 (i32.const 0))
(set_local 0 (i32.add (get_local 0) (block i32 (block i32 (br 1 (i32.const 0x1))))))
(set_local 0 (i32.add (get_local 0) (block i32 (block (br 0)) (i32.const 0x2))))
(set_local 0
(i32.add (get_local 0) (block i32 (i32.ctz (br 0 (i32.const 0x4)))))
)
(set_local 0
(i32.add (get_local 0) (block i32 (i32.ctz (block i32 (br 1 (i32.const 0x8))))))
)
(get_local 0)
)
(func (export "effects") (result i32)
(local i32) (local i32)
(block (block
(set_local 0 (i32.const 1)) (set_local 0 (i32.const 1))
(set_local 0 (i32.mul (get_local 0) (i32.const 3))) (set_local 0 (i32.mul (get_local 0) (i32.const 3)))
(set_local 0 (i32.sub (get_local 0) (i32.const 5))) (set_local 0 (i32.sub (get_local 0) (i32.const 5)))
(set_local 0 (i32.mul (get_local 0) (i32.const 7))) (set_local 0 (i32.mul (get_local 0) (i32.const 7)))
(br 0)
(set_local 0 (i32.mul (get_local 0) (i32.const 100)))
) )
(get_local 0) (i32.eq (get_local 0) (i32.const -14))
) )
(export "empty" $empty)
(export "singular" $singular)
(export "multi" $multi)
(export "effects" $effects)
) )
(invoke "empty") (assert_return (invoke "empty"))
(assert_return (invoke "singular") (i32.const 7)) (assert_return (invoke "singular") (i32.const 7))
(assert_return (invoke "multi") (i32.const 8)) (assert_return (invoke "multi") (i32.const 8))
(assert_return (invoke "effects") (i32.const -14)) (assert_return (invoke "nested") (i32.const 9))
(assert_return (invoke "deep") (i32.const 150))
(assert_return (invoke "as-unary-operand") (i32.const 0))
(assert_return (invoke "as-binary-operand") (i32.const 12))
(assert_return (invoke "as-test-operand") (i32.const 0))
(assert_return (invoke "as-compare-operand") (i32.const 0))
(assert_return (invoke "break-bare") (i32.const 19))
(assert_return (invoke "break-value") (i32.const 18))
(assert_return (invoke "break-repeated") (i32.const 18))
(assert_return (invoke "break-inner") (i32.const 0xf))
(assert_return (invoke "effects") (i32.const 1))
(assert_invalid
(module (func $type-empty-i32 (result i32) (block)))
"type mismatch"
)
(assert_invalid
(module (func $type-empty-i64 (result i64) (block)))
"type mismatch"
)
(assert_invalid
(module (func $type-empty-f32 (result f32) (block)))
"type mismatch"
)
(assert_invalid
(module (func $type-empty-f64 (result f64) (block)))
"type mismatch"
)
(assert_invalid
(module (func $type-binary (result i64)
(block i64 i64 (i64.const 1) (i64.const 2)) i64.add
))
"invalid result arity"
)
(assert_invalid
(module (func $type-binary-with-nop (result i32)
(block i32 i32 (nop) (i32.const 7) (nop) (i32.const 8)) i32.add
))
"invalid result arity"
)
(assert_invalid
(module (func $type-value-num-vs-void
(block (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-value-void-vs-num (result i32)
(block (nop))
))
"type mismatch"
)
(assert_invalid
(module (func $type-value-num-vs-num (result i32)
(block (f32.const 0))
))
"type mismatch"
)
(; TODO(stack): soft failure
(assert_invalid
(module (func $type-value-num-vs-void-after-break
(block (br 0) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-value-void-vs-num-after-break (result i32)
(block (i32.const 1) (br 0) (nop))
))
"type mismatch"
)
(assert_invalid
(module (func $type-value-num-vs-num-after-break (result i32)
(block (i32.const 1) (br 0) (f32.const 0))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-second-void-vs-num (result i32)
(block i32 (br 0 (i32.const 1)) (br 0 (nop)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-second-num-vs-num (result i32)
(block i32 (br 0 (i32.const 1)) (br 0 (f64.const 1)))
))
"type mismatch"
)
;)
;; TODO(stack): move this elsewhere
(module (func $type-break-num-vs-void
(block (i32.const 66) (br 0))
))
(assert_invalid
(module (func $type-break-last-void-vs-num (result i32)
(block i32 (br 0))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-void-vs-num (result i32)
(block i32 (br 0) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-void-vs-num (result i32)
(block (br 0 (nop)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-num-vs-num (result i32)
(block (br 0 (i64.const 1)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-first-void-vs-num (result i32)
(block (br 0 (nop)) (br 0 (i32.const 1)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-first-num-vs-num (result i32)
(block (br 0 (i64.const 1)) (br 0 (i32.const 1)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-nested-num-vs-void
(block i32 (block i32 (br 1 (i32.const 1))) (br 0))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-nested-empty-vs-num (result i32)
(block (block (br 1)) (br 0 (i32.const 1)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-nested-void-vs-num (result i32)
(block (block (br 1 (nop))) (br 0 (i32.const 1)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-nested-num-vs-num (result i32)
(block (block (br 1 (i64.const 1))) (br 0 (i32.const 1)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-operand-empty-vs-num (result i32)
(i32.ctz (block (br 0)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-operand-void-vs-num (result i32)
(i64.ctz (block (br 0 (nop))))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-operand-num-vs-num (result i32)
(i64.ctz (block (br 0 (i64.const 9))))
))
"type mismatch"
)

Просмотреть файл

@ -1,15 +0,0 @@
(;;)
(;(((((((((( ;)
(;)))))))))));)
(; (module $error) ;)
(; (module $error) ;)
(; (module $error)
;)
(;
(module $error);)
(; a (; b ;) c ;)
(; ;; bla ;)
(; ;; bla
;)
(module) ;; dummy

Просмотреть файл

@ -1,2 +0,0 @@
// |jit-test| test-also-wasm-baseline
var importedArgs = ['block_comments.wast']; load(scriptdir + '../spec.js');

Просмотреть файл

@ -0,0 +1,425 @@
;; Test `br` operator
(module
;; Auxiliary definition
(func $dummy)
(func (export "type-i32") (block (drop (i32.ctz (br 0)))))
(func (export "type-i64") (block (drop (i64.ctz (br 0)))))
(func (export "type-f32") (block (drop (f32.neg (br 0)))))
(func (export "type-f64") (block (drop (f64.neg (br 0)))))
(func (export "type-i32-value") (result i32)
(block i32 (i32.ctz (br 0 (i32.const 1))))
)
(func (export "type-i64-value") (result i64)
(block i64 (i64.ctz (br 0 (i64.const 2))))
)
(func (export "type-f32-value") (result f32)
(block f32 (f32.neg (br 0 (f32.const 3))))
)
(func (export "type-f64-value") (result f64)
(block f64 (f64.neg (br 0 (f64.const 4))))
)
(func (export "as-block-first")
(block (br 0) (call $dummy))
)
(func (export "as-block-mid")
(block (call $dummy) (br 0) (call $dummy))
)
(func (export "as-block-last")
(block (nop) (call $dummy) (br 0))
)
(func (export "as-block-value") (result i32)
(block i32 (nop) (call $dummy) (br 0 (i32.const 2)))
)
(func (export "as-loop-first") (result i32)
(block i32 (loop i32 (br 1 (i32.const 3)) (i32.const 2)))
)
(func (export "as-loop-mid") (result i32)
(block i32 (loop i32 (call $dummy) (br 1 (i32.const 4)) (i32.const 2)))
)
(func (export "as-loop-last") (result i32)
(block i32 (loop i32 (nop) (call $dummy) (br 1 (i32.const 5))))
)
(func (export "as-br-value") (result i32)
(block i32 (br 0 (br 0 (i32.const 9))))
)
(func (export "as-br_if-cond")
(block (br_if 0 (br 0)))
)
(func (export "as-br_if-value") (result i32)
(block i32 (br_if 0 (br 0 (i32.const 8)) (i32.const 1)) (i32.const 7))
)
(func (export "as-br_if-value-cond") (result i32)
(block i32 (br_if 0 (i32.const 6) (br 0 (i32.const 9))) (i32.const 7))
)
(func (export "as-br_table-index")
(block (br_table 0 0 0 (br 0)))
)
(func (export "as-br_table-value") (result i32)
(block i32
(br_table 0 0 0 (br 0 (i32.const 10)) (i32.const 1)) (i32.const 7)
)
)
(func (export "as-br_table-value-index") (result i32)
(block i32
(br_table 0 0 (i32.const 6) (br 0 (i32.const 11))) (i32.const 7)
)
)
(func (export "as-return-value") (result i64)
(block i64 (return (br 0 (i64.const 7))))
)
(func (export "as-if-cond") (result i32)
(block i32 (if i32 (br 0 (i32.const 2)) (i32.const 0) (i32.const 1)))
)
(func (export "as-if-then") (param i32 i32) (result i32)
(block i32 (if i32 (get_local 0) (br 1 (i32.const 3)) (get_local 1)))
)
(func (export "as-if-else") (param i32 i32) (result i32)
(block i32 (if i32 (get_local 0) (get_local 1) (br 1 (i32.const 4))))
)
(func (export "as-select-first") (param i32 i32) (result i32)
(block i32 (select (br 0 (i32.const 5)) (get_local 0) (get_local 1)))
)
(func (export "as-select-second") (param i32 i32) (result i32)
(block i32 (select (get_local 0) (br 0 (i32.const 6)) (get_local 1)))
)
(func (export "as-select-cond") (result i32)
(block i32 (select (i32.const 0) (i32.const 1) (br 0 (i32.const 7))))
)
(func $f (param i32 i32 i32) (result i32) (i32.const -1))
(func (export "as-call-first") (result i32)
(block i32 (call $f (br 0 (i32.const 12)) (i32.const 2) (i32.const 3)))
)
(func (export "as-call-mid") (result i32)
(block i32 (call $f (i32.const 1) (br 0 (i32.const 13)) (i32.const 3)))
)
(func (export "as-call-last") (result i32)
(block i32 (call $f (i32.const 1) (i32.const 2) (br 0 (i32.const 14))))
)
(type $sig (func (param i32 i32 i32) (result i32)))
(table anyfunc (elem $f))
(func (export "as-call_indirect-func") (result i32)
(block i32
(call_indirect $sig
(br 0 (i32.const 20))
(i32.const 1) (i32.const 2) (i32.const 3)
)
)
)
(func (export "as-call_indirect-first") (result i32)
(block i32
(call_indirect $sig
(i32.const 0)
(br 0 (i32.const 21)) (i32.const 2) (i32.const 3)
)
)
)
(func (export "as-call_indirect-mid") (result i32)
(block i32
(call_indirect $sig
(i32.const 0)
(i32.const 1) (br 0 (i32.const 22)) (i32.const 3)
)
)
)
(func (export "as-call_indirect-last") (result i32)
(block i32
(call_indirect $sig
(i32.const 0)
(i32.const 1) (i32.const 2) (br 0 (i32.const 23))
)
)
)
(func (export "as-set_local-value") (result i32) (local f32)
(block i32 (set_local 0 (br 0 (i32.const 17))) (i32.const -1))
)
(memory 1)
(func (export "as-load-address") (result f32)
(block f32 (f32.load (br 0 (f32.const 1.7))))
)
(func (export "as-loadN-address") (result i64)
(block i64 (i64.load8_s (br 0 (i64.const 30))))
)
(func (export "as-store-address") (result i32)
(block i32 (f64.store (br 0 (i32.const 30)) (f64.const 7)) (i32.const -1))
)
(func (export "as-store-value") (result i32)
(block i32 (i64.store (i32.const 2) (br 0 (i32.const 31))) (i32.const -1))
)
(func (export "as-storeN-address") (result i32)
(block i32 (i32.store8 (br 0 (i32.const 32)) (i32.const 7)) (i32.const -1))
)
(func (export "as-storeN-value") (result i32)
(block i32 (i64.store16 (i32.const 2) (br 0 (i32.const 33))) (i32.const -1))
)
(func (export "as-unary-operand") (result f32)
(block f32 (f32.neg (br 0 (f32.const 3.4))))
)
(func (export "as-binary-left") (result i32)
(block i32 (i32.add (br 0 (i32.const 3)) (i32.const 10)))
)
(func (export "as-binary-right") (result i64)
(block i64 (i64.sub (i64.const 10) (br 0 (i64.const 45))))
)
(func (export "as-test-operand") (result i32)
(block i32 (i32.eqz (br 0 (i32.const 44))))
)
(func (export "as-compare-left") (result i32)
(block i32 (f64.le (br 0 (i32.const 43)) (f64.const 10)))
)
(func (export "as-compare-right") (result i32)
(block i32 (f32.ne (f32.const 10) (br 0 (i32.const 42))))
)
(func (export "as-convert-operand") (result i32)
(block i32 (i32.wrap/i64 (br 0 (i32.const 41))))
)
(func (export "as-grow_memory-size") (result i32)
(block i32 (grow_memory (br 0 (i32.const 40))))
)
(func (export "nested-block-value") (result i32)
(i32.add
(i32.const 1)
(block i32
(call $dummy)
(i32.add (i32.const 4) (br 0 (i32.const 8)))
)
)
)
(func (export "nested-br-value") (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(drop
(block i32
(drop (i32.const 4))
(br 0 (br 1 (i32.const 8)))
)
)
(i32.const 16)
)
)
)
(func (export "nested-br_if-value") (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(drop
(block i32
(drop (i32.const 4))
(br_if 0 (br 1 (i32.const 8)) (i32.const 1))
(i32.const 32)
)
)
(i32.const 16)
)
)
)
(func (export "nested-br_if-value-cond") (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(br_if 0 (i32.const 4) (br 0 (i32.const 8)))
(i32.const 16)
)
)
)
(func (export "nested-br_table-value") (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(drop
(block i32
(drop (i32.const 4))
(br_table 0 (br 1 (i32.const 8)) (i32.const 1))
)
)
(i32.const 16)
)
)
)
(func (export "nested-br_table-value-index") (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(br_table 0 (i32.const 4) (br 0 (i32.const 8)))
(i32.const 16)
)
)
)
)
(assert_return (invoke "type-i32"))
(assert_return (invoke "type-i64"))
(assert_return (invoke "type-f32"))
(assert_return (invoke "type-f64"))
(assert_return (invoke "type-i32-value") (i32.const 1))
(assert_return (invoke "type-i64-value") (i64.const 2))
(assert_return (invoke "type-f32-value") (f32.const 3))
(assert_return (invoke "type-f64-value") (f64.const 4))
(assert_return (invoke "as-block-first"))
(assert_return (invoke "as-block-mid"))
(assert_return (invoke "as-block-last"))
(assert_return (invoke "as-block-value") (i32.const 2))
(assert_return (invoke "as-loop-first") (i32.const 3))
(assert_return (invoke "as-loop-mid") (i32.const 4))
(assert_return (invoke "as-loop-last") (i32.const 5))
(assert_return (invoke "as-br-value") (i32.const 9))
(assert_return (invoke "as-br_if-cond"))
(assert_return (invoke "as-br_if-value") (i32.const 8))
(assert_return (invoke "as-br_if-value-cond") (i32.const 9))
(assert_return (invoke "as-br_table-index"))
(assert_return (invoke "as-br_table-value") (i32.const 10))
(assert_return (invoke "as-br_table-value-index") (i32.const 11))
(assert_return (invoke "as-return-value") (i64.const 7))
(assert_return (invoke "as-if-cond") (i32.const 2))
(assert_return (invoke "as-if-then" (i32.const 1) (i32.const 6)) (i32.const 3))
(assert_return (invoke "as-if-then" (i32.const 0) (i32.const 6)) (i32.const 6))
(assert_return (invoke "as-if-else" (i32.const 0) (i32.const 6)) (i32.const 4))
(assert_return (invoke "as-if-else" (i32.const 1) (i32.const 6)) (i32.const 6))
(assert_return (invoke "as-select-first" (i32.const 0) (i32.const 6)) (i32.const 5))
(assert_return (invoke "as-select-first" (i32.const 1) (i32.const 6)) (i32.const 5))
(assert_return (invoke "as-select-second" (i32.const 0) (i32.const 6)) (i32.const 6))
(assert_return (invoke "as-select-second" (i32.const 1) (i32.const 6)) (i32.const 6))
(assert_return (invoke "as-select-cond") (i32.const 7))
(assert_return (invoke "as-call-first") (i32.const 12))
(assert_return (invoke "as-call-mid") (i32.const 13))
(assert_return (invoke "as-call-last") (i32.const 14))
(assert_return (invoke "as-call_indirect-func") (i32.const 20))
(assert_return (invoke "as-call_indirect-first") (i32.const 21))
(assert_return (invoke "as-call_indirect-mid") (i32.const 22))
(assert_return (invoke "as-call_indirect-last") (i32.const 23))
(assert_return (invoke "as-set_local-value") (i32.const 17))
(assert_return (invoke "as-load-address") (f32.const 1.7))
(assert_return (invoke "as-loadN-address") (i64.const 30))
(assert_return (invoke "as-store-address") (i32.const 30))
(assert_return (invoke "as-store-value") (i32.const 31))
(assert_return (invoke "as-storeN-address") (i32.const 32))
(assert_return (invoke "as-storeN-value") (i32.const 33))
(assert_return (invoke "as-unary-operand") (f32.const 3.4))
(assert_return (invoke "as-binary-left") (i32.const 3))
(assert_return (invoke "as-binary-right") (i64.const 45))
(assert_return (invoke "as-test-operand") (i32.const 44))
(assert_return (invoke "as-compare-left") (i32.const 43))
(assert_return (invoke "as-compare-right") (i32.const 42))
(assert_return (invoke "as-convert-operand") (i32.const 41))
(assert_return (invoke "as-grow_memory-size") (i32.const 40))
(assert_return (invoke "nested-block-value") (i32.const 9))
(assert_return (invoke "nested-br-value") (i32.const 9))
(assert_return (invoke "nested-br_if-value") (i32.const 9))
(assert_return (invoke "nested-br_if-value-cond") (i32.const 9))
(assert_return (invoke "nested-br_table-value") (i32.const 9))
(assert_return (invoke "nested-br_table-value-index") (i32.const 9))
(assert_invalid
(module (func $type-arg-empty-vs-num (result i32)
(block (br 0) (i32.const 1))
))
"type mismatch"
)
;; TODO(stack): move this elsewhere
(module (func $type-arg-num-vs-void
(block (i32.const 0) (br 0))
))
(; TODO(stack): soft failure
(assert_invalid
(module (func $type-arg-poly-vs-empty
(block (br 0 (unreachable)))
))
"type mismatch"
)
;)
(assert_invalid
(module (func $type-arg-void-vs-num (result i32)
(block (br 0 (nop)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-arg-num-vs-num (result i32)
(block (br 0 (i64.const 1)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-binary (result i64)
(block i64 i64 (i64.const 1) (i64.const 2) (br 0)) (i64.add)
))
"invalid result arity"
)
(assert_invalid
(module (func $type-binary-with-nop (result i32)
(block i32 i32 (nop) (i32.const 7) (nop) (i32.const 8) (br 0)) (i32.add)
))
"invalid result arity"
)
(assert_invalid
(module (func $unbound-label (br 1)))
"unknown label"
)
(assert_invalid
(module (func $unbound-nested-label (block (block (br 5)))))
"unknown label"
)
(assert_invalid
(module (func $large-label (br 0x10000001)))
"unknown label"
)

Просмотреть файл

@ -0,0 +1,4 @@
// |jit-test| test-also-wasm-baseline
// TODO: new anyfunc table syntax
quit();
var importedArgs = ['br.wast']; load(scriptdir + '../spec.js');

Просмотреть файл

@ -0,0 +1,321 @@
;; Test `br_if` operator
(module
(func $dummy)
(func (export "as-block-first") (param i32) (result i32)
(block (br_if 0 (get_local 0)) (return (i32.const 2))) (i32.const 3)
)
(func (export "as-block-mid") (param i32) (result i32)
(block (call $dummy) (br_if 0 (get_local 0)) (return (i32.const 2)))
(i32.const 3)
)
(func (export "as-block-last") (param i32)
(block (call $dummy) (call $dummy) (br_if 0 (get_local 0)))
)
(func (export "as-block-first-value") (param i32) (result i32)
(block i32 (br_if 0 (i32.const 10) (get_local 0)) (return (i32.const 11)))
)
(func (export "as-block-mid-value") (param i32) (result i32)
(block i32 (call $dummy) (br_if 0 (i32.const 20) (get_local 0)) (return (i32.const 21)))
)
(func (export "as-block-last-value") (param i32) (result i32)
(block i32
(call $dummy) (call $dummy) (br_if 0 (i32.const 11) (get_local 0))
)
)
(func (export "as-loop-first") (param i32) (result i32)
(block (loop (br_if 1 (get_local 0)) (return (i32.const 2)))) (i32.const 3)
)
(func (export "as-loop-mid") (param i32) (result i32)
(block (loop (call $dummy) (br_if 1 (get_local 0)) (return (i32.const 2))))
(i32.const 4)
)
(func (export "as-loop-last") (param i32)
(loop (call $dummy) (br_if 1 (get_local 0)))
)
(func (export "as-if-then") (param i32 i32)
(block (if (get_local 0) (br_if 1 (get_local 1)) (call $dummy)))
)
(func (export "as-if-else") (param i32 i32)
(block (if (get_local 0) (call $dummy) (br_if 1 (get_local 1))))
)
(func (export "nested-block-value") (param i32) (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(i32.add
(i32.const 4)
(block i32
(drop (br_if 1 (i32.const 8) (get_local 0)))
(i32.const 16)
)
)
)
)
)
(func (export "nested-br-value") (param i32) (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(br 0
(block i32 (drop (br_if 1 (i32.const 8) (get_local 0))) (i32.const 4))
)
(i32.const 16)
)
)
)
(func (export "nested-br_if-value") (param i32) (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(drop (br_if 0
(block i32 (drop (br_if 1 (i32.const 8) (get_local 0))) (i32.const 4))
(i32.const 1)
))
(i32.const 16)
)
)
)
(func (export "nested-br_if-value-cond") (param i32) (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(drop (br_if 0
(i32.const 4)
(block i32 (drop (br_if 1 (i32.const 8) (get_local 0))) (i32.const 1))
))
(i32.const 16)
)
)
)
(func (export "nested-br_table-value") (param i32) (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(br_table 0
(block i32 (drop (br_if 1 (i32.const 8) (get_local 0))) (i32.const 4))
(i32.const 1)
)
(i32.const 16)
)
)
)
(func (export "nested-br_table-value-index") (param i32) (result i32)
(i32.add
(i32.const 1)
(block i32
(drop (i32.const 2))
(br_table 0
(i32.const 4)
(block i32 (drop (br_if 1 (i32.const 8) (get_local 0))) (i32.const 1))
)
(i32.const 16)
)
)
)
)
(assert_return (invoke "as-block-first" (i32.const 0)) (i32.const 2))
(assert_return (invoke "as-block-first" (i32.const 1)) (i32.const 3))
(assert_return (invoke "as-block-mid" (i32.const 0)) (i32.const 2))
(assert_return (invoke "as-block-mid" (i32.const 1)) (i32.const 3))
(assert_return (invoke "as-block-last" (i32.const 0)))
(assert_return (invoke "as-block-last" (i32.const 1)))
(assert_return (invoke "as-block-last-value" (i32.const 0)) (i32.const 11))
(assert_return (invoke "as-block-last-value" (i32.const 1)) (i32.const 11))
(assert_return (invoke "as-loop-first" (i32.const 0)) (i32.const 2))
(assert_return (invoke "as-loop-first" (i32.const 1)) (i32.const 3))
(assert_return (invoke "as-loop-mid" (i32.const 0)) (i32.const 2))
(assert_return (invoke "as-loop-mid" (i32.const 1)) (i32.const 4))
(assert_return (invoke "as-loop-last" (i32.const 0)))
(assert_return (invoke "as-loop-last" (i32.const 1)))
(assert_return (invoke "as-if-then" (i32.const 0) (i32.const 0)))
(assert_return (invoke "as-if-then" (i32.const 4) (i32.const 0)))
(assert_return (invoke "as-if-then" (i32.const 0) (i32.const 1)))
(assert_return (invoke "as-if-then" (i32.const 4) (i32.const 1)))
(assert_return (invoke "as-if-else" (i32.const 0) (i32.const 0)))
(assert_return (invoke "as-if-else" (i32.const 3) (i32.const 0)))
(assert_return (invoke "as-if-else" (i32.const 0) (i32.const 1)))
(assert_return (invoke "as-if-else" (i32.const 3) (i32.const 1)))
(assert_return (invoke "nested-block-value" (i32.const 0)) (i32.const 21))
(assert_return (invoke "nested-block-value" (i32.const 1)) (i32.const 9))
(assert_return (invoke "nested-br-value" (i32.const 0)) (i32.const 5))
(assert_return (invoke "nested-br-value" (i32.const 1)) (i32.const 9))
(assert_return (invoke "nested-br_if-value" (i32.const 0)) (i32.const 5))
(assert_return (invoke "nested-br_if-value" (i32.const 1)) (i32.const 9))
(assert_return (invoke "nested-br_if-value-cond" (i32.const 0)) (i32.const 5))
(assert_return (invoke "nested-br_if-value-cond" (i32.const 1)) (i32.const 9))
(assert_return (invoke "nested-br_table-value" (i32.const 0)) (i32.const 5))
(assert_return (invoke "nested-br_table-value" (i32.const 1)) (i32.const 9))
(assert_return (invoke "nested-br_table-value-index" (i32.const 0)) (i32.const 5))
(assert_return (invoke "nested-br_table-value-index" (i32.const 1)) (i32.const 9))
(assert_invalid
(module (func $type-false-i32 (block (i32.ctz (br_if 0 (i32.const 0))))))
"type mismatch"
)
(assert_invalid
(module (func $type-false-i64 (block (i64.ctz (br_if 0 (i32.const 0))))))
"type mismatch"
)
(assert_invalid
(module (func $type-false-f32 (block (f32.neg (br_if 0 (i32.const 0))))))
"type mismatch"
)
(assert_invalid
(module (func $type-false-f64 (block (f64.neg (br_if 0 (i32.const 0))))))
"type mismatch"
)
(assert_invalid
(module (func $type-true-i32 (block (i32.ctz (br_if 0 (i32.const 1))))))
"type mismatch"
)
(assert_invalid
(module (func $type-true-i64 (block (i64.ctz (br_if 0 (i64.const 1))))))
"type mismatch"
)
(assert_invalid
(module (func $type-true-f32 (block (f32.neg (br_if 0 (f32.const 1))))))
"type mismatch"
)
(assert_invalid
(module (func $type-true-f64 (block (f64.neg (br_if 0 (i64.const 1))))))
"type mismatch"
)
(assert_invalid
(module (func $type-false-arg-void-vs-num (result i32)
(block i32 (br_if 0 (i32.const 0)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-true-arg-void-vs-num (result i32)
(block i32 (br_if 0 (i32.const 1)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-false-arg-num-vs-void
(block (br_if 0 (i32.const 0) (i32.const 0)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-true-arg-num-vs-void
(block (br_if 0 (i32.const 0) (i32.const 1)))
))
"type mismatch"
)
(; TODO(stack): soft failure
(assert_invalid
(module (func $type-false-arg-poly-vs-empty
(block (br_if 0 (unreachable) (i32.const 0)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-true-arg-poly-vs-empty
(block (br_if 0 (unreachable) (i32.const 1)))
))
"type mismatch"
)
;)
(assert_invalid
(module (func $type-false-arg-void-vs-num (result i32)
(block i32 (br_if 0 (nop) (i32.const 0)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-true-arg-void-vs-num (result i32)
(block i32 (br_if 0 (nop) (i32.const 1)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-false-arg-num-vs-num (result i32)
(block i32 (drop (br_if 0 (i64.const 1) (i32.const 0))) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-true-arg-num-vs-num (result i32)
(block i32 (drop (br_if 0 (i64.const 1) (i32.const 0))) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-cond-void-vs-i32
(block (br_if 0 (nop)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-cond-num-vs-i32
(block (br_if 0 (i64.const 0)))
))
"type mismatch"
)
(assert_invalid
(module (func $type-arg-cond-void-vs-i32 (result i32)
(block i32 (br_if 0 (i32.const 0) (nop)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-arg-cond-num-vs-i32 (result i32)
(block i32 (br_if 0 (i32.const 0) (i64.const 0)) (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-binary (result i64)
(block i64 i64 (i64.const 1) (i64.const 2) (i64.const 3) (br_if 0))
(i64.add)
))
"invalid result arity"
)
(assert_invalid
(module (func $type-binary-with-nop (result i32)
(block i32 i32 (nop) (i32.const 7) (nop) (i32.const 8) (i64.const 3) (br_if 0))
(i32.add)
))
"invalid result arity"
)
(assert_invalid
(module (func $unbound-label (br_if 1 (i32.const 1))))
"unknown label"
)
(assert_invalid
(module (func $unbound-nested-label (block (block (br_if 5 (i32.const 1))))))
"unknown label"
)
(assert_invalid
(module (func $large-label (br_if 0x10000001 (i32.const 1))))
"unknown label"
)

Просмотреть файл

@ -0,0 +1,2 @@
// |jit-test| test-also-wasm-baseline
var importedArgs = ['br_if.wast']; load(scriptdir + '../spec.js');

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,4 @@
// |jit-test| test-also-wasm-baseline
// TODO: new anyfunc table syntax
quit();
var importedArgs = ['br_table.wast']; load(scriptdir + '../spec.js');

Просмотреть файл

@ -1,64 +1,9 @@
(module (module
(func $br (block (br 0))) (func (export "br") (block (br 0)))
(export "br" $br) (func (export "br_if") (block (br_if 0 (i32.const 1))))
(func (export "br_table") (block (br_table 0 (i32.const 0))))
(func $br-nop (block (br 0 (nop))))
(export "br-nop" $br-nop)
(func $br-drop (block (br 0 (i32.const 1))))
(export "br-drop" $br-drop)
(func $br-block-nop (block (br 0 (block (i32.const 1) (nop)))))
(export "br-block-nop" $br-block-nop)
(func $br-block-drop (block (br 0 (block (nop) (i32.const 1)))))
(export "br-block-drop" $br-block-drop)
(func $br_if (block (br_if 0 (i32.const 1))))
(export "br_if" $br_if)
(func $br_if-nop (block (br_if 0 (nop) (i32.const 1))))
(export "br_if-nop" $br_if-nop)
(func $br_if-drop (block (br_if 0 (i32.const 1) (i32.const 1))))
(export "br_if-drop" $br_if-drop)
(func $br_if-block-nop (block (br_if 0 (block (i32.const 1) (nop)) (i32.const 1))))
(export "br_if-block-nop" $br_if-block-nop)
(func $br_if-block-drop (block (br_if 0 (block (nop) (i32.const 1)) (i32.const 1))))
(export "br_if-block-drop" $br_if-block-drop)
(func $br_table (block (br_table 0 (i32.const 0))))
(export "br_table" $br_table)
(func $br_table-nop (block (br_table 0 (nop) (i32.const 0))))
(export "br_table-nop" $br_table-nop)
(func $br_table-drop (block (br_table 0 (i32.const 1) (i32.const 0))))
(export "br_table-drop" $br_table-drop)
(func $br_table-block-nop (block (br_table 0 (block (i32.const 1) (nop)) (i32.const 0))))
(export "br_table-block-nop" $br_table-block-nop)
(func $br_table-block-drop (block (br_table 0 (block (nop) (i32.const 1)) (i32.const 0))))
(export "br_table-block-drop" $br_table-block-drop)
) )
(assert_return (invoke "br")) (assert_return (invoke "br"))
(assert_return (invoke "br-nop"))
(assert_return (invoke "br-drop"))
(assert_return (invoke "br-block-nop"))
(assert_return (invoke "br-block-drop"))
(assert_return (invoke "br_if")) (assert_return (invoke "br_if"))
(assert_return (invoke "br_if-nop"))
(assert_return (invoke "br_if-drop"))
(assert_return (invoke "br_if-block-nop"))
(assert_return (invoke "br_if-block-drop"))
(assert_return (invoke "br_table")) (assert_return (invoke "br_table"))
(assert_return (invoke "br_table-nop"))
(assert_return (invoke "br_table-drop"))
(assert_return (invoke "br_table-block-nop"))
(assert_return (invoke "br_table-block-drop"))

Просмотреть файл

@ -0,0 +1,241 @@
;; Test `call` operator
(module
;; Auxiliary definitions
(func $const-i32 (result i32) (i32.const 0x132))
(func $const-i64 (result i64) (i64.const 0x164))
(func $const-f32 (result f32) (f32.const 0xf32))
(func $const-f64 (result f64) (f64.const 0xf64))
(func $id-i32 (param i32) (result i32) (get_local 0))
(func $id-i64 (param i64) (result i64) (get_local 0))
(func $id-f32 (param f32) (result f32) (get_local 0))
(func $id-f64 (param f64) (result f64) (get_local 0))
(func $f32-i32 (param f32 i32) (result i32) (get_local 1))
(func $i32-i64 (param i32 i64) (result i64) (get_local 1))
(func $f64-f32 (param f64 f32) (result f32) (get_local 1))
(func $i64-f64 (param i64 f64) (result f64) (get_local 1))
;; Typing
(func (export "type-i32") (result i32) (call $const-i32))
(func (export "type-i64") (result i64) (call $const-i64))
(func (export "type-f32") (result f32) (call $const-f32))
(func (export "type-f64") (result f64) (call $const-f64))
(func (export "type-first-i32") (result i32) (call $id-i32 (i32.const 32)))
(func (export "type-first-i64") (result i64) (call $id-i64 (i64.const 64)))
(func (export "type-first-f32") (result f32) (call $id-f32 (f32.const 1.32)))
(func (export "type-first-f64") (result f64) (call $id-f64 (f64.const 1.64)))
(func (export "type-second-i32") (result i32)
(call $f32-i32 (f32.const 32.1) (i32.const 32))
)
(func (export "type-second-i64") (result i64)
(call $i32-i64 (i32.const 32) (i64.const 64))
)
(func (export "type-second-f32") (result f32)
(call $f64-f32 (f64.const 64) (f32.const 32))
)
(func (export "type-second-f64") (result f64)
(call $i64-f64 (i64.const 64) (f64.const 64.1))
)
;; Recursion
(func $fac (export "fac") (param i64) (result i64)
(if i64 (i64.eqz (get_local 0))
(i64.const 1)
(i64.mul (get_local 0) (call $fac (i64.sub (get_local 0) (i64.const 1))))
)
)
(func $fac-acc (export "fac-acc") (param i64 i64) (result i64)
(if i64 (i64.eqz (get_local 0))
(get_local 1)
(call $fac-acc
(i64.sub (get_local 0) (i64.const 1))
(i64.mul (get_local 0) (get_local 1))
)
)
)
(func $fib (export "fib") (param i64) (result i64)
(if i64 (i64.le_u (get_local 0) (i64.const 1))
(i64.const 1)
(i64.add
(call $fib (i64.sub (get_local 0) (i64.const 2)))
(call $fib (i64.sub (get_local 0) (i64.const 1)))
)
)
)
(func $even (export "even") (param i64) (result i32)
(if i32 (i64.eqz (get_local 0))
(i32.const 44)
(call $odd (i64.sub (get_local 0) (i64.const 1)))
)
)
(func $odd (export "odd") (param i64) (result i32)
(if i32 (i64.eqz (get_local 0))
(i32.const 99)
(call $even (i64.sub (get_local 0) (i64.const 1)))
)
)
;; Stack exhaustion
;; Implementations are required to have every call consume some abstract
;; resource towards exhausting some abstract finite limit, such that
;; infinitely recursive test cases reliably trap in finite time. This is
;; because otherwise applications could come to depend on it on those
;; implementations and be incompatible with implementations that don't do
;; it (or don't do it under the same circumstances).
(func $runaway (export "runaway") (call $runaway))
(func $mutual-runaway1 (export "mutual-runaway") (call $mutual-runaway2))
(func $mutual-runaway2 (call $mutual-runaway1))
)
(assert_return (invoke "type-i32") (i32.const 0x132))
(assert_return (invoke "type-i64") (i64.const 0x164))
(assert_return (invoke "type-f32") (f32.const 0xf32))
(assert_return (invoke "type-f64") (f64.const 0xf64))
(assert_return (invoke "type-first-i32") (i32.const 32))
(assert_return (invoke "type-first-i64") (i64.const 64))
(assert_return (invoke "type-first-f32") (f32.const 1.32))
(assert_return (invoke "type-first-f64") (f64.const 1.64))
(assert_return (invoke "type-second-i32") (i32.const 32))
(assert_return (invoke "type-second-i64") (i64.const 64))
(assert_return (invoke "type-second-f32") (f32.const 32))
(assert_return (invoke "type-second-f64") (f64.const 64.1))
(assert_return (invoke "fac" (i64.const 0)) (i64.const 1))
(assert_return (invoke "fac" (i64.const 1)) (i64.const 1))
(assert_return (invoke "fac" (i64.const 5)) (i64.const 120))
(assert_return (invoke "fac" (i64.const 25)) (i64.const 7034535277573963776))
(assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1))
(assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1))
(assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120))
(assert_return
(invoke "fac-acc" (i64.const 25) (i64.const 1))
(i64.const 7034535277573963776)
)
(assert_return (invoke "fib" (i64.const 0)) (i64.const 1))
(assert_return (invoke "fib" (i64.const 1)) (i64.const 1))
(assert_return (invoke "fib" (i64.const 2)) (i64.const 2))
(assert_return (invoke "fib" (i64.const 5)) (i64.const 8))
(assert_return (invoke "fib" (i64.const 20)) (i64.const 10946))
(assert_return (invoke "even" (i64.const 0)) (i32.const 44))
(assert_return (invoke "even" (i64.const 1)) (i32.const 99))
(assert_return (invoke "even" (i64.const 100)) (i32.const 44))
(assert_return (invoke "even" (i64.const 77)) (i32.const 99))
(assert_return (invoke "odd" (i64.const 0)) (i32.const 99))
(assert_return (invoke "odd" (i64.const 1)) (i32.const 44))
(assert_return (invoke "odd" (i64.const 200)) (i32.const 99))
(assert_return (invoke "odd" (i64.const 77)) (i32.const 44))
(assert_trap (invoke "runaway") "call stack exhausted")
(assert_trap (invoke "mutual-runaway") "call stack exhausted")
;; Invalid typing
(assert_invalid
(module
(func $type-void-vs-num (i32.eqz (call 1)))
(func)
)
"type mismatch"
)
(assert_invalid
(module
(func $type-num-vs-num (i32.eqz (call 1)))
(func (result i64) (i64.const 1))
)
"type mismatch"
)
(assert_invalid
(module
(func $arity-0-vs-1 (call 1))
(func (param i32))
)
"type mismatch"
)
(assert_invalid
(module
(func $arity-0-vs-2 (call 1))
(func (param f64 i32))
)
"type mismatch"
)
(assert_invalid
(module
(func $arity-1-vs-0 (call 1 (i32.const 1)))
(func)
)
"type mismatch"
)
(assert_invalid
(module
(func $arity-2-vs-0 (call 1 (f64.const 2) (i32.const 1)))
(func)
)
"type mismatch"
)
;; TODO(stack): move these elsewhere
(module
(func (param i32 i32))
(func $arity-nop-first (call 0 (nop) (i32.const 1) (i32.const 2)))
(func $arity-nop-mid (call 0 (i32.const 1) (nop) (i32.const 2)))
(func $arity-nop-last (call 0 (i32.const 1) (i32.const 2) (nop)))
)
(assert_invalid
(module
(func $type-first-void-vs-num (call 1 (nop) (i32.const 1)))
(func (param i32 i32))
)
"type mismatch"
)
(assert_invalid
(module
(func $type-second-void-vs-num (call 1 (i32.const 1) (nop)))
(func (param i32 i32))
)
"type mismatch"
)
(assert_invalid
(module
(func $type-first-num-vs-num (call 1 (f64.const 1) (i32.const 1)))
(func (param i32 f64))
)
"type mismatch"
)
(assert_invalid
(module
(func $type-second-num-vs-num (call 1 (i32.const 1) (f64.const 1)))
(func (param f64 i32))
)
"type mismatch"
)
;; Unbound function
(assert_invalid
(module (func $unbound-func (call 1)))
"unknown function"
)
(assert_invalid
(module (func $large-func (call 1012321300)))
"unknown function"
)

Просмотреть файл

@ -0,0 +1,2 @@
// |jit-test| test-also-wasm-baseline
var importedArgs = ['call.wast']; load(scriptdir + '../spec.js');

Просмотреть файл

@ -0,0 +1,377 @@
;; Test `call_indirect` operator
(module
;; Auxiliary definitions
(type $proc (func))
(type $out-i32 (func (result i32)))
(type $out-i64 (func (result i64)))
(type $out-f32 (func (result f32)))
(type $out-f64 (func (result f64)))
(type $over-i32 (func (param i32) (result i32)))
(type $over-i64 (func (param i64) (result i64)))
(type $over-f32 (func (param f32) (result f32)))
(type $over-f64 (func (param f64) (result f64)))
(type $f32-i32 (func (param f32 i32) (result i32)))
(type $i32-i64 (func (param i32 i64) (result i64)))
(type $f64-f32 (func (param f64 f32) (result f32)))
(type $i64-f64 (func (param i64 f64) (result f64)))
(type $over-i32-duplicate (func (param i32) (result i32)))
(type $over-i64-duplicate (func (param i64) (result i64)))
(type $over-f32-duplicate (func (param f32) (result f32)))
(type $over-f64-duplicate (func (param f64) (result f64)))
(func $const-i32 (type $out-i32) (i32.const 0x132))
(func $const-i64 (type $out-i64) (i64.const 0x164))
(func $const-f32 (type $out-f32) (f32.const 0xf32))
(func $const-f64 (type $out-f64) (f64.const 0xf64))
(func $id-i32 (type $over-i32) (get_local 0))
(func $id-i64 (type $over-i64) (get_local 0))
(func $id-f32 (type $over-f32) (get_local 0))
(func $id-f64 (type $over-f64) (get_local 0))
(func $i32-i64 (type $i32-i64) (get_local 1))
(func $i64-f64 (type $i64-f64) (get_local 1))
(func $f32-i32 (type $f32-i32) (get_local 1))
(func $f64-f32 (type $f64-f32) (get_local 1))
(func $over-i32-duplicate (type $over-i32-duplicate) (get_local 0))
(func $over-i64-duplicate (type $over-i64-duplicate) (get_local 0))
(func $over-f32-duplicate (type $over-f32-duplicate) (get_local 0))
(func $over-f64-duplicate (type $over-f64-duplicate) (get_local 0))
(table anyfunc
(elem
$const-i32 $const-i64 $const-f32 $const-f64
$id-i32 $id-i64 $id-f32 $id-f64
$f32-i32 $i32-i64 $f64-f32 $i64-f64
$fac $fib $even $odd
$runaway $mutual-runaway1 $mutual-runaway2
$over-i32-duplicate $over-i64-duplicate
$over-f32-duplicate $over-f64-duplicate
)
)
;; Typing
(func (export "type-i32") (result i32) (call_indirect $out-i32 (i32.const 0)))
(func (export "type-i64") (result i64) (call_indirect $out-i64 (i32.const 1)))
(func (export "type-f32") (result f32) (call_indirect $out-f32 (i32.const 2)))
(func (export "type-f64") (result f64) (call_indirect $out-f64 (i32.const 3)))
(func (export "type-index") (result i64)
(call_indirect $over-i64 (i64.const 100) (i32.const 5))
)
(func (export "type-first-i32") (result i32)
(call_indirect $over-i32 (i32.const 32) (i32.const 4))
)
(func (export "type-first-i64") (result i64)
(call_indirect $over-i64 (i64.const 64) (i32.const 5))
)
(func (export "type-first-f32") (result f32)
(call_indirect $over-f32 (f32.const 1.32) (i32.const 6))
)
(func (export "type-first-f64") (result f64)
(call_indirect $over-f64 (f64.const 1.64) (i32.const 7))
)
(func (export "type-second-i32") (result i32)
(call_indirect $f32-i32 (f32.const 32.1) (i32.const 32) (i32.const 8))
)
(func (export "type-second-i64") (result i64)
(call_indirect $i32-i64 (i32.const 32) (i64.const 64) (i32.const 9))
)
(func (export "type-second-f32") (result f32)
(call_indirect $f64-f32 (f64.const 64) (f32.const 32) (i32.const 10))
)
(func (export "type-second-f64") (result f64)
(call_indirect $i64-f64 (i64.const 64) (f64.const 64.1) (i32.const 11))
)
;; Dispatch
(func (export "dispatch") (param i32 i64) (result i64)
(call_indirect $over-i64 (get_local 1) (get_local 0))
)
(func (export "dispatch-structural") (param i32) (result i64)
(call_indirect $over-i64-duplicate (i64.const 9) (get_local 0))
)
;; Recursion
(func $fac (export "fac") (type $over-i64)
(if i64 (i64.eqz (get_local 0))
(i64.const 1)
(i64.mul
(get_local 0)
(call_indirect $over-i64
(i64.sub (get_local 0) (i64.const 1))
(i32.const 12)
)
)
)
)
(func $fib (export "fib") (type $over-i64)
(if i64 (i64.le_u (get_local 0) (i64.const 1))
(i64.const 1)
(i64.add
(call_indirect $over-i64
(i64.sub (get_local 0) (i64.const 2))
(i32.const 13)
)
(call_indirect $over-i64
(i64.sub (get_local 0) (i64.const 1))
(i32.const 13)
)
)
)
)
(func $even (export "even") (param i32) (result i32)
(if i32 (i32.eqz (get_local 0))
(i32.const 44)
(call_indirect $over-i32
(i32.sub (get_local 0) (i32.const 1))
(i32.const 15)
)
)
)
(func $odd (export "odd") (param i32) (result i32)
(if i32 (i32.eqz (get_local 0))
(i32.const 99)
(call_indirect $over-i32
(i32.sub (get_local 0) (i32.const 1))
(i32.const 14)
)
)
)
;; Stack exhaustion
;; Implementations are required to have every call consume some abstract
;; resource towards exhausting some abstract finite limit, such that
;; infinitely recursive test cases reliably trap in finite time. This is
;; because otherwise applications could come to depend on it on those
;; implementations and be incompatible with implementations that don't do
;; it (or don't do it under the same circumstances).
(func $runaway (export "runaway") (call_indirect $proc (i32.const 16)))
(func $mutual-runaway1 (export "mutual-runaway") (call_indirect $proc (i32.const 18)))
(func $mutual-runaway2 (call_indirect $proc (i32.const 17)))
)
(assert_return (invoke "type-i32") (i32.const 0x132))
(assert_return (invoke "type-i64") (i64.const 0x164))
(assert_return (invoke "type-f32") (f32.const 0xf32))
(assert_return (invoke "type-f64") (f64.const 0xf64))
(assert_return (invoke "type-index") (i64.const 100))
(assert_return (invoke "type-first-i32") (i32.const 32))
(assert_return (invoke "type-first-i64") (i64.const 64))
(assert_return (invoke "type-first-f32") (f32.const 1.32))
(assert_return (invoke "type-first-f64") (f64.const 1.64))
(assert_return (invoke "type-second-i32") (i32.const 32))
(assert_return (invoke "type-second-i64") (i64.const 64))
(assert_return (invoke "type-second-f32") (f32.const 32))
(assert_return (invoke "type-second-f64") (f64.const 64.1))
(assert_return (invoke "dispatch" (i32.const 5) (i64.const 2)) (i64.const 2))
(assert_return (invoke "dispatch" (i32.const 5) (i64.const 5)) (i64.const 5))
(assert_return (invoke "dispatch" (i32.const 12) (i64.const 5)) (i64.const 120))
(assert_return (invoke "dispatch" (i32.const 13) (i64.const 5)) (i64.const 8))
(assert_return (invoke "dispatch" (i32.const 20) (i64.const 2)) (i64.const 2))
(assert_trap (invoke "dispatch" (i32.const 0) (i64.const 2)) "indirect call signature mismatch")
(assert_trap (invoke "dispatch" (i32.const 15) (i64.const 2)) "indirect call signature mismatch")
(assert_trap (invoke "dispatch" (i32.const 23) (i64.const 2)) "undefined element")
(assert_trap (invoke "dispatch" (i32.const -1) (i64.const 2)) "undefined element")
(assert_trap (invoke "dispatch" (i32.const 1213432423) (i64.const 2)) "undefined element")
(assert_return (invoke "dispatch-structural" (i32.const 5)) (i64.const 9))
(assert_return (invoke "dispatch-structural" (i32.const 5)) (i64.const 9))
(assert_return (invoke "dispatch-structural" (i32.const 12)) (i64.const 362880))
(assert_return (invoke "dispatch-structural" (i32.const 20)) (i64.const 9))
(assert_trap (invoke "dispatch-structural" (i32.const 11)) "indirect call signature mismatch")
(assert_trap (invoke "dispatch-structural" (i32.const 22)) "indirect call signature mismatch")
(assert_return (invoke "fac" (i64.const 0)) (i64.const 1))
(assert_return (invoke "fac" (i64.const 1)) (i64.const 1))
(assert_return (invoke "fac" (i64.const 5)) (i64.const 120))
(assert_return (invoke "fac" (i64.const 25)) (i64.const 7034535277573963776))
(assert_return (invoke "fib" (i64.const 0)) (i64.const 1))
(assert_return (invoke "fib" (i64.const 1)) (i64.const 1))
(assert_return (invoke "fib" (i64.const 2)) (i64.const 2))
(assert_return (invoke "fib" (i64.const 5)) (i64.const 8))
(assert_return (invoke "fib" (i64.const 20)) (i64.const 10946))
(assert_return (invoke "even" (i32.const 0)) (i32.const 44))
(assert_return (invoke "even" (i32.const 1)) (i32.const 99))
(assert_return (invoke "even" (i32.const 100)) (i32.const 44))
(assert_return (invoke "even" (i32.const 77)) (i32.const 99))
(assert_return (invoke "odd" (i32.const 0)) (i32.const 99))
(assert_return (invoke "odd" (i32.const 1)) (i32.const 44))
(assert_return (invoke "odd" (i32.const 200)) (i32.const 99))
(assert_return (invoke "odd" (i32.const 77)) (i32.const 44))
(assert_trap (invoke "runaway") "call stack exhausted")
(assert_trap (invoke "mutual-runaway") "call stack exhausted")
;; Invalid typing
(assert_invalid
(module
(type (func))
(func $no-table (call_indirect 0 (i32.const 0)))
)
"unknown table"
)
(assert_invalid
(module
(type (func))
(table 0 anyfunc)
(func $type-void-vs-num (i32.eqz (call_indirect 0 (i32.const 0))))
)
"type mismatch"
)
(assert_invalid
(module
(type (func (result i64)))
(table 0 anyfunc)
(func $type-num-vs-num (i32.eqz (call_indirect 0 (i32.const 0))))
)
"type mismatch"
)
(assert_invalid
(module
(type (func (param i32)))
(table 0 anyfunc)
(func $arity-0-vs-1 (call_indirect 0 (i32.const 0)))
)
"type mismatch"
)
(assert_invalid
(module
(type (func (param f64 i32)))
(table 0 anyfunc)
(func $arity-0-vs-2 (call_indirect 0 (i32.const 0)))
)
"type mismatch"
)
(assert_invalid
(module
(type (func))
(table 0 anyfunc)
(func $arity-1-vs-0 (call_indirect 0 (i32.const 1) (i32.const 0)))
)
"type mismatch"
)
(assert_invalid
(module
(type (func))
(table 0 anyfunc)
(func $arity-2-vs-0
(call_indirect 0 (f64.const 2) (i32.const 1) (i32.const 0))
)
)
"type mismatch"
)
;; TODO(stack): move these elsewhere
(module
(type (func (param i32 i32)))
(table 0 anyfunc)
(func $arity-nop-first
(call_indirect 0 (nop) (i32.const 1) (i32.const 2) (i32.const 0))
)
(func $arity-nop-mid
(call_indirect 0 (i32.const 1) (nop) (i32.const 2) (i32.const 0))
)
(func $arity-nop-last
(call_indirect 0 (i32.const 1) (i32.const 2) (nop) (i32.const 0))
)
)
(assert_invalid
(module
(type (func (param i32)))
(table 0 anyfunc)
(func $type-func-void-vs-i32 (call_indirect 0 (i32.const 1) (nop)))
)
"type mismatch"
)
(assert_invalid
(module
(type (func (param i32)))
(table 0 anyfunc)
(func $type-func-num-vs-i32 (call_indirect 0 (i32.const 0) (i64.const 1)))
)
"type mismatch"
)
(assert_invalid
(module
(type (func (param i32 i32)))
(table 0 anyfunc)
(func $type-first-void-vs-num
(call_indirect 0 (nop) (i32.const 1) (i32.const 0))
)
)
"type mismatch"
)
(assert_invalid
(module
(type (func (param i32 i32)))
(table 0 anyfunc)
(func $type-second-void-vs-num
(call_indirect 0 (i32.const 1) (nop) (i32.const 0))
)
)
"type mismatch"
)
(assert_invalid
(module
(type (func (param i32 f64)))
(table 0 anyfunc)
(func $type-first-num-vs-num
(call_indirect 0 (f64.const 1) (i32.const 1) (i32.const 0))
)
)
"type mismatch"
)
(assert_invalid
(module
(type (func (param f64 i32)))
(table 0 anyfunc)
(func $type-second-num-vs-num
(call_indirect 0 (i32.const 1) (f64.const 1) (i32.const 0))
)
)
"type mismatch"
)
;; Unbound type
(assert_invalid
(module
(table 0 anyfunc)
(func $unbound-type (call_indirect 1 (i32.const 0)))
)
"unknown type"
)
(assert_invalid
(module
(table 0 anyfunc)
(func $large-type (call_indirect 1012321300 (i32.const 0)))
)
"unknown type"
)

Просмотреть файл

@ -0,0 +1,4 @@
// |jit-test| test-also-wasm-baseline
// TODO: new anyfunc table syntax
quit();
var importedArgs = ['call_indirect.wast']; load(scriptdir + '../spec.js');

Просмотреть файл

@ -0,0 +1,69 @@
;; Test comment syntax
;;comment
;;;;;;;;;;;
;;comment
( ;;comment
module;;comment
);;comment
;;)
;;;)
;; ;)
;; (;
(;;)
(;comment;)
(;;comment;)
(;;;comment;)
(;;;;;;;;;;;;;;)
(;(((((((((( ;)
(;)))))))))));)
(;comment";)
(;comment"";)
(;comment""";)
(;Heiße Würstchen;)
(;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;)
(;comment
comment;)
(;comment;)
(;comment;)((;comment;)
(;comment;)module(;comment;)
(;comment;))(;comment;)
(;comment(;nested;)comment;)
(;comment
(;nested
;)comment
;)
(module
(;comment(;nested(;further;)nested;)comment;)
)
(;comment;;comment;)
(;comment;;comment
;)
(module
(;comment;;comment(;nested;)comment;)
)

Просмотреть файл

@ -0,0 +1,4 @@
// |jit-test| test-also-wasm-baseline
// TODO: Error: Invalid UTF-8 in file
quit();
var importedArgs = ['comments.wast']; load(scriptdir + '../spec.js');

Просмотреть файл

@ -1,78 +1,29 @@
(module (module
(func $i64.extend_s_i32 (param $x i32) (result i64) (i64.extend_s/i32 (get_local $x))) (func (export "i64.extend_s_i32") (param $x i32) (result i64) (i64.extend_s/i32 (get_local $x)))
(export "i64.extend_s_i32" $i64.extend_s_i32) (func (export "i64.extend_u_i32") (param $x i32) (result i64) (i64.extend_u/i32 (get_local $x)))
(func (export "i32.wrap_i64") (param $x i64) (result i32) (i32.wrap/i64 (get_local $x)))
(func $i64.extend_u_i32 (param $x i32) (result i64) (i64.extend_u/i32 (get_local $x))) (func (export "i32.trunc_s_f32") (param $x f32) (result i32) (i32.trunc_s/f32 (get_local $x)))
(export "i64.extend_u_i32" $i64.extend_u_i32) (func (export "i32.trunc_u_f32") (param $x f32) (result i32) (i32.trunc_u/f32 (get_local $x)))
(func (export "i32.trunc_s_f64") (param $x f64) (result i32) (i32.trunc_s/f64 (get_local $x)))
(func $i32.wrap_i64 (param $x i64) (result i32) (i32.wrap/i64 (get_local $x))) (func (export "i32.trunc_u_f64") (param $x f64) (result i32) (i32.trunc_u/f64 (get_local $x)))
(export "i32.wrap_i64" $i32.wrap_i64) (func (export "i64.trunc_s_f32") (param $x f32) (result i64) (i64.trunc_s/f32 (get_local $x)))
(func (export "i64.trunc_u_f32") (param $x f32) (result i64) (i64.trunc_u/f32 (get_local $x)))
(func $i32.trunc_s_f32 (param $x f32) (result i32) (i32.trunc_s/f32 (get_local $x))) (func (export "i64.trunc_s_f64") (param $x f64) (result i64) (i64.trunc_s/f64 (get_local $x)))
(export "i32.trunc_s_f32" $i32.trunc_s_f32) (func (export "i64.trunc_u_f64") (param $x f64) (result i64) (i64.trunc_u/f64 (get_local $x)))
(func (export "f32.convert_s_i32") (param $x i32) (result f32) (f32.convert_s/i32 (get_local $x)))
(func $i32.trunc_u_f32 (param $x f32) (result i32) (i32.trunc_u/f32 (get_local $x))) (func (export "f32.convert_s_i64") (param $x i64) (result f32) (f32.convert_s/i64 (get_local $x)))
(export "i32.trunc_u_f32" $i32.trunc_u_f32) (func (export "f64.convert_s_i32") (param $x i32) (result f64) (f64.convert_s/i32 (get_local $x)))
(func (export "f64.convert_s_i64") (param $x i64) (result f64) (f64.convert_s/i64 (get_local $x)))
(func $i32.trunc_s_f64 (param $x f64) (result i32) (i32.trunc_s/f64 (get_local $x))) (func (export "f32.convert_u_i32") (param $x i32) (result f32) (f32.convert_u/i32 (get_local $x)))
(export "i32.trunc_s_f64" $i32.trunc_s_f64) (func (export "f32.convert_u_i64") (param $x i64) (result f32) (f32.convert_u/i64 (get_local $x)))
(func (export "f64.convert_u_i32") (param $x i32) (result f64) (f64.convert_u/i32 (get_local $x)))
(func $i32.trunc_u_f64 (param $x f64) (result i32) (i32.trunc_u/f64 (get_local $x))) (func (export "f64.convert_u_i64") (param $x i64) (result f64) (f64.convert_u/i64 (get_local $x)))
(export "i32.trunc_u_f64" $i32.trunc_u_f64) (func (export "f64.promote_f32") (param $x f32) (result f64) (f64.promote/f32 (get_local $x)))
(func (export "f32.demote_f64") (param $x f64) (result f32) (f32.demote/f64 (get_local $x)))
(func $i64.trunc_s_f32 (param $x f32) (result i64) (i64.trunc_s/f32 (get_local $x))) (func (export "f32.reinterpret_i32") (param $x i32) (result f32) (f32.reinterpret/i32 (get_local $x)))
(export "i64.trunc_s_f32" $i64.trunc_s_f32) (func (export "f64.reinterpret_i64") (param $x i64) (result f64) (f64.reinterpret/i64 (get_local $x)))
(func (export "i32.reinterpret_f32") (param $x f32) (result i32) (i32.reinterpret/f32 (get_local $x)))
(func $i64.trunc_u_f32 (param $x f32) (result i64) (i64.trunc_u/f32 (get_local $x))) (func (export "i64.reinterpret_f64") (param $x f64) (result i64) (i64.reinterpret/f64 (get_local $x)))
(export "i64.trunc_u_f32" $i64.trunc_u_f32)
(func $i64.trunc_s_f64 (param $x f64) (result i64) (i64.trunc_s/f64 (get_local $x)))
(export "i64.trunc_s_f64" $i64.trunc_s_f64)
(func $i64.trunc_u_f64 (param $x f64) (result i64) (i64.trunc_u/f64 (get_local $x)))
(export "i64.trunc_u_f64" $i64.trunc_u_f64)
(func $f32.convert_s_i32 (param $x i32) (result f32) (f32.convert_s/i32 (get_local $x)))
(export "f32.convert_s_i32" $f32.convert_s_i32)
(func $f32.convert_s_i64 (param $x i64) (result f32) (f32.convert_s/i64 (get_local $x)))
(export "f32.convert_s_i64" $f32.convert_s_i64)
(func $f64.convert_s_i32 (param $x i32) (result f64) (f64.convert_s/i32 (get_local $x)))
(export "f64.convert_s_i32" $f64.convert_s_i32)
(func $f64.convert_s_i64 (param $x i64) (result f64) (f64.convert_s/i64 (get_local $x)))
(export "f64.convert_s_i64" $f64.convert_s_i64)
(func $f32.convert_u_i32 (param $x i32) (result f32) (f32.convert_u/i32 (get_local $x)))
(export "f32.convert_u_i32" $f32.convert_u_i32)
(func $f32.convert_u_i64 (param $x i64) (result f32) (f32.convert_u/i64 (get_local $x)))
(export "f32.convert_u_i64" $f32.convert_u_i64)
(func $f64.convert_u_i32 (param $x i32) (result f64) (f64.convert_u/i32 (get_local $x)))
(export "f64.convert_u_i32" $f64.convert_u_i32)
(func $f64.convert_u_i64 (param $x i64) (result f64) (f64.convert_u/i64 (get_local $x)))
(export "f64.convert_u_i64" $f64.convert_u_i64)
(func $f64.promote_f32 (param $x f32) (result f64) (f64.promote/f32 (get_local $x)))
(export "f64.promote_f32" $f64.promote_f32)
(func $f32.demote_f64 (param $x f64) (result f32) (f32.demote/f64 (get_local $x)))
(export "f32.demote_f64" $f32.demote_f64)
(func $f32.reinterpret_i32 (param $x i32) (result f32) (f32.reinterpret/i32 (get_local $x)))
(export "f32.reinterpret_i32" $f32.reinterpret_i32)
(func $f64.reinterpret_i64 (param $x i64) (result f64) (f64.reinterpret/i64 (get_local $x)))
(export "f64.reinterpret_i64" $f64.reinterpret_i64)
(func $i32.reinterpret_f32 (param $x f32) (result i32) (i32.reinterpret/f32 (get_local $x)))
(export "i32.reinterpret_f32" $i32.reinterpret_f32)
(func $i64.reinterpret_f64 (param $x f64) (result i64) (i64.reinterpret/f64 (get_local $x)))
(export "i64.reinterpret_f64" $i64.reinterpret_f64)
) )
(assert_return (invoke "i64.extend_s_i32" (i32.const 0)) (i64.const 0)) (assert_return (invoke "i64.extend_s_i32" (i32.const 0)) (i64.const 0))
@ -365,10 +316,20 @@
(assert_return (invoke "f32.demote_f64" (f64.const -0x0.0000000000001p-1022)) (f32.const -0.0)) (assert_return (invoke "f32.demote_f64" (f64.const -0x0.0000000000001p-1022)) (f32.const -0.0))
(assert_return (invoke "f32.demote_f64" (f64.const 1.0)) (f32.const 1.0)) (assert_return (invoke "f32.demote_f64" (f64.const 1.0)) (f32.const 1.0))
(assert_return (invoke "f32.demote_f64" (f64.const -1.0)) (f32.const -1.0)) (assert_return (invoke "f32.demote_f64" (f64.const -1.0)) (f32.const -1.0))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1p-149)) (f32.const -0x1p-149)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffe0000000p-127)) (f32.const 0x1p-126))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffe0000000p-127)) (f32.const -0x1p-126))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffdfffffffp-127)) (f32.const 0x1.fffffcp-127))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffdfffffffp-127)) (f32.const -0x1.fffffcp-127))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1p-149)) (f32.const 0x1p-149)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1p-149)) (f32.const 0x1p-149))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1p-149)) (f32.const -0x1p-149))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffd0000000p+127)) (f32.const 0x1.fffffcp+127))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffd0000000p+127)) (f32.const -0x1.fffffcp+127))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffd0000001p+127)) (f32.const 0x1.fffffep+127))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffd0000001p+127)) (f32.const -0x1.fffffep+127))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffep+127)) (f32.const 0x1.fffffep+127))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffep+127)) (f32.const -0x1.fffffep+127)) (assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffep+127)) (f32.const -0x1.fffffep+127))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffefffffffp+127)) (f32.const 0x1.fffffep+127))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1.fffffefffffffp+127)) (f32.const -0x1.fffffep+127))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.ffffffp+127)) (f32.const infinity)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.ffffffp+127)) (f32.const infinity))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1.ffffffp+127)) (f32.const -infinity)) (assert_return (invoke "f32.demote_f64" (f64.const -0x1.ffffffp+127)) (f32.const -infinity))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1p-119)) (f32.const 0x1p-119)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1p-119)) (f32.const 0x1p-119))
@ -377,8 +338,15 @@
(assert_return (invoke "f32.demote_f64" (f64.const -infinity)) (f32.const -infinity)) (assert_return (invoke "f32.demote_f64" (f64.const -infinity)) (f32.const -infinity))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000000000001p+0)) (f32.const 1.0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000000000001p+0)) (f32.const 1.0))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffffffffffp-1)) (f32.const 1.0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.fffffffffffffp-1)) (f32.const 1.0))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000000p+0)) (f32.const 0x1.000000p+0))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000001p+0)) (f32.const 0x1.000002p+0))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.000002fffffffp+0)) (f32.const 0x1.000002p+0))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000030000000p+0)) (f32.const 0x1.000004p+0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000030000000p+0)) (f32.const 0x1.000004p+0))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000050000000p+0)) (f32.const 0x1.000004p+0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000050000000p+0)) (f32.const 0x1.000004p+0))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000000p+24)) (f32.const 0x1.0p+24))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000010000001p+24)) (f32.const 0x1.000002p+24))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.000002fffffffp+24)) (f32.const 0x1.000002p+24))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000030000000p+24)) (f32.const 0x1.000004p+24))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.4eae4f7024c7p+108)) (f32.const 0x1.4eae5p+108)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.4eae4f7024c7p+108)) (f32.const 0x1.4eae5p+108))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.a12e71e358685p-113)) (f32.const 0x1.a12e72p-113)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.a12e71e358685p-113)) (f32.const 0x1.a12e72p-113))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.cb98354d521ffp-127)) (f32.const 0x1.cb9834p-127)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.cb98354d521ffp-127)) (f32.const 0x1.cb9834p-127))
@ -387,10 +355,8 @@
(assert_return (invoke "f32.demote_f64" (f64.const nan)) (f32.const nan)) (assert_return (invoke "f32.demote_f64" (f64.const nan)) (f32.const nan))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1p-1022)) (f32.const 0.0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1p-1022)) (f32.const 0.0))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1p-1022)) (f32.const -0.0)) (assert_return (invoke "f32.demote_f64" (f64.const -0x1p-1022)) (f32.const -0.0))
(assert_return (invoke "f32.demote_f64" (f64.const 0x0.0000000000001p-1022)) (f32.const 0.0)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.0p-150)) (f32.const 0.0))
(assert_return (invoke "f32.demote_f64" (f64.const -0x0.0000000000001p-1022)) (f32.const -0.0)) (assert_return (invoke "f32.demote_f64" (f64.const -0x1.0p-150)) (f32.const -0.0))
(assert_return (invoke "f32.demote_f64" (f64.const 0x0.8p-149)) (f32.const 0.0))
(assert_return (invoke "f32.demote_f64" (f64.const -0x0.8p-149)) (f32.const -0.0))
(assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000000000001p-150)) (f32.const 0x1p-149)) (assert_return (invoke "f32.demote_f64" (f64.const 0x1.0000000000001p-150)) (f32.const 0x1p-149))
(assert_return (invoke "f32.demote_f64" (f64.const -0x1.0000000000001p-150)) (f32.const -0x1p-149)) (assert_return (invoke "f32.demote_f64" (f64.const -0x1.0000000000001p-150)) (f32.const -0x1p-149))

Просмотреть файл

@ -43,115 +43,91 @@
) )
) )
(func $i32_load16_s (param $value i32) (result i32) (func (export "i32_load16_s") (param $value i32) (result i32)
(call $i16_store_little (i32.const 0) (get_local $value)) (call $i16_store_little (i32.const 0) (get_local $value))
(i32.load16_s (i32.const 0)) (i32.load16_s (i32.const 0))
) )
(func $i32_load16_u (param $value i32) (result i32) (func (export "i32_load16_u") (param $value i32) (result i32)
(call $i16_store_little (i32.const 0) (get_local $value)) (call $i16_store_little (i32.const 0) (get_local $value))
(i32.load16_u (i32.const 0)) (i32.load16_u (i32.const 0))
) )
(func $i32_load (param $value i32) (result i32) (func (export "i32_load") (param $value i32) (result i32)
(call $i32_store_little (i32.const 0) (get_local $value)) (call $i32_store_little (i32.const 0) (get_local $value))
(i32.load (i32.const 0)) (i32.load (i32.const 0))
) )
(func $i64_load16_s (param $value i64) (result i64) (func (export "i64_load16_s") (param $value i64) (result i64)
(call $i16_store_little (i32.const 0) (i32.wrap/i64 (get_local $value))) (call $i16_store_little (i32.const 0) (i32.wrap/i64 (get_local $value)))
(i64.load16_s (i32.const 0)) (i64.load16_s (i32.const 0))
) )
(func $i64_load16_u (param $value i64) (result i64) (func (export "i64_load16_u") (param $value i64) (result i64)
(call $i16_store_little (i32.const 0) (i32.wrap/i64 (get_local $value))) (call $i16_store_little (i32.const 0) (i32.wrap/i64 (get_local $value)))
(i64.load16_u (i32.const 0)) (i64.load16_u (i32.const 0))
) )
(func $i64_load32_s (param $value i64) (result i64) (func (export "i64_load32_s") (param $value i64) (result i64)
(call $i32_store_little (i32.const 0) (i32.wrap/i64 (get_local $value))) (call $i32_store_little (i32.const 0) (i32.wrap/i64 (get_local $value)))
(i64.load32_s (i32.const 0)) (i64.load32_s (i32.const 0))
) )
(func $i64_load32_u (param $value i64) (result i64) (func (export "i64_load32_u") (param $value i64) (result i64)
(call $i32_store_little (i32.const 0) (i32.wrap/i64 (get_local $value))) (call $i32_store_little (i32.const 0) (i32.wrap/i64 (get_local $value)))
(i64.load32_u (i32.const 0)) (i64.load32_u (i32.const 0))
) )
(func $i64_load (param $value i64) (result i64) (func (export "i64_load") (param $value i64) (result i64)
(call $i64_store_little (i32.const 0) (get_local $value)) (call $i64_store_little (i32.const 0) (get_local $value))
(i64.load (i32.const 0)) (i64.load (i32.const 0))
) )
(func $f32_load (param $value f32) (result f32) (func (export "f32_load") (param $value f32) (result f32)
(call $i32_store_little (i32.const 0) (i32.reinterpret/f32 (get_local $value))) (call $i32_store_little (i32.const 0) (i32.reinterpret/f32 (get_local $value)))
(f32.load (i32.const 0)) (f32.load (i32.const 0))
) )
(func $f64_load (param $value f64) (result f64) (func (export "f64_load") (param $value f64) (result f64)
(call $i64_store_little (i32.const 0) (i64.reinterpret/f64 (get_local $value))) (call $i64_store_little (i32.const 0) (i64.reinterpret/f64 (get_local $value)))
(f64.load (i32.const 0)) (f64.load (i32.const 0))
) )
(func $i32_store16 (param $value i32) (result i32) (func (export "i32_store16") (param $value i32) (result i32)
(i32.store16 (i32.const 0) (get_local $value)) (i32.store16 (i32.const 0) (get_local $value))
(call $i16_load_little (i32.const 0)) (call $i16_load_little (i32.const 0))
) )
(func $i32_store (param $value i32) (result i32) (func (export "i32_store") (param $value i32) (result i32)
(i32.store (i32.const 0) (get_local $value)) (i32.store (i32.const 0) (get_local $value))
(call $i32_load_little (i32.const 0)) (call $i32_load_little (i32.const 0))
) )
(func $i64_store16 (param $value i64) (result i64) (func (export "i64_store16") (param $value i64) (result i64)
(i64.store16 (i32.const 0) (get_local $value)) (i64.store16 (i32.const 0) (get_local $value))
(i64.extend_u/i32 (call $i16_load_little (i32.const 0))) (i64.extend_u/i32 (call $i16_load_little (i32.const 0)))
) )
(func $i64_store32 (param $value i64) (result i64) (func (export "i64_store32") (param $value i64) (result i64)
(i64.store32 (i32.const 0) (get_local $value)) (i64.store32 (i32.const 0) (get_local $value))
(i64.extend_u/i32 (call $i32_load_little (i32.const 0))) (i64.extend_u/i32 (call $i32_load_little (i32.const 0)))
) )
(func $i64_store (param $value i64) (result i64) (func (export "i64_store") (param $value i64) (result i64)
(i64.store (i32.const 0) (get_local $value)) (i64.store (i32.const 0) (get_local $value))
(call $i64_load_little (i32.const 0)) (call $i64_load_little (i32.const 0))
) )
(func $f32_store (param $value f32) (result f32) (func (export "f32_store") (param $value f32) (result f32)
(f32.store (i32.const 0) (get_local $value)) (f32.store (i32.const 0) (get_local $value))
(f32.reinterpret/i32 (call $i32_load_little (i32.const 0))) (f32.reinterpret/i32 (call $i32_load_little (i32.const 0)))
) )
(func $f64_store (param $value f64) (result f64) (func (export "f64_store") (param $value f64) (result f64)
(f64.store (i32.const 0) (get_local $value)) (f64.store (i32.const 0) (get_local $value))
(f64.reinterpret/i64 (call $i64_load_little (i32.const 0))) (f64.reinterpret/i64 (call $i64_load_little (i32.const 0)))
) )
(export "i32_load16_s" $i32_load16_s)
(export "i32_load16_u" $i32_load16_u)
(export "i32_load" $i32_load)
(export "i64_load16_s" $i64_load16_s)
(export "i64_load16_u" $i64_load16_u)
(export "i64_load32_s" $i64_load32_s)
(export "i64_load32_u" $i64_load32_u)
(export "i64_load" $i64_load)
(export "f32_load" $f32_load)
(export "f64_load" $f64_load)
(export "i32_store16" $i32_store16)
(export "i32_store" $i32_store)
(export "i64_store16" $i64_store16)
(export "i64_store32" $i64_store32)
(export "i64_store" $i64_store)
(export "f32_store" $f32_store)
(export "f64_store" $f64_store)
) )
(assert_return (invoke "i32_load16_s" (i32.const -1)) (i32.const -1)) (assert_return (invoke "i32_load16_s" (i32.const -1)) (i32.const -1))

Просмотреть файл

@ -1,26 +1,172 @@
(module (func (i32.const 1)) (export "a" 0)) ;; Functions
(module (func (i32.const 1)) (export "a" 0) (export "b" 0))
(module (func (i32.const 1)) (func (i32.const 2)) (export "a" 0) (export "b" 1))
(assert_invalid
(module (func (i32.const 1)) (export "a" 1))
"unknown function 1")
(assert_invalid
(module (func (i32.const 1)) (func (i32.const 2)) (export "a" 0) (export "a" 1))
"duplicate export name")
(assert_invalid
(module (func (i32.const 1)) (export "a" 0) (export "a" 0))
"duplicate export name")
(module (module (func) (export "a" (func 0)))
(module (func) (export "a" (func 0)) (export "b" (func 0)))
(module (func) (func) (export "a" (func 0)) (export "b" (func 1)))
(module (func (export "a")))
(module (func $a (export "a")))
(module $Func
(export "e" (func $f))
(func $f (param $n i32) (result i32) (func $f (param $n i32) (result i32)
(return (i32.add (get_local $n) (i32.const 1))) (return (i32.add (get_local $n) (i32.const 1)))
) )
)
(assert_return (invoke "e" (i32.const 42)) (i32.const 43))
(assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43))
(module)
(module $Other)
(assert_return (invoke $Func "e" (i32.const 42)) (i32.const 43))
(export "e" $f) (assert_invalid
(module (func) (export "a" (func 1)))
"unknown function"
)
(assert_invalid
(module (func) (export "a" (func 0)) (export "a" (func 0)))
"duplicate export name"
)
(assert_invalid
(module (func) (func) (export "a" (func 0)) (export "a" (func 1)))
"duplicate export name"
)
(assert_invalid
(module (func) (global i32 (i32.const 0)) (export "a" (func 0)) (export "a" (global 0)))
"duplicate export name"
)
(assert_invalid
(module (func) (table 0 anyfunc) (export "a" (func 0)) (export "a" (table 0)))
"duplicate export name"
)
(assert_invalid
(module (func) (memory 0) (export "a" (func 0)) (export "a" (memory 0)))
"duplicate export name"
) )
(assert_return (invoke "e" (i32.const 42)) (i32.const 43))
(module (memory 0 0) (export "a" memory)) ;; Globals
(module (memory 0 0) (export "a" memory) (export "b" memory))
(assert_invalid (module (export "a" memory)) "no memory to export") (module (global i32 (i32.const 0)) (export "a" (global 0)))
(module (global i32 (i32.const 0)) (export "a" (global 0)) (export "b" (global 0)))
(module (global i32 (i32.const 0)) (global i32 (i32.const 0)) (export "a" (global 0)) (export "b" (global 1)))
(module (global (export "a") i32 (i32.const 0)))
(module (global $a (export "a") i32 (i32.const 0)))
(module $Global
(export "e" (global $g))
(global $g i32 (i32.const 42))
)
(assert_return (get "e") (i32.const 42))
(assert_return (get $Global "e") (i32.const 42))
(module)
(module $Other)
(assert_return (get $Global "e") (i32.const 42))
(assert_invalid
(module (global i32 (i32.const 0)) (export "a" (global 1)))
"unknown global"
)
(assert_invalid
(module (global i32 (i32.const 0)) (export "a" (global 0)) (export "a" (global 0)))
"duplicate export name"
)
(assert_invalid
(module (global i32 (i32.const 0)) (global i32 (i32.const 0)) (export "a" (global 0)) (export "a" (global 1)))
"duplicate export name"
)
(assert_invalid
(module (global i32 (i32.const 0)) (func) (export "a" (global 0)) (export "a" (func 0)))
"duplicate export name"
)
(assert_invalid
(module (global i32 (i32.const 0)) (table 0 anyfunc) (export "a" (global 0)) (export "a" (table 0)))
"duplicate export name"
)
(assert_invalid
(module (global i32 (i32.const 0)) (memory 0) (export "a" (global 0)) (export "a" (memory 0)))
"duplicate export name"
)
;; Tables
(module (table 0 anyfunc) (export "a" (table 0)))
(module (table 0 anyfunc) (export "a" (table 0)) (export "b" (table 0)))
;; No multiple tables yet.
;; (module (table 0 anyfunc) (table 0 anyfunc) (export "a" (table 0)) (export "b" (table 1)))
(module (table (export "a") 0 anyfunc))
(module (table (export "a") 0 1 anyfunc))
(module (table $a (export "a") 0 anyfunc))
(module (table $a (export "a") 0 1 anyfunc))
(; TODO: access table ;)
(assert_invalid
(module (table 0 anyfunc) (export "a" (table 1)))
"unknown table"
)
(assert_invalid
(module (table 0 anyfunc) (export "a" (table 0)) (export "a" (table 0)))
"duplicate export name"
)
;; No multiple tables yet.
;; (assert_invalid
;; (module (table 0 anyfunc) (table 0 anyfunc) (export "a" (table 0)) (export "a" (table 1)))
;; "duplicate export name"
;; )
(assert_invalid
(module (table 0 anyfunc) (func) (export "a" (table 0)) (export "a" (func 0)))
"duplicate export name"
)
(assert_invalid
(module (table 0 anyfunc) (global i32 (i32.const 0)) (export "a" (table 0)) (export "a" (global 0)))
"duplicate export name"
)
(assert_invalid
(module (table 0 anyfunc) (memory 0) (export "a" (table 0)) (export "a" (memory 0)))
"duplicate export name"
)
;; Memories
(module (memory 0) (export "a" (memory 0)))
(module (memory 0) (export "a" (memory 0)) (export "b" (memory 0)))
;; No multiple memories yet.
;; (module (memory 0) (memory 0) (export "a" (memory 0)) (export "b" (memory 1)))
(module (memory (export "a") 0))
(module (memory (export "a") 0 1))
(module (memory $a (export "a") 0))
(module (memory $a (export "a") 0 1))
(; TODO: access memory ;)
(assert_invalid
(module (memory 0) (export "a" (memory 1)))
"unknown memory"
)
(assert_invalid
(module (memory 0) (export "a" (memory 0)) (export "a" (memory 0)))
"duplicate export name"
)
;; No multiple memories yet.
;; (assert_invalid
;; (module (memory 0) (memory 0) (export "a" (memory 0)) (export "a" (memory 1)))
;; "duplicate export name"
;; )
(assert_invalid
(module (memory 0) (func) (export "a" (memory 0)) (export "a" (func 0)))
"duplicate export name"
)
(assert_invalid
(module (memory 0) (global i32 (i32.const 0)) (export "a" (memory 0)) (export "a" (global 0)))
"duplicate export name"
)
(assert_invalid
(module (memory 0) (table 0 anyfunc) (export "a" (memory 0)) (export "a" (table 0)))
"duplicate export name"
)

Просмотреть файл

@ -1,2 +1,5 @@
// |jit-test| test-also-wasm-baseline // |jit-test| test-also-wasm-baseline
// TODO: module names
// TODO: new anyfunc table syntax
quit();
var importedArgs = ['exports.wast']; load(scriptdir + '../spec.js'); var importedArgs = ['exports.wast']; load(scriptdir + '../spec.js');

Просмотреть файл

@ -2,35 +2,20 @@
;; values (except comparison operators, which are tested in f32_cmp.wast). ;; values (except comparison operators, which are tested in f32_cmp.wast).
(module (module
(func $add (param $x f32) (param $y f32) (result f32) (f32.add (get_local $x) (get_local $y))) (func (export "add") (param $x f32) (param $y f32) (result f32) (f32.add (get_local $x) (get_local $y)))
(func $sub (param $x f32) (param $y f32) (result f32) (f32.sub (get_local $x) (get_local $y))) (func (export "sub") (param $x f32) (param $y f32) (result f32) (f32.sub (get_local $x) (get_local $y)))
(func $mul (param $x f32) (param $y f32) (result f32) (f32.mul (get_local $x) (get_local $y))) (func (export "mul") (param $x f32) (param $y f32) (result f32) (f32.mul (get_local $x) (get_local $y)))
(func $div (param $x f32) (param $y f32) (result f32) (f32.div (get_local $x) (get_local $y))) (func (export "div") (param $x f32) (param $y f32) (result f32) (f32.div (get_local $x) (get_local $y)))
(func $sqrt (param $x f32) (result f32) (f32.sqrt (get_local $x))) (func (export "sqrt") (param $x f32) (result f32) (f32.sqrt (get_local $x)))
(func $min (param $x f32) (param $y f32) (result f32) (f32.min (get_local $x) (get_local $y))) (func (export "min") (param $x f32) (param $y f32) (result f32) (f32.min (get_local $x) (get_local $y)))
(func $max (param $x f32) (param $y f32) (result f32) (f32.max (get_local $x) (get_local $y))) (func (export "max") (param $x f32) (param $y f32) (result f32) (f32.max (get_local $x) (get_local $y)))
(func $ceil (param $x f32) (result f32) (f32.ceil (get_local $x))) (func (export "ceil") (param $x f32) (result f32) (f32.ceil (get_local $x)))
(func $floor (param $x f32) (result f32) (f32.floor (get_local $x))) (func (export "floor") (param $x f32) (result f32) (f32.floor (get_local $x)))
(func $trunc (param $x f32) (result f32) (f32.trunc (get_local $x))) (func (export "trunc") (param $x f32) (result f32) (f32.trunc (get_local $x)))
(func $nearest (param $x f32) (result f32) (f32.nearest (get_local $x))) (func (export "nearest") (param $x f32) (result f32) (f32.nearest (get_local $x)))
(func $abs (param $x f32) (result f32) (f32.abs (get_local $x))) (func (export "abs") (param $x f32) (result f32) (f32.abs (get_local $x)))
(func $neg (param $x f32) (result f32) (f32.neg (get_local $x))) (func (export "neg") (param $x f32) (result f32) (f32.neg (get_local $x)))
(func $copysign (param $x f32) (param $y f32) (result f32) (f32.copysign (get_local $x) (get_local $y))) (func (export "copysign") (param $x f32) (param $y f32) (result f32) (f32.copysign (get_local $x) (get_local $y)))
(export "add" $add)
(export "sub" $sub)
(export "mul" $mul)
(export "div" $div)
(export "sqrt" $sqrt)
(export "min" $min)
(export "max" $max)
(export "ceil" $ceil)
(export "floor" $floor)
(export "trunc" $trunc)
(export "nearest" $nearest)
(export "abs" $abs)
(export "neg" $neg)
(export "copysign" $copysign)
) )
(assert_return (invoke "add" (f32.const -0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "add" (f32.const -0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0))
@ -1361,10 +1346,10 @@
(assert_return (invoke "min" (f32.const -0x0p+0) (f32.const infinity)) (f32.const -0x0p+0)) (assert_return (invoke "min" (f32.const -0x0p+0) (f32.const infinity)) (f32.const -0x0p+0))
(assert_return (invoke "min" (f32.const 0x0p+0) (f32.const -infinity)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const 0x0p+0) (f32.const -infinity)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const 0x0p+0) (f32.const infinity)) (f32.const 0x0p+0)) (assert_return (invoke "min" (f32.const 0x0p+0) (f32.const infinity)) (f32.const 0x0p+0))
(assert_return (invoke "min" (f32.const -0x0p+0) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -0x0p+0) (f32.const -nan)))
(assert_return (invoke "min" (f32.const -0x0p+0) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const -0x0p+0) (f32.const nan)))
(assert_return (invoke "min" (f32.const 0x0p+0) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const 0x0p+0) (f32.const -nan)))
(assert_return (invoke "min" (f32.const 0x0p+0) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const 0x0p+0) (f32.const nan)))
(assert_return (invoke "min" (f32.const -0x1p-149) (f32.const -0x0p+0)) (f32.const -0x1p-149)) (assert_return (invoke "min" (f32.const -0x1p-149) (f32.const -0x0p+0)) (f32.const -0x1p-149))
(assert_return (invoke "min" (f32.const -0x1p-149) (f32.const 0x0p+0)) (f32.const -0x1p-149)) (assert_return (invoke "min" (f32.const -0x1p-149) (f32.const 0x0p+0)) (f32.const -0x1p-149))
(assert_return (invoke "min" (f32.const 0x1p-149) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "min" (f32.const 0x1p-149) (f32.const -0x0p+0)) (f32.const -0x0p+0))
@ -1397,10 +1382,10 @@
(assert_return (invoke "min" (f32.const -0x1p-149) (f32.const infinity)) (f32.const -0x1p-149)) (assert_return (invoke "min" (f32.const -0x1p-149) (f32.const infinity)) (f32.const -0x1p-149))
(assert_return (invoke "min" (f32.const 0x1p-149) (f32.const -infinity)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const 0x1p-149) (f32.const -infinity)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const 0x1p-149) (f32.const infinity)) (f32.const 0x1p-149)) (assert_return (invoke "min" (f32.const 0x1p-149) (f32.const infinity)) (f32.const 0x1p-149))
(assert_return (invoke "min" (f32.const -0x1p-149) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -0x1p-149) (f32.const -nan)))
(assert_return (invoke "min" (f32.const -0x1p-149) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const -0x1p-149) (f32.const nan)))
(assert_return (invoke "min" (f32.const 0x1p-149) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const 0x1p-149) (f32.const -nan)))
(assert_return (invoke "min" (f32.const 0x1p-149) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const 0x1p-149) (f32.const nan)))
(assert_return (invoke "min" (f32.const -0x1p-126) (f32.const -0x0p+0)) (f32.const -0x1p-126)) (assert_return (invoke "min" (f32.const -0x1p-126) (f32.const -0x0p+0)) (f32.const -0x1p-126))
(assert_return (invoke "min" (f32.const -0x1p-126) (f32.const 0x0p+0)) (f32.const -0x1p-126)) (assert_return (invoke "min" (f32.const -0x1p-126) (f32.const 0x0p+0)) (f32.const -0x1p-126))
(assert_return (invoke "min" (f32.const 0x1p-126) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "min" (f32.const 0x1p-126) (f32.const -0x0p+0)) (f32.const -0x0p+0))
@ -1433,10 +1418,10 @@
(assert_return (invoke "min" (f32.const -0x1p-126) (f32.const infinity)) (f32.const -0x1p-126)) (assert_return (invoke "min" (f32.const -0x1p-126) (f32.const infinity)) (f32.const -0x1p-126))
(assert_return (invoke "min" (f32.const 0x1p-126) (f32.const -infinity)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const 0x1p-126) (f32.const -infinity)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const 0x1p-126) (f32.const infinity)) (f32.const 0x1p-126)) (assert_return (invoke "min" (f32.const 0x1p-126) (f32.const infinity)) (f32.const 0x1p-126))
(assert_return (invoke "min" (f32.const -0x1p-126) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -0x1p-126) (f32.const -nan)))
(assert_return (invoke "min" (f32.const -0x1p-126) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const -0x1p-126) (f32.const nan)))
(assert_return (invoke "min" (f32.const 0x1p-126) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const 0x1p-126) (f32.const -nan)))
(assert_return (invoke "min" (f32.const 0x1p-126) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const 0x1p-126) (f32.const nan)))
(assert_return (invoke "min" (f32.const -0x1p-1) (f32.const -0x0p+0)) (f32.const -0x1p-1)) (assert_return (invoke "min" (f32.const -0x1p-1) (f32.const -0x0p+0)) (f32.const -0x1p-1))
(assert_return (invoke "min" (f32.const -0x1p-1) (f32.const 0x0p+0)) (f32.const -0x1p-1)) (assert_return (invoke "min" (f32.const -0x1p-1) (f32.const 0x0p+0)) (f32.const -0x1p-1))
(assert_return (invoke "min" (f32.const 0x1p-1) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "min" (f32.const 0x1p-1) (f32.const -0x0p+0)) (f32.const -0x0p+0))
@ -1469,10 +1454,10 @@
(assert_return (invoke "min" (f32.const -0x1p-1) (f32.const infinity)) (f32.const -0x1p-1)) (assert_return (invoke "min" (f32.const -0x1p-1) (f32.const infinity)) (f32.const -0x1p-1))
(assert_return (invoke "min" (f32.const 0x1p-1) (f32.const -infinity)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const 0x1p-1) (f32.const -infinity)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const 0x1p-1) (f32.const infinity)) (f32.const 0x1p-1)) (assert_return (invoke "min" (f32.const 0x1p-1) (f32.const infinity)) (f32.const 0x1p-1))
(assert_return (invoke "min" (f32.const -0x1p-1) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -0x1p-1) (f32.const -nan)))
(assert_return (invoke "min" (f32.const -0x1p-1) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const -0x1p-1) (f32.const nan)))
(assert_return (invoke "min" (f32.const 0x1p-1) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const 0x1p-1) (f32.const -nan)))
(assert_return (invoke "min" (f32.const 0x1p-1) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const 0x1p-1) (f32.const nan)))
(assert_return (invoke "min" (f32.const -0x1p+0) (f32.const -0x0p+0)) (f32.const -0x1p+0)) (assert_return (invoke "min" (f32.const -0x1p+0) (f32.const -0x0p+0)) (f32.const -0x1p+0))
(assert_return (invoke "min" (f32.const -0x1p+0) (f32.const 0x0p+0)) (f32.const -0x1p+0)) (assert_return (invoke "min" (f32.const -0x1p+0) (f32.const 0x0p+0)) (f32.const -0x1p+0))
(assert_return (invoke "min" (f32.const 0x1p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "min" (f32.const 0x1p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0))
@ -1505,10 +1490,10 @@
(assert_return (invoke "min" (f32.const -0x1p+0) (f32.const infinity)) (f32.const -0x1p+0)) (assert_return (invoke "min" (f32.const -0x1p+0) (f32.const infinity)) (f32.const -0x1p+0))
(assert_return (invoke "min" (f32.const 0x1p+0) (f32.const -infinity)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const 0x1p+0) (f32.const -infinity)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const 0x1p+0) (f32.const infinity)) (f32.const 0x1p+0)) (assert_return (invoke "min" (f32.const 0x1p+0) (f32.const infinity)) (f32.const 0x1p+0))
(assert_return (invoke "min" (f32.const -0x1p+0) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -0x1p+0) (f32.const -nan)))
(assert_return (invoke "min" (f32.const -0x1p+0) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const -0x1p+0) (f32.const nan)))
(assert_return (invoke "min" (f32.const 0x1p+0) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const 0x1p+0) (f32.const -nan)))
(assert_return (invoke "min" (f32.const 0x1p+0) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const 0x1p+0) (f32.const nan)))
(assert_return (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (f32.const -0x1.921fb6p+2)) (assert_return (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (f32.const -0x1.921fb6p+2))
(assert_return (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (f32.const -0x1.921fb6p+2)) (assert_return (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (f32.const -0x1.921fb6p+2))
(assert_return (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (f32.const -0x0p+0))
@ -1541,10 +1526,10 @@
(assert_return (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const infinity)) (f32.const -0x1.921fb6p+2)) (assert_return (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const infinity)) (f32.const -0x1.921fb6p+2))
(assert_return (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const -infinity)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const -infinity)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const infinity)) (f32.const 0x1.921fb6p+2)) (assert_return (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const infinity)) (f32.const 0x1.921fb6p+2))
(assert_return (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const -nan)))
(assert_return (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const nan)))
(assert_return (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const -nan)))
(assert_return (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const nan)))
(assert_return (invoke "min" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (f32.const -0x1.fffffep+127)) (assert_return (invoke "min" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (f32.const -0x1.fffffep+127))
(assert_return (invoke "min" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (f32.const -0x1.fffffep+127)) (assert_return (invoke "min" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (f32.const -0x1.fffffep+127))
(assert_return (invoke "min" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "min" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (f32.const -0x0p+0))
@ -1577,10 +1562,10 @@
(assert_return (invoke "min" (f32.const -0x1.fffffep+127) (f32.const infinity)) (f32.const -0x1.fffffep+127)) (assert_return (invoke "min" (f32.const -0x1.fffffep+127) (f32.const infinity)) (f32.const -0x1.fffffep+127))
(assert_return (invoke "min" (f32.const 0x1.fffffep+127) (f32.const -infinity)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const 0x1.fffffep+127) (f32.const -infinity)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const 0x1.fffffep+127) (f32.const infinity)) (f32.const 0x1.fffffep+127)) (assert_return (invoke "min" (f32.const 0x1.fffffep+127) (f32.const infinity)) (f32.const 0x1.fffffep+127))
(assert_return (invoke "min" (f32.const -0x1.fffffep+127) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -0x1.fffffep+127) (f32.const -nan)))
(assert_return (invoke "min" (f32.const -0x1.fffffep+127) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const -0x1.fffffep+127) (f32.const nan)))
(assert_return (invoke "min" (f32.const 0x1.fffffep+127) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const 0x1.fffffep+127) (f32.const -nan)))
(assert_return (invoke "min" (f32.const 0x1.fffffep+127) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const 0x1.fffffep+127) (f32.const nan)))
(assert_return (invoke "min" (f32.const -infinity) (f32.const -0x0p+0)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const -infinity) (f32.const -0x0p+0)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const -infinity) (f32.const 0x0p+0)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const -infinity) (f32.const 0x0p+0)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const infinity) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "min" (f32.const infinity) (f32.const -0x0p+0)) (f32.const -0x0p+0))
@ -1613,46 +1598,46 @@
(assert_return (invoke "min" (f32.const -infinity) (f32.const infinity)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const -infinity) (f32.const infinity)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const infinity) (f32.const -infinity)) (f32.const -infinity)) (assert_return (invoke "min" (f32.const infinity) (f32.const -infinity)) (f32.const -infinity))
(assert_return (invoke "min" (f32.const infinity) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "min" (f32.const infinity) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "min" (f32.const -infinity) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -infinity) (f32.const -nan)))
(assert_return (invoke "min" (f32.const -infinity) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const -infinity) (f32.const nan)))
(assert_return (invoke "min" (f32.const infinity) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const infinity) (f32.const -nan)))
(assert_return (invoke "min" (f32.const infinity) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const infinity) (f32.const nan)))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x0p+0)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x0p+0)))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x0p+0)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x0p+0)))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x0p+0)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x0p+0)))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x0p+0)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x0p+0)))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1p-149)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1p-149)))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1p-149)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1p-149)))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1p-149)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1p-149)))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1p-149)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1p-149)))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1p-126)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1p-126)))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1p-126)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1p-126)))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1p-126)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1p-126)))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1p-126)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1p-126)))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1p-1)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1p-1)))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1p-1)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1p-1)))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1p-1)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1p-1)))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1p-1)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1p-1)))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1p+0)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1p+0)))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1p+0)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1p+0)))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1p+0)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1p+0)))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1p+0)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1p+0)))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1.921fb6p+2)))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1.921fb6p+2)))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1.921fb6p+2)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1.921fb6p+2)))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1.921fb6p+2)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1.921fb6p+2)))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1.fffffep+127)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1.fffffep+127)))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1.fffffep+127)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1.fffffep+127)))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1.fffffep+127)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1.fffffep+127)))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1.fffffep+127)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1.fffffep+127)))
(assert_return (invoke "min" (f32.const -nan) (f32.const -infinity)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const -infinity)))
(assert_return (invoke "min" (f32.const -nan) (f32.const infinity)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const infinity)))
(assert_return (invoke "min" (f32.const nan) (f32.const -infinity)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const -infinity)))
(assert_return (invoke "min" (f32.const nan) (f32.const infinity)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const infinity)))
(assert_return (invoke "min" (f32.const -nan) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const -nan)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const nan))) (assert_return_nan (invoke "min" (f32.const -nan) (f32.const nan)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const -nan))) (assert_return_nan (invoke "min" (f32.const nan) (f32.const -nan)))
(assert_return (invoke "min" (f32.const nan) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "min" (f32.const nan) (f32.const nan)))
(assert_return (invoke "max" (f32.const -0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "max" (f32.const -0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0))
(assert_return (invoke "max" (f32.const -0x0p+0) (f32.const 0x0p+0)) (f32.const 0x0p+0)) (assert_return (invoke "max" (f32.const -0x0p+0) (f32.const 0x0p+0)) (f32.const 0x0p+0))
(assert_return (invoke "max" (f32.const 0x0p+0) (f32.const -0x0p+0)) (f32.const 0x0p+0)) (assert_return (invoke "max" (f32.const 0x0p+0) (f32.const -0x0p+0)) (f32.const 0x0p+0))
@ -1685,10 +1670,10 @@
(assert_return (invoke "max" (f32.const -0x0p+0) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const -0x0p+0) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const 0x0p+0) (f32.const -infinity)) (f32.const 0x0p+0)) (assert_return (invoke "max" (f32.const 0x0p+0) (f32.const -infinity)) (f32.const 0x0p+0))
(assert_return (invoke "max" (f32.const 0x0p+0) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const 0x0p+0) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const -0x0p+0) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -0x0p+0) (f32.const -nan)))
(assert_return (invoke "max" (f32.const -0x0p+0) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const -0x0p+0) (f32.const nan)))
(assert_return (invoke "max" (f32.const 0x0p+0) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const 0x0p+0) (f32.const -nan)))
(assert_return (invoke "max" (f32.const 0x0p+0) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const 0x0p+0) (f32.const nan)))
(assert_return (invoke "max" (f32.const -0x1p-149) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "max" (f32.const -0x1p-149) (f32.const -0x0p+0)) (f32.const -0x0p+0))
(assert_return (invoke "max" (f32.const -0x1p-149) (f32.const 0x0p+0)) (f32.const 0x0p+0)) (assert_return (invoke "max" (f32.const -0x1p-149) (f32.const 0x0p+0)) (f32.const 0x0p+0))
(assert_return (invoke "max" (f32.const 0x1p-149) (f32.const -0x0p+0)) (f32.const 0x1p-149)) (assert_return (invoke "max" (f32.const 0x1p-149) (f32.const -0x0p+0)) (f32.const 0x1p-149))
@ -1721,10 +1706,10 @@
(assert_return (invoke "max" (f32.const -0x1p-149) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const -0x1p-149) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const 0x1p-149) (f32.const -infinity)) (f32.const 0x1p-149)) (assert_return (invoke "max" (f32.const 0x1p-149) (f32.const -infinity)) (f32.const 0x1p-149))
(assert_return (invoke "max" (f32.const 0x1p-149) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const 0x1p-149) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const -0x1p-149) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -0x1p-149) (f32.const -nan)))
(assert_return (invoke "max" (f32.const -0x1p-149) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const -0x1p-149) (f32.const nan)))
(assert_return (invoke "max" (f32.const 0x1p-149) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const 0x1p-149) (f32.const -nan)))
(assert_return (invoke "max" (f32.const 0x1p-149) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const 0x1p-149) (f32.const nan)))
(assert_return (invoke "max" (f32.const -0x1p-126) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "max" (f32.const -0x1p-126) (f32.const -0x0p+0)) (f32.const -0x0p+0))
(assert_return (invoke "max" (f32.const -0x1p-126) (f32.const 0x0p+0)) (f32.const 0x0p+0)) (assert_return (invoke "max" (f32.const -0x1p-126) (f32.const 0x0p+0)) (f32.const 0x0p+0))
(assert_return (invoke "max" (f32.const 0x1p-126) (f32.const -0x0p+0)) (f32.const 0x1p-126)) (assert_return (invoke "max" (f32.const 0x1p-126) (f32.const -0x0p+0)) (f32.const 0x1p-126))
@ -1757,10 +1742,10 @@
(assert_return (invoke "max" (f32.const -0x1p-126) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const -0x1p-126) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const 0x1p-126) (f32.const -infinity)) (f32.const 0x1p-126)) (assert_return (invoke "max" (f32.const 0x1p-126) (f32.const -infinity)) (f32.const 0x1p-126))
(assert_return (invoke "max" (f32.const 0x1p-126) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const 0x1p-126) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const -0x1p-126) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -0x1p-126) (f32.const -nan)))
(assert_return (invoke "max" (f32.const -0x1p-126) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const -0x1p-126) (f32.const nan)))
(assert_return (invoke "max" (f32.const 0x1p-126) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const 0x1p-126) (f32.const -nan)))
(assert_return (invoke "max" (f32.const 0x1p-126) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const 0x1p-126) (f32.const nan)))
(assert_return (invoke "max" (f32.const -0x1p-1) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "max" (f32.const -0x1p-1) (f32.const -0x0p+0)) (f32.const -0x0p+0))
(assert_return (invoke "max" (f32.const -0x1p-1) (f32.const 0x0p+0)) (f32.const 0x0p+0)) (assert_return (invoke "max" (f32.const -0x1p-1) (f32.const 0x0p+0)) (f32.const 0x0p+0))
(assert_return (invoke "max" (f32.const 0x1p-1) (f32.const -0x0p+0)) (f32.const 0x1p-1)) (assert_return (invoke "max" (f32.const 0x1p-1) (f32.const -0x0p+0)) (f32.const 0x1p-1))
@ -1793,10 +1778,10 @@
(assert_return (invoke "max" (f32.const -0x1p-1) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const -0x1p-1) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const 0x1p-1) (f32.const -infinity)) (f32.const 0x1p-1)) (assert_return (invoke "max" (f32.const 0x1p-1) (f32.const -infinity)) (f32.const 0x1p-1))
(assert_return (invoke "max" (f32.const 0x1p-1) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const 0x1p-1) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const -0x1p-1) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -0x1p-1) (f32.const -nan)))
(assert_return (invoke "max" (f32.const -0x1p-1) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const -0x1p-1) (f32.const nan)))
(assert_return (invoke "max" (f32.const 0x1p-1) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const 0x1p-1) (f32.const -nan)))
(assert_return (invoke "max" (f32.const 0x1p-1) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const 0x1p-1) (f32.const nan)))
(assert_return (invoke "max" (f32.const -0x1p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "max" (f32.const -0x1p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0))
(assert_return (invoke "max" (f32.const -0x1p+0) (f32.const 0x0p+0)) (f32.const 0x0p+0)) (assert_return (invoke "max" (f32.const -0x1p+0) (f32.const 0x0p+0)) (f32.const 0x0p+0))
(assert_return (invoke "max" (f32.const 0x1p+0) (f32.const -0x0p+0)) (f32.const 0x1p+0)) (assert_return (invoke "max" (f32.const 0x1p+0) (f32.const -0x0p+0)) (f32.const 0x1p+0))
@ -1829,10 +1814,10 @@
(assert_return (invoke "max" (f32.const -0x1p+0) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const -0x1p+0) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const 0x1p+0) (f32.const -infinity)) (f32.const 0x1p+0)) (assert_return (invoke "max" (f32.const 0x1p+0) (f32.const -infinity)) (f32.const 0x1p+0))
(assert_return (invoke "max" (f32.const 0x1p+0) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const 0x1p+0) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const -0x1p+0) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -0x1p+0) (f32.const -nan)))
(assert_return (invoke "max" (f32.const -0x1p+0) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const -0x1p+0) (f32.const nan)))
(assert_return (invoke "max" (f32.const 0x1p+0) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const 0x1p+0) (f32.const -nan)))
(assert_return (invoke "max" (f32.const 0x1p+0) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const 0x1p+0) (f32.const nan)))
(assert_return (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const -0x0p+0)) (f32.const -0x0p+0))
(assert_return (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (f32.const 0x0p+0)) (assert_return (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const 0x0p+0)) (f32.const 0x0p+0))
(assert_return (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (f32.const 0x1.921fb6p+2)) (assert_return (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const -0x0p+0)) (f32.const 0x1.921fb6p+2))
@ -1865,10 +1850,10 @@
(assert_return (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const -infinity)) (f32.const 0x1.921fb6p+2)) (assert_return (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const -infinity)) (f32.const 0x1.921fb6p+2))
(assert_return (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const -nan)))
(assert_return (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const nan)))
(assert_return (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const -nan)))
(assert_return (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const nan)))
(assert_return (invoke "max" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "max" (f32.const -0x1.fffffep+127) (f32.const -0x0p+0)) (f32.const -0x0p+0))
(assert_return (invoke "max" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (f32.const 0x0p+0)) (assert_return (invoke "max" (f32.const -0x1.fffffep+127) (f32.const 0x0p+0)) (f32.const 0x0p+0))
(assert_return (invoke "max" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (f32.const 0x1.fffffep+127)) (assert_return (invoke "max" (f32.const 0x1.fffffep+127) (f32.const -0x0p+0)) (f32.const 0x1.fffffep+127))
@ -1901,10 +1886,10 @@
(assert_return (invoke "max" (f32.const -0x1.fffffep+127) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const -0x1.fffffep+127) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const 0x1.fffffep+127) (f32.const -infinity)) (f32.const 0x1.fffffep+127)) (assert_return (invoke "max" (f32.const 0x1.fffffep+127) (f32.const -infinity)) (f32.const 0x1.fffffep+127))
(assert_return (invoke "max" (f32.const 0x1.fffffep+127) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const 0x1.fffffep+127) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const -0x1.fffffep+127) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -0x1.fffffep+127) (f32.const -nan)))
(assert_return (invoke "max" (f32.const -0x1.fffffep+127) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const -0x1.fffffep+127) (f32.const nan)))
(assert_return (invoke "max" (f32.const 0x1.fffffep+127) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const 0x1.fffffep+127) (f32.const -nan)))
(assert_return (invoke "max" (f32.const 0x1.fffffep+127) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const 0x1.fffffep+127) (f32.const nan)))
(assert_return (invoke "max" (f32.const -infinity) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "max" (f32.const -infinity) (f32.const -0x0p+0)) (f32.const -0x0p+0))
(assert_return (invoke "max" (f32.const -infinity) (f32.const 0x0p+0)) (f32.const 0x0p+0)) (assert_return (invoke "max" (f32.const -infinity) (f32.const 0x0p+0)) (f32.const 0x0p+0))
(assert_return (invoke "max" (f32.const infinity) (f32.const -0x0p+0)) (f32.const infinity)) (assert_return (invoke "max" (f32.const infinity) (f32.const -0x0p+0)) (f32.const infinity))
@ -1937,46 +1922,46 @@
(assert_return (invoke "max" (f32.const -infinity) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const -infinity) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const infinity) (f32.const -infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const infinity) (f32.const -infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const infinity) (f32.const infinity)) (f32.const infinity)) (assert_return (invoke "max" (f32.const infinity) (f32.const infinity)) (f32.const infinity))
(assert_return (invoke "max" (f32.const -infinity) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -infinity) (f32.const -nan)))
(assert_return (invoke "max" (f32.const -infinity) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const -infinity) (f32.const nan)))
(assert_return (invoke "max" (f32.const infinity) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const infinity) (f32.const -nan)))
(assert_return (invoke "max" (f32.const infinity) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const infinity) (f32.const nan)))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x0p+0)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x0p+0)))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x0p+0)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x0p+0)))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x0p+0)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x0p+0)))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x0p+0)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x0p+0)))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1p-149)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1p-149)))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1p-149)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1p-149)))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1p-149)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1p-149)))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1p-149)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1p-149)))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1p-126)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1p-126)))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1p-126)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1p-126)))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1p-126)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1p-126)))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1p-126)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1p-126)))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1p-1)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1p-1)))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1p-1)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1p-1)))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1p-1)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1p-1)))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1p-1)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1p-1)))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1p+0)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1p+0)))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1p+0)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1p+0)))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1p+0)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1p+0)))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1p+0)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1p+0)))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1.921fb6p+2)))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1.921fb6p+2)))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1.921fb6p+2)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1.921fb6p+2)))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1.921fb6p+2)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1.921fb6p+2)))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1.fffffep+127)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1.fffffep+127)))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1.fffffep+127)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1.fffffep+127)))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1.fffffep+127)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1.fffffep+127)))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1.fffffep+127)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1.fffffep+127)))
(assert_return (invoke "max" (f32.const -nan) (f32.const -infinity)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const -infinity)))
(assert_return (invoke "max" (f32.const -nan) (f32.const infinity)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const infinity)))
(assert_return (invoke "max" (f32.const nan) (f32.const -infinity)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const -infinity)))
(assert_return (invoke "max" (f32.const nan) (f32.const infinity)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const infinity)))
(assert_return (invoke "max" (f32.const -nan) (f32.const -nan)) (f32.const -nan)) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const -nan)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const nan))) (assert_return_nan (invoke "max" (f32.const -nan) (f32.const nan)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const -nan))) (assert_return_nan (invoke "max" (f32.const nan) (f32.const -nan)))
(assert_return (invoke "max" (f32.const nan) (f32.const nan)) (f32.const nan)) (assert_return_nan (invoke "max" (f32.const nan) (f32.const nan)))
(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0))
(assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x0p+0)) (f32.const 0x0p+0)) (assert_return (invoke "copysign" (f32.const -0x0p+0) (f32.const 0x0p+0)) (f32.const 0x0p+0))
(assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0)) (assert_return (invoke "copysign" (f32.const 0x0p+0) (f32.const -0x0p+0)) (f32.const -0x0p+0))

Просмотреть файл

@ -2,19 +2,12 @@
;; special values. ;; special values.
(module (module
(func $eq (param $x f32) (param $y f32) (result i32) (f32.eq (get_local $x) (get_local $y))) (func (export "eq") (param $x f32) (param $y f32) (result i32) (f32.eq (get_local $x) (get_local $y)))
(func $ne (param $x f32) (param $y f32) (result i32) (f32.ne (get_local $x) (get_local $y))) (func (export "ne") (param $x f32) (param $y f32) (result i32) (f32.ne (get_local $x) (get_local $y)))
(func $lt (param $x f32) (param $y f32) (result i32) (f32.lt (get_local $x) (get_local $y))) (func (export "lt") (param $x f32) (param $y f32) (result i32) (f32.lt (get_local $x) (get_local $y)))
(func $le (param $x f32) (param $y f32) (result i32) (f32.le (get_local $x) (get_local $y))) (func (export "le") (param $x f32) (param $y f32) (result i32) (f32.le (get_local $x) (get_local $y)))
(func $gt (param $x f32) (param $y f32) (result i32) (f32.gt (get_local $x) (get_local $y))) (func (export "gt") (param $x f32) (param $y f32) (result i32) (f32.gt (get_local $x) (get_local $y)))
(func $ge (param $x f32) (param $y f32) (result i32) (f32.ge (get_local $x) (get_local $y))) (func (export "ge") (param $x f32) (param $y f32) (result i32) (f32.ge (get_local $x) (get_local $y)))
(export "eq" $eq)
(export "ne" $ne)
(export "lt" $lt)
(export "le" $le)
(export "gt" $gt)
(export "ge" $ge)
) )
(assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -0x0p+0)) (i32.const 1)) (assert_return (invoke "eq" (f32.const -0x0p+0) (f32.const -0x0p+0)) (i32.const 1))

Просмотреть файл

@ -2,35 +2,20 @@
;; values (except comparison operators, which are tested in f64_cmp.wast). ;; values (except comparison operators, which are tested in f64_cmp.wast).
(module (module
(func $add (param $x f64) (param $y f64) (result f64) (f64.add (get_local $x) (get_local $y))) (func (export "add") (param $x f64) (param $y f64) (result f64) (f64.add (get_local $x) (get_local $y)))
(func $sub (param $x f64) (param $y f64) (result f64) (f64.sub (get_local $x) (get_local $y))) (func (export "sub") (param $x f64) (param $y f64) (result f64) (f64.sub (get_local $x) (get_local $y)))
(func $mul (param $x f64) (param $y f64) (result f64) (f64.mul (get_local $x) (get_local $y))) (func (export "mul") (param $x f64) (param $y f64) (result f64) (f64.mul (get_local $x) (get_local $y)))
(func $div (param $x f64) (param $y f64) (result f64) (f64.div (get_local $x) (get_local $y))) (func (export "div") (param $x f64) (param $y f64) (result f64) (f64.div (get_local $x) (get_local $y)))
(func $sqrt (param $x f64) (result f64) (f64.sqrt (get_local $x))) (func (export "sqrt") (param $x f64) (result f64) (f64.sqrt (get_local $x)))
(func $min (param $x f64) (param $y f64) (result f64) (f64.min (get_local $x) (get_local $y))) (func (export "min") (param $x f64) (param $y f64) (result f64) (f64.min (get_local $x) (get_local $y)))
(func $max (param $x f64) (param $y f64) (result f64) (f64.max (get_local $x) (get_local $y))) (func (export "max") (param $x f64) (param $y f64) (result f64) (f64.max (get_local $x) (get_local $y)))
(func $ceil (param $x f64) (result f64) (f64.ceil (get_local $x))) (func (export "ceil") (param $x f64) (result f64) (f64.ceil (get_local $x)))
(func $floor (param $x f64) (result f64) (f64.floor (get_local $x))) (func (export "floor") (param $x f64) (result f64) (f64.floor (get_local $x)))
(func $trunc (param $x f64) (result f64) (f64.trunc (get_local $x))) (func (export "trunc") (param $x f64) (result f64) (f64.trunc (get_local $x)))
(func $nearest (param $x f64) (result f64) (f64.nearest (get_local $x))) (func (export "nearest") (param $x f64) (result f64) (f64.nearest (get_local $x)))
(func $abs (param $x f64) (result f64) (f64.abs (get_local $x))) (func (export "abs") (param $x f64) (result f64) (f64.abs (get_local $x)))
(func $neg (param $x f64) (result f64) (f64.neg (get_local $x))) (func (export "neg") (param $x f64) (result f64) (f64.neg (get_local $x)))
(func $copysign (param $x f64) (param $y f64) (result f64) (f64.copysign (get_local $x) (get_local $y))) (func (export "copysign") (param $x f64) (param $y f64) (result f64) (f64.copysign (get_local $x) (get_local $y)))
(export "add" $add)
(export "sub" $sub)
(export "mul" $mul)
(export "div" $div)
(export "sqrt" $sqrt)
(export "min" $min)
(export "max" $max)
(export "ceil" $ceil)
(export "floor" $floor)
(export "trunc" $trunc)
(export "nearest" $nearest)
(export "abs" $abs)
(export "neg" $neg)
(export "copysign" $copysign)
) )
(assert_return (invoke "add" (f64.const -0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "add" (f64.const -0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0))
@ -1361,10 +1346,10 @@
(assert_return (invoke "min" (f64.const -0x0p+0) (f64.const infinity)) (f64.const -0x0p+0)) (assert_return (invoke "min" (f64.const -0x0p+0) (f64.const infinity)) (f64.const -0x0p+0))
(assert_return (invoke "min" (f64.const 0x0p+0) (f64.const -infinity)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const 0x0p+0) (f64.const -infinity)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const 0x0p+0) (f64.const infinity)) (f64.const 0x0p+0)) (assert_return (invoke "min" (f64.const 0x0p+0) (f64.const infinity)) (f64.const 0x0p+0))
(assert_return (invoke "min" (f64.const -0x0p+0) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -0x0p+0) (f64.const -nan)))
(assert_return (invoke "min" (f64.const -0x0p+0) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const -0x0p+0) (f64.const nan)))
(assert_return (invoke "min" (f64.const 0x0p+0) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const 0x0p+0) (f64.const -nan)))
(assert_return (invoke "min" (f64.const 0x0p+0) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const 0x0p+0) (f64.const nan)))
(assert_return (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (f64.const -0x0.0000000000001p-1022)) (assert_return (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (f64.const -0x0.0000000000001p-1022))
(assert_return (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (f64.const -0x0.0000000000001p-1022)) (assert_return (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (f64.const -0x0.0000000000001p-1022))
(assert_return (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (f64.const -0x0p+0))
@ -1397,10 +1382,10 @@
(assert_return (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const infinity)) (f64.const -0x0.0000000000001p-1022)) (assert_return (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const infinity)) (f64.const -0x0.0000000000001p-1022))
(assert_return (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const -infinity)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const -infinity)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const infinity)) (f64.const 0x0.0000000000001p-1022)) (assert_return (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const infinity)) (f64.const 0x0.0000000000001p-1022))
(assert_return (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)))
(assert_return (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const nan)))
(assert_return (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)))
(assert_return (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const nan)))
(assert_return (invoke "min" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (f64.const -0x1p-1022)) (assert_return (invoke "min" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (f64.const -0x1p-1022))
(assert_return (invoke "min" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (f64.const -0x1p-1022)) (assert_return (invoke "min" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (f64.const -0x1p-1022))
(assert_return (invoke "min" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "min" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (f64.const -0x0p+0))
@ -1433,10 +1418,10 @@
(assert_return (invoke "min" (f64.const -0x1p-1022) (f64.const infinity)) (f64.const -0x1p-1022)) (assert_return (invoke "min" (f64.const -0x1p-1022) (f64.const infinity)) (f64.const -0x1p-1022))
(assert_return (invoke "min" (f64.const 0x1p-1022) (f64.const -infinity)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const 0x1p-1022) (f64.const -infinity)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const 0x1p-1022) (f64.const infinity)) (f64.const 0x1p-1022)) (assert_return (invoke "min" (f64.const 0x1p-1022) (f64.const infinity)) (f64.const 0x1p-1022))
(assert_return (invoke "min" (f64.const -0x1p-1022) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -0x1p-1022) (f64.const -nan)))
(assert_return (invoke "min" (f64.const -0x1p-1022) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const -0x1p-1022) (f64.const nan)))
(assert_return (invoke "min" (f64.const 0x1p-1022) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const 0x1p-1022) (f64.const -nan)))
(assert_return (invoke "min" (f64.const 0x1p-1022) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const 0x1p-1022) (f64.const nan)))
(assert_return (invoke "min" (f64.const -0x1p-1) (f64.const -0x0p+0)) (f64.const -0x1p-1)) (assert_return (invoke "min" (f64.const -0x1p-1) (f64.const -0x0p+0)) (f64.const -0x1p-1))
(assert_return (invoke "min" (f64.const -0x1p-1) (f64.const 0x0p+0)) (f64.const -0x1p-1)) (assert_return (invoke "min" (f64.const -0x1p-1) (f64.const 0x0p+0)) (f64.const -0x1p-1))
(assert_return (invoke "min" (f64.const 0x1p-1) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "min" (f64.const 0x1p-1) (f64.const -0x0p+0)) (f64.const -0x0p+0))
@ -1469,10 +1454,10 @@
(assert_return (invoke "min" (f64.const -0x1p-1) (f64.const infinity)) (f64.const -0x1p-1)) (assert_return (invoke "min" (f64.const -0x1p-1) (f64.const infinity)) (f64.const -0x1p-1))
(assert_return (invoke "min" (f64.const 0x1p-1) (f64.const -infinity)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const 0x1p-1) (f64.const -infinity)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const 0x1p-1) (f64.const infinity)) (f64.const 0x1p-1)) (assert_return (invoke "min" (f64.const 0x1p-1) (f64.const infinity)) (f64.const 0x1p-1))
(assert_return (invoke "min" (f64.const -0x1p-1) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -0x1p-1) (f64.const -nan)))
(assert_return (invoke "min" (f64.const -0x1p-1) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const -0x1p-1) (f64.const nan)))
(assert_return (invoke "min" (f64.const 0x1p-1) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const 0x1p-1) (f64.const -nan)))
(assert_return (invoke "min" (f64.const 0x1p-1) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const 0x1p-1) (f64.const nan)))
(assert_return (invoke "min" (f64.const -0x1p+0) (f64.const -0x0p+0)) (f64.const -0x1p+0)) (assert_return (invoke "min" (f64.const -0x1p+0) (f64.const -0x0p+0)) (f64.const -0x1p+0))
(assert_return (invoke "min" (f64.const -0x1p+0) (f64.const 0x0p+0)) (f64.const -0x1p+0)) (assert_return (invoke "min" (f64.const -0x1p+0) (f64.const 0x0p+0)) (f64.const -0x1p+0))
(assert_return (invoke "min" (f64.const 0x1p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "min" (f64.const 0x1p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0))
@ -1505,10 +1490,10 @@
(assert_return (invoke "min" (f64.const -0x1p+0) (f64.const infinity)) (f64.const -0x1p+0)) (assert_return (invoke "min" (f64.const -0x1p+0) (f64.const infinity)) (f64.const -0x1p+0))
(assert_return (invoke "min" (f64.const 0x1p+0) (f64.const -infinity)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const 0x1p+0) (f64.const -infinity)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const 0x1p+0) (f64.const infinity)) (f64.const 0x1p+0)) (assert_return (invoke "min" (f64.const 0x1p+0) (f64.const infinity)) (f64.const 0x1p+0))
(assert_return (invoke "min" (f64.const -0x1p+0) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -0x1p+0) (f64.const -nan)))
(assert_return (invoke "min" (f64.const -0x1p+0) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const -0x1p+0) (f64.const nan)))
(assert_return (invoke "min" (f64.const 0x1p+0) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const 0x1p+0) (f64.const -nan)))
(assert_return (invoke "min" (f64.const 0x1p+0) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const 0x1p+0) (f64.const nan)))
(assert_return (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (f64.const -0x1.921fb54442d18p+2)) (assert_return (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (f64.const -0x1.921fb54442d18p+2))
(assert_return (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (f64.const -0x1.921fb54442d18p+2)) (assert_return (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (f64.const -0x1.921fb54442d18p+2))
(assert_return (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (f64.const -0x0p+0))
@ -1541,10 +1526,10 @@
(assert_return (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const infinity)) (f64.const -0x1.921fb54442d18p+2)) (assert_return (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const infinity)) (f64.const -0x1.921fb54442d18p+2))
(assert_return (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const -infinity)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const -infinity)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const infinity)) (f64.const 0x1.921fb54442d18p+2)) (assert_return (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const infinity)) (f64.const 0x1.921fb54442d18p+2))
(assert_return (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)))
(assert_return (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)))
(assert_return (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)))
(assert_return (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)))
(assert_return (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (f64.const -0x1.fffffffffffffp+1023)) (assert_return (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (f64.const -0x1.fffffffffffffp+1023))
(assert_return (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (f64.const -0x1.fffffffffffffp+1023)) (assert_return (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (f64.const -0x1.fffffffffffffp+1023))
(assert_return (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (f64.const -0x0p+0))
@ -1577,10 +1562,10 @@
(assert_return (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const infinity)) (f64.const -0x1.fffffffffffffp+1023)) (assert_return (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const infinity)) (f64.const -0x1.fffffffffffffp+1023))
(assert_return (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const -infinity)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const -infinity)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const infinity)) (f64.const 0x1.fffffffffffffp+1023)) (assert_return (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const infinity)) (f64.const 0x1.fffffffffffffp+1023))
(assert_return (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)))
(assert_return (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)))
(assert_return (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)))
(assert_return (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)))
(assert_return (invoke "min" (f64.const -infinity) (f64.const -0x0p+0)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const -infinity) (f64.const -0x0p+0)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const -infinity) (f64.const 0x0p+0)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const -infinity) (f64.const 0x0p+0)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const infinity) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "min" (f64.const infinity) (f64.const -0x0p+0)) (f64.const -0x0p+0))
@ -1613,46 +1598,46 @@
(assert_return (invoke "min" (f64.const -infinity) (f64.const infinity)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const -infinity) (f64.const infinity)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const infinity) (f64.const -infinity)) (f64.const -infinity)) (assert_return (invoke "min" (f64.const infinity) (f64.const -infinity)) (f64.const -infinity))
(assert_return (invoke "min" (f64.const infinity) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "min" (f64.const infinity) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "min" (f64.const -infinity) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -infinity) (f64.const -nan)))
(assert_return (invoke "min" (f64.const -infinity) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const -infinity) (f64.const nan)))
(assert_return (invoke "min" (f64.const infinity) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const infinity) (f64.const -nan)))
(assert_return (invoke "min" (f64.const infinity) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const infinity) (f64.const nan)))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x0p+0)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x0p+0)))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x0p+0)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x0p+0)))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x0p+0)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x0p+0)))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x0p+0)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x0p+0)))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x0.0000000000001p-1022)))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x0.0000000000001p-1022)))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x1p-1022)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x1p-1022)))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x1p-1022)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x1p-1022)))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x1p-1022)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x1p-1022)))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x1p-1022)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x1p-1022)))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x1p-1)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x1p-1)))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x1p-1)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x1p-1)))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x1p-1)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x1p-1)))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x1p-1)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x1p-1)))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x1p+0)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x1p+0)))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x1p+0)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x1p+0)))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x1p+0)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x1p+0)))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x1p+0)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x1p+0)))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)))
(assert_return (invoke "min" (f64.const -nan) (f64.const -infinity)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const -infinity)))
(assert_return (invoke "min" (f64.const -nan) (f64.const infinity)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const infinity)))
(assert_return (invoke "min" (f64.const nan) (f64.const -infinity)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const -infinity)))
(assert_return (invoke "min" (f64.const nan) (f64.const infinity)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const infinity)))
(assert_return (invoke "min" (f64.const -nan) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const -nan)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const nan))) (assert_return_nan (invoke "min" (f64.const -nan) (f64.const nan)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const -nan))) (assert_return_nan (invoke "min" (f64.const nan) (f64.const -nan)))
(assert_return (invoke "min" (f64.const nan) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "min" (f64.const nan) (f64.const nan)))
(assert_return (invoke "max" (f64.const -0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "max" (f64.const -0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0))
(assert_return (invoke "max" (f64.const -0x0p+0) (f64.const 0x0p+0)) (f64.const 0x0p+0)) (assert_return (invoke "max" (f64.const -0x0p+0) (f64.const 0x0p+0)) (f64.const 0x0p+0))
(assert_return (invoke "max" (f64.const 0x0p+0) (f64.const -0x0p+0)) (f64.const 0x0p+0)) (assert_return (invoke "max" (f64.const 0x0p+0) (f64.const -0x0p+0)) (f64.const 0x0p+0))
@ -1685,10 +1670,10 @@
(assert_return (invoke "max" (f64.const -0x0p+0) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const -0x0p+0) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const 0x0p+0) (f64.const -infinity)) (f64.const 0x0p+0)) (assert_return (invoke "max" (f64.const 0x0p+0) (f64.const -infinity)) (f64.const 0x0p+0))
(assert_return (invoke "max" (f64.const 0x0p+0) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const 0x0p+0) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const -0x0p+0) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -0x0p+0) (f64.const -nan)))
(assert_return (invoke "max" (f64.const -0x0p+0) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const -0x0p+0) (f64.const nan)))
(assert_return (invoke "max" (f64.const 0x0p+0) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const 0x0p+0) (f64.const -nan)))
(assert_return (invoke "max" (f64.const 0x0p+0) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const 0x0p+0) (f64.const nan)))
(assert_return (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const -0x0p+0)) (f64.const -0x0p+0))
(assert_return (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (f64.const 0x0p+0)) (assert_return (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const 0x0p+0)) (f64.const 0x0p+0))
(assert_return (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (f64.const 0x0.0000000000001p-1022)) (assert_return (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const -0x0p+0)) (f64.const 0x0.0000000000001p-1022))
@ -1721,10 +1706,10 @@
(assert_return (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const -infinity)) (f64.const 0x0.0000000000001p-1022)) (assert_return (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const -infinity)) (f64.const 0x0.0000000000001p-1022))
(assert_return (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const -nan)))
(assert_return (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const nan)))
(assert_return (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)))
(assert_return (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const nan)))
(assert_return (invoke "max" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "max" (f64.const -0x1p-1022) (f64.const -0x0p+0)) (f64.const -0x0p+0))
(assert_return (invoke "max" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (f64.const 0x0p+0)) (assert_return (invoke "max" (f64.const -0x1p-1022) (f64.const 0x0p+0)) (f64.const 0x0p+0))
(assert_return (invoke "max" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (f64.const 0x1p-1022)) (assert_return (invoke "max" (f64.const 0x1p-1022) (f64.const -0x0p+0)) (f64.const 0x1p-1022))
@ -1757,10 +1742,10 @@
(assert_return (invoke "max" (f64.const -0x1p-1022) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const -0x1p-1022) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const 0x1p-1022) (f64.const -infinity)) (f64.const 0x1p-1022)) (assert_return (invoke "max" (f64.const 0x1p-1022) (f64.const -infinity)) (f64.const 0x1p-1022))
(assert_return (invoke "max" (f64.const 0x1p-1022) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const 0x1p-1022) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const -0x1p-1022) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -0x1p-1022) (f64.const -nan)))
(assert_return (invoke "max" (f64.const -0x1p-1022) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const -0x1p-1022) (f64.const nan)))
(assert_return (invoke "max" (f64.const 0x1p-1022) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const 0x1p-1022) (f64.const -nan)))
(assert_return (invoke "max" (f64.const 0x1p-1022) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const 0x1p-1022) (f64.const nan)))
(assert_return (invoke "max" (f64.const -0x1p-1) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "max" (f64.const -0x1p-1) (f64.const -0x0p+0)) (f64.const -0x0p+0))
(assert_return (invoke "max" (f64.const -0x1p-1) (f64.const 0x0p+0)) (f64.const 0x0p+0)) (assert_return (invoke "max" (f64.const -0x1p-1) (f64.const 0x0p+0)) (f64.const 0x0p+0))
(assert_return (invoke "max" (f64.const 0x1p-1) (f64.const -0x0p+0)) (f64.const 0x1p-1)) (assert_return (invoke "max" (f64.const 0x1p-1) (f64.const -0x0p+0)) (f64.const 0x1p-1))
@ -1793,10 +1778,10 @@
(assert_return (invoke "max" (f64.const -0x1p-1) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const -0x1p-1) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const 0x1p-1) (f64.const -infinity)) (f64.const 0x1p-1)) (assert_return (invoke "max" (f64.const 0x1p-1) (f64.const -infinity)) (f64.const 0x1p-1))
(assert_return (invoke "max" (f64.const 0x1p-1) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const 0x1p-1) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const -0x1p-1) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -0x1p-1) (f64.const -nan)))
(assert_return (invoke "max" (f64.const -0x1p-1) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const -0x1p-1) (f64.const nan)))
(assert_return (invoke "max" (f64.const 0x1p-1) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const 0x1p-1) (f64.const -nan)))
(assert_return (invoke "max" (f64.const 0x1p-1) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const 0x1p-1) (f64.const nan)))
(assert_return (invoke "max" (f64.const -0x1p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "max" (f64.const -0x1p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0))
(assert_return (invoke "max" (f64.const -0x1p+0) (f64.const 0x0p+0)) (f64.const 0x0p+0)) (assert_return (invoke "max" (f64.const -0x1p+0) (f64.const 0x0p+0)) (f64.const 0x0p+0))
(assert_return (invoke "max" (f64.const 0x1p+0) (f64.const -0x0p+0)) (f64.const 0x1p+0)) (assert_return (invoke "max" (f64.const 0x1p+0) (f64.const -0x0p+0)) (f64.const 0x1p+0))
@ -1829,10 +1814,10 @@
(assert_return (invoke "max" (f64.const -0x1p+0) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const -0x1p+0) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const 0x1p+0) (f64.const -infinity)) (f64.const 0x1p+0)) (assert_return (invoke "max" (f64.const 0x1p+0) (f64.const -infinity)) (f64.const 0x1p+0))
(assert_return (invoke "max" (f64.const 0x1p+0) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const 0x1p+0) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const -0x1p+0) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -0x1p+0) (f64.const -nan)))
(assert_return (invoke "max" (f64.const -0x1p+0) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const -0x1p+0) (f64.const nan)))
(assert_return (invoke "max" (f64.const 0x1p+0) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const 0x1p+0) (f64.const -nan)))
(assert_return (invoke "max" (f64.const 0x1p+0) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const 0x1p+0) (f64.const nan)))
(assert_return (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (f64.const -0x0p+0))
(assert_return (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (f64.const 0x0p+0)) (assert_return (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const 0x0p+0)) (f64.const 0x0p+0))
(assert_return (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (f64.const 0x1.921fb54442d18p+2)) (assert_return (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const -0x0p+0)) (f64.const 0x1.921fb54442d18p+2))
@ -1865,10 +1850,10 @@
(assert_return (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const -infinity)) (f64.const 0x1.921fb54442d18p+2)) (assert_return (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const -infinity)) (f64.const 0x1.921fb54442d18p+2))
(assert_return (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const -nan)))
(assert_return (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)))
(assert_return (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)))
(assert_return (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const nan)))
(assert_return (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (f64.const -0x0p+0))
(assert_return (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (f64.const 0x0p+0)) (assert_return (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const 0x0p+0)) (f64.const 0x0p+0))
(assert_return (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (f64.const 0x1.fffffffffffffp+1023)) (assert_return (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const -0x0p+0)) (f64.const 0x1.fffffffffffffp+1023))
@ -1901,10 +1886,10 @@
(assert_return (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const -infinity)) (f64.const 0x1.fffffffffffffp+1023)) (assert_return (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const -infinity)) (f64.const 0x1.fffffffffffffp+1023))
(assert_return (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const -nan)))
(assert_return (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)))
(assert_return (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)))
(assert_return (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const nan)))
(assert_return (invoke "max" (f64.const -infinity) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "max" (f64.const -infinity) (f64.const -0x0p+0)) (f64.const -0x0p+0))
(assert_return (invoke "max" (f64.const -infinity) (f64.const 0x0p+0)) (f64.const 0x0p+0)) (assert_return (invoke "max" (f64.const -infinity) (f64.const 0x0p+0)) (f64.const 0x0p+0))
(assert_return (invoke "max" (f64.const infinity) (f64.const -0x0p+0)) (f64.const infinity)) (assert_return (invoke "max" (f64.const infinity) (f64.const -0x0p+0)) (f64.const infinity))
@ -1937,46 +1922,46 @@
(assert_return (invoke "max" (f64.const -infinity) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const -infinity) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const infinity) (f64.const -infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const infinity) (f64.const -infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const infinity) (f64.const infinity)) (f64.const infinity)) (assert_return (invoke "max" (f64.const infinity) (f64.const infinity)) (f64.const infinity))
(assert_return (invoke "max" (f64.const -infinity) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -infinity) (f64.const -nan)))
(assert_return (invoke "max" (f64.const -infinity) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const -infinity) (f64.const nan)))
(assert_return (invoke "max" (f64.const infinity) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const infinity) (f64.const -nan)))
(assert_return (invoke "max" (f64.const infinity) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const infinity) (f64.const nan)))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x0p+0)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x0p+0)))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x0p+0)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x0p+0)))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x0p+0)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x0p+0)))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x0p+0)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x0p+0)))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x0.0000000000001p-1022)))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x0.0000000000001p-1022)))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x1p-1022)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x1p-1022)))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x1p-1022)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x1p-1022)))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x1p-1022)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x1p-1022)))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x1p-1022)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x1p-1022)))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x1p-1)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x1p-1)))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x1p-1)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x1p-1)))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x1p-1)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x1p-1)))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x1p-1)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x1p-1)))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x1p+0)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x1p+0)))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x1p+0)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x1p+0)))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x1p+0)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x1p+0)))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x1p+0)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x1p+0)))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)))
(assert_return (invoke "max" (f64.const -nan) (f64.const -infinity)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const -infinity)))
(assert_return (invoke "max" (f64.const -nan) (f64.const infinity)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const infinity)))
(assert_return (invoke "max" (f64.const nan) (f64.const -infinity)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const -infinity)))
(assert_return (invoke "max" (f64.const nan) (f64.const infinity)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const infinity)))
(assert_return (invoke "max" (f64.const -nan) (f64.const -nan)) (f64.const -nan)) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const -nan)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const nan))) (assert_return_nan (invoke "max" (f64.const -nan) (f64.const nan)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const -nan))) (assert_return_nan (invoke "max" (f64.const nan) (f64.const -nan)))
(assert_return (invoke "max" (f64.const nan) (f64.const nan)) (f64.const nan)) (assert_return_nan (invoke "max" (f64.const nan) (f64.const nan)))
(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0))
(assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const 0x0p+0)) (f64.const 0x0p+0)) (assert_return (invoke "copysign" (f64.const -0x0p+0) (f64.const 0x0p+0)) (f64.const 0x0p+0))
(assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0)) (assert_return (invoke "copysign" (f64.const 0x0p+0) (f64.const -0x0p+0)) (f64.const -0x0p+0))

Просмотреть файл

@ -2,19 +2,12 @@
;; special values. ;; special values.
(module (module
(func $eq (param $x f64) (param $y f64) (result i32) (f64.eq (get_local $x) (get_local $y))) (func (export "eq") (param $x f64) (param $y f64) (result i32) (f64.eq (get_local $x) (get_local $y)))
(func $ne (param $x f64) (param $y f64) (result i32) (f64.ne (get_local $x) (get_local $y))) (func (export "ne") (param $x f64) (param $y f64) (result i32) (f64.ne (get_local $x) (get_local $y)))
(func $lt (param $x f64) (param $y f64) (result i32) (f64.lt (get_local $x) (get_local $y))) (func (export "lt") (param $x f64) (param $y f64) (result i32) (f64.lt (get_local $x) (get_local $y)))
(func $le (param $x f64) (param $y f64) (result i32) (f64.le (get_local $x) (get_local $y))) (func (export "le") (param $x f64) (param $y f64) (result i32) (f64.le (get_local $x) (get_local $y)))
(func $gt (param $x f64) (param $y f64) (result i32) (f64.gt (get_local $x) (get_local $y))) (func (export "gt") (param $x f64) (param $y f64) (result i32) (f64.gt (get_local $x) (get_local $y)))
(func $ge (param $x f64) (param $y f64) (result i32) (f64.ge (get_local $x) (get_local $y))) (func (export "ge") (param $x f64) (param $y f64) (result i32) (f64.ge (get_local $x) (get_local $y)))
(export "eq" $eq)
(export "ne" $ne)
(export "lt" $lt)
(export "le" $le)
(export "gt" $gt)
(export "ge" $ge)
) )
(assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -0x0p+0)) (i32.const 1)) (assert_return (invoke "eq" (f64.const -0x0p+0) (f64.const -0x0p+0)) (i32.const 1))

Просмотреть файл

@ -1,64 +1,68 @@
(module (module
;; Recursive factorial ;; Recursive factorial
(func (param i64) (result i64) (func (export "fac-rec") (param i64) (result i64)
(if (i64.eq (get_local 0) (i64.const 0)) (if i64 (i64.eq (get_local 0) (i64.const 0))
(i64.const 1) (i64.const 1)
(i64.mul (get_local 0) (call 0 (i64.sub (get_local 0) (i64.const 1)))) (i64.mul (get_local 0) (call 0 (i64.sub (get_local 0) (i64.const 1))))
) )
) )
;; Recursive factorial named ;; Recursive factorial named
(func $fac-rec (param $n i64) (result i64) (func $fac-rec-named (export "fac-rec-named") (param $n i64) (result i64)
(if (i64.eq (get_local $n) (i64.const 0)) (if i64 (i64.eq (get_local $n) (i64.const 0))
(i64.const 1) (i64.const 1)
(i64.mul (i64.mul
(get_local $n) (get_local $n)
(call $fac-rec (i64.sub (get_local $n) (i64.const 1))) (call $fac-rec-named (i64.sub (get_local $n) (i64.const 1)))
) )
) )
) )
;; Iterative factorial ;; Iterative factorial
(func (param i64) (result i64) (func (export "fac-iter") (param i64) (result i64)
(local i64 i64) (local i64 i64)
(set_local 1 (get_local 0)) (set_local 1 (get_local 0))
(set_local 2 (i64.const 1)) (set_local 2 (i64.const 1))
(loop (block
(if (loop
(i64.eq (get_local 1) (i64.const 0)) (if
(br 2) (i64.eq (get_local 1) (i64.const 0))
(block (br 2)
(set_local 2 (i64.mul (get_local 1) (get_local 2))) (block
(set_local 1 (i64.sub (get_local 1) (i64.const 1))) (set_local 2 (i64.mul (get_local 1) (get_local 2)))
(set_local 1 (i64.sub (get_local 1) (i64.const 1)))
)
) )
(br 0)
) )
(br 0)
) )
(get_local 2) (get_local 2)
) )
;; Iterative factorial named ;; Iterative factorial named
(func $fac-iter (param $n i64) (result i64) (func (export "fac-iter-named") (param $n i64) (result i64)
(local $i i64) (local $i i64)
(local $res i64) (local $res i64)
(set_local $i (get_local $n)) (set_local $i (get_local $n))
(set_local $res (i64.const 1)) (set_local $res (i64.const 1))
(loop $done $loop (block $done
(if (loop $loop
(i64.eq (get_local $i) (i64.const 0)) (if
(br $done) (i64.eq (get_local $i) (i64.const 0))
(block (br $done)
(set_local $res (i64.mul (get_local $i) (get_local $res))) (block
(set_local $i (i64.sub (get_local $i) (i64.const 1))) (set_local $res (i64.mul (get_local $i) (get_local $res)))
(set_local $i (i64.sub (get_local $i) (i64.const 1)))
)
) )
(br $loop)
) )
(br $loop)
) )
(get_local $res) (get_local $res)
) )
;; More-realistically optimized factorial. ;; Optimized factorial.
(func $fac-opt (param i64) (result i64) (func (export "fac-opt") (param i64) (result i64)
(local i64) (local i64)
(set_local 1 (i64.const 1)) (set_local 1 (i64.const 1))
(block (block
@ -71,12 +75,6 @@
) )
(get_local 1) (get_local 1)
) )
(export "fac-rec" 0)
(export "fac-iter" 2)
(export "fac-rec-named" $fac-rec)
(export "fac-iter-named" $fac-iter)
(export "fac-opt" $fac-opt)
) )
(assert_return (invoke "fac-rec" (i64.const 25)) (i64.const 7034535277573963776)) (assert_return (invoke "fac-rec" (i64.const 25)) (i64.const 7034535277573963776))

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -2,138 +2,76 @@
(module (module
;; f32 special values ;; f32 special values
(func $f32.nan (result i32) (i32.reinterpret/f32 (f32.const nan))) (func (export "f32.nan") (result i32) (i32.reinterpret/f32 (f32.const nan)))
(func $f32.positive_nan (result i32) (i32.reinterpret/f32 (f32.const +nan))) (func (export "f32.positive_nan") (result i32) (i32.reinterpret/f32 (f32.const +nan)))
(func $f32.negative_nan (result i32) (i32.reinterpret/f32 (f32.const -nan))) (func (export "f32.negative_nan") (result i32) (i32.reinterpret/f32 (f32.const -nan)))
(func $f32.plain_nan (result i32) (i32.reinterpret/f32 (f32.const nan:0x400000))) (func (export "f32.plain_nan") (result i32) (i32.reinterpret/f32 (f32.const nan:0x400000)))
(func $f32.informally_known_as_plain_snan (result i32) (i32.reinterpret/f32 (f32.const nan:0x200000))) (func (export "f32.informally_known_as_plain_snan") (result i32) (i32.reinterpret/f32 (f32.const nan:0x200000)))
(func $f32.allones_nan (result i32) (i32.reinterpret/f32 (f32.const -nan:0x7fffff))) (func (export "f32.all_ones_nan") (result i32) (i32.reinterpret/f32 (f32.const -nan:0x7fffff)))
(func $f32.misc_nan (result i32) (i32.reinterpret/f32 (f32.const nan:0x012345))) (func (export "f32.misc_nan") (result i32) (i32.reinterpret/f32 (f32.const nan:0x012345)))
(func $f32.misc_positive_nan (result i32) (i32.reinterpret/f32 (f32.const +nan:0x304050))) (func (export "f32.misc_positive_nan") (result i32) (i32.reinterpret/f32 (f32.const +nan:0x304050)))
(func $f32.misc_negative_nan (result i32) (i32.reinterpret/f32 (f32.const -nan:0x2abcde))) (func (export "f32.misc_negative_nan") (result i32) (i32.reinterpret/f32 (f32.const -nan:0x2abcde)))
(func $f32.infinity (result i32) (i32.reinterpret/f32 (f32.const infinity))) (func (export "f32.infinity") (result i32) (i32.reinterpret/f32 (f32.const infinity)))
(func $f32.positive_infinity (result i32) (i32.reinterpret/f32 (f32.const +infinity))) (func (export "f32.positive_infinity") (result i32) (i32.reinterpret/f32 (f32.const +infinity)))
(func $f32.negative_infinity (result i32) (i32.reinterpret/f32 (f32.const -infinity))) (func (export "f32.negative_infinity") (result i32) (i32.reinterpret/f32 (f32.const -infinity)))
;; f32 numbers ;; f32 numbers
(func $f32.zero (result i32) (i32.reinterpret/f32 (f32.const 0x0.0p0))) (func (export "f32.zero") (result i32) (i32.reinterpret/f32 (f32.const 0x0.0p0)))
(func $f32.positive_zero (result i32) (i32.reinterpret/f32 (f32.const +0x0.0p0))) (func (export "f32.positive_zero") (result i32) (i32.reinterpret/f32 (f32.const +0x0.0p0)))
(func $f32.negative_zero (result i32) (i32.reinterpret/f32 (f32.const -0x0.0p0))) (func (export "f32.negative_zero") (result i32) (i32.reinterpret/f32 (f32.const -0x0.0p0)))
(func $f32.misc (result i32) (i32.reinterpret/f32 (f32.const 0x1.921fb6p+2))) (func (export "f32.misc") (result i32) (i32.reinterpret/f32 (f32.const 0x1.921fb6p+2)))
(func $f32.min_positive (result i32) (i32.reinterpret/f32 (f32.const 0x1p-149))) (func (export "f32.min_positive") (result i32) (i32.reinterpret/f32 (f32.const 0x1p-149)))
(func $f32.min_normal (result i32) (i32.reinterpret/f32 (f32.const 0x1p-126))) (func (export "f32.min_normal") (result i32) (i32.reinterpret/f32 (f32.const 0x1p-126)))
(func $f32.max_finite (result i32) (i32.reinterpret/f32 (f32.const 0x1.fffffep+127))) (func (export "f32.max_finite") (result i32) (i32.reinterpret/f32 (f32.const 0x1.fffffep+127)))
(func $f32.max_subnormal (result i32) (i32.reinterpret/f32 (f32.const 0x1.fffffcp-127))) (func (export "f32.max_subnormal") (result i32) (i32.reinterpret/f32 (f32.const 0x1.fffffcp-127)))
(func $f32.trailing_dot (result i32) (i32.reinterpret/f32 (f32.const 0x1.p10))) (func (export "f32.trailing_dot") (result i32) (i32.reinterpret/f32 (f32.const 0x1.p10)))
;; f32 in decimal format ;; f32 in decimal format
(func $f32_dec.zero (result i32) (i32.reinterpret/f32 (f32.const 0.0e0))) (func (export "f32_dec.zero") (result i32) (i32.reinterpret/f32 (f32.const 0.0e0)))
(func $f32_dec.positive_zero (result i32) (i32.reinterpret/f32 (f32.const +0.0e0))) (func (export "f32_dec.positive_zero") (result i32) (i32.reinterpret/f32 (f32.const +0.0e0)))
(func $f32_dec.negative_zero (result i32) (i32.reinterpret/f32 (f32.const -0.0e0))) (func (export "f32_dec.negative_zero") (result i32) (i32.reinterpret/f32 (f32.const -0.0e0)))
(func $f32_dec.misc (result i32) (i32.reinterpret/f32 (f32.const 6.28318548202514648))) (func (export "f32_dec.misc") (result i32) (i32.reinterpret/f32 (f32.const 6.28318548202514648)))
(func $f32_dec.min_positive (result i32) (i32.reinterpret/f32 (f32.const 1.4013e-45))) (func (export "f32_dec.min_positive") (result i32) (i32.reinterpret/f32 (f32.const 1.4013e-45)))
(func $f32_dec.min_normal (result i32) (i32.reinterpret/f32 (f32.const 1.1754944e-38))) (func (export "f32_dec.min_normal") (result i32) (i32.reinterpret/f32 (f32.const 1.1754944e-38)))
(func $f32_dec.max_subnormal (result i32) (i32.reinterpret/f32 (f32.const 1.1754942e-38))) (func (export "f32_dec.max_subnormal") (result i32) (i32.reinterpret/f32 (f32.const 1.1754942e-38)))
(func $f32_dec.max_finite (result i32) (i32.reinterpret/f32 (f32.const 3.4028234e+38))) (func (export "f32_dec.max_finite") (result i32) (i32.reinterpret/f32 (f32.const 3.4028234e+38)))
(func $f32_dec.trailing_dot (result i32) (i32.reinterpret/f32 (f32.const 1.e10))) (func (export "f32_dec.trailing_dot") (result i32) (i32.reinterpret/f32 (f32.const 1.e10)))
;; f64 special values ;; f64 special values
(func $f64.nan (result i64) (i64.reinterpret/f64 (f64.const nan))) (func (export "f64.nan") (result i64) (i64.reinterpret/f64 (f64.const nan)))
(func $f64.positive_nan (result i64) (i64.reinterpret/f64 (f64.const +nan))) (func (export "f64.positive_nan") (result i64) (i64.reinterpret/f64 (f64.const +nan)))
(func $f64.negative_nan (result i64) (i64.reinterpret/f64 (f64.const -nan))) (func (export "f64.negative_nan") (result i64) (i64.reinterpret/f64 (f64.const -nan)))
(func $f64.plain_nan (result i64) (i64.reinterpret/f64 (f64.const nan:0x8000000000000))) (func (export "f64.plain_nan") (result i64) (i64.reinterpret/f64 (f64.const nan:0x8000000000000)))
(func $f64.informally_known_as_plain_snan (result i64) (i64.reinterpret/f64 (f64.const nan:0x4000000000000))) (func (export "f64.informally_known_as_plain_snan") (result i64) (i64.reinterpret/f64 (f64.const nan:0x4000000000000)))
(func $f64.allones_nan (result i64) (i64.reinterpret/f64 (f64.const -nan:0xfffffffffffff))) (func (export "f64.all_ones_nan") (result i64) (i64.reinterpret/f64 (f64.const -nan:0xfffffffffffff)))
(func $f64.misc_nan (result i64) (i64.reinterpret/f64 (f64.const nan:0x0123456789abc))) (func (export "f64.misc_nan") (result i64) (i64.reinterpret/f64 (f64.const nan:0x0123456789abc)))
(func $f64.misc_positive_nan (result i64) (i64.reinterpret/f64 (f64.const +nan:0x3040506070809))) (func (export "f64.misc_positive_nan") (result i64) (i64.reinterpret/f64 (f64.const +nan:0x3040506070809)))
(func $f64.misc_negative_nan (result i64) (i64.reinterpret/f64 (f64.const -nan:0x2abcdef012345))) (func (export "f64.misc_negative_nan") (result i64) (i64.reinterpret/f64 (f64.const -nan:0x2abcdef012345)))
(func $f64.infinity (result i64) (i64.reinterpret/f64 (f64.const infinity))) (func (export "f64.infinity") (result i64) (i64.reinterpret/f64 (f64.const infinity)))
(func $f64.positive_infinity (result i64) (i64.reinterpret/f64 (f64.const +infinity))) (func (export "f64.positive_infinity") (result i64) (i64.reinterpret/f64 (f64.const +infinity)))
(func $f64.negative_infinity (result i64) (i64.reinterpret/f64 (f64.const -infinity))) (func (export "f64.negative_infinity") (result i64) (i64.reinterpret/f64 (f64.const -infinity)))
;; f64 numbers ;; f64 numbers
(func $f64.zero (result i64) (i64.reinterpret/f64 (f64.const 0x0.0p0))) (func (export "f64.zero") (result i64) (i64.reinterpret/f64 (f64.const 0x0.0p0)))
(func $f64.positive_zero (result i64) (i64.reinterpret/f64 (f64.const +0x0.0p0))) (func (export "f64.positive_zero") (result i64) (i64.reinterpret/f64 (f64.const +0x0.0p0)))
(func $f64.negative_zero (result i64) (i64.reinterpret/f64 (f64.const -0x0.0p0))) (func (export "f64.negative_zero") (result i64) (i64.reinterpret/f64 (f64.const -0x0.0p0)))
(func $f64.misc (result i64) (i64.reinterpret/f64 (f64.const 0x1.921fb54442d18p+2))) (func (export "f64.misc") (result i64) (i64.reinterpret/f64 (f64.const 0x1.921fb54442d18p+2)))
(func $f64.min_positive (result i64) (i64.reinterpret/f64 (f64.const 0x0.0000000000001p-1022))) (func (export "f64.min_positive") (result i64) (i64.reinterpret/f64 (f64.const 0x0.0000000000001p-1022)))
(func $f64.min_normal (result i64) (i64.reinterpret/f64 (f64.const 0x1p-1022))) (func (export "f64.min_normal") (result i64) (i64.reinterpret/f64 (f64.const 0x1p-1022)))
(func $f64.max_subnormal (result i64) (i64.reinterpret/f64 (f64.const 0x0.fffffffffffffp-1022))) (func (export "f64.max_subnormal") (result i64) (i64.reinterpret/f64 (f64.const 0x0.fffffffffffffp-1022)))
(func $f64.max_finite (result i64) (i64.reinterpret/f64 (f64.const 0x1.fffffffffffffp+1023))) (func (export "f64.max_finite") (result i64) (i64.reinterpret/f64 (f64.const 0x1.fffffffffffffp+1023)))
(func $f64.trailing_dot (result i64) (i64.reinterpret/f64 (f64.const 0x1.p100))) (func (export "f64.trailing_dot") (result i64) (i64.reinterpret/f64 (f64.const 0x1.p100)))
;; f64 numbers in decimal format ;; f64 numbers in decimal format
(func $f64_dec.zero (result i64) (i64.reinterpret/f64 (f64.const 0.0e0))) (func (export "f64_dec.zero") (result i64) (i64.reinterpret/f64 (f64.const 0.0e0)))
(func $f64_dec.positive_zero (result i64) (i64.reinterpret/f64 (f64.const +0.0e0))) (func (export "f64_dec.positive_zero") (result i64) (i64.reinterpret/f64 (f64.const +0.0e0)))
(func $f64_dec.negative_zero (result i64) (i64.reinterpret/f64 (f64.const -0.0e0))) (func (export "f64_dec.negative_zero") (result i64) (i64.reinterpret/f64 (f64.const -0.0e0)))
(func $f64_dec.misc (result i64) (i64.reinterpret/f64 (f64.const 6.28318530717958623))) (func (export "f64_dec.misc") (result i64) (i64.reinterpret/f64 (f64.const 6.28318530717958623)))
(func $f64_dec.min_positive (result i64) (i64.reinterpret/f64 (f64.const 4.94066e-324))) (func (export "f64_dec.min_positive") (result i64) (i64.reinterpret/f64 (f64.const 4.94066e-324)))
(func $f64_dec.min_normal (result i64) (i64.reinterpret/f64 (f64.const 2.2250738585072012e-308))) (func (export "f64_dec.min_normal") (result i64) (i64.reinterpret/f64 (f64.const 2.2250738585072012e-308)))
(func $f64_dec.max_subnormal (result i64) (i64.reinterpret/f64 (f64.const 2.2250738585072011e-308))) (func (export "f64_dec.max_subnormal") (result i64) (i64.reinterpret/f64 (f64.const 2.2250738585072011e-308)))
(func $f64_dec.max_finite (result i64) (i64.reinterpret/f64 (f64.const 1.7976931348623157e+308))) (func (export "f64_dec.max_finite") (result i64) (i64.reinterpret/f64 (f64.const 1.7976931348623157e+308)))
(func $f64_dec.trailing_dot (result i64) (i64.reinterpret/f64 (f64.const 1.e100))) (func (export "f64_dec.trailing_dot") (result i64) (i64.reinterpret/f64 (f64.const 1.e100)))
(export "f32.nan" $f32.nan)
(export "f32.positive_nan" $f32.positive_nan)
(export "f32.negative_nan" $f32.negative_nan)
(export "f32.plain_nan" $f32.plain_nan)
(export "f32.informally_known_as_plain_snan" $f32.informally_known_as_plain_snan)
(export "f32.allones_nan" $f32.allones_nan)
(export "f32.misc_nan" $f32.misc_nan)
(export "f32.misc_positive_nan" $f32.misc_positive_nan)
(export "f32.misc_negative_nan" $f32.misc_negative_nan)
(export "f32.infinity" $f32.infinity)
(export "f32.positive_infinity" $f32.positive_infinity)
(export "f32.negative_infinity" $f32.negative_infinity)
(export "f32.zero" $f32.zero)
(export "f32.positive_zero" $f32.positive_zero)
(export "f32.negative_zero" $f32.negative_zero)
(export "f32.misc" $f32.misc)
(export "f32.min_positive" $f32.min_positive)
(export "f32.min_normal" $f32.min_normal)
(export "f32.max_subnormal" $f32.max_subnormal)
(export "f32.max_finite" $f32.max_finite)
(export "f32.trailing_dot" $f32.trailing_dot)
(export "f32_dec.zero" $f32_dec.zero)
(export "f32_dec.positive_zero" $f32_dec.positive_zero)
(export "f32_dec.negative_zero" $f32_dec.negative_zero)
(export "f32_dec.misc" $f32_dec.misc)
(export "f32_dec.min_positive" $f32_dec.min_positive)
(export "f32_dec.min_normal" $f32_dec.min_normal)
(export "f32_dec.max_subnormal" $f32_dec.max_subnormal)
(export "f32_dec.max_finite" $f32_dec.max_finite)
(export "f32_dec.trailing_dot" $f32_dec.trailing_dot)
(export "f64.nan" $f64.nan)
(export "f64.positive_nan" $f64.positive_nan)
(export "f64.negative_nan" $f64.negative_nan)
(export "f64.plain_nan" $f64.plain_nan)
(export "f64.informally_known_as_plain_snan" $f64.informally_known_as_plain_snan)
(export "f64.allones_nan" $f64.allones_nan)
(export "f64.misc_nan" $f64.misc_nan)
(export "f64.misc_positive_nan" $f64.misc_positive_nan)
(export "f64.misc_negative_nan" $f64.misc_negative_nan)
(export "f64.infinity" $f64.infinity)
(export "f64.positive_infinity" $f64.positive_infinity)
(export "f64.negative_infinity" $f64.negative_infinity)
(export "f64.zero" $f64.zero)
(export "f64.positive_zero" $f64.positive_zero)
(export "f64.negative_zero" $f64.negative_zero)
(export "f64.misc" $f64.misc)
(export "f64.min_positive" $f64.min_positive)
(export "f64.min_normal" $f64.min_normal)
(export "f64.max_subnormal" $f64.max_subnormal)
(export "f64.max_finite" $f64.max_finite)
(export "f64.trailing_dot" $f64.trailing_dot)
(export "f64_dec.zero" $f64_dec.zero)
(export "f64_dec.positive_zero" $f64_dec.positive_zero)
(export "f64_dec.negative_zero" $f64_dec.negative_zero)
(export "f64_dec.misc" $f64_dec.misc)
(export "f64_dec.min_positive" $f64_dec.min_positive)
(export "f64_dec.min_normal" $f64_dec.min_normal)
(export "f64_dec.max_subnormal" $f64_dec.max_subnormal)
(export "f64_dec.max_finite" $f64_dec.max_finite)
(export "f64_dec.trailing_dot" $f64_dec.trailing_dot)
) )
(assert_return (invoke "f32.nan") (i32.const 0x7fc00000)) (assert_return (invoke "f32.nan") (i32.const 0x7fc00000))
@ -141,7 +79,7 @@
(assert_return (invoke "f32.negative_nan") (i32.const 0xffc00000)) (assert_return (invoke "f32.negative_nan") (i32.const 0xffc00000))
(assert_return (invoke "f32.plain_nan") (i32.const 0x7fc00000)) (assert_return (invoke "f32.plain_nan") (i32.const 0x7fc00000))
(assert_return (invoke "f32.informally_known_as_plain_snan") (i32.const 0x7fa00000)) (assert_return (invoke "f32.informally_known_as_plain_snan") (i32.const 0x7fa00000))
(assert_return (invoke "f32.allones_nan") (i32.const 0xffffffff)) (assert_return (invoke "f32.all_ones_nan") (i32.const 0xffffffff))
(assert_return (invoke "f32.misc_nan") (i32.const 0x7f812345)) (assert_return (invoke "f32.misc_nan") (i32.const 0x7f812345))
(assert_return (invoke "f32.misc_positive_nan") (i32.const 0x7fb04050)) (assert_return (invoke "f32.misc_positive_nan") (i32.const 0x7fb04050))
(assert_return (invoke "f32.misc_negative_nan") (i32.const 0xffaabcde)) (assert_return (invoke "f32.misc_negative_nan") (i32.const 0xffaabcde))
@ -172,7 +110,7 @@
(assert_return (invoke "f64.negative_nan") (i64.const 0xfff8000000000000)) (assert_return (invoke "f64.negative_nan") (i64.const 0xfff8000000000000))
(assert_return (invoke "f64.plain_nan") (i64.const 0x7ff8000000000000)) (assert_return (invoke "f64.plain_nan") (i64.const 0x7ff8000000000000))
(assert_return (invoke "f64.informally_known_as_plain_snan") (i64.const 0x7ff4000000000000)) (assert_return (invoke "f64.informally_known_as_plain_snan") (i64.const 0x7ff4000000000000))
(assert_return (invoke "f64.allones_nan") (i64.const 0xffffffffffffffff)) (assert_return (invoke "f64.all_ones_nan") (i64.const 0xffffffffffffffff))
(assert_return (invoke "f64.misc_nan") (i64.const 0x7ff0123456789abc)) (assert_return (invoke "f64.misc_nan") (i64.const 0x7ff0123456789abc))
(assert_return (invoke "f64.misc_positive_nan") (i64.const 0x7ff3040506070809)) (assert_return (invoke "f64.misc_positive_nan") (i64.const 0x7ff3040506070809))
(assert_return (invoke "f64.misc_negative_nan") (i64.const 0xfff2abcdef012345)) (assert_return (invoke "f64.misc_negative_nan") (i64.const 0xfff2abcdef012345))

Просмотреть файл

@ -3,22 +3,13 @@
;; Test that load and store do not canonicalize NaNs as x87 does. ;; Test that load and store do not canonicalize NaNs as x87 does.
(module (module
(memory 1 1 (segment 0 "\00\00\a0\7f")) (memory (data "\00\00\a0\7f"))
(func $f32.load (result f32) (f32.load (i32.const 0))) (func (export "f32.load") (result f32) (f32.load (i32.const 0)))
(export "f32.load" $f32.load) (func (export "i32.load") (result i32) (i32.load (i32.const 0)))
(func (export "f32.store") (f32.store (i32.const 0) (f32.const nan:0x200000)))
(func $i32.load (result i32) (i32.load (i32.const 0))) (func (export "i32.store") (i32.store (i32.const 0) (i32.const 0x7fa00000)))
(export "i32.load" $i32.load) (func (export "reset") (i32.store (i32.const 0) (i32.const 0)))
(func $f32.store (f32.store (i32.const 0) (f32.const nan:0x200000)))
(export "f32.store" $f32.store)
(func $i32.store (i32.store (i32.const 0) (i32.const 0x7fa00000)))
(export "i32.store" $i32.store)
(func $reset (i32.store (i32.const 0) (i32.const 0)))
(export "reset" $reset)
) )
(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) (assert_return (invoke "i32.load") (i32.const 0x7fa00000))
@ -37,22 +28,13 @@
(assert_return (invoke "f32.load") (f32.const nan:0x200000)) (assert_return (invoke "f32.load") (f32.const nan:0x200000))
(module (module
(memory 1 1 (segment 0 "\00\00\00\00\00\00\f4\7f")) (memory (data "\00\00\00\00\00\00\f4\7f"))
(func $f64.load (result f64) (f64.load (i32.const 0))) (func (export "f64.load") (result f64) (f64.load (i32.const 0)))
(export "f64.load" $f64.load) (func (export "i64.load") (result i64) (i64.load (i32.const 0)))
(func (export "f64.store") (f64.store (i32.const 0) (f64.const nan:0x4000000000000)))
(func $i64.load (result i64) (i64.load (i32.const 0))) (func (export "i64.store") (i64.store (i32.const 0) (i64.const 0x7ff4000000000000)))
(export "i64.load" $i64.load) (func (export "reset") (i64.store (i32.const 0) (i64.const 0)))
(func $f64.store (f64.store (i32.const 0) (f64.const nan:0x4000000000000)))
(export "f64.store" $f64.store)
(func $i64.store (i64.store (i32.const 0) (i64.const 0x7ff4000000000000)))
(export "i64.store" $i64.store)
(func $reset (i64.store (i32.const 0) (i64.const 0)))
(export "reset" $reset)
) )
(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) (assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000))
@ -73,22 +55,13 @@
;; Test that unaligned load and store do not canonicalize NaNs. ;; Test that unaligned load and store do not canonicalize NaNs.
(module (module
(memory 1 1 (segment 1 "\00\00\a0\7f")) (memory (data "\00\00\00\a0\7f"))
(func $f32.load (result f32) (f32.load (i32.const 1))) (func (export "f32.load") (result f32) (f32.load (i32.const 1)))
(export "f32.load" $f32.load) (func (export "i32.load") (result i32) (i32.load (i32.const 1)))
(func (export "f32.store") (f32.store (i32.const 1) (f32.const nan:0x200000)))
(func $i32.load (result i32) (i32.load (i32.const 1))) (func (export "i32.store") (i32.store (i32.const 1) (i32.const 0x7fa00000)))
(export "i32.load" $i32.load) (func (export "reset") (i32.store (i32.const 1) (i32.const 0)))
(func $f32.store (f32.store (i32.const 1) (f32.const nan:0x200000)))
(export "f32.store" $f32.store)
(func $i32.store (i32.store (i32.const 1) (i32.const 0x7fa00000)))
(export "i32.store" $i32.store)
(func $reset (i32.store (i32.const 1) (i32.const 0)))
(export "reset" $reset)
) )
(assert_return (invoke "i32.load") (i32.const 0x7fa00000)) (assert_return (invoke "i32.load") (i32.const 0x7fa00000))
@ -107,22 +80,13 @@
(assert_return (invoke "f32.load") (f32.const nan:0x200000)) (assert_return (invoke "f32.load") (f32.const nan:0x200000))
(module (module
(memory 1 1 (segment 1 "\00\00\00\00\00\00\f4\7f")) (memory (data "\00\00\00\00\00\00\00\f4\7f"))
(func $f64.load (result f64) (f64.load (i32.const 1))) (func (export "f64.load") (result f64) (f64.load (i32.const 1)))
(export "f64.load" $f64.load) (func (export "i64.load") (result i64) (i64.load (i32.const 1)))
(func (export "f64.store") (f64.store (i32.const 1) (f64.const nan:0x4000000000000)))
(func $i64.load (result i64) (i64.load (i32.const 1))) (func (export "i64.store") (i64.store (i32.const 1) (i64.const 0x7ff4000000000000)))
(export "i64.load" $i64.load) (func (export "reset") (i64.store (i32.const 1) (i64.const 0)))
(func $f64.store (f64.store (i32.const 1) (f64.const nan:0x4000000000000)))
(export "f64.store" $f64.store)
(func $i64.store (i64.store (i32.const 1) (i64.const 0x7ff4000000000000)))
(export "i64.store" $i64.store)
(func $reset (i64.store (i32.const 1) (i64.const 0)))
(export "reset" $reset)
) )
(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000)) (assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000))
@ -143,22 +107,13 @@
;; Test that load and store do not canonicalize NaNs as some JS engines do. ;; Test that load and store do not canonicalize NaNs as some JS engines do.
(module (module
(memory 1 1 (segment 0 "\01\00\d0\7f")) (memory (data "\01\00\d0\7f"))
(func $f32.load (result f32) (f32.load (i32.const 0))) (func (export "f32.load") (result f32) (f32.load (i32.const 0)))
(export "f32.load" $f32.load) (func (export "i32.load") (result i32) (i32.load (i32.const 0)))
(func (export "f32.store") (f32.store (i32.const 0) (f32.const nan:0x500001)))
(func $i32.load (result i32) (i32.load (i32.const 0))) (func (export "i32.store") (i32.store (i32.const 0) (i32.const 0x7fd00001)))
(export "i32.load" $i32.load) (func (export "reset") (i32.store (i32.const 0) (i32.const 0)))
(func $f32.store (f32.store (i32.const 0) (f32.const nan:0x500001)))
(export "f32.store" $f32.store)
(func $i32.store (i32.store (i32.const 0) (i32.const 0x7fd00001)))
(export "i32.store" $i32.store)
(func $reset (i32.store (i32.const 0) (i32.const 0)))
(export "reset" $reset)
) )
(assert_return (invoke "i32.load") (i32.const 0x7fd00001)) (assert_return (invoke "i32.load") (i32.const 0x7fd00001))
@ -177,22 +132,13 @@
(assert_return (invoke "f32.load") (f32.const nan:0x500001)) (assert_return (invoke "f32.load") (f32.const nan:0x500001))
(module (module
(memory 1 1 (segment 0 "\01\00\00\00\00\00\fc\7f")) (memory (data "\01\00\00\00\00\00\fc\7f"))
(func $f64.load (result f64) (f64.load (i32.const 0))) (func (export "f64.load") (result f64) (f64.load (i32.const 0)))
(export "f64.load" $f64.load) (func (export "i64.load") (result i64) (i64.load (i32.const 0)))
(func (export "f64.store") (f64.store (i32.const 0) (f64.const nan:0xc000000000001)))
(func $i64.load (result i64) (i64.load (i32.const 0))) (func (export "i64.store") (i64.store (i32.const 0) (i64.const 0x7ffc000000000001)))
(export "i64.load" $i64.load) (func (export "reset") (i64.store (i32.const 0) (i64.const 0)))
(func $f64.store (f64.store (i32.const 0) (f64.const nan:0xc000000000001)))
(export "f64.store" $f64.store)
(func $i64.store (i64.store (i32.const 0) (i64.const 0x7ffc000000000001)))
(export "i64.store" $i64.store)
(func $reset (i64.store (i32.const 0) (i64.const 0)))
(export "reset" $reset)
) )
(assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001)) (assert_return (invoke "i64.load") (i64.const 0x7ffc000000000001))

Просмотреть файл

@ -6,106 +6,78 @@
;; What this testsuite does test is that (a) the platform is basically IEEE 754 ;; What this testsuite does test is that (a) the platform is basically IEEE 754
;; rather than something else entirely, (b) it's configured correctly for ;; rather than something else entirely, (b) it's configured correctly for
;; WebAssembly (rounding direction, exception masks, precision level, subnormal ;; WebAssembly (rounding direction, exception masks, precision level, subnormal
;; mode, etc.), and (c) the WebAssembly implementation doesn't perform any ;; mode, etc.), (c) the WebAssembly implementation doesn't perform any common
;; common value-changing optimizations. ;; value-changing optimizations, and (d) that the WebAssembly implementation
;; doesn't exhibit any known implementation bugs.
;; ;;
;; This file supplements f32.wast, f64.wast, f32_cmp.wast, and f64_cmp.wast with ;; This file supplements f32.wast, f64.wast, f32_cmp.wast, and f64_cmp.wast with
;; additional single-instruction tests covering additional miscellaneous ;; additional single-instruction tests covering additional miscellaneous
;; interesting cases. ;; interesting cases.
(module (module
(func $f32.add (param $x f32) (param $y f32) (result f32) (f32.add (get_local $x) (get_local $y))) (func (export "f32.add") (param $x f32) (param $y f32) (result f32) (f32.add (get_local $x) (get_local $y)))
(func $f32.sub (param $x f32) (param $y f32) (result f32) (f32.sub (get_local $x) (get_local $y))) (func (export "f32.sub") (param $x f32) (param $y f32) (result f32) (f32.sub (get_local $x) (get_local $y)))
(func $f32.mul (param $x f32) (param $y f32) (result f32) (f32.mul (get_local $x) (get_local $y))) (func (export "f32.mul") (param $x f32) (param $y f32) (result f32) (f32.mul (get_local $x) (get_local $y)))
(func $f32.div (param $x f32) (param $y f32) (result f32) (f32.div (get_local $x) (get_local $y))) (func (export "f32.div") (param $x f32) (param $y f32) (result f32) (f32.div (get_local $x) (get_local $y)))
(func $f32.sqrt (param $x f32) (result f32) (f32.sqrt (get_local $x))) (func (export "f32.sqrt") (param $x f32) (result f32) (f32.sqrt (get_local $x)))
(func $f32.abs (param $x f32) (result f32) (f32.abs (get_local $x))) (func (export "f32.abs") (param $x f32) (result f32) (f32.abs (get_local $x)))
(func $f32.neg (param $x f32) (result f32) (f32.neg (get_local $x))) (func (export "f32.neg") (param $x f32) (result f32) (f32.neg (get_local $x)))
(func $f32.copysign (param $x f32) (param $y f32) (result f32) (f32.copysign (get_local $x) (get_local $y))) (func (export "f32.copysign") (param $x f32) (param $y f32) (result f32) (f32.copysign (get_local $x) (get_local $y)))
(func $f32.ceil (param $x f32) (result f32) (f32.ceil (get_local $x))) (func (export "f32.ceil") (param $x f32) (result f32) (f32.ceil (get_local $x)))
(func $f32.floor (param $x f32) (result f32) (f32.floor (get_local $x))) (func (export "f32.floor") (param $x f32) (result f32) (f32.floor (get_local $x)))
(func $f32.trunc (param $x f32) (result f32) (f32.trunc (get_local $x))) (func (export "f32.trunc") (param $x f32) (result f32) (f32.trunc (get_local $x)))
(func $f32.nearest (param $x f32) (result f32) (f32.nearest (get_local $x))) (func (export "f32.nearest") (param $x f32) (result f32) (f32.nearest (get_local $x)))
(func $f32.min (param $x f32) (param $y f32) (result f32) (f32.min (get_local $x) (get_local $y))) (func (export "f32.min") (param $x f32) (param $y f32) (result f32) (f32.min (get_local $x) (get_local $y)))
(func $f32.max (param $x f32) (param $y f32) (result f32) (f32.max (get_local $x) (get_local $y))) (func (export "f32.max") (param $x f32) (param $y f32) (result f32) (f32.max (get_local $x) (get_local $y)))
(func $f64.add (param $x f64) (param $y f64) (result f64) (f64.add (get_local $x) (get_local $y))) (func (export "f64.add") (param $x f64) (param $y f64) (result f64) (f64.add (get_local $x) (get_local $y)))
(func $f64.sub (param $x f64) (param $y f64) (result f64) (f64.sub (get_local $x) (get_local $y))) (func (export "f64.sub") (param $x f64) (param $y f64) (result f64) (f64.sub (get_local $x) (get_local $y)))
(func $f64.mul (param $x f64) (param $y f64) (result f64) (f64.mul (get_local $x) (get_local $y))) (func (export "f64.mul") (param $x f64) (param $y f64) (result f64) (f64.mul (get_local $x) (get_local $y)))
(func $f64.div (param $x f64) (param $y f64) (result f64) (f64.div (get_local $x) (get_local $y))) (func (export "f64.div") (param $x f64) (param $y f64) (result f64) (f64.div (get_local $x) (get_local $y)))
(func $f64.sqrt (param $x f64) (result f64) (f64.sqrt (get_local $x))) (func (export "f64.sqrt") (param $x f64) (result f64) (f64.sqrt (get_local $x)))
(func $f64.abs (param $x f64) (result f64) (f64.abs (get_local $x))) (func (export "f64.abs") (param $x f64) (result f64) (f64.abs (get_local $x)))
(func $f64.neg (param $x f64) (result f64) (f64.neg (get_local $x))) (func (export "f64.neg") (param $x f64) (result f64) (f64.neg (get_local $x)))
(func $f64.copysign (param $x f64) (param $y f64) (result f64) (f64.copysign (get_local $x) (get_local $y))) (func (export "f64.copysign") (param $x f64) (param $y f64) (result f64) (f64.copysign (get_local $x) (get_local $y)))
(func $f64.ceil (param $x f64) (result f64) (f64.ceil (get_local $x))) (func (export "f64.ceil") (param $x f64) (result f64) (f64.ceil (get_local $x)))
(func $f64.floor (param $x f64) (result f64) (f64.floor (get_local $x))) (func (export "f64.floor") (param $x f64) (result f64) (f64.floor (get_local $x)))
(func $f64.trunc (param $x f64) (result f64) (f64.trunc (get_local $x))) (func (export "f64.trunc") (param $x f64) (result f64) (f64.trunc (get_local $x)))
(func $f64.nearest (param $x f64) (result f64) (f64.nearest (get_local $x))) (func (export "f64.nearest") (param $x f64) (result f64) (f64.nearest (get_local $x)))
(func $f64.min (param $x f64) (param $y f64) (result f64) (f64.min (get_local $x) (get_local $y))) (func (export "f64.min") (param $x f64) (param $y f64) (result f64) (f64.min (get_local $x) (get_local $y)))
(func $f64.max (param $x f64) (param $y f64) (result f64) (f64.max (get_local $x) (get_local $y))) (func (export "f64.max") (param $x f64) (param $y f64) (result f64) (f64.max (get_local $x) (get_local $y)))
(export "f32.add" $f32.add)
(export "f32.sub" $f32.sub)
(export "f32.mul" $f32.mul)
(export "f32.div" $f32.div)
(export "f32.sqrt" $f32.sqrt)
(export "f32.abs" $f32.abs)
(export "f32.neg" $f32.neg)
(export "f32.copysign" $f32.copysign)
(export "f32.ceil" $f32.ceil)
(export "f32.floor" $f32.floor)
(export "f32.trunc" $f32.trunc)
(export "f32.nearest" $f32.nearest)
(export "f32.min" $f32.min)
(export "f32.max" $f32.max)
(export "f64.add" $f64.add)
(export "f64.sub" $f64.sub)
(export "f64.mul" $f64.mul)
(export "f64.div" $f64.div)
(export "f64.sqrt" $f64.sqrt)
(export "f64.abs" $f64.abs)
(export "f64.neg" $f64.neg)
(export "f64.copysign" $f64.copysign)
(export "f64.ceil" $f64.ceil)
(export "f64.floor" $f64.floor)
(export "f64.trunc" $f64.trunc)
(export "f64.nearest" $f64.nearest)
(export "f64.min" $f64.min)
(export "f64.max" $f64.max)
) )
;; Miscellaneous values.
(assert_return (invoke "f32.add" (f32.const 1.1234567890) (f32.const 1.2345e-10)) (f32.const 1.123456789)) (assert_return (invoke "f32.add" (f32.const 1.1234567890) (f32.const 1.2345e-10)) (f32.const 1.123456789))
(assert_return (invoke "f64.add" (f64.const 1.1234567890) (f64.const 1.2345e-10)) (f64.const 0x1.1f9add37c11f7p+0))
;; Test adding the greatest value to 1.0 that rounds back to 1.0, and the ;; Test adding the greatest value to 1.0 that rounds back to 1.0, and the
;; least that rounds to something greater. ;; least that rounds to something greater.
(assert_return (invoke "f32.add" (f32.const 1.0) (f32.const 0x1p-24)) (f32.const 0x1.0p+0)) (assert_return (invoke "f32.add" (f32.const 1.0) (f32.const 0x1p-24)) (f32.const 0x1.0p+0))
(assert_return (invoke "f32.add" (f32.const 1.0) (f32.const 0x1.000002p-24)) (f32.const 0x1.000002p+0)) (assert_return (invoke "f32.add" (f32.const 1.0) (f32.const 0x1.000002p-24)) (f32.const 0x1.000002p+0))
(assert_return (invoke "f64.add" (f64.const 1.0) (f64.const 0x1p-53)) (f64.const 0x1.0p+0))
;; Computations that round differently in ties-to-odd mode. (assert_return (invoke "f64.add" (f64.const 1.0) (f64.const 0x1.0000000000001p-53)) (f64.const 0x1.0000000000001p+0))
(assert_return (invoke "f32.add" (f32.const 0x1p23) (f32.const 0x1p-1)) (f32.const 0x1p23))
(assert_return (invoke "f32.add" (f32.const 0x1.000002p+23) (f32.const 0x1p-1)) (f32.const 0x1.000004p+23))
;; Test that what some systems call signaling NaN behaves as a quiet NaN. ;; Test that what some systems call signaling NaN behaves as a quiet NaN.
(assert_return (invoke "f32.add" (f32.const nan:0x200000) (f32.const 1.0)) (f32.const nan:0x600000)) (assert_return (invoke "f32.add" (f32.const nan:0x200000) (f32.const 1.0)) (f32.const nan:0x600000))
(assert_return (invoke "f64.add" (f64.const nan:0x4000000000000) (f64.const 1.0)) (f64.const nan:0xc000000000000))
(assert_return (invoke "f64.add" (f64.const 1.1234567890) (f64.const 1.2345e-10)) (f64.const 0x1.1f9add37c11f7p+0)) ;; Max subnornmal + min subnormal = min normal.
(assert_return (invoke "f32.add" (f32.const 0x1p-149) (f32.const 0x1.fffffcp-127)) (f32.const 0x1p-126))
(assert_return (invoke "f64.add" (f64.const 0x0.0000000000001p-1022) (f64.const 0x0.fffffffffffffp-1022)) (f64.const 0x1p-1022))
;; Test for a case of double rounding, example from: ;; Test for a case of double rounding, example from:
;; http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html ;; http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html
;; section 3.3.1: A typical problem: "double rounding" ;; section 3.3.1: A typical problem: "double rounding"
(assert_return (invoke "f32.add" (f32.const 0x1p+31) (f32.const 1024.25)) (f32.const 0x1.000008p+31))
(assert_return (invoke "f64.add" (f64.const 0x1p+63) (f64.const 1024.25)) (f64.const 0x1.0000000000001p+63)) (assert_return (invoke "f64.add" (f64.const 0x1p+63) (f64.const 1024.25)) (f64.const 0x1.0000000000001p+63))
;; Test a case that was "tricky" on MMIX. ;; Test a case that was "tricky" on MMIX.
;; http://mmix.cs.hm.edu/bugs/bug_rounding.html ;; http://mmix.cs.hm.edu/bugs/bug_rounding.html
(assert_return (invoke "f64.add" (f64.const -0x1p-1008) (f64.const 0x0.0000000001716p-1022)) (f64.const -0x1.fffffffffffffp-1009)) (assert_return (invoke "f64.add" (f64.const -0x1p-1008) (f64.const 0x0.0000000001716p-1022)) (f64.const -0x1.fffffffffffffp-1009))
;; Test adding the greatest value to 1.0 that rounds back to 1.0, and the
;; least that rounds to something greater.
(assert_return (invoke "f64.add" (f64.const 1.0) (f64.const 0x1p-53)) (f64.const 0x1.0p+0))
(assert_return (invoke "f64.add" (f64.const 1.0) (f64.const 0x1.0000000000001p-53)) (f64.const 0x1.0000000000001p+0))
;; Computations that round differently in ties-to-odd mode. ;; Computations that round differently in ties-to-odd mode.
(assert_return (invoke "f32.add" (f32.const 0x1p23) (f32.const 0x1p-1)) (f32.const 0x1p23))
(assert_return (invoke "f32.add" (f32.const 0x1.000002p+23) (f32.const 0x1p-1)) (f32.const 0x1.000004p+23))
(assert_return (invoke "f64.add" (f64.const 0x1p52) (f64.const 0x1p-1)) (f64.const 0x1p52)) (assert_return (invoke "f64.add" (f64.const 0x1p52) (f64.const 0x1p-1)) (f64.const 0x1p52))
(assert_return (invoke "f64.add" (f64.const 0x1.0000000000001p+52) (f64.const 0x1p-1)) (f64.const 0x1.0000000000002p+52)) (assert_return (invoke "f64.add" (f64.const 0x1.0000000000001p+52) (f64.const 0x1p-1)) (f64.const 0x1.0000000000002p+52))
@ -160,37 +132,43 @@
(assert_return (invoke "f64.add" (f64.const -0x1.ac627bd7cbf38p-198) (f64.const 0x1.2312e265b8d59p-990)) (f64.const -0x1.ac627bd7cbf38p-198)) (assert_return (invoke "f64.add" (f64.const -0x1.ac627bd7cbf38p-198) (f64.const 0x1.2312e265b8d59p-990)) (f64.const -0x1.ac627bd7cbf38p-198))
;; Computations that utilize the maximum exponent value to avoid overflow. ;; Computations that utilize the maximum exponent value to avoid overflow.
(assert_return (invoke "f64.add" (f64.const -0x1.397be95d10fddp+719) (f64.const -0x1.e13909d198d32p+1023)) (f64.const -0x1.e13909d198d32p+1023)) (assert_return (invoke "f32.add" (f32.const 0x1.2b91ap+116) (f32.const 0x1.cbcd52p+127)) (f32.const 0x1.cbf2c4p+127))
(assert_return (invoke "f64.add" (f64.const -0x1.234a5a0412f41p+1023) (f64.const -0x1.53e9106c9367p+161)) (f64.const -0x1.234a5a0412f41p+1023)) (assert_return (invoke "f32.add" (f32.const 0x1.96f392p+127) (f32.const -0x1.6b3fecp+107)) (f32.const 0x1.96f37cp+127))
(assert_return (invoke "f64.add" (f64.const -0x1.a86bdb66cbb32p+562) (f64.const 0x1.d10ff29e1d6e8p+1023)) (f64.const 0x1.d10ff29e1d6e8p+1023)) (assert_return (invoke "f32.add" (f32.const 0x1.132f1cp+118) (f32.const -0x1.63d632p+127)) (f32.const -0x1.634c9ap+127))
(assert_return (invoke "f64.add" (f64.const -0x1.dc295727a06e2p+1023) (f64.const 0x1.5e6979d7b24fp+485)) (f64.const -0x1.dc295727a06e2p+1023)) (assert_return (invoke "f32.add" (f32.const -0x1.1dda64p+120) (f32.const -0x1.ef02ep+127)) (f32.const -0x1.f13e94p+127))
(assert_return (invoke "f64.add" (f64.const -0x1.3ff7dee2861c6p-557) (f64.const 0x1.84a2c18238b4cp+1023)) (f64.const 0x1.84a2c18238b4cp+1023)) (assert_return (invoke "f32.add" (f32.const -0x1.4ad8dap+127) (f32.const -0x1.eae082p+125)) (f32.const -0x1.c590fap+127))
(assert_return (invoke "f64.add" (f64.const 0x1.017099f2a4b8bp+1023) (f64.const 0x1.1f63b28f05454p+981)) (f64.const 0x1.017099f2a5009p+1023))
(assert_return (invoke "f64.add" (f64.const 0x1.d88b6c74984efp+1023) (f64.const 0x1.33b444775eabcp+990)) (f64.const 0x1.d88b6c7532291p+1023))
(assert_return (invoke "f64.add" (f64.const -0x1.84576422fdf5p+1023) (f64.const 0x1.60ee6aa12fb9cp+1012)) (f64.const -0x1.842b4655a9cf1p+1023))
(assert_return (invoke "f64.add" (f64.const -0x1.9aaace3e79f7dp+1001) (f64.const 0x1.e4068af295cb6p+1023)) (f64.const 0x1.e4068487ea926p+1023))
(assert_return (invoke "f64.add" (f64.const 0x1.06cdae79f27b9p+1023) (f64.const -0x1.e05cb0c96f975p+991)) (f64.const 0x1.06cdae78121eep+1023))
;; Computations that utilize the minimum exponent value. ;; Computations that utilize the minimum exponent value.
(assert_return (invoke "f64.add" (f64.const -0x0.2d2c9b631ae47p-1022) (f64.const -0x0.8e173a51d11a7p-1022)) (f64.const -0x0.bb43d5b4ebfeep-1022)) (assert_return (invoke "f32.add" (f32.const 0x1.6a1a2p-127) (f32.const 0x1.378p-140)) (f32.const 0x1.6a23dcp-127))
(assert_return (invoke "f64.add" (f64.const -0x0.ce7d534f2c7ep-1022) (f64.const -0x0.32f94dc4b7ee5p-1022)) (f64.const -0x1.0176a113e46c5p-1022)) (assert_return (invoke "f32.add" (f32.const 0x1.28p-144) (f32.const -0x1p-148)) (f32.const 0x1.18p-144))
(assert_return (invoke "f64.add" (f64.const -0x1.44d9fb78bf5d3p-1021) (f64.const -0x0.02766a20d263fp-1022)) (f64.const -0x1.46153089288f2p-1021)) (assert_return (invoke "f32.add" (f32.const -0x1p-146) (f32.const 0x1.c3cap-128)) (f32.const 0x1.c3c9cp-128))
(assert_return (invoke "f64.add" (f64.const 0x0.89e17f0fdc567p-1022) (f64.const -0x1.d9a93a01fd27dp-1021)) (f64.const -0x1.94b87a7a0efcap-1021)) (assert_return (invoke "f32.add" (f32.const -0x1.4p-145) (f32.const 0x1.424052p-122)) (f32.const 0x1.42405p-122))
(assert_return (invoke "f64.add" (f64.const -0x0.3f3d1a052fa2bp-1022) (f64.const -0x1.4b78292c7d2adp-1021)) (f64.const -0x1.6b16b62f14fc2p-1021)) (assert_return (invoke "f32.add" (f32.const 0x1.c5p-141) (f32.const -0x1.72f8p-135)) (f32.const -0x1.6be4p-135))
(assert_return (invoke "f64.add" (f64.const 0x1.4774c681d1e21p-1022) (f64.const -0x1.271e58e9f58cap-1021)) (f64.const -0x1.06c7eb5219373p-1022))
(assert_return (invoke "f64.add" (f64.const 0x1.10b3a75e31916p-1021) (f64.const -0x1.ffb82b0e868a7p-1021)) (f64.const -0x1.de090760a9f22p-1022))
(assert_return (invoke "f64.add" (f64.const -0x0.6b58448b8098ap-1022) (f64.const -0x1.579796ed04cbep-1022)) (f64.const -0x1.c2efdb7885648p-1022))
(assert_return (invoke "f64.add" (f64.const 0x1.9eb9e7baae8d1p-1020) (f64.const -0x1.d58e136f8c6eep-1020)) (f64.const -0x0.db50aed377874p-1022))
(assert_return (invoke "f64.add" (f64.const -0x1.f1115deeafa0bp-1022) (f64.const 0x1.221b1c87dca29p-1022)) (f64.const -0x0.cef64166d2fe2p-1022))
;; Test that what some systems call signaling NaN behaves as a quiet NaN. ;; Test an add of the second-greatest finite value with the distance to greatest
(assert_return (invoke "f64.add" (f64.const nan:0x4000000000000) (f64.const 1.0)) (f64.const nan:0xc000000000000)) ;; finite value.
(assert_return (invoke "f32.add" (f32.const 0x1.fffffcp+127) (f32.const 0x1p+104)) (f32.const 0x1.fffffep+127))
(assert_return (invoke "f64.add" (f64.const 0x1.ffffffffffffep+1023) (f64.const 0x1p+971)) (f64.const 0x1.fffffffffffffp+1023))
;; Test for a historic spreadsheet bug. ;; Test for a historic spreadsheet bug.
;; https://blogs.office.com/2007/09/25/calculation-issue-update/ ;; https://blogs.office.com/2007/09/25/calculation-issue-update/
(assert_return (invoke "f32.sub" (f32.const 65536.0) (f32.const 0x1p-37)) (f32.const 65536.0)) (assert_return (invoke "f32.sub" (f32.const 65536.0) (f32.const 0x1p-37)) (f32.const 65536.0))
;; Test for a historic spreadsheet bug.
;; https://blogs.office.com/2007/09/25/calculation-issue-update/
(assert_return (invoke "f64.sub" (f64.const 65536.0) (f64.const 0x1p-37)) (f64.const 0x1.fffffffffffffp+15)) (assert_return (invoke "f64.sub" (f64.const 65536.0) (f64.const 0x1p-37)) (f64.const 0x1.fffffffffffffp+15))
;; Test subtracting the greatest value from 1.0 that rounds back to 1.0, and the ;; Test subtracting the greatest value from 1.0 that rounds back to 1.0, and the
;; least that rounds to something less. ;; least that rounds to something less.
(assert_return (invoke "f32.sub" (f32.const 1.0) (f32.const 0x1p-25)) (f32.const 0x1.0p+0)) (assert_return (invoke "f32.sub" (f32.const 1.0) (f32.const 0x1p-25)) (f32.const 0x1.0p+0))
(assert_return (invoke "f32.sub" (f32.const 1.0) (f32.const 0x1.000002p-25)) (f32.const 0x1.fffffep-1)) (assert_return (invoke "f32.sub" (f32.const 1.0) (f32.const 0x1.000002p-25)) (f32.const 0x1.fffffep-1))
;; Test subtracting the greatest value from 1.0 that rounds back to 1.0, and the
;; least that rounds to something less.
(assert_return (invoke "f64.sub" (f64.const 1.0) (f64.const 0x1p-54)) (f64.const 0x1.0p+0)) (assert_return (invoke "f64.sub" (f64.const 1.0) (f64.const 0x1p-54)) (f64.const 0x1.0p+0))
(assert_return (invoke "f64.sub" (f64.const 1.0) (f64.const 0x1.0000000000001p-54)) (f64.const 0x1.fffffffffffffp-1)) (assert_return (invoke "f64.sub" (f64.const 1.0) (f64.const 0x1.0000000000001p-54)) (f64.const 0x1.fffffffffffffp-1))
@ -244,19 +222,35 @@
(assert_return (invoke "f64.sub" (f64.const 0x1.b60f9b2fbd9ecp-489) (f64.const -0x1.6f81c59ec5b8ep-694)) (f64.const 0x1.b60f9b2fbd9ecp-489)) (assert_return (invoke "f64.sub" (f64.const 0x1.b60f9b2fbd9ecp-489) (f64.const -0x1.6f81c59ec5b8ep-694)) (f64.const 0x1.b60f9b2fbd9ecp-489))
(assert_return (invoke "f64.sub" (f64.const 0x1.5e423fe8571f4p-57) (f64.const 0x1.9624ed7c162dfp-618)) (f64.const 0x1.5e423fe8571f4p-57)) (assert_return (invoke "f64.sub" (f64.const 0x1.5e423fe8571f4p-57) (f64.const 0x1.9624ed7c162dfp-618)) (f64.const 0x1.5e423fe8571f4p-57))
;; pow(e, π) - π
;; https://xkcd.com/217
(assert_return (invoke "f32.sub" (f32.const 0x1.724046p+4) (f32.const 0x1.921fb6p+1)) (f32.const 0x1.3ffc5p+4))
(assert_return (invoke "f64.sub" (f64.const 0x1.724046eb0933ap+4) (f64.const 0x1.921fb54442d18p+1)) (f64.const 0x1.3ffc504280d97p+4))
;; https://www.cnet.com/news/googles-calculator-muffs-some-math-problems/
(assert_return (invoke "f32.sub" (f32.const 2999999) (f32.const 2999998)) (f32.const 1.0))
(assert_return (invoke "f32.sub" (f32.const 1999999) (f32.const 1999995)) (f32.const 4.0))
(assert_return (invoke "f32.sub" (f32.const 1999999) (f32.const 1999993)) (f32.const 6.0))
(assert_return (invoke "f32.sub" (f32.const 400002) (f32.const 400001)) (f32.const 1.0))
(assert_return (invoke "f32.sub" (f32.const 400002) (f32.const 400000)) (f32.const 2.0))
(assert_return (invoke "f64.sub" (f64.const 2999999999999999) (f64.const 2999999999999998)) (f64.const 1.0))
(assert_return (invoke "f64.sub" (f64.const 1999999999999999) (f64.const 1999999999999995)) (f64.const 4.0))
(assert_return (invoke "f64.sub" (f64.const 1999999999999999) (f64.const 1999999999999993)) (f64.const 6.0))
(assert_return (invoke "f64.sub" (f64.const 400000000000002) (f64.const 400000000000001)) (f64.const 1.0))
(assert_return (invoke "f64.sub" (f64.const 400000000000002) (f64.const 400000000000000)) (f64.const 2.0))
;; Min normal - min subnormal = max subnornmal.
(assert_return (invoke "f32.sub" (f32.const 0x1p-126) (f32.const 0x1p-149)) (f32.const 0x1.fffffcp-127))
(assert_return (invoke "f64.sub" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x0.fffffffffffffp-1022))
;; Min normal - max subnormal = min subnornmal.
(assert_return (invoke "f32.sub" (f32.const 0x1p-126) (f32.const 0x1.fffffcp-127)) (f32.const 0x1p-149))
(assert_return (invoke "f64.sub" (f64.const 0x1p-1022) (f64.const 0x0.fffffffffffffp-1022)) (f64.const 0x0.0000000000001p-1022))
;; Miscellaneous values.
(assert_return (invoke "f32.mul" (f32.const 1e15) (f32.const 1e15)) (f32.const 0x1.93e592p+99)) (assert_return (invoke "f32.mul" (f32.const 1e15) (f32.const 1e15)) (f32.const 0x1.93e592p+99))
(assert_return (invoke "f32.mul" (f32.const 1e20) (f32.const 1e20)) (f32.const infinity)) (assert_return (invoke "f32.mul" (f32.const 1e20) (f32.const 1e20)) (f32.const infinity))
(assert_return (invoke "f32.mul" (f32.const 1e25) (f32.const 1e25)) (f32.const infinity)) (assert_return (invoke "f32.mul" (f32.const 1e25) (f32.const 1e25)) (f32.const infinity))
;; Test for a case of double rounding, example from:
;; http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html
;; section 3.3.1: A typical problem: "double rounding"
(assert_return (invoke "f32.mul" (f32.const 1848874880.0) (f32.const 19954563072.0)) (f32.const 0x1.000002p+65))
;; Test for a historic spreadsheet bug.
;; http://www.joelonsoftware.com/items/2007/09/26b.html
(assert_return (invoke "f32.mul" (f32.const 77.1) (f32.const 850)) (f32.const 65535))
(assert_return (invoke "f64.mul" (f64.const 1e15) (f64.const 1e15)) (f64.const 0x1.93e5939a08ceap+99)) (assert_return (invoke "f64.mul" (f64.const 1e15) (f64.const 1e15)) (f64.const 0x1.93e5939a08ceap+99))
(assert_return (invoke "f64.mul" (f64.const 1e20) (f64.const 1e20)) (f64.const 0x1.d6329f1c35ca5p+132)) (assert_return (invoke "f64.mul" (f64.const 1e20) (f64.const 1e20)) (f64.const 0x1.d6329f1c35ca5p+132))
(assert_return (invoke "f64.mul" (f64.const 1e25) (f64.const 1e25)) (f64.const 0x1.11b0ec57e649bp+166)) (assert_return (invoke "f64.mul" (f64.const 1e25) (f64.const 1e25)) (f64.const 0x1.11b0ec57e649bp+166))
@ -264,10 +258,12 @@
;; Test for a case of double rounding, example from: ;; Test for a case of double rounding, example from:
;; http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html ;; http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html
;; section 3.3.1: A typical problem: "double rounding" ;; section 3.3.1: A typical problem: "double rounding"
(assert_return (invoke "f32.mul" (f32.const 1848874880.0) (f32.const 19954563072.0)) (f32.const 0x1.000002p+65))
(assert_return (invoke "f64.mul" (f64.const 1848874847.0) (f64.const 19954562207.0)) (f64.const 3.6893488147419111424e+19)) (assert_return (invoke "f64.mul" (f64.const 1848874847.0) (f64.const 19954562207.0)) (f64.const 3.6893488147419111424e+19))
;; Test for a historic spreadsheet bug. ;; Test for a historic spreadsheet bug.
;; http://www.joelonsoftware.com/items/2007/09/26b.html ;; http://www.joelonsoftware.com/items/2007/09/26b.html
(assert_return (invoke "f32.mul" (f32.const 77.1) (f32.const 850)) (f32.const 65535))
(assert_return (invoke "f64.mul" (f64.const 77.1) (f64.const 850)) (f64.const 65534.99999999999272404)) (assert_return (invoke "f64.mul" (f64.const 77.1) (f64.const 850)) (f64.const 65534.99999999999272404))
;; Computations that round differently in round-upward mode. ;; Computations that round differently in round-upward mode.
@ -327,29 +323,38 @@
(assert_return (invoke "f64.mul" (f64.const 0x1.e4d235961d543p-373) (f64.const 0x1.bc56f20ef9a48p-205)) (f64.const 0x1.a4c09efcb71d6p-577)) (assert_return (invoke "f64.mul" (f64.const 0x1.e4d235961d543p-373) (f64.const 0x1.bc56f20ef9a48p-205)) (f64.const 0x1.a4c09efcb71d6p-577))
(assert_return (invoke "f64.mul" (f64.const -0x1.b9612e66faba8p+77) (f64.const 0x1.e2bc6aa782273p-348)) (f64.const -0x1.a026ea4f81db1p-270)) (assert_return (invoke "f64.mul" (f64.const -0x1.b9612e66faba8p+77) (f64.const 0x1.e2bc6aa782273p-348)) (f64.const -0x1.a026ea4f81db1p-270))
;; Test the least value with a positive square. ;; Test the least positive value with a positive square.
(assert_return (invoke "f32.mul" (f32.const 0x1p-75) (f32.const 0x1p-75)) (f32.const 0x0p+0)) (assert_return (invoke "f32.mul" (f32.const 0x1p-75) (f32.const 0x1p-75)) (f32.const 0x0p+0))
(assert_return (invoke "f32.mul" (f32.const 0x1.000002p-75) (f32.const 0x1.000002p-75)) (f32.const 0x1p-149)) (assert_return (invoke "f32.mul" (f32.const 0x1.000002p-75) (f32.const 0x1.000002p-75)) (f32.const 0x1p-149))
(assert_return (invoke "f64.mul" (f64.const 0x1.6a09e667f3bccp-538) (f64.const 0x1.6a09e667f3bccp-538)) (f64.const 0x0p+0)) (assert_return (invoke "f64.mul" (f64.const 0x1.6a09e667f3bccp-538) (f64.const 0x1.6a09e667f3bccp-538)) (f64.const 0x0p+0))
(assert_return (invoke "f64.mul" (f64.const 0x1.6a09e667f3bcdp-538) (f64.const 0x1.6a09e667f3bcdp-538)) (f64.const 0x0.0000000000001p-1022)) (assert_return (invoke "f64.mul" (f64.const 0x1.6a09e667f3bcdp-538) (f64.const 0x1.6a09e667f3bcdp-538)) (f64.const 0x0.0000000000001p-1022))
;; Test the greatest positive value with a finite square.
(assert_return (invoke "f32.mul" (f32.const 0x1.fffffep+63) (f32.const 0x1.fffffep+63)) (f32.const 0x1.fffffcp+127))
(assert_return (invoke "f32.mul" (f32.const 0x1p+64) (f32.const 0x1p+64)) (f32.const infinity))
(assert_return (invoke "f64.mul" (f64.const 0x1.fffffffffffffp+511) (f64.const 0x1.fffffffffffffp+511)) (f64.const 0x1.ffffffffffffep+1023))
(assert_return (invoke "f64.mul" (f64.const 0x1p+512) (f64.const 0x1p+512)) (f64.const infinity))
;; Test MIN * EPSILON.
;; http://www.mpfr.org/mpfr-2.0.1/patch2
(assert_return (invoke "f32.mul" (f32.const 0x1p-126) (f32.const 0x1p-23)) (f32.const 0x1p-149))
(assert_return (invoke "f64.mul" (f64.const 0x1p-1022) (f64.const 0x1p-52)) (f64.const 0x0.0000000000001p-1022))
;; Miscellaneous values.
(assert_return (invoke "f32.div" (f32.const 1.123456789) (f32.const 100)) (f32.const 0x1.702264p-7)) (assert_return (invoke "f32.div" (f32.const 1.123456789) (f32.const 100)) (f32.const 0x1.702264p-7))
(assert_return (invoke "f32.div" (f32.const 8391667.0) (f32.const 12582905.0)) (f32.const 0x1.55754p-1)) (assert_return (invoke "f32.div" (f32.const 8391667.0) (f32.const 12582905.0)) (f32.const 0x1.55754p-1))
(assert_return (invoke "f32.div" (f32.const 65536.0) (f32.const 0x1p-37)) (f32.const 0x1p+53)) (assert_return (invoke "f32.div" (f32.const 65536.0) (f32.const 0x1p-37)) (f32.const 0x1p+53))
(assert_return (invoke "f32.div" (f32.const 0x1.dcbf6ap+0) (f32.const 0x1.fffffep+127)) (f32.const 0x1.dcbf68p-128)) (assert_return (invoke "f32.div" (f32.const 0x1.dcbf6ap+0) (f32.const 0x1.fffffep+127)) (f32.const 0x1.dcbf68p-128))
(assert_return (invoke "f32.div" (f32.const 4) (f32.const 3)) (f32.const 0x1.555556p+0)) (assert_return (invoke "f32.div" (f32.const 4) (f32.const 3)) (f32.const 0x1.555556p+0))
;; Test for a historic hardware bug.
;; https://en.wikipedia.org/wiki/Pentium_FDIV_bug
(assert_return (invoke "f32.div" (f32.const 4195835) (f32.const 3145727)) (f32.const 0x1.557542p+0))
(assert_return (invoke "f64.div" (f64.const 1.123456789) (f64.const 100)) (f64.const 0.01123456789)) (assert_return (invoke "f64.div" (f64.const 1.123456789) (f64.const 100)) (f64.const 0.01123456789))
(assert_return (invoke "f64.div" (f64.const 8391667.0) (f64.const 12582905.0)) (f64.const 0x1.55753f1d9ba27p-1)) (assert_return (invoke "f64.div" (f64.const 8391667.0) (f64.const 12582905.0)) (f64.const 0x1.55753f1d9ba27p-1))
(assert_return (invoke "f64.div" (f64.const 65536.0) (f64.const 0x1p-37)) (f64.const 0x1p+53)) (assert_return (invoke "f64.div" (f64.const 65536.0) (f64.const 0x1p-37)) (f64.const 0x1p+53))
(assert_return (invoke "f64.div" (f64.const 0x1.dcbf6ap+0) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0.772fda8p-1022))
(assert_return (invoke "f64.div" (f64.const 4) (f64.const 3)) (f64.const 0x1.5555555555555p+0)) (assert_return (invoke "f64.div" (f64.const 4) (f64.const 3)) (f64.const 0x1.5555555555555p+0))
;; Test for a historic hardware bug. ;; Test for a historic hardware bug.
;; https://en.wikipedia.org/wiki/Pentium_FDIV_bug ;; https://en.wikipedia.org/wiki/Pentium_FDIV_bug
(assert_return (invoke "f32.div" (f32.const 4195835) (f32.const 3145727)) (f32.const 0x1.557542p+0))
(assert_return (invoke "f64.div" (f64.const 4195835) (f64.const 3145727)) (f64.const 0x1.557541c7c6b43p+0)) (assert_return (invoke "f64.div" (f64.const 4195835) (f64.const 3145727)) (f64.const 0x1.557541c7c6b43p+0))
;; Computations that round differently in round-upward mode. ;; Computations that round differently in round-upward mode.
@ -404,6 +409,11 @@
(assert_return (invoke "f64.div" (f64.const 0x1.7057d6ab553cap-1005) (f64.const -0x1.2abf1e98660ebp+23)) (f64.const -0x0.04ee8d8ec01cdp-1022)) (assert_return (invoke "f64.div" (f64.const 0x1.7057d6ab553cap-1005) (f64.const -0x1.2abf1e98660ebp+23)) (f64.const -0x0.04ee8d8ec01cdp-1022))
;; Computations that round differently when div is mul by reciprocal. ;; Computations that round differently when div is mul by reciprocal.
(assert_return (invoke "f32.div" (f32.const 0x1.ada9aap+89) (f32.const 0x1.69884cp+42)) (f32.const 0x1.303e2ep+47))
(assert_return (invoke "f32.div" (f32.const 0x1.8281c8p+90) (f32.const -0x1.62883cp+106)) (f32.const -0x1.17169cp-16))
(assert_return (invoke "f32.div" (f32.const 0x1.5c6be2p+81) (f32.const 0x1.d01dfep-1)) (f32.const 0x1.805e32p+81))
(assert_return (invoke "f32.div" (f32.const -0x1.bbd252p+19) (f32.const -0x1.fba95p+33)) (f32.const 0x1.bf9d56p-15))
(assert_return (invoke "f32.div" (f32.const -0x1.0f41d6p-42) (f32.const -0x1.3f2dbep+56)) (f32.const 0x1.b320d8p-99))
(assert_return (invoke "f64.div" (f64.const 0x1.b2348a1c81899p+61) (f64.const -0x1.4a58aad903dd3p-861)) (f64.const -0x1.507c1e2a41b35p+922)) (assert_return (invoke "f64.div" (f64.const 0x1.b2348a1c81899p+61) (f64.const -0x1.4a58aad903dd3p-861)) (f64.const -0x1.507c1e2a41b35p+922))
(assert_return (invoke "f64.div" (f64.const 0x1.23fa5137a918ap-130) (f64.const -0x1.7268db1951263p-521)) (f64.const -0x1.93965e0d896bep+390)) (assert_return (invoke "f64.div" (f64.const 0x1.23fa5137a918ap-130) (f64.const -0x1.7268db1951263p-521)) (f64.const -0x1.93965e0d896bep+390))
(assert_return (invoke "f64.div" (f64.const 0x1.dcb3915d82deep+669) (f64.const 0x1.50caaa1dc6b19p+638)) (f64.const 0x1.6a58ec814b09dp+31)) (assert_return (invoke "f64.div" (f64.const 0x1.dcb3915d82deep+669) (f64.const 0x1.50caaa1dc6b19p+638)) (f64.const 0x1.6a58ec814b09dp+31))
@ -423,22 +433,50 @@
(assert_return (invoke "f64.div" (f64.const 0x1p-1022) (f64.const 0x0.fffffffffffffp-1022)) (f64.const 0x1.0000000000001p+0)) (assert_return (invoke "f64.div" (f64.const 0x1p-1022) (f64.const 0x0.fffffffffffffp-1022)) (f64.const 0x1.0000000000001p+0))
(assert_return (invoke "f64.div" (f64.const 0x0.fffffffffffffp-1022) (f64.const 0x1p-1022)) (f64.const 0x1.ffffffffffffep-1)) (assert_return (invoke "f64.div" (f64.const 0x0.fffffffffffffp-1022) (f64.const 0x1p-1022)) (f64.const 0x1.ffffffffffffep-1))
;; Test the least value with a positive quotient with the maximum value. ;; Test the least positive value with a positive quotient with the maximum value.
(assert_return (invoke "f32.div" (f32.const 0x1.fffffep-23) (f32.const 0x1.fffffep+127)) (f32.const 0x0p+0)) (assert_return (invoke "f32.div" (f32.const 0x1.fffffep-23) (f32.const 0x1.fffffep+127)) (f32.const 0x0p+0))
(assert_return (invoke "f32.div" (f32.const 0x1p-22) (f32.const 0x1.fffffep+127)) (f32.const 0x1p-149)) (assert_return (invoke "f32.div" (f32.const 0x1p-22) (f32.const 0x1.fffffep+127)) (f32.const 0x1p-149))
(assert_return (invoke "f64.div" (f64.const 0x1.fffffffffffffp-52) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0p+0)) (assert_return (invoke "f64.div" (f64.const 0x1.fffffffffffffp-52) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0p+0))
(assert_return (invoke "f64.div" (f64.const 0x1p-51) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0.0000000000001p-1022)) (assert_return (invoke "f64.div" (f64.const 0x1p-51) (f64.const 0x1.fffffffffffffp+1023)) (f64.const 0x0.0000000000001p-1022))
;; Test the least value with a finite reciprocal. ;; Test the least positive value with a finite reciprocal.
(assert_return (invoke "f32.div" (f32.const 1.0) (f32.const 0x1p-128)) (f32.const infinity)) (assert_return (invoke "f32.div" (f32.const 1.0) (f32.const 0x1p-128)) (f32.const infinity))
(assert_return (invoke "f32.div" (f32.const 1.0) (f32.const 0x1.000008p-128)) (f32.const 0x1.fffffp+127)) (assert_return (invoke "f32.div" (f32.const 1.0) (f32.const 0x1.000008p-128)) (f32.const 0x1.fffffp+127))
(assert_return (invoke "f64.div" (f64.const 1.0) (f64.const 0x0.4p-1022)) (f64.const infinity)) (assert_return (invoke "f64.div" (f64.const 1.0) (f64.const 0x0.4p-1022)) (f64.const infinity))
(assert_return (invoke "f64.div" (f64.const 1.0) (f64.const 0x0.4000000000001p-1022)) (f64.const 0x1.ffffffffffff8p+1023)) (assert_return (invoke "f64.div" (f64.const 1.0) (f64.const 0x0.4000000000001p-1022)) (f64.const 0x1.ffffffffffff8p+1023))
;; Test the least positive value that has a subnormal reciprocal.
(assert_return (invoke "f32.div" (f32.const 1.0) (f32.const 0x1.000002p+126)) (f32.const 0x1.fffffcp-127))
(assert_return (invoke "f32.div" (f32.const 1.0) (f32.const 0x1p+126)) (f32.const 0x1p-126))
(assert_return (invoke "f64.div" (f64.const 1.0) (f64.const 0x1.0000000000001p+1022)) (f64.const 0x0.fffffffffffffp-1022))
(assert_return (invoke "f64.div" (f64.const 1.0) (f64.const 0x1p+1022)) (f64.const 0x1p-1022))
;; Test the minimum positive normal number divided by the minimum positive
;; subnormal number.
(assert_return (invoke "f32.div" (f32.const 0x1p-126) (f32.const 0x1p-149)) (f32.const 0x1p+23))
(assert_return (invoke "f64.div" (f64.const 0x1p-1022) (f64.const 0x0.0000000000001p-1022)) (f64.const 0x1p+52))
;; Test that the last binary digit of 1.0/3.0 is even in f32,
;; https://en.wikipedia.org/wiki/Single-precision_floating-point_format#Single-precision_examples
;;
;; and odd in f64,
;; https://en.wikipedia.org/wiki/Double-precision_floating-point_format#Double-precision_examples
;;
;; and that 1.0/3.0, 3.0/9.0, and 9.0/27.0 all agree.
;; http://www.netlib.org/paranoia
(assert_return (invoke "f32.div" (f32.const 0x1p+0) (f32.const 0x1.8p+1)) (f32.const 0x1.555556p-2))
(assert_return (invoke "f32.div" (f32.const 0x3p+0) (f32.const 0x1.2p+3)) (f32.const 0x1.555556p-2))
(assert_return (invoke "f32.div" (f32.const 0x1.2p+3) (f32.const 0x1.bp+4)) (f32.const 0x1.555556p-2))
(assert_return (invoke "f64.div" (f64.const 0x1p+0) (f64.const 0x1.8p+1)) (f64.const 0x1.5555555555555p-2))
(assert_return (invoke "f64.div" (f64.const 0x3p+0) (f64.const 0x1.2p+3)) (f64.const 0x1.5555555555555p-2))
(assert_return (invoke "f64.div" (f64.const 0x1.2p+3) (f64.const 0x1.bp+4)) (f64.const 0x1.5555555555555p-2))
;; Test for bugs found in an early RISC-V implementation. ;; Test for bugs found in an early RISC-V implementation.
;; https://github.com/riscv/riscv-tests/pull/8 ;; https://github.com/riscv/riscv-tests/pull/8
(assert_return (invoke "f32.sqrt" (f32.const 0x1.56p+7)) (f32.const 0x1.a2744cp+3)) (assert_return (invoke "f32.sqrt" (f32.const 0x1.56p+7)) (f32.const 0x1.a2744cp+3))
(assert_return (invoke "f32.sqrt" (f32.const 0x1.594dfcp-23)) (f32.const 0x1.a4789cp-12)) (assert_return (invoke "f32.sqrt" (f32.const 0x1.594dfcp-23)) (f32.const 0x1.a4789cp-12))
(assert_return (invoke "f64.sqrt" (f64.const 0x1.56p+7)) (f64.const 0x1.a2744ce9674f5p+3))
(assert_return (invoke "f64.sqrt" (f64.const 0x1.594dfc70aa105p-23)) (f64.const 0x1.a4789c0e37f99p-12))
;; Computations that round differently on x87. ;; Computations that round differently on x87.
(assert_return (invoke "f64.sqrt" (f64.const 0x1.0263fcc94f259p-164)) (f64.const 0x1.0131485de579fp-82)) (assert_return (invoke "f64.sqrt" (f64.const 0x1.0263fcc94f259p-164)) (f64.const 0x1.0131485de579fp-82))
@ -451,11 +489,6 @@
;; https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52593 ;; https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52593
(assert_return (invoke "f64.sqrt" (f64.const 0x1.fffffffffffffp-1)) (f64.const 0x1.fffffffffffffp-1)) (assert_return (invoke "f64.sqrt" (f64.const 0x1.fffffffffffffp-1)) (f64.const 0x1.fffffffffffffp-1))
;; Test for bugs found in an early RISC-V implementation.
;; https://github.com/riscv/riscv-tests/pull/8
(assert_return (invoke "f64.sqrt" (f64.const 0x1.56p+7)) (f64.const 0x1.a2744ce9674f5p+3))
(assert_return (invoke "f64.sqrt" (f64.const 0x1.594dfc70aa105p-23)) (f64.const 0x1.a4789c0e37f99p-12))
;; Computations that round differently in round-upward mode. ;; Computations that round differently in round-upward mode.
(assert_return (invoke "f32.sqrt" (f32.const 0x1.098064p-3)) (f32.const 0x1.70b23p-2)) (assert_return (invoke "f32.sqrt" (f32.const 0x1.098064p-3)) (f32.const 0x1.70b23p-2))
(assert_return (invoke "f32.sqrt" (f32.const 0x1.d9befp+100)) (f32.const 0x1.5c4052p+50)) (assert_return (invoke "f32.sqrt" (f32.const 0x1.d9befp+100)) (f32.const 0x1.5c4052p+50))
@ -499,13 +532,18 @@
(assert_return (invoke "f64.sqrt" (f64.const 0x1.e5522a741babep-276)) (f64.const 0x1.607ae2b6feb7dp-138)) (assert_return (invoke "f64.sqrt" (f64.const 0x1.e5522a741babep-276)) (f64.const 0x1.607ae2b6feb7dp-138))
(assert_return (invoke "f64.sqrt" (f64.const 0x1.4832badc0c061p+567)) (f64.const 0x1.99ec7934139b2p+283)) (assert_return (invoke "f64.sqrt" (f64.const 0x1.4832badc0c061p+567)) (f64.const 0x1.99ec7934139b2p+283))
;; Test the least greatest value with a sqrt that rounds to one.
(assert_return (invoke "f32.sqrt" (f32.const 0x1.000002p+0)) (f32.const 0x1p+0))
(assert_return (invoke "f32.sqrt" (f32.const 0x1.000004p+0)) (f32.const 0x1.000002p+0))
(assert_return (invoke "f64.sqrt" (f64.const 0x1.0000000000001p+0)) (f64.const 0x1p+0))
(assert_return (invoke "f64.sqrt" (f64.const 0x1.0000000000002p+0)) (f64.const 0x1.0000000000001p+0))
;; Test that the bitwise floating point operators are bitwise on NaN. ;; Test that the bitwise floating point operators are bitwise on NaN.
(assert_return (invoke "f32.abs" (f32.const nan)) (f32.const nan)) (assert_return (invoke "f32.abs" (f32.const nan)) (f32.const nan))
(assert_return (invoke "f32.abs" (f32.const -nan)) (f32.const nan)) (assert_return (invoke "f32.abs" (f32.const -nan)) (f32.const nan))
(assert_return (invoke "f32.abs" (f32.const nan:0x0f1e2)) (f32.const nan:0x0f1e2)) (assert_return (invoke "f32.abs" (f32.const nan:0x0f1e2)) (f32.const nan:0x0f1e2))
(assert_return (invoke "f32.abs" (f32.const -nan:0x0f1e2)) (f32.const nan:0x0f1e2)) (assert_return (invoke "f32.abs" (f32.const -nan:0x0f1e2)) (f32.const nan:0x0f1e2))
(assert_return (invoke "f64.abs" (f64.const nan)) (f64.const nan)) (assert_return (invoke "f64.abs" (f64.const nan)) (f64.const nan))
(assert_return (invoke "f64.abs" (f64.const -nan)) (f64.const nan)) (assert_return (invoke "f64.abs" (f64.const -nan)) (f64.const nan))
(assert_return (invoke "f64.abs" (f64.const nan:0x0f1e27a6b)) (f64.const nan:0x0f1e27a6b)) (assert_return (invoke "f64.abs" (f64.const nan:0x0f1e27a6b)) (f64.const nan:0x0f1e27a6b))
@ -515,7 +553,6 @@
(assert_return (invoke "f32.neg" (f32.const -nan)) (f32.const nan)) (assert_return (invoke "f32.neg" (f32.const -nan)) (f32.const nan))
(assert_return (invoke "f32.neg" (f32.const nan:0x0f1e2)) (f32.const -nan:0x0f1e2)) (assert_return (invoke "f32.neg" (f32.const nan:0x0f1e2)) (f32.const -nan:0x0f1e2))
(assert_return (invoke "f32.neg" (f32.const -nan:0x0f1e2)) (f32.const nan:0x0f1e2)) (assert_return (invoke "f32.neg" (f32.const -nan:0x0f1e2)) (f32.const nan:0x0f1e2))
(assert_return (invoke "f64.neg" (f64.const nan)) (f64.const -nan)) (assert_return (invoke "f64.neg" (f64.const nan)) (f64.const -nan))
(assert_return (invoke "f64.neg" (f64.const -nan)) (f64.const nan)) (assert_return (invoke "f64.neg" (f64.const -nan)) (f64.const nan))
(assert_return (invoke "f64.neg" (f64.const nan:0x0f1e27a6b)) (f64.const -nan:0x0f1e27a6b)) (assert_return (invoke "f64.neg" (f64.const nan:0x0f1e27a6b)) (f64.const -nan:0x0f1e27a6b))
@ -529,7 +566,6 @@
(assert_return (invoke "f32.copysign" (f32.const nan:0x0f1e2) (f32.const -nan)) (f32.const -nan:0x0f1e2)) (assert_return (invoke "f32.copysign" (f32.const nan:0x0f1e2) (f32.const -nan)) (f32.const -nan:0x0f1e2))
(assert_return (invoke "f32.copysign" (f32.const -nan:0x0f1e2) (f32.const nan)) (f32.const nan:0x0f1e2)) (assert_return (invoke "f32.copysign" (f32.const -nan:0x0f1e2) (f32.const nan)) (f32.const nan:0x0f1e2))
(assert_return (invoke "f32.copysign" (f32.const -nan:0x0f1e2) (f32.const -nan)) (f32.const -nan:0x0f1e2)) (assert_return (invoke "f32.copysign" (f32.const -nan:0x0f1e2) (f32.const -nan)) (f32.const -nan:0x0f1e2))
(assert_return (invoke "f64.copysign" (f64.const nan) (f64.const nan)) (f64.const nan)) (assert_return (invoke "f64.copysign" (f64.const nan) (f64.const nan)) (f64.const nan))
(assert_return (invoke "f64.copysign" (f64.const nan) (f64.const -nan)) (f64.const -nan)) (assert_return (invoke "f64.copysign" (f64.const nan) (f64.const -nan)) (f64.const -nan))
(assert_return (invoke "f64.copysign" (f64.const -nan) (f64.const nan)) (f64.const nan)) (assert_return (invoke "f64.copysign" (f64.const -nan) (f64.const nan)) (f64.const nan))
@ -542,28 +578,44 @@
;; Test that ceil isn't implemented as adding 0.5 and rounding to nearest. ;; Test that ceil isn't implemented as adding 0.5 and rounding to nearest.
(assert_return (invoke "f32.ceil" (f32.const 0x1.fffffep-1)) (f32.const 1.0)) (assert_return (invoke "f32.ceil" (f32.const 0x1.fffffep-1)) (f32.const 1.0))
(assert_return (invoke "f32.ceil" (f32.const 0x1p-126)) (f32.const 1.0)) (assert_return (invoke "f32.ceil" (f32.const 0x1p-126)) (f32.const 1.0))
;; Test that ceil isn't implemented as adding 0.5 and rounding to nearest.
(assert_return (invoke "f64.ceil" (f64.const 0x1.fffffffffffffp-1)) (f64.const 1.0)) (assert_return (invoke "f64.ceil" (f64.const 0x1.fffffffffffffp-1)) (f64.const 1.0))
(assert_return (invoke "f64.ceil" (f64.const 0x1p-1022)) (f64.const 1.0)) (assert_return (invoke "f64.ceil" (f64.const 0x1p-1022)) (f64.const 1.0))
;; Test the maximum and minimum value for which ceil is not an identity operator.
(assert_return (invoke "f32.ceil" (f32.const 0x1.fffffep+22)) (f32.const 0x1p+23))
(assert_return (invoke "f32.ceil" (f32.const -0x1.fffffep+22)) (f32.const -0x1.fffffcp+22))
(assert_return (invoke "f64.ceil" (f64.const 0x1.fffffffffffffp+51)) (f64.const 0x1p+52))
(assert_return (invoke "f64.ceil" (f64.const -0x1.fffffffffffffp+51)) (f64.const -0x1.ffffffffffffep+51))
;; Test that floor isn't implemented as subtracting 0.5 and rounding to nearest. ;; Test that floor isn't implemented as subtracting 0.5 and rounding to nearest.
(assert_return (invoke "f32.floor" (f32.const -0x1.fffffep-1)) (f32.const -1.0)) (assert_return (invoke "f32.floor" (f32.const -0x1.fffffep-1)) (f32.const -1.0))
(assert_return (invoke "f32.floor" (f32.const -0x1p-126)) (f32.const -1.0)) (assert_return (invoke "f32.floor" (f32.const -0x1p-126)) (f32.const -1.0))
;; Test that floor isn't implemented as subtracting 0.5 and rounding to nearest.
(assert_return (invoke "f64.floor" (f64.const -0x1.fffffffffffffp-1)) (f64.const -1.0)) (assert_return (invoke "f64.floor" (f64.const -0x1.fffffffffffffp-1)) (f64.const -1.0))
(assert_return (invoke "f64.floor" (f64.const -0x1p-1022)) (f64.const -1.0)) (assert_return (invoke "f64.floor" (f64.const -0x1p-1022)) (f64.const -1.0))
;; Test the maximum and minimum value for which floor is not an identity operator.
(assert_return (invoke "f32.floor" (f32.const -0x1.fffffep+22)) (f32.const -0x1p+23))
(assert_return (invoke "f32.floor" (f32.const 0x1.fffffep+22)) (f32.const 0x1.fffffcp+22))
(assert_return (invoke "f64.floor" (f64.const -0x1.fffffffffffffp+51)) (f64.const -0x1p+52))
(assert_return (invoke "f64.floor" (f64.const 0x1.fffffffffffffp+51)) (f64.const 0x1.ffffffffffffep+51))
;; Test the maximum and minimum value for which trunc is not an identity operator.
(assert_return (invoke "f32.trunc" (f32.const -0x1.fffffep+22)) (f32.const -0x1.fffffcp+22))
(assert_return (invoke "f32.trunc" (f32.const 0x1.fffffep+22)) (f32.const 0x1.fffffcp+22))
(assert_return (invoke "f64.trunc" (f64.const -0x1.fffffffffffffp+51)) (f64.const -0x1.ffffffffffffep+51))
(assert_return (invoke "f64.trunc" (f64.const 0x1.fffffffffffffp+51)) (f64.const 0x1.ffffffffffffep+51))
;; Test that nearest isn't implemented naively. ;; Test that nearest isn't implemented naively.
;; http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1 ;; http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1
;; http://blog.frama-c.com/index.php?post/2013/05/04/nearbyintf3 ;; http://blog.frama-c.com/index.php?post/2013/05/04/nearbyintf3
(assert_return (invoke "f32.nearest" (f32.const 0x1.000002p+23)) (f32.const 0x1.000002p+23)) (assert_return (invoke "f32.nearest" (f32.const 0x1.000002p+23)) (f32.const 0x1.000002p+23))
(assert_return (invoke "f32.nearest" (f32.const 0x1.000004p+23)) (f32.const 0x1.000004p+23)) (assert_return (invoke "f32.nearest" (f32.const 0x1.000004p+23)) (f32.const 0x1.000004p+23))
(assert_return (invoke "f32.nearest" (f32.const 0x1.fffffep-2)) (f32.const 0.0)) (assert_return (invoke "f32.nearest" (f32.const 0x1.fffffep-2)) (f32.const 0.0))
(assert_return (invoke "f32.nearest" (f32.const 0x1.fffffep+47)) (f32.const 0x1.fffffep+47))
(assert_return (invoke "f64.nearest" (f64.const 0x1.0000000000001p+52)) (f64.const 0x1.0000000000001p+52)) (assert_return (invoke "f64.nearest" (f64.const 0x1.0000000000001p+52)) (f64.const 0x1.0000000000001p+52))
(assert_return (invoke "f64.nearest" (f64.const 0x1.0000000000002p+52)) (f64.const 0x1.0000000000002p+52)) (assert_return (invoke "f64.nearest" (f64.const 0x1.0000000000002p+52)) (f64.const 0x1.0000000000002p+52))
(assert_return (invoke "f64.nearest" (f64.const 0x1.fffffffffffffp-2)) (f64.const 0.0)) (assert_return (invoke "f64.nearest" (f64.const 0x1.fffffffffffffp-2)) (f64.const 0.0))
(assert_return (invoke "f64.nearest" (f64.const 0x1.fffffffffffffp+105)) (f64.const 0x1.fffffffffffffp+105))
;; Nearest should not round halfway cases away from zero (as C's round(3) does) ;; Nearest should not round halfway cases away from zero (as C's round(3) does)
;; or up (as JS's Math.round does). ;; or up (as JS's Math.round does).
@ -574,6 +626,12 @@
(assert_return (invoke "f64.nearest" (f64.const -4.5)) (f64.const -4.0)) (assert_return (invoke "f64.nearest" (f64.const -4.5)) (f64.const -4.0))
(assert_return (invoke "f64.nearest" (f64.const -3.5)) (f64.const -4.0)) (assert_return (invoke "f64.nearest" (f64.const -3.5)) (f64.const -4.0))
;; Test the maximum and minimum value for which nearest is not an identity operator.
(assert_return (invoke "f32.nearest" (f32.const -0x1.fffffep+22)) (f32.const -0x1p+23))
(assert_return (invoke "f32.nearest" (f32.const 0x1.fffffep+22)) (f32.const 0x1p+23))
(assert_return (invoke "f64.nearest" (f64.const -0x1.fffffffffffffp+51)) (f64.const -0x1p+52))
(assert_return (invoke "f64.nearest" (f64.const 0x1.fffffffffffffp+51)) (f64.const 0x1p+52))
;; Test that min and max behave properly with signaling NaNs. ;; Test that min and max behave properly with signaling NaNs.
(assert_return (invoke "f32.min" (f32.const 0.0) (f32.const nan:0x200000)) (f32.const nan:0x600000)) (assert_return (invoke "f32.min" (f32.const 0.0) (f32.const nan:0x200000)) (f32.const nan:0x600000))
(assert_return (invoke "f32.min" (f32.const nan:0x200000) (f32.const 0.0)) (f32.const nan:0x600000)) (assert_return (invoke "f32.min" (f32.const nan:0x200000) (f32.const 0.0)) (f32.const nan:0x600000))

Просмотреть файл

@ -1,16 +1,13 @@
(module (module
(export "even" $even) (func $even (export "even") (param $n i32) (result i32)
(export "odd" $odd) (if i32 (i32.eq (get_local $n) (i32.const 0))
(func $even (param $n i32) (result i32)
(if (i32.eq (get_local $n) (i32.const 0))
(i32.const 1) (i32.const 1)
(call $odd (i32.sub (get_local $n) (i32.const 1))) (call $odd (i32.sub (get_local $n) (i32.const 1)))
) )
) )
(func $odd (param $n i32) (result i32) (func $odd (export "odd") (param $n i32) (result i32)
(if (i32.eq (get_local $n) (i32.const 0)) (if i32 (i32.eq (get_local $n) (i32.const 0))
(i32.const 0) (i32.const 0)
(call $even (i32.sub (get_local $n) (i32.const 1))) (call $even (i32.sub (get_local $n) (i32.const 1)))
) )

Просмотреть файл

@ -0,0 +1,541 @@
;; Test `func` declarations, i.e. functions
(module
;; Auxiliary definition
(type $sig (func))
(func $dummy)
;; Syntax
(func)
(func (export "f"))
(func $f)
(func $h (export "g"))
(func (local))
(func (local) (local))
(func (local i32))
(func (local $x i32))
(func (local i32 f64 i64))
(func (local i32) (local f64))
(func (local i32 f32) (local $x i64) (local) (local i32 f64))
(func (param))
(func (param) (param))
(func (param i32))
(func (param $x i32))
(func (param i32 f64 i64))
(func (param i32) (param f64))
(func (param i32 f32) (param $x i64) (param) (param i32 f64))
(func (result i32) (unreachable))
(func (type $sig))
(func $complex
(param i32 f32) (param $x i64) (param) (param i32)
(result i32)
(local f32) (local $y i32) (local i64 i32) (local) (local f64 i32)
(unreachable) (unreachable)
)
(func $complex-sig
(type $sig)
(local f32) (local $y i32) (local i64 i32) (local) (local f64 i32)
(unreachable) (unreachable)
)
;; Typing of locals
(func (export "local-first-i32") (result i32) (local i32 i32) (get_local 0))
(func (export "local-first-i64") (result i64) (local i64 i64) (get_local 0))
(func (export "local-first-f32") (result f32) (local f32 f32) (get_local 0))
(func (export "local-first-f64") (result f64) (local f64 f64) (get_local 0))
(func (export "local-second-i32") (result i32) (local i32 i32) (get_local 1))
(func (export "local-second-i64") (result i64) (local i64 i64) (get_local 1))
(func (export "local-second-f32") (result f32) (local f32 f32) (get_local 1))
(func (export "local-second-f64") (result f64) (local f64 f64) (get_local 1))
(func (export "local-mixed") (result f64)
(local f32) (local $x i32) (local i64 i32) (local) (local f64 i32)
(drop (f32.neg (get_local 0)))
(drop (i32.eqz (get_local 1)))
(drop (i64.eqz (get_local 2)))
(drop (i32.eqz (get_local 3)))
(drop (f64.neg (get_local 4)))
(drop (i32.eqz (get_local 5)))
(get_local 4)
)
;; Typing of parameters
(func (export "param-first-i32") (param i32 i32) (result i32) (get_local 0))
(func (export "param-first-i64") (param i64 i64) (result i64) (get_local 0))
(func (export "param-first-f32") (param f32 f32) (result f32) (get_local 0))
(func (export "param-first-f64") (param f64 f64) (result f64) (get_local 0))
(func (export "param-second-i32") (param i32 i32) (result i32) (get_local 1))
(func (export "param-second-i64") (param i64 i64) (result i64) (get_local 1))
(func (export "param-second-f32") (param f32 f32) (result f32) (get_local 1))
(func (export "param-second-f64") (param f64 f64) (result f64) (get_local 1))
(func (export "param-mixed") (param f32 i32) (param) (param $x i64) (param i32 f64 i32)
(result f64)
(drop (f32.neg (get_local 0)))
(drop (i32.eqz (get_local 1)))
(drop (i64.eqz (get_local 2)))
(drop (i32.eqz (get_local 3)))
(drop (f64.neg (get_local 4)))
(drop (i32.eqz (get_local 5)))
(get_local 4)
)
;; Typing of result
(func (export "empty"))
(func (export "value-void") (call $dummy))
(func (export "value-i32") (result i32) (i32.const 77))
(func (export "value-i64") (result i64) (i64.const 7777))
(func (export "value-f32") (result f32) (f32.const 77.7))
(func (export "value-f64") (result f64) (f64.const 77.77))
(func (export "value-block-void") (block (call $dummy) (call $dummy)))
(func (export "value-block-i32") (result i32)
(block i32 (call $dummy) (i32.const 77))
)
(func (export "return-empty") (return))
(func (export "return-i32") (result i32) (return (i32.const 78)))
(func (export "return-i64") (result i64) (return (i64.const 7878)))
(func (export "return-f32") (result f32) (return (f32.const 78.7)))
(func (export "return-f64") (result f64) (return (f64.const 78.78)))
(func (export "return-block-i32") (result i32)
(return (block i32 (call $dummy) (i32.const 77)))
)
(func (export "break-empty") (br 0))
(func (export "break-i32") (result i32) (br 0 (i32.const 79)))
(func (export "break-i64") (result i64) (br 0 (i64.const 7979)))
(func (export "break-f32") (result f32) (br 0 (f32.const 79.9)))
(func (export "break-f64") (result f64) (br 0 (f64.const 79.79)))
(func (export "break-block-i32") (result i32)
(br 0 (block i32 (call $dummy) (i32.const 77)))
)
(func (export "break-br_if-empty") (param i32)
(br_if 0 (get_local 0))
)
(func (export "break-br_if-num") (param i32) (result i32)
(drop (br_if 0 (i32.const 50) (get_local 0))) (i32.const 51)
)
(func (export "break-br_table-empty") (param i32)
(br_table 0 0 0 (get_local 0))
)
(func (export "break-br_table-num") (param i32) (result i32)
(br_table 0 0 (i32.const 50) (get_local 0)) (i32.const 51)
)
(func (export "break-br_table-nested-empty") (param i32)
(block (br_table 0 1 0 (get_local 0)))
)
(func (export "break-br_table-nested-num") (param i32) (result i32)
(i32.add
(block i32 (br_table 0 1 0 (i32.const 50) (get_local 0)) (i32.const 51))
(i32.const 2)
)
)
;; Default initialization of locals
(func (export "init-local-i32") (result i32) (local i32) (get_local 0))
(func (export "init-local-i64") (result i64) (local i64) (get_local 0))
(func (export "init-local-f32") (result f32) (local f32) (get_local 0))
(func (export "init-local-f64") (result f64) (local f64) (get_local 0))
;; Desugaring of implicit type signature
(func $empty-sig-1) ;; should be assigned type $sig
(func $complex-sig-1 (param f64 i64 f64 i64 f64 i64 f32 i32))
(func $empty-sig-2) ;; should be assigned type $sig
(func $complex-sig-2 (param f64 i64 f64 i64 f64 i64 f32 i32))
(func $complex-sig-3 (param f64 i64 f64 i64 f64 i64 f32 i32))
(type $empty-sig-duplicate (func))
(type $complex-sig-duplicate (func (param f64 i64 f64 i64 f64 i64 f32 i32)))
(table anyfunc
(elem
$complex-sig-3 $empty-sig-2 $complex-sig-1 $complex-sig-3 $empty-sig-1
)
)
(func (export "signature-explicit-reused")
(call_indirect $sig (i32.const 1))
(call_indirect $sig (i32.const 4))
)
(func (export "signature-implicit-reused")
;; The implicit index 16 in this test depends on the function and
;; type definitions, and may need adapting if they change.
(call_indirect 16
(f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0)
(f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0)
(i32.const 0)
)
(call_indirect 16
(f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0)
(f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0)
(i32.const 2)
)
(call_indirect 16
(f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0)
(f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0)
(i32.const 3)
)
)
(func (export "signature-explicit-duplicate")
(call_indirect $empty-sig-duplicate (i32.const 1))
)
(func (export "signature-implicit-duplicate")
(call_indirect $complex-sig-duplicate
(f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0)
(f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0)
(i32.const 0)
)
)
)
(assert_return (invoke "local-first-i32") (i32.const 0))
(assert_return (invoke "local-first-i64") (i64.const 0))
(assert_return (invoke "local-first-f32") (f32.const 0))
(assert_return (invoke "local-first-f64") (f64.const 0))
(assert_return (invoke "local-second-i32") (i32.const 0))
(assert_return (invoke "local-second-i64") (i64.const 0))
(assert_return (invoke "local-second-f32") (f32.const 0))
(assert_return (invoke "local-second-f64") (f64.const 0))
(assert_return (invoke "local-mixed") (f64.const 0))
(assert_return
(invoke "param-first-i32" (i32.const 2) (i32.const 3)) (i32.const 2)
)
(assert_return
(invoke "param-first-i64" (i64.const 2) (i64.const 3)) (i64.const 2)
)
(assert_return
(invoke "param-first-f32" (f32.const 2) (f32.const 3)) (f32.const 2)
)
(assert_return
(invoke "param-first-f64" (f64.const 2) (f64.const 3)) (f64.const 2)
)
(assert_return
(invoke "param-second-i32" (i32.const 2) (i32.const 3)) (i32.const 3)
)
(assert_return
(invoke "param-second-i64" (i64.const 2) (i64.const 3)) (i64.const 3)
)
(assert_return
(invoke "param-second-f32" (f32.const 2) (f32.const 3)) (f32.const 3)
)
(assert_return
(invoke "param-second-f64" (f64.const 2) (f64.const 3)) (f64.const 3)
)
(assert_return
(invoke "param-mixed"
(f32.const 1) (i32.const 2) (i64.const 3)
(i32.const 4) (f64.const 5.5) (i32.const 6)
)
(f64.const 5.5)
)
(assert_return (invoke "empty"))
(assert_return (invoke "value-void"))
(assert_return (invoke "value-i32") (i32.const 77))
(assert_return (invoke "value-i64") (i64.const 7777))
(assert_return (invoke "value-f32") (f32.const 77.7))
(assert_return (invoke "value-f64") (f64.const 77.77))
(assert_return (invoke "value-block-void"))
(assert_return (invoke "value-block-i32") (i32.const 77))
(assert_return (invoke "return-empty"))
(assert_return (invoke "return-i32") (i32.const 78))
(assert_return (invoke "return-i64") (i64.const 7878))
(assert_return (invoke "return-f32") (f32.const 78.7))
(assert_return (invoke "return-f64") (f64.const 78.78))
(assert_return (invoke "return-block-i32") (i32.const 77))
(assert_return (invoke "break-empty"))
(assert_return (invoke "break-i32") (i32.const 79))
(assert_return (invoke "break-i64") (i64.const 7979))
(assert_return (invoke "break-f32") (f32.const 79.9))
(assert_return (invoke "break-f64") (f64.const 79.79))
(assert_return (invoke "break-block-i32") (i32.const 77))
(assert_return (invoke "break-br_if-empty" (i32.const 0)))
(assert_return (invoke "break-br_if-empty" (i32.const 2)))
(assert_return (invoke "break-br_if-num" (i32.const 0)) (i32.const 51))
(assert_return (invoke "break-br_if-num" (i32.const 1)) (i32.const 50))
(assert_return (invoke "break-br_table-empty" (i32.const 0)))
(assert_return (invoke "break-br_table-empty" (i32.const 1)))
(assert_return (invoke "break-br_table-empty" (i32.const 5)))
(assert_return (invoke "break-br_table-empty" (i32.const -1)))
(assert_return (invoke "break-br_table-num" (i32.const 0)) (i32.const 50))
(assert_return (invoke "break-br_table-num" (i32.const 1)) (i32.const 50))
(assert_return (invoke "break-br_table-num" (i32.const 10)) (i32.const 50))
(assert_return (invoke "break-br_table-num" (i32.const -100)) (i32.const 50))
(assert_return (invoke "break-br_table-nested-empty" (i32.const 0)))
(assert_return (invoke "break-br_table-nested-empty" (i32.const 1)))
(assert_return (invoke "break-br_table-nested-empty" (i32.const 3)))
(assert_return (invoke "break-br_table-nested-empty" (i32.const -2)))
(assert_return
(invoke "break-br_table-nested-num" (i32.const 0)) (i32.const 52)
)
(assert_return
(invoke "break-br_table-nested-num" (i32.const 1)) (i32.const 50)
)
(assert_return
(invoke "break-br_table-nested-num" (i32.const 2)) (i32.const 52)
)
(assert_return
(invoke "break-br_table-nested-num" (i32.const -3)) (i32.const 52)
)
(assert_return (invoke "init-local-i32") (i32.const 0))
(assert_return (invoke "init-local-i64") (i64.const 0))
(assert_return (invoke "init-local-f32") (f32.const 0))
(assert_return (invoke "init-local-f64") (f64.const 0))
(assert_return (invoke "signature-explicit-reused"))
(assert_return (invoke "signature-implicit-reused"))
(assert_return (invoke "signature-explicit-duplicate"))
(assert_return (invoke "signature-implicit-duplicate"))
;; Invalid typing of locals
(assert_invalid
(module (func $type-local-num-vs-num (result i64) (local i32) (get_local 0)))
"type mismatch"
)
(assert_invalid
(module (func $type-local-num-vs-num (local f32) (i32.eqz (get_local 0))))
"type mismatch"
)
(assert_invalid
(module (func $type-local-num-vs-num (local f64 i64) (f64.neg (get_local 1))))
"type mismatch"
)
;; Invalid typing of parameters
(assert_invalid
(module (func $type-param-num-vs-num (param i32) (result i64) (get_local 0)))
"type mismatch"
)
(assert_invalid
(module (func $type-param-num-vs-num (param f32) (i32.eqz (get_local 0))))
"type mismatch"
)
(assert_invalid
(module (func $type-param-num-vs-num (param f64 i64) (f64.neg (get_local 1))))
"type mismatch"
)
;; Invalid typing of result
(assert_invalid
(module (func $type-multiple-result (result i32 i32) (unreachable)))
"invalid result arity"
)
(assert_invalid
(module
(type (func (result i32 i32)))
(func $type-multiple-result (type 0) (unreachable))
)
"invalid result arity"
)
(assert_invalid
(module (func $type-empty-i32 (result i32)))
"type mismatch"
)
(assert_invalid
(module (func $type-empty-i64 (result i64)))
"type mismatch"
)
(assert_invalid
(module (func $type-empty-f32 (result f32)))
"type mismatch"
)
(assert_invalid
(module (func $type-empty-f64 (result f64)))
"type mismatch"
)
(assert_invalid
(module (func $type-value-void-vs-num (result i32)
(nop)
))
"type mismatch"
)
(assert_invalid
(module (func $type-value-num-vs-void
(i32.const 0)
))
"type mismatch"
)
(assert_invalid
(module (func $type-value-num-vs-num (result i32)
(f32.const 0)
))
"type mismatch"
)
(; TODO(stack): Should these become legal?
(assert_invalid
(module (func $type-value-void-vs-num-after-return (result i32)
(return (i32.const 1)) (nop)
))
"type mismatch"
)
(assert_invalid
(module (func $type-value-num-vs-num-after-return (result i32)
(return (i32.const 1)) (f32.const 0)
))
"type mismatch"
)
(assert_invalid
(module (func $type-value-void-vs-num-after-break (result i32)
(br 0 (i32.const 1)) (nop)
))
"type mismatch"
)
(assert_invalid
(module (func $type-value-num-vs-num-after-break (result i32)
(br 0 (i32.const 1)) (f32.const 0)
))
"arity mismatch"
)
;)
;; TODO(stack): move these somewhere else
(module (func $type-return-void-vs-enpty (return (nop))))
(module (func $type-return-num-vs-enpty (return (i32.const 0))))
(assert_invalid
(module (func $type-return-last-empty-vs-num (result i32)
(return)
))
"type mismatch"
)
(assert_invalid
(module (func $type-return-last-void-vs-num (result i32)
(return (nop))
))
"type mismatch"
)
(assert_invalid
(module (func $type-return-last-num-vs-num (result i32)
(return (i64.const 0))
))
"type mismatch"
)
(assert_invalid
(module (func $type-return-empty-vs-num (result i32)
(return) (i32.const 1)
))
"type mismatch"
)
(assert_invalid
(module (func $type-return-void-vs-num (result i32)
(return (nop)) (i32.const 1)
))
"type mismatch"
)
(assert_invalid
(module (func $type-return-num-vs-num (result i32)
(return (i64.const 1)) (i32.const 1)
))
"type mismatch"
)
(assert_invalid
(module (func $type-return-first-num-vs-num (result i32)
(return (i64.const 1)) (return (i32.const 1))
))
"type mismatch"
)
(; TODO(stack): Should this become legal?
(assert_invalid
(module (func $type-return-second-num-vs-num (result i32)
(return (i32.const 1)) (return (f64.const 1))
))
"type mismatch"
)
;)
;; TODO(stack): move this elsewhere
(module (func $type-break-last-num-vs-void
(i32.const 0) (br 0)
))
(assert_invalid
(module (func $type-break-last-void-vs-num (result i32)
(br 0)
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-last-num-vs-num (result i32)
(br 0 (f32.const 0))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-void-vs-num (result i32)
(br 0) (i32.const 1)
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-num-vs-num (result i32)
(br 0 (i64.const 1)) (i32.const 1)
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-first-num-vs-num (result i32)
(br 0 (i64.const 1)) (br 0 (i32.const 1))
))
"type mismatch"
)
(; TODO(stack): soft failure
(assert_invalid
(module (func $type-break-second-num-vs-num (result i32)
(br 0 (i32.const 1)) (br 0 (f64.const 1))
))
"type mismatch"
)
;)
(assert_invalid
(module (func $type-break-nested-empty-vs-num (result i32)
(block (br 1)) (br 0 (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-nested-void-vs-num (result i32)
(block (br 1 (nop))) (br 0 (i32.const 1))
))
"type mismatch"
)
(assert_invalid
(module (func $type-break-nested-num-vs-num (result i32)
(block (br 1 (i64.const 1))) (br 0 (i32.const 1))
))
"type mismatch"
)

Просмотреть файл

@ -0,0 +1,4 @@
// |jit-test| test-also-wasm-baseline
// TODO: new anyfunc table syntax
quit();
var importedArgs = ['func.wast']; load(scriptdir + '../spec.js');

Просмотреть файл

@ -1,58 +1,70 @@
(module (module
(type (func)) ;; 0: void -> void (type (func)) ;; 0: void -> void
(type $S (func)) ;; 1: void -> void (type $S (func)) ;; 1: void -> void
(type (func (param))) ;; 2: void -> void (type (func (param))) ;; 2: void -> void
(type (func (result i32))) ;; 3: void -> i32 (type (func (result i32))) ;; 3: void -> i32
(type (func (param) (result i32))) ;; 4: void -> i32 (type (func (param) (result i32))) ;; 4: void -> i32
(type $T (func (param i32) (result i32))) ;; 5: i32 -> i32 (type $T (func (param i32) (result i32))) ;; 5: i32 -> i32
(type $U (func (param i32))) ;; 6: i32 -> void (type $U (func (param i32))) ;; 6: i32 -> void
(func (type 0)) (func $print (import "spectest" "print") (type 6))
(func (type $S))
(func $one (type 4) (i32.const 13)) (func (type 0))
(export "one" $one) (func (type $S))
(func $two (type $T) (i32.add (get_local 0) (i32.const 1))) (func (export "one") (type 4) (i32.const 13))
(export "two" $two) (func (export "two") (type $T) (i32.add (get_local 0) (i32.const 1)))
;; Both signature and parameters are allowed (and required to match) ;; Both signature and parameters are allowed (and required to match)
;; since this allows the naming of parameters. ;; since this allows the naming of parameters.
(func $three (type $T) (param $a i32) (result i32) (i32.sub (get_local 0) (i32.const 2))) (func (export "three") (type $T) (param $a i32) (result i32)
(export "three" $three) (i32.sub (get_local 0) (i32.const 2))
)
(import $print "spectest" "print" (type 6)) (func (export "four") (type $U) (call $print (get_local 0)))
(func $four (type $U) (call_import $print (get_local 0)))
(export "four" $four)
) )
(assert_return (invoke "one") (i32.const 13)) (assert_return (invoke "one") (i32.const 13))
(assert_return (invoke "two" (i32.const 13)) (i32.const 14)) (assert_return (invoke "two" (i32.const 13)) (i32.const 14))
(assert_return (invoke "three" (i32.const 13)) (i32.const 11)) (assert_return (invoke "three" (i32.const 13)) (i32.const 11))
(invoke "four" (i32.const 83)) (invoke "four" (i32.const 83))
(assert_invalid (module (func (type 42))) "unknown function type 42") (assert_invalid (module (elem (i32.const 0))) "unknown table")
(assert_invalid (module (import "spectest" "print" (type 43))) "unknown function type 43") (assert_invalid (module (elem (i32.const 0) 0) (func)) "unknown table")
(assert_invalid
(module (table 1 anyfunc) (elem (i64.const 0)))
"type mismatch"
)
(assert_invalid
(module (table 1 anyfunc) (elem (i32.ctz (i32.const 0))))
"constant expression required"
)
(assert_invalid
(module (table 1 anyfunc) (elem (nop)))
"constant expression required"
)
(assert_invalid (module (func (type 42))) "unknown type")
(assert_invalid (module (import "spectest" "print" (func (type 43)))) "unknown type")
(module (module
(type $T (func (param) (result i32))) (type $T (func (param) (result i32)))
(type $U (func (param) (result i32))) (type $U (func (param) (result i32)))
(table $t1 $t2 $t3 $u1 $u2 $t1 $t3) (table anyfunc (elem $t1 $t2 $t3 $u1 $u2 $t1 $t3))
(func $t1 (type $T) (i32.const 1)) (func $t1 (type $T) (i32.const 1))
(func $t2 (type $T) (i32.const 2)) (func $t2 (type $T) (i32.const 2))
(func $t3 (type $T) (i32.const 3)) (func $t3 (type $T) (i32.const 3))
(func $u1 (type $U) (i32.const 4)) (func $u1 (type $U) (i32.const 4))
(func $u2 (type $U) (i32.const 5)) (func $u2 (type $U) (i32.const 5))
(func $callt (param $i i32) (result i32) (func (export "callt") (param $i i32) (result i32)
(call_indirect $T (get_local $i)) (call_indirect $T (get_local $i))
) )
(export "callt" $callt)
(func $callu (param $i i32) (result i32) (func (export "callu") (param $i i32) (result i32)
(call_indirect $U (get_local $i)) (call_indirect $U (get_local $i))
) )
(export "callu" $callu)
) )
(assert_return (invoke "callt" (i32.const 0)) (i32.const 1)) (assert_return (invoke "callt" (i32.const 0)) (i32.const 1))
@ -62,9 +74,9 @@
(assert_return (invoke "callt" (i32.const 4)) (i32.const 5)) (assert_return (invoke "callt" (i32.const 4)) (i32.const 5))
(assert_return (invoke "callt" (i32.const 5)) (i32.const 1)) (assert_return (invoke "callt" (i32.const 5)) (i32.const 1))
(assert_return (invoke "callt" (i32.const 6)) (i32.const 3)) (assert_return (invoke "callt" (i32.const 6)) (i32.const 3))
(assert_trap (invoke "callt" (i32.const 7)) "undefined table index 7") (assert_trap (invoke "callt" (i32.const 7)) "undefined element")
(assert_trap (invoke "callt" (i32.const 100)) "undefined table index 100") (assert_trap (invoke "callt" (i32.const 100)) "undefined element")
(assert_trap (invoke "callt" (i32.const -1)) "undefined table index -1") (assert_trap (invoke "callt" (i32.const -1)) "undefined element")
(assert_return (invoke "callu" (i32.const 0)) (i32.const 1)) (assert_return (invoke "callu" (i32.const 0)) (i32.const 1))
(assert_return (invoke "callu" (i32.const 1)) (i32.const 2)) (assert_return (invoke "callu" (i32.const 1)) (i32.const 2))
@ -73,21 +85,20 @@
(assert_return (invoke "callu" (i32.const 4)) (i32.const 5)) (assert_return (invoke "callu" (i32.const 4)) (i32.const 5))
(assert_return (invoke "callu" (i32.const 5)) (i32.const 1)) (assert_return (invoke "callu" (i32.const 5)) (i32.const 1))
(assert_return (invoke "callu" (i32.const 6)) (i32.const 3)) (assert_return (invoke "callu" (i32.const 6)) (i32.const 3))
(assert_trap (invoke "callu" (i32.const 7)) "undefined table index 7") (assert_trap (invoke "callu" (i32.const 7)) "undefined element")
(assert_trap (invoke "callu" (i32.const -1)) "undefined table index -1") (assert_trap (invoke "callu" (i32.const 100)) "undefined element")
(assert_trap (invoke "callu" (i32.const -1)) "undefined element")
(module (module
(type $T (func (result i32))) (type $T (func (result i32)))
(table $t1 $t2) (table anyfunc (elem 0 1))
(import $print_i32 "spectest" "print" (param i32)) (func $t1 (type $T) (i32.const 1))
(func $t2 (type $T) (i32.const 2))
(func $t1 (type $T) (i32.const 1)) (func (export "callt") (param $i i32) (result i32)
(func $t2 (type $T) (i32.const 2)) (call_indirect $T (get_local $i))
)
(func $callt (param $i i32) (result i32)
(call_indirect $T (get_local $i)))
(export "callt" $callt)
) )
(assert_return (invoke "callt" (i32.const 0)) (i32.const 1)) (assert_return (invoke "callt" (i32.const 0)) (i32.const 1))

Просмотреть файл

@ -1,2 +1,4 @@
// |jit-test| test-also-wasm-baseline // |jit-test| test-also-wasm-baseline
// TODO: new anyfunc table syntax
quit();
var importedArgs = ['func_ptrs.wast']; load(scriptdir + '../spec.js'); var importedArgs = ['func_ptrs.wast']; load(scriptdir + '../spec.js');

Просмотреть файл

@ -1,44 +0,0 @@
(module
(func $empty)
(export "empty" $empty)
(func $result-nop (nop))
(export "result-nop" $result-nop)
(func $result-drop (i32.const 1))
(export "result-drop" $result-drop)
(func $result-block-nop (block (i32.const 1) (nop)))
(export "result-block-nop" $result-block-nop)
(func $result-block-drop (block (nop) (i32.const 1)))
(export "result-block-drop" $result-block-drop)
(func $return (return))
(export "return" $return)
(func $return-nop (return (nop)))
(export "return-nop" $return-nop)
(func $return-drop (return (i32.const 1)))
(export "return-drop" $return-drop)
(func $return-block-nop (return (block (i32.const 1) (nop))))
(export "return-block-nop" $return-block-nop)
(func $return-block-drop (return (block (nop) (i32.const 1))))
(export "return-block-drop" $return-block-drop)
)
(assert_return (invoke "empty"))
(assert_return (invoke "result-nop"))
(assert_return (invoke "result-drop"))
(assert_return (invoke "result-block-nop"))
(assert_return (invoke "result-block-drop"))
(assert_return (invoke "return"))
(assert_return (invoke "return-nop"))
(assert_return (invoke "return-drop"))
(assert_return (invoke "return-block-nop"))
(assert_return (invoke "return-block-drop"))

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше