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

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

@ -195,13 +195,18 @@ enum class AstExprKind
ComparisonOperator,
Const,
ConversionOperator,
Drop,
First,
GetGlobal,
GetLocal,
If,
Load,
Nop,
Pop,
Return,
SetGlobal,
SetLocal,
TeeLocal,
Store,
TernaryOperator,
UnaryOperator,
@ -212,15 +217,22 @@ enum class AstExprKind
class AstExpr : public AstNode
{
const AstExprKind kind_;
ExprType type_;
protected:
explicit AstExpr(AstExprKind kind)
: kind_(kind)
AstExpr(AstExprKind kind, ExprType type)
: kind_(kind), type_(type)
{}
public:
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>
T& as() {
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
{
static const AstExprKind Kind = AstExprKind::Unreachable;
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
{
const Val val_;
@ -243,7 +278,7 @@ class AstConst : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::Const;
explicit AstConst(Val val)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Limit),
val_(val)
{}
Val val() const { return val_; }
@ -256,7 +291,7 @@ class AstGetLocal : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::GetLocal;
explicit AstGetLocal(AstRef local)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Limit),
local_(local)
{}
AstRef& local() {
@ -272,7 +307,7 @@ class AstSetLocal : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::SetLocal;
AstSetLocal(AstRef local, AstExpr& value)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Void),
local_(local),
value_(value)
{}
@ -291,7 +326,7 @@ class AstGetGlobal : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::GetGlobal;
explicit AstGetGlobal(AstRef global)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Limit),
global_(global)
{}
AstRef& global() {
@ -307,7 +342,7 @@ class AstSetGlobal : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::SetGlobal;
AstSetGlobal(AstRef global, AstExpr& value)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Void),
global_(global),
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
{
Expr expr_;
AstName breakName_;
AstName continueName_;
AstName name_;
AstExprVector exprs_;
public:
static const AstExprKind Kind = AstExprKind::Block;
explicit AstBlock(Expr expr, AstName breakName, AstName continueName, AstExprVector&& exprs)
: AstExpr(Kind),
explicit AstBlock(Expr expr, ExprType type, AstName name, AstExprVector&& exprs)
: AstExpr(Kind, type),
expr_(expr),
breakName_(breakName),
continueName_(continueName),
name_(name),
exprs_(Move(exprs))
{}
Expr expr() const { return expr_; }
AstName breakName() const { return breakName_; }
AstName continueName() const { return continueName_; }
AstName name() const { return name_; }
const AstExprVector& exprs() const { return exprs_; }
};
@ -351,8 +403,9 @@ class AstBranch : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::Branch;
explicit AstBranch(Expr expr, AstExpr* cond, AstRef target, AstExpr* value)
: AstExpr(Kind),
explicit AstBranch(Expr expr, ExprType type,
AstExpr* cond, AstRef target, AstExpr* value)
: AstExpr(Kind, type),
expr_(expr),
cond_(cond),
target_(target),
@ -373,8 +426,8 @@ class AstCall : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::Call;
AstCall(Expr expr, AstRef func, AstExprVector&& args)
: AstExpr(Kind), expr_(expr), func_(func), args_(Move(args))
AstCall(Expr expr, ExprType type, AstRef func, AstExprVector&& args)
: AstExpr(Kind, type), expr_(expr), func_(func), args_(Move(args))
{}
Expr expr() const { return expr_; }
@ -385,17 +438,17 @@ class AstCall : public AstExpr
class AstCallIndirect : public AstExpr
{
AstRef sig_;
AstExpr* index_;
AstExprVector args_;
AstExpr* index_;
public:
static const AstExprKind Kind = AstExprKind::CallIndirect;
AstCallIndirect(AstRef sig, AstExpr* index, AstExprVector&& args)
: AstExpr(Kind), sig_(sig), index_(index), args_(Move(args))
AstCallIndirect(AstRef sig, ExprType type, AstExprVector&& args, AstExpr* index)
: AstExpr(Kind, type), sig_(sig), args_(Move(args)), index_(index)
{}
AstRef& sig() { return sig_; }
AstExpr* index() const { return index_; }
const AstExprVector& args() const { return args_; }
AstExpr* index() const { return index_; }
};
class AstReturn : public AstExpr
@ -405,7 +458,7 @@ class AstReturn : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::Return;
explicit AstReturn(AstExpr* maybeExpr)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Void),
maybeExpr_(maybeExpr)
{}
AstExpr* maybeExpr() const { return maybeExpr_; }
@ -414,20 +467,18 @@ class AstReturn : public AstExpr
class AstIf : public AstExpr
{
AstExpr* cond_;
AstName thenName_;
AstName name_;
AstExprVector thenExprs_;
AstName elseName_;
AstExprVector elseExprs_;
public:
static const AstExprKind Kind = AstExprKind::If;
AstIf(AstExpr* cond, AstName thenName, AstExprVector&& thenExprs,
AstName elseName, AstExprVector&& elseExprs)
: AstExpr(Kind),
AstIf(ExprType type, AstExpr* cond, AstName name,
AstExprVector&& thenExprs, AstExprVector&& elseExprs)
: AstExpr(Kind, type),
cond_(cond),
thenName_(thenName),
name_(name),
thenExprs_(Move(thenExprs)),
elseName_(elseName),
elseExprs_(Move(elseExprs))
{}
@ -435,8 +486,7 @@ class AstIf : public AstExpr
const AstExprVector& thenExprs() const { return thenExprs_; }
bool hasElse() const { return elseExprs_.length(); }
const AstExprVector& elseExprs() const { MOZ_ASSERT(hasElse()); return elseExprs_; }
AstName thenName() const { return thenName_; }
AstName elseName() const { return elseName_; }
AstName name() const { return name_; }
};
class AstLoadStoreAddress
@ -465,7 +515,7 @@ class AstLoad : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::Load;
explicit AstLoad(Expr expr, const AstLoadStoreAddress &address)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Limit),
expr_(expr),
address_(address)
{}
@ -484,7 +534,7 @@ class AstStore : public AstExpr
static const AstExprKind Kind = AstExprKind::Store;
explicit AstStore(Expr expr, const AstLoadStoreAddress &address,
AstExpr* value)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Void),
expr_(expr),
address_(address),
value_(value)
@ -506,7 +556,7 @@ class AstBranchTable : public AstExpr
static const AstExprKind Kind = AstExprKind::BranchTable;
explicit AstBranchTable(AstExpr& index, AstRef def, AstRefVector&& table,
AstExpr* maybeValue)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Void),
index_(index),
default_(def),
table_(Move(table)),
@ -542,20 +592,6 @@ class AstFunc : public AstNode
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
{
AstName name_;
@ -590,14 +626,14 @@ class AstImport : public AstNode
DefinitionKind kind_;
AstRef funcSig_;
AstResizable resizable_;
ResizableLimits resizable_;
AstGlobal global_;
public:
AstImport(AstName name, AstName module, AstName field, AstRef 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)
{}
AstImport(AstName name, AstName module, AstName field, AstGlobal global)
@ -613,7 +649,7 @@ class AstImport : public AstNode
MOZ_ASSERT(kind_ == DefinitionKind::Function);
return funcSig_;
}
AstResizable resizable() const {
ResizableLimits resizable() const {
MOZ_ASSERT(kind_ == DefinitionKind::Memory || kind_ == DefinitionKind::Table);
return resizable_;
}
@ -698,6 +734,7 @@ class AstModule : public AstNode
typedef AstVector<AstImport*> ImportVector;
typedef AstVector<AstExport*> ExportVector;
typedef AstVector<AstSig*> SigVector;
typedef AstVector<AstName> NameVector;
private:
typedef AstHashMap<AstSig*, uint32_t, AstSig> SigMap;
@ -706,8 +743,9 @@ class AstModule : public AstNode
SigVector sigs_;
SigMap sigMap_;
ImportVector imports_;
Maybe<AstResizable> table_;
Maybe<AstResizable> memory_;
NameVector funcImportNames_;
Maybe<ResizableLimits> table_;
Maybe<ResizableLimits> memory_;
ExportVector exports_;
Maybe<AstStartFunc> startFunc_;
FuncVector funcs_;
@ -721,6 +759,7 @@ class AstModule : public AstNode
sigs_(lifo),
sigMap_(lifo),
imports_(lifo),
funcImportNames_(lifo),
exports_(lifo),
funcs_(lifo),
dataSegments_(lifo),
@ -730,7 +769,7 @@ class AstModule : public AstNode
bool init() {
return sigMap_.init();
}
bool setMemory(AstResizable memory) {
bool setMemory(ResizableLimits memory) {
if (memory_)
return false;
memory_.emplace(memory);
@ -739,10 +778,10 @@ class AstModule : public AstNode
bool hasMemory() const {
return !!memory_;
}
const AstResizable& memory() const {
const ResizableLimits& memory() const {
return *memory_;
}
bool setTable(AstResizable table) {
bool setTable(ResizableLimits table) {
if (table_)
return false;
table_.emplace(table);
@ -751,7 +790,7 @@ class AstModule : public AstNode
bool hasTable() const {
return !!table_;
}
const AstResizable& table() const {
const ResizableLimits& table() const {
return *table_;
}
bool append(AstDataSegment* seg) {
@ -807,11 +846,19 @@ class AstModule : public AstNode
return funcs_;
}
bool append(AstImport* imp) {
if (imp->kind() == DefinitionKind::Function) {
if (!funcImportNames_.append(imp->name()))
return false;
}
return imports_.append(imp);
}
const ImportVector& imports() const {
return imports_;
}
const NameVector& funcImportNames() const {
return funcImportNames_;
}
bool append(AstExport* exp) {
return exports_.append(exp);
}
@ -833,7 +880,7 @@ class AstNullaryOperator final : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::NullaryOperator;
explicit AstNullaryOperator(Expr expr)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Limit),
expr_(expr)
{}
@ -848,7 +895,7 @@ class AstUnaryOperator final : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::UnaryOperator;
explicit AstUnaryOperator(Expr expr, AstExpr* op)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Limit),
expr_(expr), op_(op)
{}
@ -865,7 +912,7 @@ class AstBinaryOperator final : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::BinaryOperator;
explicit AstBinaryOperator(Expr expr, AstExpr* lhs, AstExpr* rhs)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Limit),
expr_(expr), lhs_(lhs), rhs_(rhs)
{}
@ -884,7 +931,7 @@ class AstTernaryOperator : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::TernaryOperator;
AstTernaryOperator(Expr expr, AstExpr* op0, AstExpr* op1, AstExpr* op2)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Limit),
expr_(expr), op0_(op0), op1_(op1), op2_(op2)
{}
@ -903,7 +950,7 @@ class AstComparisonOperator final : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::ComparisonOperator;
explicit AstComparisonOperator(Expr expr, AstExpr* lhs, AstExpr* rhs)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Limit),
expr_(expr), lhs_(lhs), rhs_(rhs)
{}
@ -920,7 +967,7 @@ class AstConversionOperator final : public AstExpr
public:
static const AstExprKind Kind = AstExprKind::ConversionOperator;
explicit AstConversionOperator(Expr expr, AstExpr* op)
: AstExpr(Kind),
: AstExpr(Kind, ExprType::Limit),
expr_(expr), op_(op)
{}
@ -928,6 +975,36 @@ class AstConversionOperator final : public AstExpr
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 js namespace

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

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

@ -18,11 +18,50 @@
#include "asmjs/WasmBinary.h"
#include <stdarg.h>
#include "jsprf.h"
#include "asmjs/WasmTypes.h"
using namespace js;
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
wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals)
{
@ -85,3 +124,63 @@ wasm::DecodeLocalEntries(Decoder& d, ValTypeVector* locals)
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 EncodingVersion = 0x0b;
static const uint32_t EncodingVersion = 0x0c;
static const char TypeSectionId[] = "type";
static const char GlobalSectionId[] = "global";
static const char ImportSectionId[] = "import";
static const char FunctionSectionId[] = "function";
static const char TableSectionId[] = "table";
static const char MemorySectionId[] = "memory";
static const char ExportSectionId[] = "export";
static const char StartSectionId[] = "start";
static const char CodeSectionId[] = "code";
static const char ElemSectionId[] = "elem";
static const char DataSectionId[] = "data";
static const char NameSectionId[] = "name";
enum class SectionId {
UserDefined = 0,
Type = 1,
Import = 2,
Function = 3,
Table = 4,
Memory = 5,
Global = 6,
Export = 7,
Start = 8,
Elem = 9,
Code = 10,
Data = 11
};
static const char NameSectionName[] = "name";
enum class ValType
{
@ -135,7 +139,7 @@ enum class GlobalFlags
enum class Expr
{
// Control flow operators
Nop = 0x00,
Unreachable = 0x00,
Block = 0x01,
Loop = 0x02,
If = 0x03,
@ -145,7 +149,8 @@ enum class Expr
BrIf = 0x07,
BrTable = 0x08,
Return = 0x09,
Unreachable = 0x0a,
Nop = 0x0a,
Drop = 0x0b,
End = 0x0f,
// Basic operators
@ -158,6 +163,7 @@ enum class Expr
Call = 0x16,
CallIndirect = 0x17,
CallImport = 0x18,
TeeLocal = 0x19,
// Memory-related operators
I32Load8S = 0x20,
@ -332,13 +338,23 @@ enum class Expr
// compiling asm.js and are rejected by wasm validation.
// asm.js-specific operators
TeeGlobal = 0xc8,
I32Min,
I32Max,
I32Neg,
I32BitNot,
I32Abs,
F32StoreF64,
F64StoreF32,
F32TeeStoreF64,
F64TeeStoreF32,
I32TeeStore8,
I32TeeStore16,
I64TeeStore8,
I64TeeStore16,
I64TeeStore32,
I32TeeStore,
I64TeeStore,
F32TeeStore,
F64TeeStore,
F64Mod,
F64Sin,
F64Cos,
@ -351,6 +367,9 @@ enum class Expr
F64Pow,
F64Atan2,
// asm.js-style call_indirect with the callee evaluated first.
OldCallIndirect,
// Atomics
I32AtomicsCompareExchange,
I32AtomicsExchange,
@ -523,6 +542,16 @@ class Encoder
} 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 {
size_t start = offset;
while (bytes_[offset] & 0x80)
@ -545,6 +574,10 @@ class Encoder
// Fixed-size encoding operations simply copy the literal bytes (without
// 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) {
return write<uint8_t>(i);
}
@ -588,6 +621,10 @@ class Encoder
static_assert(size_t(ValType::Limit) <= INT8_MAX, "fits");
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) {
static_assert(size_t(Expr::Limit) <= ExprLimit, "fits");
if (size_t(expr) < UINT8_MAX)
@ -596,6 +633,16 @@ class Encoder
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.
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
// after the section length is the string id of the section.
template <size_t IdSizeWith0>
MOZ_MUST_USE bool startSection(const char (&id)[IdSizeWith0], size_t* offset) {
static const size_t IdSize = IdSizeWith0 - 1;
MOZ_ASSERT(id[IdSize] == '\0');
return writeVarU32(IdSize) &&
bytes_.append(reinterpret_cast<const uint8_t*>(id), IdSize) &&
MOZ_MUST_USE bool startSection(SectionId id, size_t* offset) {
MOZ_ASSERT(id != SectionId::UserDefined); // not supported yet
return writeVarU32(uint32_t(id)) &&
writePatchableVarU32(offset);
}
void finishSection(size_t offset) {
@ -740,14 +785,8 @@ class Decoder
error_(error)
{}
bool fail(const char* msg) {
error_->reset(strdup(msg));
return false;
}
bool fail(UniqueChars msg) {
*error_ = Move(msg);
return false;
}
bool fail(const char* msg, ...);
bool fail(UniqueChars msg);
void clearError() {
if (error_)
error_->reset();
@ -859,48 +898,102 @@ class Decoder
static const uint32_t NotStarted = UINT32_MAX;
template <size_t IdSizeWith0>
MOZ_MUST_USE bool startSection(const char (&id)[IdSizeWith0],
MOZ_MUST_USE bool startSection(SectionId id,
uint32_t* startOffset,
uint32_t* size) {
static const size_t IdSize = IdSizeWith0 - 1;
MOZ_ASSERT(id[IdSize] == '\0');
const uint8_t* before = cur_;
uint32_t idSize;
if (!readVarU32(&idSize))
uint32_t* size,
const char* sectionName)
{
const uint8_t* const before = cur_;
const uint8_t* beforeId = before;
uint32_t idValue;
if (!readVarU32(&idValue))
goto backup;
if (bytesRemain() < idSize)
while (idValue != uint32_t(id)) {
if (idValue != uint32_t(SectionId::UserDefined))
goto backup;
// Rewind to the section id since skipUserDefinedSection expects it.
cur_ = beforeId;
if (!skipUserDefinedSection())
return false;
if (idSize != IdSize || !!memcmp(cur_, id, IdSize))
beforeId = cur_;
if (!readVarU32(&idValue))
goto backup;
cur_ += IdSize;
}
if (!readVarU32(size))
goto backup;
goto fail;
if (bytesRemain() < *size)
return false;
goto fail;
*startOffset = cur_ - beg_;
return true;
backup:
cur_ = before;
*startOffset = NotStarted;
return true;
fail:
return fail("failed to start %s section", sectionName);
}
MOZ_MUST_USE bool finishSection(uint32_t startOffset, uint32_t size) {
return size == (cur_ - beg_) - startOffset;
MOZ_MUST_USE bool finishSection(uint32_t startOffset, uint32_t size,
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;
MOZ_ASSERT(cur_ <= end_);
// "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;
}
MOZ_MUST_USE bool skipSection() {
uint32_t idSize;
if (!readVarU32(&idSize) || bytesRemain() < idSize)
return false;
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;
uint32_t size;
if (!readVarU32(&size) || bytesRemain() < size)
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_);
cur_ = (beg_ + sectionStart) + sectionSize;
MOZ_ASSERT(cur_ <= end_);
clearError();
}
MOZ_MUST_USE bool skipUserDefinedSection() {
uint32_t sectionStart, sectionSize;
if (!startUserDefinedSection(nullptr, 0, &sectionStart, &sectionSize))
return false;
cur_ += size;
if (sectionStart == NotStarted)
return fail("expected user-defined section");
finishUserDefinedSection(sectionStart, sectionSize);
return true;
}
@ -991,12 +1084,26 @@ class Decoder
typedef Vector<ValType, 8, SystemAllocPolicy> ValTypeVector;
MOZ_MUST_USE bool
DecodePreamble(Decoder& d);
MOZ_MUST_USE bool
EncodeLocalEntries(Encoder& d, const ValTypeVector& locals);
MOZ_MUST_USE bool
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 js

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

@ -33,6 +33,8 @@ wasm::Classify(Expr expr)
return ExprKind::Loop;
case Expr::Unreachable:
return ExprKind::Unreachable;
case Expr::Drop:
return ExprKind::Drop;
case Expr::I32Const:
return ExprKind::I32;
case Expr::I64Const:
@ -62,7 +64,7 @@ wasm::Classify(Expr expr)
case Expr::BrTable:
return ExprKind::BrTable;
case Expr::Nop:
return ExprKind::Nullary;
return ExprKind::Nop;
case Expr::I32Clz:
case Expr::I32Ctz:
case Expr::I32Popcnt:
@ -314,8 +316,18 @@ wasm::Classify(Expr expr)
case Expr::I64Store:
case Expr::F32Store:
case Expr::F64Store:
case Expr::F32StoreF64:
case Expr::F64StoreF32:
return ExprKind::Store;
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::I16x8store:
case Expr::I32x4store:
@ -326,19 +338,27 @@ wasm::Classify(Expr expr)
case Expr::F32x4store1:
case Expr::F32x4store2:
case Expr::F32x4store3:
return ExprKind::Store;
return ExprKind::TeeStore;
case Expr::Select:
return ExprKind::Select;
case Expr::GetLocal:
case Expr::GetGlobal:
return ExprKind::GetVar;
return ExprKind::GetLocal;
case Expr::SetLocal:
return ExprKind::SetLocal;
case Expr::TeeLocal:
return ExprKind::TeeLocal;
case Expr::GetGlobal:
return ExprKind::GetGlobal;
case Expr::SetGlobal:
return ExprKind::SetVar;
return ExprKind::SetGlobal;
case Expr::TeeGlobal:
return ExprKind::TeeGlobal;
case Expr::Call:
return ExprKind::Call;
case Expr::CallIndirect:
return ExprKind::CallIndirect;
case Expr::OldCallIndirect:
return ExprKind::OldCallIndirect;
case Expr::CallImport:
return ExprKind::CallImport;
case Expr::Return:

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

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

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

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

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

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

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

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

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

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

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

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

@ -21,6 +21,8 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/Maybe.h"
#include "jsprf.h"
#include "asmjs/WasmCompile.h"
#include "asmjs/WasmInstance.h"
#include "asmjs/WasmModule.h"
@ -336,6 +338,9 @@ bool
wasm::Eval(JSContext* cx, Handle<TypedArrayObject*> code, HandleObject importObj,
MutableHandleWasmInstanceObject instanceObj)
{
if (!GlobalObject::ensureConstructor(cx, cx->global(), JSProto_WebAssembly))
return false;
MutableBytes bytecode = cx->new_<ShareableBytes>();
if (!bytecode)
return false;
@ -356,9 +361,11 @@ wasm::Eval(JSContext* cx, Handle<TypedArrayObject*> code, HandleObject importObj
UniqueChars error;
SharedModule module = Compile(*bytecode, compileArgs, &error);
if (!module) {
if (error)
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_FAIL, error.get());
else
if (error) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_DECODE_FAIL,
error.get());
return false;
}
ReportOutOfMemory(cx);
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);
}
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
static bool
wasm_toSource(JSContext* cx, unsigned argc, Value* vp)
@ -416,7 +394,6 @@ static const JSFunctionSpec wasm_static_methods[] = {
#if JS_HAS_TOSOURCE
JS_FN(js_toSource_str, wasm_toSource, 0, 0),
#endif
JS_FN("instantiateModule", InstantiateModule, 1, 0),
JS_FS_END
};
@ -601,7 +578,6 @@ GetCompileArgs(JSContext* cx, CallArgs callArgs, const char* name, MutableBytes*
if (!compileArgs->initFromContext(cx, Move(scriptedCaller)))
return false;
compileArgs->assumptions.newFormat = true;
return true;
}
@ -621,9 +597,11 @@ WasmModuleObject::construct(JSContext* cx, unsigned argc, Value* vp)
UniqueChars error;
SharedModule module = Compile(*bytecode, compileArgs, &error);
if (!module) {
if (error)
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_FAIL, error.get());
else
if (error) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_DECODE_FAIL,
error.get());
return false;
}
ReportOutOfMemory(cx);
return false;
}
@ -1478,7 +1456,14 @@ Reject(JSContext* cx, const CompileArgs& args, UniqueChars error, Handle<Promise
unsigned line = args.scriptedCaller.line;
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)
return false;
@ -1598,7 +1583,7 @@ WebAssembly_validate(JSContext* cx, unsigned argc, Value* vp)
if (error) {
JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING, GetErrorMessage, nullptr,
JSMSG_WASM_DECODE_FAIL, "?", error.get());
JSMSG_WASM_DECODE_FAIL, error.get());
}
callArgs.rval().setBoolean(validated);

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

@ -101,7 +101,7 @@ ExportedFunctionToDefinitionIndex(JSFunction* fun);
} // 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.
extern const Class WasmClass;

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

@ -559,9 +559,7 @@ Module::instantiateMemory(JSContext* cx, MutableHandleWasmMemoryObject memory) c
if (!buffer)
return false;
RootedObject proto(cx);
if (metadata_->assumptions.newFormat)
proto = &cx->global()->getPrototype(JSProto_WasmMemory).toObject();
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmMemory).toObject());
memory.set(WasmMemoryObject::create(cx, buffer, proto));
if (!memory)
@ -744,10 +742,7 @@ CreateExportObject(JSContext* cx,
val = ObjectValue(*tableObj);
break;
case DefinitionKind::Memory:
if (metadata.assumptions.newFormat)
val = ObjectValue(*memoryObj);
else
val = ObjectValue(memoryObj->buffer());
break;
case DefinitionKind::Global:
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
// 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'.
// 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
TextToBinary(const char16_t* text, bool newFormat, Bytes* bytes, UniqueChars* error);
TextToBinary(const char16_t* text, Bytes* bytes, UniqueChars* error);
} // namespace wasm
} // namespace js

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

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

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

@ -146,24 +146,6 @@ struct ShareableBase : RefCounted<T>
// 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
IsVoid(ExprType et)
{
@ -927,7 +909,6 @@ struct Assumptions
{
uint32_t cpuId;
JS::BuildIdCharVector buildId;
bool newFormat;
explicit Assumptions(JS::BuildIdCharVector&& buildId);

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

@ -532,28 +532,16 @@ WasmTextToBinary(JSContext* cx, unsigned argc, Value* vp)
if (!twoByteChars.initTwoByte(cx, args[0].toString()))
return false;
bool newFormat = false;
if (args.hasDefined(1)) {
if (!args[1].isString()) {
ReportUsageError(cx, callee, "Second argument, if present, must be a String");
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;
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,
error.get() ? error.get() : "out of memory");
return false;

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

@ -55,7 +55,7 @@ evaluated in the same lexical environment.
For `Debugger.Script` instances referring to a block of WebAssembly code, they
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.
`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
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
underlying WebAssembly module per [`Debugger`][debugger-object] instance.
@ -107,7 +107,7 @@ from its prototype:
return `undefined`.)
**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`
: **If the instance refers to JavaScript source**, if this source was

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

@ -3,17 +3,8 @@ if (!wasmIsSupported())
load(libdir + "asserts.js");
function textToBinary(str) {
// TODO when mass-switching to the new-format, just rename
// 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');
function wasmEvalText(str, imports) {
let binary = wasmTextToBinary(str);
let valid = WebAssembly.validate(binary);
let m;
@ -29,22 +20,15 @@ function evalText(str, imports) {
}
function wasmValidateText(str) {
assertEq(WebAssembly.validate(wasmTextToBinary(str, 'new-format')), true);
assertEq(WebAssembly.validate(wasmTextToBinary(str)), true);
}
function wasmFailValidateText(str, errorType, pattern) {
let binary = wasmTextToBinary(str, 'new-format');
let binary = wasmTextToBinary(str);
assertEq(WebAssembly.validate(binary), false);
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) {
var str = `type mismatch: expression has type ${actual} but expected ${expect}`;
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);
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);
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);
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))
(func $h (result i32) (call_import $f (i32.const 1)))
(export "h" $h)
)`), {imp:{f}}).exports.h;
)`)), {imp:{f}}).exports.h;
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});
assertEq(j(), 0);
}

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

@ -7,5 +7,5 @@ var dbg = new Debugger(g);
dbg.onNewScript = (function(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;

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

@ -4,7 +4,7 @@ if (!wasmIsSupported())
quit();
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"; }
@ -14,7 +14,7 @@ assertEq(foundScripts1.length, 1);
var found = foundScripts1[0];
// 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);
assertEq(foundScripts2.length, 2);

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

@ -11,11 +11,11 @@ dbg.onNewScript = (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");
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");
// The two wasm Debugger.Scripts are distinct.

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

@ -13,7 +13,7 @@ dbg.onNewScript = (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");
var source = s.source;

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

@ -13,7 +13,7 @@ dbg.onNewScript = (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");
assertThrowsInstanceOf(() => s.displayName, Error);

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

@ -15,7 +15,7 @@ function getAllOffsets(wast) {
dbg.addDebuggee(sandbox);
sandbox.eval(`
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 lines = wasmScript.source.text.split('\n');
@ -24,7 +24,7 @@ function getAllOffsets(wast) {
var result1 = getAllOffsets('(module \
(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);
@ -35,11 +35,12 @@ assertEq(nopLine[0].offsets[0] > 0, true);
var sqrtLine = result1.filter(i => i.str.indexOf('sqrt') >= 0);
assertEq(sqrtLine.length, 1);
// The sqrtLine shall have 4 offsets but they were produced from AST postorder decoding:
// f32.sqrt(1.0 + 2.0) ~~> 74,73,63,68
assertEq(sqrtLine[0].offsets.length, 4);
assertEq(sqrtLine[0].offsets[2] > 0, true);
assertEq(sqrtLine[0].offsets[2] < sqrtLine[0].offsets[3], true);
// The sqrtLine shall have 5 offsets but they were produced from AST postorder decoding:
// drop(f32.sqrt(1.0 + 2.0)) ~~> 88,87,86,76,81
assertEq(sqrtLine[0].offsets.length, 5);
assertEq(sqrtLine[0].offsets[3] > 0, 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[0] > sqrtLine[0].offsets[1], true);

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

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

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

@ -4,13 +4,13 @@ load(libdir + "wasm.js");
// ----------------------------------------------------------------------------
// exports
var o = wasmEvalText('(module)');
var o = wasmEvalText('(module)').exports;
assertEq(Object.getOwnPropertyNames(o).length, 0);
var o = wasmEvalText('(module (func))');
var o = wasmEvalText('(module (func))').exports;
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);
assertEq(names.length, 1);
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) (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(o.a.name, "wasm-function[0]");
assertEq(o.b.name, "wasm-function[0]");
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(o.a.name, "wasm-function[0]");
assertEq(o.b.name, "wasm-function[1]");
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.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.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 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/);
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/);
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/);
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/);
setJitCompilerOption('wasm.test-mode', 1);
assertEqI64(wasmEvalText('(module (func (result i64) (i64.const 123)) (export "" 0))')(), {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 (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))').exports[""]({ 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);
// ----------------------------------------------------------------------------
@ -132,126 +132,127 @@ wasmFailValidateText('(module (memory 65536))', TypeError, /initial memory size
try {
wasmEvalText('(module (memory 65535))');
} 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.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))');
assertEq(obj.memory instanceof ArrayBuffer, true);
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.buffer instanceof ArrayBuffer, true);
assertEq(obj.b 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.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);
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);
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));
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)[1], 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)[65535], 'c'.charCodeAt(0));
wasmFailValidateText('(module (memory 1 (segment 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 65536 "a") (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
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))')(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 1)) (export "" 0))')(42, 43), 43);
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))').exports[""](42), 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))').exports[""](42, 43), 43);
wasmFailValidateText('(module (func (get_local 0)))', TypeError, /get_local index out of range/);
wasmValidateText('(module (func (local i32)))');
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 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 f32) (param i32) (local f32) (get_local 1)) (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))').exports[""](), 0);
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 (set_local 0 (i32.const 0))))', TypeError, /set_local index out of range/);
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 (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 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 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) (set_local 0 (get_local 0))) (export "" 0))')(), 0);
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) (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) (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) (result i32) (get_local $a)) (export "" 0))').exports[""](), 0);
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))))');
// ----------------------------------------------------------------------------
// 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 (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 (result i32) (block (i32.const 42))) (export "" 0))')(), 42);
assertEq(wasmEvalText('(module (func (result i32) (block (block (i32.const 42)))) (export "" 0))')(), 42);
wasmFailValidateText('(module (func (result f32) (block (i32.const 0))))', TypeError, mismatchError("i32", "f32"));
assertEq(wasmEvalText('(module (func (block (block ))) (export "" 0))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (result i32) (block i32 (i32.const 42))) (export "" 0))').exports[""](), 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 (i32.const 0))))', TypeError, mismatchError("i32", "f32"));
assertEq(wasmEvalText('(module (func (result i32) (block (i32.const 13) (block (i32.const 42)))) (export "" 0))')(), 42);
wasmFailValidateText('(module (func (result f32) (param f32) (block (get_local 0) (i32.const 0))))', TypeError, mismatchError("i32", "f32"));
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 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
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 (nop)) (func (call 3)))', TypeError, /callee index out of range/);
wasmValidateText('(module (func (nop)) (func (call 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);
assertThrowsInstanceOf(() => wasmEvalText('(module (func (call 0)) (export "" 0))')(), InternalError);
assertThrowsInstanceOf(() => wasmEvalText('(module (func (call 1)) (func (call 0)) (export "" 0))')(), InternalError);
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))').exports[""](), 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))))');
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" "" (param i32)) (func (call_import 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, /peeking at value from outside block/);
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" (param i32)) (func (call_import 0 (i32.const 0))))', {"":{a:()=>{}}});
function checkF32CallImport(v) {
assertEq(wasmEvalText('(module (import "" "a" (result f32)) (func (result f32) (call_import 0)) (export "" 0))', {"":{a:()=>{ return v; }}})(), 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);
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 "" 1))', {"":{a:x=>{ assertEq(Math.fround(v), x); }}}).exports[""](v);
}
checkF32CallImport(13.37);
checkF32CallImport(NaN);
@ -260,31 +261,31 @@ checkF32CallImport(-0);
checkF32CallImport(Math.pow(2, 32) - 1);
var counter = 0;
var f = wasmEvalText('(module (import "" "inc") (func (call_import 0)) (export "" 0))', {"":{inc:()=>counter++}});
var g = wasmEvalText('(module (import "" "f") (func (block (call_import 0) (call_import 0))) (export "" 0))', {"":{f}});
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 "" 1))', {"":{f}}).exports[""];
f();
assertEq(counter, 1);
g();
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);
var f = wasmEvalText('(module (import "" "callg") (func (call_import 0)) (export "" 0))', {"":{callg:()=>g()}});
var g = wasmEvalText('(module (import "" "callf") (func (call_import 0)) (export "" 0))', {"":{callf:()=>f()}});
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 "" 1))', {"":{callf:()=>f()}}).exports[""];
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}};
assertEq(wasmEvalText(code.replace('BODY', '(call_import 0)'), imports)(), 1);
assertEq(wasmEvalText(code.replace('BODY', '(call_import 1)'), imports)(), 2);
assertEq(wasmEvalText(code.replace('BODY', '(call 0)'), imports)(), 3);
assertEq(wasmEvalText(code.replace('BODY', '(call 1)'), imports)(), 4);
assertEq(wasmEvalText(code.replace('BODY', '(call_import 0)'), imports).exports[""](), 1);
assertEq(wasmEvalText(code.replace('BODY', '(call_import 1)'), imports).exports[""](), 2);
assertEq(wasmEvalText(code.replace('BODY', '(call 2)'), imports).exports[""](), 3);
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')
evaluate(`Wasm.instantiateModule(wasmTextToBinary('(module)')) `, { fileName: null });
evaluate(`new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary('(module)'))) `, { fileName: null });
{
setJitCompilerOption('wasm.test-mode', 1);
@ -316,17 +317,17 @@ if (typeof evaluate === 'function')
assertEq(wasmEvalText(`(module
(import "" "param" (param i64) (result i32))
(func (result i32) (call_import 0 (i64.const 0x123456789abcdef0)))
(export "" 0))`, imp)(), 42);
(export "" 1))`, imp).exports[""](), 42);
assertEq(wasmEvalText(`(module
(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)))
(export "" 0))`, imp)(), 42);
(export "" 1))`, imp).exports[""](), 42);
assertEqI64(wasmEvalText(`(module
(import "" "result" (param i32) (result i64))
(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.
let ionThreshold = 2 * getJitCompilerOptions()['ion.warmup.trigger'];
@ -341,7 +342,22 @@ if (typeof evaluate === 'function')
)
(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);
}
@ -360,12 +376,12 @@ var {v2i, i2i, i2v} = wasmEvalText(`(module
(func (type 1) (i32.add (get_local 0) (i32.const 4)))
(table 0 1 2 3 4 5)
(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) (call_indirect 2 (get_local 0) (i32.const 0)))
(func (param i32) (param i32) (result i32) (call_indirect 1 (get_local 1) (get_local 0)))
(func (param i32) (call_indirect 2 (i32.const 0) (get_local 0)))
(export "v2i" 6)
(export "i2i" 7)
(export "i2v" 8)
)`);
)`).exports;
const signatureMismatch = /indirect call signature mismatch/;
@ -405,7 +421,7 @@ assertErrorMessage(() => i2v(5), Error, signatureMismatch);
(export "" $bar)
)`,
{"":{f:() => { stack = new Error().stack }}}
)(), undefined);
).exports[""](), undefined);
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"));
assertEq(wasmEvalText('(module (func (select (i32.const 0) (f32.const 0) (i32.const 0))) (export "" 0))')(), undefined);
assertEq(wasmEvalText('(module (func (select (block) (i32.const 0) (i32.const 0))) (export "" 0))')(), undefined);
assertEq(wasmEvalText('(module (func (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))')(), 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);
assertEq(wasmEvalText('(module (func) (func (select (call 0) (call 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/);
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))').exports[""](), undefined);
assertEq(wasmEvalText('(module (func (i32.add (i32.const 0) (select (return) (i32.const 0) (i32.const 0)))) (export "" 0))').exports[""](), 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"));
wasmFailValidateText('(module (func) (func (select (call 0) (call 0) (i32.const 0))) (export "" 0))', TypeError, /popping value from empty stack/);
(function testSideEffects() {
@ -460,9 +476,9 @@ var f = wasmEvalText(`
(get_local 0)
)
)
(export "" 0)
(export "" 2)
)
`, imports);
`, imports).exports[""];
assertEq(f(-1), numT);
assertEq(numT, 1);
@ -507,7 +523,7 @@ function testSelect(type, trueVal, falseVal) {
)
(export "" 0)
)
`, imports);
`, imports).exports[""];
assertEq(alwaysTrue(0), trueJS);
assertEq(alwaysTrue(1), trueJS);
@ -525,7 +541,7 @@ function testSelect(type, trueVal, falseVal) {
)
(export "" 0)
)
`, imports);
`, imports).exports[""];
assertEq(alwaysFalse(0), falseJS);
assertEq(alwaysFalse(1), falseJS);
@ -543,7 +559,7 @@ function testSelect(type, trueVal, falseVal) {
)
(export "" 0)
)
`, imports);
`, imports).exports[""];
assertEq(f(0), falseJS);
assertEq(f(1), trueJS);
@ -574,7 +590,7 @@ testSelect('f64', 'nan', Math.pow(2, -31));
)
)
(export "" 0)
)`, imports);
)`, imports).exports[""];
assertEqI64(f(0), { low: 0xdeadc0de, high: 0x12345678});
assertEqI64(f(1), { low: 0x8badf00d, high: 0xc0010ff0});

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

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

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

@ -1,6 +1,6 @@
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)
(func $test (result i32)
(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 ver3 = (Wasm.experimentalVersion >>> 24) & 0xff;
// Section names
const sigId = "type";
const importId = "import";
const functionSignaturesId = "function";
const functionTableId = "table";
const exportTableId = "export";
const functionBodiesId = "code";
const dataSegmentsId = "data";
const nameId = "name";
// Section opcodes
const userDefinedId = 0;
const typeId = 1;
const importId = 2;
const functionId = 3;
const tableId = 4;
const memoryId = 5;
const globalId = 6;
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 versionError = /failed to match binary version/;
const unknownSectionError = /failed to skip unknown section at end/;
const sectionError = /failed to start section/;
const unknownSection = /expected user-defined 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 I32Code = 1;
@ -34,11 +48,27 @@ const I64Code = 2;
const F32Code = 3;
const F64Code = 4;
const AnyFuncCode = 0x20;
const FunctionConstructorCode = 0x40;
const Unreachable = 0x00;
const Block = 0x01;
const End = 0x0f;
const CallImport = 0x18;
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) {
for (let b of array)
@ -60,18 +90,32 @@ function varU32(u32) {
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 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([42])), TypeError, magicError);
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2])), 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, 1])), TypeError, versionError);
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0])), TypeError, versionError);
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0, ver1, ver2])), TypeError, versionError);
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3])), TypeError, versionError(0x6d736100));
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, 1])), TypeError, versionError(0x6d736100));
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0])), TypeError, versionError(0x6d736100));
assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0, ver1, ver2])), TypeError, versionError(0x6d736100));
function moduleHeaderThen(...rest) {
return [magic0, magic1, magic2, magic3, ver0, ver1, ver2, ver3, ...rest];
@ -80,19 +124,34 @@ function moduleHeaderThen(...rest) {
var o = wasmEval(toU8(moduleHeaderThen()));
assertEq(Object.getOwnPropertyNames(o).length, 0);
wasmEval(toU8(moduleHeaderThen(0, 0))); // unknown section containing 0-length string
wasmEval(toU8(moduleHeaderThen(1, 0, 0))); // unknown section containing 1-length string ("\0")
wasmEval(toU8(moduleHeaderThen(0, 0, 0, 0)));
wasmEval(toU8(moduleHeaderThen(0, 0, 1, 0, 0)));
wasmEval(toU8(moduleHeaderThen(1, 0, 0, 1, 0, 0)));
wasmEval(toU8(moduleHeaderThen(1, 0, 0, 0, 0)));
// unfinished known sections
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(typeId))), TypeError, sectionError("type"));
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(importId))), TypeError, sectionError("import"));
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(functionId))), TypeError, sectionError("function"));
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(tableId))), TypeError, sectionError("table"));
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);
assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 1))), TypeError, unknownSectionError);
// unknown sections are unconditionally rejected
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) {
return (name + '\0').split('').map(c => c.charCodeAt(0));
}
// user sections have special rules
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) {
var nameBytes = name.split('').map(c => {
@ -112,7 +171,7 @@ function encodedString(name, len) {
function moduleWithSections(sectionArray) {
var bytes = moduleHeaderThen();
for (let section of sectionArray) {
bytes.push(...string(section.name));
bytes.push(section.name);
bytes.push(...varU32(section.body.length));
bytes.push(...section.body);
}
@ -131,7 +190,7 @@ function sigSection(sigs) {
if (sig.ret != VoidCode)
body.push(...varU32(sig.ret));
}
return { name: sigId, body };
return { name: typeId, body };
}
function declSection(decls) {
@ -139,7 +198,7 @@ function declSection(decls) {
body.push(...varU32(decls.length));
for (let decl of decls)
body.push(...varU32(decl));
return { name: functionSignaturesId, body };
return { name: functionId, body };
}
function funcBody(func) {
@ -147,22 +206,24 @@ function funcBody(func) {
for (let local of func.locals)
body.push(...varU32(local));
body = body.concat(...func.body);
body.push(End);
body.splice(0, 0, ...varU32(body.length));
return body;
}
function bodySection(bodies) {
var body = varU32(bodies.length).concat(...bodies);
return { name: functionBodiesId, body };
return { name: codeId, body };
}
function importSection(imports) {
var body = [];
body.push(...varU32(imports.length));
for (let imp of imports) {
body.push(...varU32(imp.sigIndex));
body.push(...string(imp.module));
body.push(...string(imp.func));
body.push(...varU32(FunctionCode));
body.push(...varU32(imp.sigIndex));
}
return { name: importId, body };
}
@ -171,22 +232,50 @@ function exportSection(exports) {
var body = [];
body.push(...varU32(exports.length));
for (let exp of exports) {
body.push(...varU32(exp.funcIndex));
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 = [];
body.push(...varU32(elems.length));
for (let i of elems)
body.push(...varU32(i));
return { name: functionTableId, body };
body.push(...varU32(1)); // number of tables
body.push(...varU32(AnyFuncCode));
body.push(...varU32(DefaultFlag)); // for now, no maximum
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) {
var body = [];
body.push(...string(nameName));
body.push(...varU32(elems.length));
for (let fn of elems) {
body.push(...encodedString(fn.name, fn.nameLen));
@ -198,19 +287,23 @@ function nameSection(elems) {
for (let local of fn.locals)
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 i2vSig = {args:[I32Code], ret:VoidCode};
const v2vBody = funcBody({locals:[], body:[]});
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: sigId, body: U32MAX_LEB } ])), TypeError, /too many signatures/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: sigId, 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: U32MAX_LEB } ])), TypeError, /too many signatures/);
assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, 0], } ])), TypeError, /expected function form/);
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: sigId, body: [1, 1, 0]}])), TypeError);
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1]}])), TypeError);
assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1, 1, 0]}])), TypeError);
wasmEval(moduleWithSections([sigSection([])]));
wasmEval(moduleWithSections([sigSection([v2vSig])]));
@ -225,6 +318,8 @@ assertThrowsInstanceOf(() => wasmEval(moduleWithSections([sigSection([v2vSig]),
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0])])), TypeError, /expected function bodies/);
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);
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/);
@ -238,40 +333,91 @@ wasmEval(moduleWithSections([
bodySection([v2vBody])
]), {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([])]));
assertErrorMessage(() => wasmEval(moduleWithSections([tableSection([0])])), TypeError, /table element out of range/);
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0]), bodySection([v2vBody])]));
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,0]), bodySection([v2vBody])]));
assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), tableSection([0,1]), bodySection([v2vBody])])), TypeError, /table element out of range/);
wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0,0,0]), tableSection([0,1,0,2]), bodySection([v2vBody, v2vBody, v2vBody])]));
wasmEval(moduleWithSections([sigSection([v2vSig,i2vSig]), declSection([0,0,1]), tableSection([0,1,2]), bodySection([v2vBody, v2vBody, v2vBody])]));
wasmEval(moduleWithSections([tableSection(0)]));
wasmEval(moduleWithSections([elemSection([])]));
wasmEval(moduleWithSections([tableSection(0), elemSection([])]));
wasmEval(moduleWithSections([tableSection(1), elemSection([{offset:1, elems:[]}])]));
assertErrorMessage(() => wasmEval(moduleWithSections([tableSection(1), elemSection([{offset:0, elems:[0]}])])), TypeError, /table element out of range/);
assertErrorMessage(() => wasmEval(moduleWithSections([tableSection(0), elemSection([{offset:0, elems:[0]}])])), TypeError, /element segment does not fit/);
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.
var manyBlocks = [];
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})])]));
// Ignore errors in name section.
var tooBigNameSection = {
name: nameId,
body: [...varU32(Math.pow(2, 31))] // declare 2**31 functions.
name: userDefinedId,
body: [...string(nameName), ...varU32(Math.pow(2, 31))] // declare 2**31 functions.
};
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.
function runStackTraceTest(namesContent, expectedName) {
var sections = [
sigSection([v2vSig]),
importSection([{sigIndex:0, module:"env", func:"callback"}]),
declSection([0]),
exportSection([{funcIndex:0, name: "run"}]),
bodySection([funcBody({locals: [], body: [CallImport, varU32(0), varU32(0)]})])
exportSection([{funcIndex:1, name: "run"}]),
bodySection([funcBody({locals: [], body: [Call, varU32(0)]})]),
userDefinedSection("whoa"),
userDefinedSection("wee", 42),
];
if (namesContent)
sections.push(nameSection(namesContent));
sections.push(userDefinedSection("yay", 13));
var result = "";
var callback = () => {
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(';;start\n(module (func))');
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");
// multi-line comments
@ -21,7 +21,7 @@ var o = wasmEvalText('(module (func))\n(;;)');
var o = wasmEvalText('(;start;)(module (func))');
var o = wasmEvalText('(;start;)\n(module (func))');
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");
// nested comments

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

@ -18,4 +18,4 @@ var module = `(module
(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) {
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
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) {
// 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);

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

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

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

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

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

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

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

@ -1,29 +1,29 @@
// |jit-test| test-also-wasm-baseline
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))')(), 1);
assertEq(wasmEvalText('(module (func (result f64) (f64.const -2)) (export "" 0))')(), -2);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 2)) (export "" 0))')(), 2);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 4294967296)) (export "" 0))')(), 4294967296);
assertEq(wasmEvalText('(module (func (result f32) (f32.const 1.5)) (export "" 0))')(), 1.5);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 2.5)) (export "" 0))')(), 2.5);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 10e2)) (export "" 0))')(), 10e2);
assertEq(wasmEvalText('(module (func (result f32) (f32.const 10e2)) (export "" 0))')(), 10e2);
assertEq(wasmEvalText('(module (func (result f64) (f64.const -0x8000000000000000)) (export "" 0))')(), -0x8000000000000000);
assertEq(wasmEvalText('(module (func (result f64) (f64.const -9223372036854775808)) (export "" 0))')(), -9223372036854775808);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 1797693134862315708145274e284)) (export "" 0))')(), 1797693134862315708145274e284);
assertEq(wasmEvalText('(module (func (result f32) (f32.const -1)) (export "" 0))').exports[""](), -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))').exports[""](), -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))').exports[""](), 4294967296);
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))').exports[""](), 2.5);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 10e2)) (export "" 0))').exports[""](), 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))').exports[""](), -0x8000000000000000);
assertEq(wasmEvalText('(module (func (result f64) (f64.const -9223372036854775808)) (export "" 0))').exports[""](), -9223372036854775808);
assertEq(wasmEvalText('(module (func (result f64) (f64.const 1797693134862315708145274e284)) (export "" 0))').exports[""](), 1797693134862315708145274e284);
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) {
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) {
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);
@ -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 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 (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 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"));
// 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.min (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))')(), -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.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.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) (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))').exports[""](), -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))').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))').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))').exports[""](), -0x44480000);

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

@ -4,22 +4,22 @@ load(libdir + "wasm.js");
const { Instance, Module } = WebAssembly;
// Locally-defined globals
assertErrorMessage(() => evalText(`(module (global))`), SyntaxError, /parsing/);
assertErrorMessage(() => evalText(`(module (global i32))`), SyntaxError, /parsing/);
assertErrorMessage(() => evalText(`(module (global i32 immutable))`), SyntaxError, /parsing/);
assertErrorMessage(() => wasmEvalText(`(module (global))`), SyntaxError, /parsing/);
assertErrorMessage(() => wasmEvalText(`(module (global i32))`), SyntaxError, /parsing/);
assertErrorMessage(() => wasmEvalText(`(module (global i32 immutable))`), SyntaxError, /parsing/);
// Initializer expressions.
assertErrorMessage(() => evalText(`(module (global i32 (f32.const 13.37)))`), TypeError, /type mismatch/);
assertErrorMessage(() => evalText(`(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 (f32.const 13.37)))`), TypeError, /type mismatch/);
assertErrorMessage(() => wasmEvalText(`(module (global f64 (f32.const 13.37)))`), TypeError, /type mismatch/);
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(() => evalText(`(module (global i32 (get_global 1)) (global i32 immutable (i32.const 1)))`), TypeError, /out of range/);
assertErrorMessage(() => wasmEvalText(`(module (global i32 (get_global 0)))`), 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.
function testInner(type, initialValue, nextValue, coercion, assertFunc = assertEq)
{
var module = evalText(`(module
var module = wasmEvalText(`(module
(global ${type} (${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);
// Semantic errors.
assertErrorMessage(() => evalText(`(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 (i32.const 1337)) (func (set_global 1 (i32.const 0))))`), TypeError, /out of range/);
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
// 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 10))
(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.
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))
(table (resizable 4))
(elem (get_global 0) $f)
@ -110,11 +110,11 @@ module = evalText(`(module
assertEq(module.f, module.tbl.get(1));
// Import/export rules.
assertErrorMessage(() => evalText(`(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 (import "globals" "x" (global i32)))`), TypeError, /can't import.* 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.
module = evalText(`(module
module = wasmEvalText(`(module
(import $g "globals" "x" (global i32 immutable))
(func $get (result i32) (get_global $g))
(export "getter" $get)
@ -125,7 +125,7 @@ assertEq(module.getter(), 42);
assertEq(module.value, 42);
// Imported globals and locally defined globals use the same index space.
module = evalText(`(module
module = wasmEvalText(`(module
(import "globals" "x" (global i32 immutable))
(global i32 immutable (i32.const 1337))
(export "imported" global 0)
@ -136,14 +136,14 @@ assertEq(module.imported, 42);
assertEq(module.defined, 1337);
// 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(() => evalText(`(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 f32 immutable (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(() => 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) {
var module = evalText(`(module
var module = wasmEvalText(`(module
(import "globals" "a" (global ${type} immutable))
(global ${type} (get_global 0))
@ -183,14 +183,14 @@ testInitExpr('f64', 13.37, 0.1989, x => +x);
// Int64.
{
assertErrorMessage(() => evalText(`(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 (import "globals" "x" (global i64 immutable)))`), TypeError, /can't import.* 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);
testInner('i64', '0x531642753864975F', '0x123456789abcdef0', createI64, assertEqI64);
testInitExpr('i64', '0x531642753864975F', '0x123456789abcdef0', createI64, assertEqI64);
module = evalText(`(module
module = wasmEvalText(`(module
(import "globals" "x" (global i64 immutable))
(global i64 immutable (i64.const 0xFAFADADABABA))
(export "imported" global 0)

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

@ -4,11 +4,11 @@ load(libdir + "wasm.js");
function linearModule(min, max, ops) {
var opsText = ops.map(function (op) {
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.const 0))`
} 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.const 0))`
} else if (op[0] == "L") {
@ -31,15 +31,15 @@ function linearModule(min, max, ops) {
text =
`(module
(memory ${min} ${max}` +
(min != 0 ? `(segment 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")`
(memory ${min} ${max})
` + (min != 0 ? `(data (i32.const 0) "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(data (i32.const 16) "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")`
: "") +
`)
`
(func (result i32)
` + opsText + `
(drop ` + opsText + `)
(current_memory)
) (export "" 0))`
) (export "" 0))`;
return wasmEvalText(text);
}
@ -49,4 +49,4 @@ function assertOOB(lambda) {
}
// 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
load(libdir + 'wasm.js');
load(libdir + 'asserts.js');
const Module = WebAssembly.Module;
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/);
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, {foo:null}), TypeError, /import object field is not an Object/);
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/);
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, {x:null}), TypeError, /import object field is not an Object/);
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);
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, {foo:null}), TypeError, /import object field is not an Object/);
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/);
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, {baz:null}), TypeError, /import object field is not an Object/);
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/);
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/);
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: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/);
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: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: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: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(textToBinary('(module (import "a" "b" (memory 2 1)))')), TypeError, /maximum length less than initial length/);
assertErrorMessage(() => new Module(textToBinary('(module (table (resizable 2 1)))')), TypeError, /maximum length less than initial length/);
assertErrorMessage(() => new Module(textToBinary('(module (import "a" "b" (table 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(wasmTextToBinary('(module (import "a" "b" (memory 2 1)))')), TypeError, /maximum length 1 is less than initial length 2/);
assertErrorMessage(() => new Module(wasmTextToBinary('(module (table (resizable 2 1)))')), TypeError, /maximum length 1 is less than initial length 2/);
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
var e = evalText('(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 f2vm = new Module(textToBinary('(module (import "a" "b" (param f32)))'));
var e = wasmEvalText('(module (func $i2v (param i32)) (export "i2v" $i2v) (func $f2v (param f32)) (export "f2v" $f2v))').exports;
var i2vm = new Module(wasmTextToBinary('(module (import "a" "b" (param i32)))'));
var f2vm = new Module(wasmTextToBinary('(module (import "a" "b" (param f32)))'));
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(f2vm, {a:{b:e.i2v}}), TypeError, /imported function signature mismatch/);
@ -152,34 +151,34 @@ assertEq(arr.join(), "baz,quux,foo,bar");
// Export key order:
var code = textToBinary('(module)');
var code = wasmTextToBinary('(module)');
var e = new Instance(new Module(code)).exports;
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;
assertEq(Object.keys(e).join(), "foo");
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;
assertEq(Object.keys(e).join(), "foo,bar");
assertEq(e.foo(), undefined);
assertEq(e.bar(), undefined);
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;
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;
assertEq(Object.keys(e).join(), "foo,bar");
assertEq(e.foo, e.bar);
assertEq(e.foo instanceof Memory, true);
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;
assertEq(Object.keys(e).join(), "foo,bar");
assertEq(e.foo(), undefined);
@ -187,25 +186,25 @@ assertEq(e.bar instanceof Memory, true);
assertEq(e.bar instanceof Memory, true);
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;
assertEq(Object.keys(e).join(), "bar,foo");
assertEq(e.foo(), undefined);
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;
assertEq(Object.keys(e).length, 1);
assertEq(String(Object.keys(e)), "");
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;
assertEq(Object.keys(e).join(), "tbl");
assertEq(e.tbl instanceof Table, true);
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;
assertEq(Object.keys(e).join(), "t1,t2");
assertEq(e.t1 instanceof Table, true);
@ -213,7 +212,7 @@ assertEq(e.t2 instanceof Table, true);
assertEq(e.t1, e.t2);
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;
assertEq(Object.keys(e).join(), "t,m,f");
assertEq(e.f(), undefined);
@ -221,7 +220,7 @@ assertEq(e.t instanceof Table, true);
assertEq(e.m instanceof Memory, true);
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;
assertEq(Object.keys(e).join(), "m,f,t");
assertEq(e.f(), undefined);
@ -229,7 +228,7 @@ assertEq(e.t instanceof Table, true);
assertEq(e.m instanceof Memory, true);
+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;
assertEq(Object.keys(e).length, 1);
assertEq(String(Object.keys(e)), "");
@ -238,7 +237,7 @@ assertEq(e[""] instanceof Table, true);
// Table export function identity
var code = textToBinary(`(module
var code = wasmTextToBinary(`(module
(func $f (result i32) (i32.const 1))
(func $g (result i32) (i32.const 2))
(func $h (result i32) (i32.const 3))
@ -275,19 +274,19 @@ assertEq(e.tbl1.get(0), e.tbl1.get(3));
// 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 e = new Instance(new Module(code), {a:{b:mem}}).exports;
assertEq(mem, e.foo);
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 e = new Instance(new Module(code), {a:{b:tbl}}).exports;
assertEq(tbl, e.foo);
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 e1 = new Instance(new Module(code), {a:{b:tbl}}).exports;
assertEq(e1.foo, tbl.get(0));
@ -299,8 +298,8 @@ assertEq(e1.foo, tbl.get(1));
assertEq(tbl.get(0) === e1.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 foo = new Instance(new Module(textToBinary('(module (func (result i32) (i32.const 42)) (export "foo" 0))'))).exports.foo;
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(wasmTextToBinary('(module (func (result i32) (i32.const 42)) (export "foo" 0))'))).exports.foo;
var e1 = new Instance(new Module(code), {a:{b:foo}}).exports;
assertEq(foo, e1.foo);
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
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 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;
assertEq(e2.f(), 52);
// Non-existent export errors
assertErrorMessage(() => new Module(textToBinary('(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(textToBinary('(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" 0))')), TypeError, /exported function index out of bounds/);
assertErrorMessage(() => new Module(wasmTextToBinary('(module (export "a" global 0))')), TypeError, /exported global index out of bounds/);
assertErrorMessage(() => new Module(wasmTextToBinary('(module (export "a" memory))')), TypeError, /exported memory index out of bounds/);
assertErrorMessage(() => new Module(wasmTextToBinary('(module (export "a" table))')), TypeError, /exported table index out of bounds/);
// 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(textToBinary('(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(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" (memory 1 1)) (memory 1 1))')), 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(wasmTextToBinary('(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)) (import "x" "y" (table 2 2)))')), TypeError, /already have default table/);
// Data segments on imports
var m = new Module(textToBinary(`
var m = new Module(wasmTextToBinary(`
(module
(import "a" "b" (memory 1 1))
(data 0 "\\0a\\0b")
@ -365,7 +364,7 @@ assertEq(i8[102], 0x0);
// Data segments with imported offsets
var m = new Module(textToBinary(`
var m = new Module(wasmTextToBinary(`
(module
(import "glob" "a" (global i32 immutable))
(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
// initial length.
var m = new Module(textToBinary(`
var m = new Module(wasmTextToBinary(`
(module
(import "a" "mem" (memory 1))
(import "a" "tbl" (table 1))
@ -419,7 +418,7 @@ assertEq(tbl.get(1), i.exports.g);
// Elem segments on imports
var m = new Module(textToBinary(`
var m = new Module(wasmTextToBinary(`
(module
(import "a" "b" (table 10))
(elem (i32.const 0) $one $two)
@ -441,17 +440,17 @@ for (var i = 5; i < 10; i++)
// 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 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 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(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);
var i1 = new Instance(new Module(textToBinary(`(module
var i1 = new Instance(new Module(wasmTextToBinary(`(module
(memory 1 1)
(data (i32.const 0) "\\42")
(func $f (result i32) (i32.load (i32.const 0)))
(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))
(memory 1 1)
(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(1), 0x13);
var m = new Module(textToBinary(`(module
var m = new Module(wasmTextToBinary(`(module
(import $val "a" "val" (global i32 immutable))
(import $next "a" "next" (result i32))
(memory 1)

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

@ -3,13 +3,12 @@
// adding spurious edges to the GC graph.
load(libdir + 'wasm.js');
load(libdir + 'asserts.js');
const Module = WebAssembly.Module;
const Instance = WebAssembly.Instance;
const m1 = new Module(textToBinary(`(module (func $f) (export "f" $f))`));
const m2 = new Module(textToBinary(`(module (import "a" "f") (func $f) (export "g" $f))`));
const m1 = new Module(wasmTextToBinary(`(module (func $f) (export "f" $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.
resetFinalizeCount();

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

@ -1,9 +1,9 @@
// |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js");
assertEq(wasmEvalText('(module (func (result i32) (i32.const -1)) (export "" 0))')(), -1);
assertEq(wasmEvalText('(module (func (result i32) (i32.const -2147483648)) (export "" 0))')(), -2147483648);
assertEq(wasmEvalText('(module (func (result i32) (i32.const 4294967295)) (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))').exports[""](), -2147483648);
assertEq(wasmEvalText('(module (func (result i32) (i32.const 4294967295)) (export "" 0))').exports[""](), -1);
function testUnary(type, opcode, op, expect) {
var assertFunc = assertEq;
@ -13,14 +13,14 @@ function testUnary(type, opcode, op, expect) {
}
// 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') {
op = createI64(op);
}
// 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) {
@ -28,23 +28,23 @@ function testBinary64(opcode, lhs, rhs, expect) {
let robj = createI64(rhs);
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.
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.
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) {
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.
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.
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) {
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) {
let lobj = createI64(lhs);
@ -52,39 +52,39 @@ function testComparison64(opcode, lhs, rhs, expect) {
assertEq(wasmEvalText(`(module
(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.
assertEq(wasmEvalText(`(module
(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 0)))
(export "" 0))`)(lobj, robj), expect);
(export "" 0))`).exports[""](lobj, robj), 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);
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) {
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.
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.
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) {
let lobj = createI64(lhs);
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.
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.
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);
@ -143,7 +143,7 @@ testComparison32('ge_s', 40, 40, 1);
testComparison32('ge_u', 40, 40, 1);
// 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(13.37), 1);
@ -278,14 +278,14 @@ assertEq(testTrunc(13.37), 1);
testI64Eqz(40, 0);
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.
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(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);
}

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

@ -1,9 +1,8 @@
load(libdir + 'wasm.js');
load(libdir + 'asserts.js');
const WasmPage = 64 * 1024;
const emptyModule = textToBinary('(module)');
const emptyModule = wasmTextToBinary('(module)');
// 'WebAssembly' data property on global object
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(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(new Uint8Array()), /* TODO: WebAssembly.CompileError */ TypeError, /compile error/);
assertErrorMessage(() => new Module(new ArrayBuffer()), /* 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, /failed to match magic number/);
assertEq(new Module(emptyModule) 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([1], /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 ArrayBuffer()], /compile error/);
assertCompileError([new Uint8Array()], /failed to match magic number/);
assertCompileError([new ArrayBuffer()], /failed to match magic number/);
function assertCompileSuccess(bytes) {
var module = null;
compile(bytes).then(m => module = m);

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

@ -3,7 +3,7 @@ load(libdir + "wasm.js");
var i = wasmEvalText(
`(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)
(i32.add
(i32.load8_u (get_local $base))
@ -16,7 +16,7 @@ var i = wasmEvalText(
(i32.load8_u offset=2 (get_local $base)))
)
(export "off2" $off2)
)`);
)`).exports;
assertEq(i.off1(0), 3);
assertEq(i.off1(1), 5);
assertEq(i.off1(2), 7);

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

@ -4,10 +4,9 @@ load(libdir + "wasm.js");
function loadModule(type, ext, offset, align) {
return wasmEvalText(
`(module
(memory 1
(segment 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")
)
(memory 1)
(data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
(func (param i32) (result ${type})
(${type}.load${ext}
offset=${offset}
@ -15,18 +14,17 @@ function loadModule(type, ext, offset, align) {
(get_local 0)
)
) (export "" 0))`
);
).exports[""];
}
function storeModule(type, ext, offset, align) {
var load_ext = ext === '' ? '' : ext + '_s';
return wasmEvalText(
`(module
(memory 1
(segment 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")
)
(func (param i32) (param ${type}) (result ${type})
(memory 1)
(data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
(func (param i32) (param ${type})
(${type}.store${ext}
offset=${offset}
${align != 0 ? 'align=' + align : ''}
@ -41,18 +39,17 @@ function storeModule(type, ext, offset, align) {
(get_local 0)
)
) (export "load" 1))`
);
).exports;
}
function storeModuleCst(type, ext, offset, align, value) {
var load_ext = ext === '' ? '' : ext + '_s';
return wasmEvalText(
`(module
(memory 1
(segment 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")
)
(func (param i32) (result ${type})
(memory 1)
(data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(data 16 "\\f0\\f1\\f2\\f3\\f4\\f5\\f6\\f7\\f8\\f9\\fa\\fb\\fc\\fd\\fe\\ff")
(func (param i32)
(${type}.store${ext}
offset=${offset}
${align != 0 ? 'align=' + align : ''}
@ -67,7 +64,7 @@ function storeModuleCst(type, ext, offset, align, value) {
(get_local 0)
)
) (export "load" 1))`
);
).exports;
}
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);
if (type === 'i64') {
var i64 = createI64(value);
assertEqI64(module.store(base, i64), i64);
module.store(base, i64);
assertEqI64(module.load(base), i64);
assertEqI64(moduleCst.store(base), i64);
moduleCst.store(base);
assertEqI64(moduleCst.load(base), i64);
} else {
assertEq(module.store(base, value), value);
module.store(base, value);
assertEq(module.load(base), value);
assertEq(moduleCst.store(base), value);
moduleCst.store(base);
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', '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.
const align = 0;
@ -283,10 +280,9 @@ for (var foldOffsets = 0; foldOffsets <= 1; foldOffsets++) {
function testRegisters() {
assertEq(wasmEvalText(
`(module
(memory 1
(segment 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")
)
(memory 1)
(data 0 "\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09\\0a\\0b\\0c\\0d\\0e\\0f")
(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)
(set_local 1 (i32.load8_s offset=4 (get_local 0)))
(set_local 2 (i32.load16_s (get_local 1)))
@ -316,7 +312,7 @@ for (var foldOffsets = 0; foldOffsets <= 1; foldOffsets++) {
)
)
) (export "" 0))`
)(1), 50464523);
).exports[""](1), 50464523);
}
testRegisters();

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

@ -13,7 +13,7 @@ function assertSameBitPattern(from, to, offset) {
f32[0] = NaN;
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);
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] = 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);
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.
setJitCompilerOption('wasm.test-mode', 1);
@ -53,11 +53,11 @@ setJitCompilerOption('wasm.test-mode', 1);
var f32_nan_base = 0x7f800000;
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 });
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 });
// 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_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 });
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 });
// Actual tests.
// An example where a signaling nan gets transformed into a quiet nan:
// 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);
// Globals.
var m = evalText(`(module
var m = wasmEvalText(`(module
(import "globals" "x" (global f32 immutable))
(func (result f32) (get_global 0))
(export "global" global 0)
@ -90,7 +90,7 @@ var m = evalText(`(module
assertEqNaN(m.test(), f32_snan);
assertEqNaN(m.global, f32_snan);
var m = evalText(`(module
var m = wasmEvalText(`(module
(import "globals" "x" (global f64 immutable))
(func (result f64) (get_global 0))
(export "global" global 0)
@ -109,7 +109,7 @@ function getConstant(code) {
return constantCache.get(code);
}
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);
return val;
}
@ -123,10 +123,10 @@ function test(type, opcode, snan_code, rhs_code, qnan_val) {
// - (constant, variable),
// - (variable, constant),
// - (variable, variable)
assertEqNaN(wasmEvalText(`(module (func (result ${type}) (${type}.${opcode} ${snan_code} ${rhs_code})) (export "" 0))`)(), 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} ${snan_code} (get_local 0))) (export "" 0))`)(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 (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))`).exports[""](snan_val), 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))`).exports[""](snan_val, rhs), qnan_val);
}
var f32_zero = '(f32.const 0)';

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

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

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

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

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

@ -7,6 +7,6 @@ if (typeof oomTest !== 'function' || !wasmIsSupported()) {
function foo() {
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);

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -1,34 +1,34 @@
(module
(memory 1 (segment 0 "abcdefghijklmnopqrstuvwxyz"))
(import $print "spectest" "print" (param i32))
(import "spectest" "print" (func $print (param i32)))
(func $good (param $i i32)
(call_import $print (i32.load8_u offset=0 (get_local $i))) ;; 97 'a'
(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'
(memory 1)
(data (i32.const 0) "abcdefghijklmnopqrstuvwxyz")
(call_import $print (i32.load16_u offset=0 (get_local $i))) ;; 25185 'ab'
(call_import $print (i32.load16_u align=1 (get_local $i))) ;; 25185 'ab'
(call_import $print (i32.load16_u offset=1 align=1 (get_local $i))) ;; 25442 'bc'
(call_import $print (i32.load16_u offset=2 (get_local $i))) ;; 25699 'cd'
(call_import $print (i32.load16_u offset=25 align=1 (get_local $i))) ;; 122 'z\0'
(func (export "good") (param $i i32)
(call $print (i32.load8_u offset=0 (get_local $i))) ;; 97 'a'
(call $print (i32.load8_u offset=1 (get_local $i))) ;; 98 'b'
(call $print (i32.load8_u offset=2 (get_local $i))) ;; 99 'c'
(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_import $print (i32.load offset=1 align=1 (get_local $i))) ;; 1701077858 'bcde'
(call_import $print (i32.load offset=2 align=2 (get_local $i))) ;; 1717920867 'cdef'
(call_import $print (i32.load offset=25 align=1 (get_local $i))) ;; 122 'z\0\0\0'
(call $print (i32.load16_u offset=0 (get_local $i))) ;; 25185 'ab'
(call $print (i32.load16_u align=1 (get_local $i))) ;; 25185 'ab'
(call $print (i32.load16_u offset=1 align=1 (get_local $i))) ;; 25442 'bc'
(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)))
(export "bad2" $bad2)
(func (export "bad") (param $i i32) (drop (i32.load offset=4294967295 (get_local $i))))
)
(invoke "good" (i32.const 0))
(invoke "good" (i32.const 65507))
(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 "bad2" (i32.const 1)) "out of bounds memory access")
(assert_trap (invoke "bad" (i32.const 0)) "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" "\0b\00\00\00")
(module "\00asm\0c\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 "\01") "unexpected end")
@ -8,7 +10,7 @@
(assert_invalid (module "asm\00") "magic header not detected")
(assert_invalid (module "\00asm") "unexpected end")
(assert_invalid (module "\00asm\0b") "unexpected end")
(assert_invalid (module "\00asm\0b\00\00") "unexpected end")
(assert_invalid (module "\00asm\0c") "unexpected end")
(assert_invalid (module "\00asm\0c\00\00") "unexpected end")
(assert_invalid (module "\00asm\10\00\00\00") "unknown binary version")

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

@ -1,35 +1,302 @@
;; Test `block` operator
(module
(func $empty
;; Auxiliary definition
(func $dummy)
(func (export "empty")
(block)
(block $l)
)
(func $singular (result i32)
(block (i32.const 7))
(func (export "singular") (result i32)
(block (nop))
(block i32 (i32.const 7))
)
(func $multi (result i32)
(block (i32.const 5) (i32.const 6) (i32.const 7) (i32.const 8))
(func (export "multi") (result i32)
(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)
(block
(set_local 0 (i32.const 1))
(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.mul (get_local 0) (i32.const 7)))
(br 0)
(set_local 0 (i32.mul (get_local 0) (i32.const 100)))
)
(i32.eq (get_local 0) (i32.const -14))
)
(get_local 0)
)
(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 "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
(func $br (block (br 0)))
(export "br" $br)
(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)
(func (export "br") (block (br 0)))
(func (export "br_if") (block (br_if 0 (i32.const 1))))
(func (export "br_table") (block (br_table 0 (i32.const 0))))
)
(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-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-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
(func $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 $i64.extend_u_i32 (param $x i32) (result i64) (i64.extend_u/i32 (get_local $x)))
(export "i64.extend_u_i32" $i64.extend_u_i32)
(func $i32.wrap_i64 (param $x i64) (result i32) (i32.wrap/i64 (get_local $x)))
(export "i32.wrap_i64" $i32.wrap_i64)
(func $i32.trunc_s_f32 (param $x f32) (result i32) (i32.trunc_s/f32 (get_local $x)))
(export "i32.trunc_s_f32" $i32.trunc_s_f32)
(func $i32.trunc_u_f32 (param $x f32) (result i32) (i32.trunc_u/f32 (get_local $x)))
(export "i32.trunc_u_f32" $i32.trunc_u_f32)
(func $i32.trunc_s_f64 (param $x f64) (result i32) (i32.trunc_s/f64 (get_local $x)))
(export "i32.trunc_s_f64" $i32.trunc_s_f64)
(func $i32.trunc_u_f64 (param $x f64) (result i32) (i32.trunc_u/f64 (get_local $x)))
(export "i32.trunc_u_f64" $i32.trunc_u_f64)
(func $i64.trunc_s_f32 (param $x f32) (result i64) (i64.trunc_s/f32 (get_local $x)))
(export "i64.trunc_s_f32" $i64.trunc_s_f32)
(func $i64.trunc_u_f32 (param $x f32) (result i64) (i64.trunc_u/f32 (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)
(func (export "i64.extend_s_i32") (param $x i32) (result i64) (i64.extend_s/i32 (get_local $x)))
(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 (export "i32.trunc_s_f32") (param $x f32) (result i32) (i32.trunc_s/f32 (get_local $x)))
(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 (export "i32.trunc_u_f64") (param $x f64) (result i32) (i32.trunc_u/f64 (get_local $x)))
(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 (export "i64.trunc_s_f64") (param $x f64) (result i64) (i64.trunc_s/f64 (get_local $x)))
(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 (export "f32.convert_s_i64") (param $x i64) (result f32) (f32.convert_s/i64 (get_local $x)))
(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 (export "f32.convert_u_i32") (param $x i32) (result f32) (f32.convert_u/i32 (get_local $x)))
(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 (export "f64.convert_u_i64") (param $x i64) (result f64) (f64.convert_u/i64 (get_local $x)))
(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 (export "f32.reinterpret_i32") (param $x i32) (result f32) (f32.reinterpret/i32 (get_local $x)))
(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 (export "i64.reinterpret_f64") (param $x f64) (result i64) (i64.reinterpret/f64 (get_local $x)))
)
(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 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 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.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 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 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.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.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.a12e71e358685p-113)) (f32.const 0x1.a12e72p-113))
(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 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 -0x0.0000000000001p-1022)) (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.0p-150)) (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 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))
(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))
(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))
(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)))
(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)))
(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)))
(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)))
(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))
(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)))
(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)))
(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))
(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))
(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.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.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))
(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.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.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))

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

@ -1,26 +1,172 @@
(module (func (i32.const 1)) (export "a" 0))
(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")
;; Functions
(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)
(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))
(module (memory 0 0) (export "a" memory) (export "b" memory))
(assert_invalid (module (export "a" memory)) "no memory to export")
;; Globals
(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
// TODO: module names
// TODO: new anyfunc table syntax
quit();
var importedArgs = ['exports.wast']; load(scriptdir + '../spec.js');

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

@ -2,35 +2,20 @@
;; values (except comparison operators, which are tested in f32_cmp.wast).
(module
(func $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 $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 $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 $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 $floor (param $x f32) (result f32) (f32.floor (get_local $x)))
(func $trunc (param $x f32) (result f32) (f32.trunc (get_local $x)))
(func $nearest (param $x f32) (result f32) (f32.nearest (get_local $x)))
(func $abs (param $x f32) (result f32) (f32.abs (get_local $x)))
(func $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)))
(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)
(func (export "add") (param $x f32) (param $y f32) (result f32) (f32.add (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 (export "mul") (param $x f32) (param $y f32) (result f32) (f32.mul (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 (export "sqrt") (param $x f32) (result f32) (f32.sqrt (get_local $x)))
(func (export "min") (param $x f32) (param $y f32) (result f32) (f32.min (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 (export "ceil") (param $x f32) (result f32) (f32.ceil (get_local $x)))
(func (export "floor") (param $x f32) (result f32) (f32.floor (get_local $x)))
(func (export "trunc") (param $x f32) (result f32) (f32.trunc (get_local $x)))
(func (export "nearest") (param $x f32) (result f32) (f32.nearest (get_local $x)))
(func (export "abs") (param $x f32) (result f32) (f32.abs (get_local $x)))
(func (export "neg") (param $x f32) (result f32) (f32.neg (get_local $x)))
(func (export "copysign") (param $x f32) (param $y f32) (result f32) (f32.copysign (get_local $x) (get_local $y)))
)
(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 -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 -nan)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -0x0p+0) (f32.const nan)) (f32.const nan))
(assert_return (invoke "min" (f32.const 0x0p+0) (f32.const -nan)) (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_nan (invoke "min" (f32.const -0x0p+0) (f32.const nan)))
(assert_return_nan (invoke "min" (f32.const 0x0p+0) (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 -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 -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 -nan)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -0x1p-149) (f32.const nan)) (f32.const nan))
(assert_return (invoke "min" (f32.const 0x1p-149) (f32.const -nan)) (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_nan (invoke "min" (f32.const -0x1p-149) (f32.const nan)))
(assert_return_nan (invoke "min" (f32.const 0x1p-149) (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 -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 -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 -nan)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -0x1p-126) (f32.const nan)) (f32.const nan))
(assert_return (invoke "min" (f32.const 0x1p-126) (f32.const -nan)) (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_nan (invoke "min" (f32.const -0x1p-126) (f32.const nan)))
(assert_return_nan (invoke "min" (f32.const 0x1p-126) (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 -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 -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 -nan)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -0x1p-1) (f32.const nan)) (f32.const nan))
(assert_return (invoke "min" (f32.const 0x1p-1) (f32.const -nan)) (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_nan (invoke "min" (f32.const -0x1p-1) (f32.const nan)))
(assert_return_nan (invoke "min" (f32.const 0x1p-1) (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 -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 -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 -nan)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -0x1p+0) (f32.const nan)) (f32.const nan))
(assert_return (invoke "min" (f32.const 0x1p+0) (f32.const -nan)) (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_nan (invoke "min" (f32.const -0x1p+0) (f32.const nan)))
(assert_return_nan (invoke "min" (f32.const 0x1p+0) (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 -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 -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 -nan)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const nan)) (f32.const nan))
(assert_return (invoke "min" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (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_nan (invoke "min" (f32.const -0x1.921fb6p+2) (f32.const nan)))
(assert_return_nan (invoke "min" (f32.const 0x1.921fb6p+2) (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 -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 -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 -nan)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -0x1.fffffep+127) (f32.const nan)) (f32.const nan))
(assert_return (invoke "min" (f32.const 0x1.fffffep+127) (f32.const -nan)) (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_nan (invoke "min" (f32.const -0x1.fffffep+127) (f32.const nan)))
(assert_return_nan (invoke "min" (f32.const 0x1.fffffep+127) (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 -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 -nan)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -infinity) (f32.const nan)) (f32.const nan))
(assert_return (invoke "min" (f32.const infinity) (f32.const -nan)) (f32.const -nan))
(assert_return (invoke "min" (f32.const infinity) (f32.const nan)) (f32.const nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x0p+0)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x0p+0)) (f32.const -nan))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x0p+0)) (f32.const nan))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x0p+0)) (f32.const nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1p-149)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1p-149)) (f32.const -nan))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1p-149)) (f32.const nan))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1p-149)) (f32.const nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1p-126)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1p-126)) (f32.const -nan))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1p-126)) (f32.const nan))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1p-126)) (f32.const nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1p-1)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1p-1)) (f32.const -nan))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1p-1)) (f32.const nan))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1p-1)) (f32.const nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1p+0)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1p+0)) (f32.const -nan))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1p+0)) (f32.const nan))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1p+0)) (f32.const nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (f32.const -nan))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1.921fb6p+2)) (f32.const nan))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1.921fb6p+2)) (f32.const nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const -0x1.fffffep+127)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const 0x1.fffffep+127)) (f32.const -nan))
(assert_return (invoke "min" (f32.const nan) (f32.const -0x1.fffffep+127)) (f32.const nan))
(assert_return (invoke "min" (f32.const nan) (f32.const 0x1.fffffep+127)) (f32.const nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const -infinity)) (f32.const -nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const infinity)) (f32.const -nan))
(assert_return (invoke "min" (f32.const nan) (f32.const -infinity)) (f32.const nan))
(assert_return (invoke "min" (f32.const nan) (f32.const infinity)) (f32.const nan))
(assert_return (invoke "min" (f32.const -nan) (f32.const -nan)) (f32.const -nan))
(assert_return_nan (invoke "min" (f32.const -infinity) (f32.const -nan)))
(assert_return_nan (invoke "min" (f32.const -infinity) (f32.const nan)))
(assert_return_nan (invoke "min" (f32.const infinity) (f32.const -nan)))
(assert_return_nan (invoke "min" (f32.const infinity) (f32.const nan)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x0p+0)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x0p+0)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x0p+0)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x0p+0)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1p-149)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1p-149)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1p-149)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1p-149)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1p-126)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1p-126)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1p-126)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1p-126)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1p-1)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1p-1)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1p-1)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1p-1)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1p+0)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1p+0)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1p+0)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1p+0)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1.921fb6p+2)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1.921fb6p+2)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1.921fb6p+2)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1.921fb6p+2)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const -0x1.fffffep+127)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const 0x1.fffffep+127)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const -0x1.fffffep+127)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const 0x1.fffffep+127)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const -infinity)))
(assert_return_nan (invoke "min" (f32.const -nan) (f32.const infinity)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const -infinity)))
(assert_return_nan (invoke "min" (f32.const nan) (f32.const infinity)))
(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))
@ -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 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 -nan)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -0x0p+0) (f32.const nan)) (f32.const nan))
(assert_return (invoke "max" (f32.const 0x0p+0) (f32.const -nan)) (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_nan (invoke "max" (f32.const -0x0p+0) (f32.const nan)))
(assert_return_nan (invoke "max" (f32.const 0x0p+0) (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 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 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 -nan)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -0x1p-149) (f32.const nan)) (f32.const nan))
(assert_return (invoke "max" (f32.const 0x1p-149) (f32.const -nan)) (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_nan (invoke "max" (f32.const -0x1p-149) (f32.const nan)))
(assert_return_nan (invoke "max" (f32.const 0x1p-149) (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 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 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 -nan)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -0x1p-126) (f32.const nan)) (f32.const nan))
(assert_return (invoke "max" (f32.const 0x1p-126) (f32.const -nan)) (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_nan (invoke "max" (f32.const -0x1p-126) (f32.const nan)))
(assert_return_nan (invoke "max" (f32.const 0x1p-126) (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 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 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 -nan)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -0x1p-1) (f32.const nan)) (f32.const nan))
(assert_return (invoke "max" (f32.const 0x1p-1) (f32.const -nan)) (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_nan (invoke "max" (f32.const -0x1p-1) (f32.const nan)))
(assert_return_nan (invoke "max" (f32.const 0x1p-1) (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 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 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 -nan)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -0x1p+0) (f32.const nan)) (f32.const nan))
(assert_return (invoke "max" (f32.const 0x1p+0) (f32.const -nan)) (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_nan (invoke "max" (f32.const -0x1p+0) (f32.const nan)))
(assert_return_nan (invoke "max" (f32.const 0x1p+0) (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 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 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 -nan)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const nan)) (f32.const nan))
(assert_return (invoke "max" (f32.const 0x1.921fb6p+2) (f32.const -nan)) (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_nan (invoke "max" (f32.const -0x1.921fb6p+2) (f32.const nan)))
(assert_return_nan (invoke "max" (f32.const 0x1.921fb6p+2) (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 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 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 -nan)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -0x1.fffffep+127) (f32.const nan)) (f32.const nan))
(assert_return (invoke "max" (f32.const 0x1.fffffep+127) (f32.const -nan)) (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_nan (invoke "max" (f32.const -0x1.fffffep+127) (f32.const nan)))
(assert_return_nan (invoke "max" (f32.const 0x1.fffffep+127) (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 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 -nan)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -infinity) (f32.const nan)) (f32.const nan))
(assert_return (invoke "max" (f32.const infinity) (f32.const -nan)) (f32.const -nan))
(assert_return (invoke "max" (f32.const infinity) (f32.const nan)) (f32.const nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x0p+0)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x0p+0)) (f32.const -nan))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x0p+0)) (f32.const nan))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x0p+0)) (f32.const nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1p-149)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1p-149)) (f32.const -nan))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1p-149)) (f32.const nan))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1p-149)) (f32.const nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1p-126)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1p-126)) (f32.const -nan))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1p-126)) (f32.const nan))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1p-126)) (f32.const nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1p-1)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1p-1)) (f32.const -nan))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1p-1)) (f32.const nan))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1p-1)) (f32.const nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1p+0)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1p+0)) (f32.const -nan))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1p+0)) (f32.const nan))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1p+0)) (f32.const nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1.921fb6p+2)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1.921fb6p+2)) (f32.const -nan))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1.921fb6p+2)) (f32.const nan))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1.921fb6p+2)) (f32.const nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const -0x1.fffffep+127)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const 0x1.fffffep+127)) (f32.const -nan))
(assert_return (invoke "max" (f32.const nan) (f32.const -0x1.fffffep+127)) (f32.const nan))
(assert_return (invoke "max" (f32.const nan) (f32.const 0x1.fffffep+127)) (f32.const nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const -infinity)) (f32.const -nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const infinity)) (f32.const -nan))
(assert_return (invoke "max" (f32.const nan) (f32.const -infinity)) (f32.const nan))
(assert_return (invoke "max" (f32.const nan) (f32.const infinity)) (f32.const nan))
(assert_return (invoke "max" (f32.const -nan) (f32.const -nan)) (f32.const -nan))
(assert_return_nan (invoke "max" (f32.const -infinity) (f32.const -nan)))
(assert_return_nan (invoke "max" (f32.const -infinity) (f32.const nan)))
(assert_return_nan (invoke "max" (f32.const infinity) (f32.const -nan)))
(assert_return_nan (invoke "max" (f32.const infinity) (f32.const nan)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x0p+0)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x0p+0)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x0p+0)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x0p+0)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1p-149)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1p-149)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1p-149)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1p-149)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1p-126)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1p-126)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1p-126)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1p-126)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1p-1)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1p-1)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1p-1)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1p-1)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1p+0)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1p+0)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1p+0)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1p+0)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1.921fb6p+2)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1.921fb6p+2)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1.921fb6p+2)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1.921fb6p+2)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const -0x1.fffffep+127)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const 0x1.fffffep+127)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const -0x1.fffffep+127)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const 0x1.fffffep+127)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const -infinity)))
(assert_return_nan (invoke "max" (f32.const -nan) (f32.const infinity)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const -infinity)))
(assert_return_nan (invoke "max" (f32.const nan) (f32.const infinity)))
(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))

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

@ -2,19 +2,12 @@
;; special values.
(module
(func $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 $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 $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)))
(export "eq" $eq)
(export "ne" $ne)
(export "lt" $lt)
(export "le" $le)
(export "gt" $gt)
(export "ge" $ge)
(func (export "eq") (param $x f32) (param $y f32) (result i32) (f32.eq (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 (export "lt") (param $x f32) (param $y f32) (result i32) (f32.lt (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 (export "gt") (param $x f32) (param $y f32) (result i32) (f32.gt (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)))
)
(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).
(module
(func $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 $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 $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 $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 $floor (param $x f64) (result f64) (f64.floor (get_local $x)))
(func $trunc (param $x f64) (result f64) (f64.trunc (get_local $x)))
(func $nearest (param $x f64) (result f64) (f64.nearest (get_local $x)))
(func $abs (param $x f64) (result f64) (f64.abs (get_local $x)))
(func $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)))
(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)
(func (export "add") (param $x f64) (param $y f64) (result f64) (f64.add (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 (export "mul") (param $x f64) (param $y f64) (result f64) (f64.mul (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 (export "sqrt") (param $x f64) (result f64) (f64.sqrt (get_local $x)))
(func (export "min") (param $x f64) (param $y f64) (result f64) (f64.min (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 (export "ceil") (param $x f64) (result f64) (f64.ceil (get_local $x)))
(func (export "floor") (param $x f64) (result f64) (f64.floor (get_local $x)))
(func (export "trunc") (param $x f64) (result f64) (f64.trunc (get_local $x)))
(func (export "nearest") (param $x f64) (result f64) (f64.nearest (get_local $x)))
(func (export "abs") (param $x f64) (result f64) (f64.abs (get_local $x)))
(func (export "neg") (param $x f64) (result f64) (f64.neg (get_local $x)))
(func (export "copysign") (param $x f64) (param $y f64) (result f64) (f64.copysign (get_local $x) (get_local $y)))
)
(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 -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 -nan)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -0x0p+0) (f64.const nan)) (f64.const nan))
(assert_return (invoke "min" (f64.const 0x0p+0) (f64.const -nan)) (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_nan (invoke "min" (f64.const -0x0p+0) (f64.const nan)))
(assert_return_nan (invoke "min" (f64.const 0x0p+0) (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 -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 -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 -nan)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (f64.const nan))
(assert_return (invoke "min" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (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_nan (invoke "min" (f64.const -0x0.0000000000001p-1022) (f64.const nan)))
(assert_return_nan (invoke "min" (f64.const 0x0.0000000000001p-1022) (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 -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 -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 -nan)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -0x1p-1022) (f64.const nan)) (f64.const nan))
(assert_return (invoke "min" (f64.const 0x1p-1022) (f64.const -nan)) (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_nan (invoke "min" (f64.const -0x1p-1022) (f64.const nan)))
(assert_return_nan (invoke "min" (f64.const 0x1p-1022) (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 -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 -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 -nan)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -0x1p-1) (f64.const nan)) (f64.const nan))
(assert_return (invoke "min" (f64.const 0x1p-1) (f64.const -nan)) (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_nan (invoke "min" (f64.const -0x1p-1) (f64.const nan)))
(assert_return_nan (invoke "min" (f64.const 0x1p-1) (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 -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 -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 -nan)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -0x1p+0) (f64.const nan)) (f64.const nan))
(assert_return (invoke "min" (f64.const 0x1p+0) (f64.const -nan)) (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_nan (invoke "min" (f64.const -0x1p+0) (f64.const nan)))
(assert_return_nan (invoke "min" (f64.const 0x1p+0) (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 -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 -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 -nan)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (f64.const nan))
(assert_return (invoke "min" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (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_nan (invoke "min" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)))
(assert_return_nan (invoke "min" (f64.const 0x1.921fb54442d18p+2) (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 -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 -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 -nan)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (f64.const nan))
(assert_return (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (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_nan (invoke "min" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)))
(assert_return_nan (invoke "min" (f64.const 0x1.fffffffffffffp+1023) (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 -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 -nan)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -infinity) (f64.const nan)) (f64.const nan))
(assert_return (invoke "min" (f64.const infinity) (f64.const -nan)) (f64.const -nan))
(assert_return (invoke "min" (f64.const infinity) (f64.const nan)) (f64.const nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x0p+0)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x0p+0)) (f64.const -nan))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x0p+0)) (f64.const nan))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x0p+0)) (f64.const nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (f64.const -nan))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (f64.const nan))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (f64.const nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x1p-1022)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x1p-1022)) (f64.const -nan))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x1p-1022)) (f64.const nan))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x1p-1022)) (f64.const nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x1p-1)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x1p-1)) (f64.const -nan))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x1p-1)) (f64.const nan))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x1p-1)) (f64.const nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x1p+0)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x1p+0)) (f64.const -nan))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x1p+0)) (f64.const nan))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x1p+0)) (f64.const nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (f64.const -nan))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (f64.const nan))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (f64.const nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (f64.const -nan))
(assert_return (invoke "min" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (f64.const nan))
(assert_return (invoke "min" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (f64.const nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const -infinity)) (f64.const -nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const infinity)) (f64.const -nan))
(assert_return (invoke "min" (f64.const nan) (f64.const -infinity)) (f64.const nan))
(assert_return (invoke "min" (f64.const nan) (f64.const infinity)) (f64.const nan))
(assert_return (invoke "min" (f64.const -nan) (f64.const -nan)) (f64.const -nan))
(assert_return_nan (invoke "min" (f64.const -infinity) (f64.const -nan)))
(assert_return_nan (invoke "min" (f64.const -infinity) (f64.const nan)))
(assert_return_nan (invoke "min" (f64.const infinity) (f64.const -nan)))
(assert_return_nan (invoke "min" (f64.const infinity) (f64.const nan)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x0p+0)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x0p+0)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x0p+0)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x0p+0)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x0.0000000000001p-1022)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x0.0000000000001p-1022)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x1p-1022)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x1p-1022)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x1p-1022)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x1p-1022)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x1p-1)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x1p-1)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x1p-1)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x1p-1)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x1p+0)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x1p+0)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x1p+0)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x1p+0)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const -infinity)))
(assert_return_nan (invoke "min" (f64.const -nan) (f64.const infinity)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const -infinity)))
(assert_return_nan (invoke "min" (f64.const nan) (f64.const infinity)))
(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))
@ -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 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 -nan)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -0x0p+0) (f64.const nan)) (f64.const nan))
(assert_return (invoke "max" (f64.const 0x0p+0) (f64.const -nan)) (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_nan (invoke "max" (f64.const -0x0p+0) (f64.const nan)))
(assert_return_nan (invoke "max" (f64.const 0x0p+0) (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 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 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 -nan)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const nan)) (f64.const nan))
(assert_return (invoke "max" (f64.const 0x0.0000000000001p-1022) (f64.const -nan)) (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_nan (invoke "max" (f64.const -0x0.0000000000001p-1022) (f64.const nan)))
(assert_return_nan (invoke "max" (f64.const 0x0.0000000000001p-1022) (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 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 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 -nan)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -0x1p-1022) (f64.const nan)) (f64.const nan))
(assert_return (invoke "max" (f64.const 0x1p-1022) (f64.const -nan)) (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_nan (invoke "max" (f64.const -0x1p-1022) (f64.const nan)))
(assert_return_nan (invoke "max" (f64.const 0x1p-1022) (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 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 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 -nan)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -0x1p-1) (f64.const nan)) (f64.const nan))
(assert_return (invoke "max" (f64.const 0x1p-1) (f64.const -nan)) (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_nan (invoke "max" (f64.const -0x1p-1) (f64.const nan)))
(assert_return_nan (invoke "max" (f64.const 0x1p-1) (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 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 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 -nan)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -0x1p+0) (f64.const nan)) (f64.const nan))
(assert_return (invoke "max" (f64.const 0x1p+0) (f64.const -nan)) (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_nan (invoke "max" (f64.const -0x1p+0) (f64.const nan)))
(assert_return_nan (invoke "max" (f64.const 0x1p+0) (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 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 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 -nan)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)) (f64.const nan))
(assert_return (invoke "max" (f64.const 0x1.921fb54442d18p+2) (f64.const -nan)) (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_nan (invoke "max" (f64.const -0x1.921fb54442d18p+2) (f64.const nan)))
(assert_return_nan (invoke "max" (f64.const 0x1.921fb54442d18p+2) (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 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 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 -nan)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)) (f64.const nan))
(assert_return (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (f64.const -nan)) (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_nan (invoke "max" (f64.const -0x1.fffffffffffffp+1023) (f64.const nan)))
(assert_return_nan (invoke "max" (f64.const 0x1.fffffffffffffp+1023) (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 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 -nan)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -infinity) (f64.const nan)) (f64.const nan))
(assert_return (invoke "max" (f64.const infinity) (f64.const -nan)) (f64.const -nan))
(assert_return (invoke "max" (f64.const infinity) (f64.const nan)) (f64.const nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x0p+0)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x0p+0)) (f64.const -nan))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x0p+0)) (f64.const nan))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x0p+0)) (f64.const nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)) (f64.const -nan))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x0.0000000000001p-1022)) (f64.const nan))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x0.0000000000001p-1022)) (f64.const nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x1p-1022)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x1p-1022)) (f64.const -nan))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x1p-1022)) (f64.const nan))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x1p-1022)) (f64.const nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x1p-1)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x1p-1)) (f64.const -nan))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x1p-1)) (f64.const nan))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x1p-1)) (f64.const nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x1p+0)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x1p+0)) (f64.const -nan))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x1p+0)) (f64.const nan))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x1p+0)) (f64.const nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)) (f64.const -nan))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)) (f64.const nan))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)) (f64.const nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)) (f64.const -nan))
(assert_return (invoke "max" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)) (f64.const nan))
(assert_return (invoke "max" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)) (f64.const nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const -infinity)) (f64.const -nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const infinity)) (f64.const -nan))
(assert_return (invoke "max" (f64.const nan) (f64.const -infinity)) (f64.const nan))
(assert_return (invoke "max" (f64.const nan) (f64.const infinity)) (f64.const nan))
(assert_return (invoke "max" (f64.const -nan) (f64.const -nan)) (f64.const -nan))
(assert_return_nan (invoke "max" (f64.const -infinity) (f64.const -nan)))
(assert_return_nan (invoke "max" (f64.const -infinity) (f64.const nan)))
(assert_return_nan (invoke "max" (f64.const infinity) (f64.const -nan)))
(assert_return_nan (invoke "max" (f64.const infinity) (f64.const nan)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x0p+0)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x0p+0)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x0p+0)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x0p+0)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x0.0000000000001p-1022)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x0.0000000000001p-1022)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x0.0000000000001p-1022)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x0.0000000000001p-1022)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x1p-1022)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x1p-1022)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x1p-1022)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x1p-1022)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x1p-1)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x1p-1)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x1p-1)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x1p-1)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x1p+0)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x1p+0)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x1p+0)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x1p+0)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x1.921fb54442d18p+2)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x1.921fb54442d18p+2)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x1.921fb54442d18p+2)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x1.921fb54442d18p+2)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const -0x1.fffffffffffffp+1023)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const 0x1.fffffffffffffp+1023)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const -0x1.fffffffffffffp+1023)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const 0x1.fffffffffffffp+1023)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const -infinity)))
(assert_return_nan (invoke "max" (f64.const -nan) (f64.const infinity)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const -infinity)))
(assert_return_nan (invoke "max" (f64.const nan) (f64.const infinity)))
(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))

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

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

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

@ -1,28 +1,29 @@
(module
;; Recursive factorial
(func (param i64) (result i64)
(if (i64.eq (get_local 0) (i64.const 0))
(func (export "fac-rec") (param i64) (result i64)
(if i64 (i64.eq (get_local 0) (i64.const 0))
(i64.const 1)
(i64.mul (get_local 0) (call 0 (i64.sub (get_local 0) (i64.const 1))))
)
)
;; Recursive factorial named
(func $fac-rec (param $n i64) (result i64)
(if (i64.eq (get_local $n) (i64.const 0))
(func $fac-rec-named (export "fac-rec-named") (param $n i64) (result i64)
(if i64 (i64.eq (get_local $n) (i64.const 0))
(i64.const 1)
(i64.mul
(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
(func (param i64) (result i64)
(func (export "fac-iter") (param i64) (result i64)
(local i64 i64)
(set_local 1 (get_local 0))
(set_local 2 (i64.const 1))
(block
(loop
(if
(i64.eq (get_local 1) (i64.const 0))
@ -34,16 +35,18 @@
)
(br 0)
)
)
(get_local 2)
)
;; 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 $res i64)
(set_local $i (get_local $n))
(set_local $res (i64.const 1))
(loop $done $loop
(block $done
(loop $loop
(if
(i64.eq (get_local $i) (i64.const 0))
(br $done)
@ -54,11 +57,12 @@
)
(br $loop)
)
)
(get_local $res)
)
;; More-realistically optimized factorial.
(func $fac-opt (param i64) (result i64)
;; Optimized factorial.
(func (export "fac-opt") (param i64) (result i64)
(local i64)
(set_local 1 (i64.const 1))
(block
@ -71,12 +75,6 @@
)
(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))

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

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

@ -2,138 +2,76 @@
(module
;; f32 special values
(func $f32.nan (result i32) (i32.reinterpret/f32 (f32.const nan)))
(func $f32.positive_nan (result i32) (i32.reinterpret/f32 (f32.const +nan)))
(func $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 $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 $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 $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 $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.nan") (result i32) (i32.reinterpret/f32 (f32.const nan)))
(func (export "f32.positive_nan") (result i32) (i32.reinterpret/f32 (f32.const +nan)))
(func (export "f32.negative_nan") (result i32) (i32.reinterpret/f32 (f32.const -nan)))
(func (export "f32.plain_nan") (result i32) (i32.reinterpret/f32 (f32.const nan:0x400000)))
(func (export "f32.informally_known_as_plain_snan") (result i32) (i32.reinterpret/f32 (f32.const nan:0x200000)))
(func (export "f32.all_ones_nan") (result i32) (i32.reinterpret/f32 (f32.const -nan:0x7fffff)))
(func (export "f32.misc_nan") (result i32) (i32.reinterpret/f32 (f32.const nan:0x012345)))
(func (export "f32.misc_positive_nan") (result i32) (i32.reinterpret/f32 (f32.const +nan:0x304050)))
(func (export "f32.misc_negative_nan") (result i32) (i32.reinterpret/f32 (f32.const -nan:0x2abcde)))
(func (export "f32.infinity") (result i32) (i32.reinterpret/f32 (f32.const infinity)))
(func (export "f32.positive_infinity") (result i32) (i32.reinterpret/f32 (f32.const +infinity)))
(func (export "f32.negative_infinity") (result i32) (i32.reinterpret/f32 (f32.const -infinity)))
;; f32 numbers
(func $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 $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 $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 $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 $f32.trailing_dot (result i32) (i32.reinterpret/f32 (f32.const 0x1.p10)))
(func (export "f32.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 (export "f32.negative_zero") (result i32) (i32.reinterpret/f32 (f32.const -0x0.0p0)))
(func (export "f32.misc") (result i32) (i32.reinterpret/f32 (f32.const 0x1.921fb6p+2)))
(func (export "f32.min_positive") (result i32) (i32.reinterpret/f32 (f32.const 0x1p-149)))
(func (export "f32.min_normal") (result i32) (i32.reinterpret/f32 (f32.const 0x1p-126)))
(func (export "f32.max_finite") (result i32) (i32.reinterpret/f32 (f32.const 0x1.fffffep+127)))
(func (export "f32.max_subnormal") (result i32) (i32.reinterpret/f32 (f32.const 0x1.fffffcp-127)))
(func (export "f32.trailing_dot") (result i32) (i32.reinterpret/f32 (f32.const 0x1.p10)))
;; f32 in decimal format
(func $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 $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 $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 $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 $f32_dec.trailing_dot (result i32) (i32.reinterpret/f32 (f32.const 1.e10)))
(func (export "f32_dec.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 (export "f32_dec.negative_zero") (result i32) (i32.reinterpret/f32 (f32.const -0.0e0)))
(func (export "f32_dec.misc") (result i32) (i32.reinterpret/f32 (f32.const 6.28318548202514648)))
(func (export "f32_dec.min_positive") (result i32) (i32.reinterpret/f32 (f32.const 1.4013e-45)))
(func (export "f32_dec.min_normal") (result i32) (i32.reinterpret/f32 (f32.const 1.1754944e-38)))
(func (export "f32_dec.max_subnormal") (result i32) (i32.reinterpret/f32 (f32.const 1.1754942e-38)))
(func (export "f32_dec.max_finite") (result i32) (i32.reinterpret/f32 (f32.const 3.4028234e+38)))
(func (export "f32_dec.trailing_dot") (result i32) (i32.reinterpret/f32 (f32.const 1.e10)))
;; f64 special values
(func $f64.nan (result i64) (i64.reinterpret/f64 (f64.const nan)))
(func $f64.positive_nan (result i64) (i64.reinterpret/f64 (f64.const +nan)))
(func $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 $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 $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 $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 $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.nan") (result i64) (i64.reinterpret/f64 (f64.const nan)))
(func (export "f64.positive_nan") (result i64) (i64.reinterpret/f64 (f64.const +nan)))
(func (export "f64.negative_nan") (result i64) (i64.reinterpret/f64 (f64.const -nan)))
(func (export "f64.plain_nan") (result i64) (i64.reinterpret/f64 (f64.const nan:0x8000000000000)))
(func (export "f64.informally_known_as_plain_snan") (result i64) (i64.reinterpret/f64 (f64.const nan:0x4000000000000)))
(func (export "f64.all_ones_nan") (result i64) (i64.reinterpret/f64 (f64.const -nan:0xfffffffffffff)))
(func (export "f64.misc_nan") (result i64) (i64.reinterpret/f64 (f64.const nan:0x0123456789abc)))
(func (export "f64.misc_positive_nan") (result i64) (i64.reinterpret/f64 (f64.const +nan:0x3040506070809)))
(func (export "f64.misc_negative_nan") (result i64) (i64.reinterpret/f64 (f64.const -nan:0x2abcdef012345)))
(func (export "f64.infinity") (result i64) (i64.reinterpret/f64 (f64.const infinity)))
(func (export "f64.positive_infinity") (result i64) (i64.reinterpret/f64 (f64.const +infinity)))
(func (export "f64.negative_infinity") (result i64) (i64.reinterpret/f64 (f64.const -infinity)))
;; f64 numbers
(func $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 $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 $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 $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 $f64.trailing_dot (result i64) (i64.reinterpret/f64 (f64.const 0x1.p100)))
(func (export "f64.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 (export "f64.negative_zero") (result i64) (i64.reinterpret/f64 (f64.const -0x0.0p0)))
(func (export "f64.misc") (result i64) (i64.reinterpret/f64 (f64.const 0x1.921fb54442d18p+2)))
(func (export "f64.min_positive") (result i64) (i64.reinterpret/f64 (f64.const 0x0.0000000000001p-1022)))
(func (export "f64.min_normal") (result i64) (i64.reinterpret/f64 (f64.const 0x1p-1022)))
(func (export "f64.max_subnormal") (result i64) (i64.reinterpret/f64 (f64.const 0x0.fffffffffffffp-1022)))
(func (export "f64.max_finite") (result i64) (i64.reinterpret/f64 (f64.const 0x1.fffffffffffffp+1023)))
(func (export "f64.trailing_dot") (result i64) (i64.reinterpret/f64 (f64.const 0x1.p100)))
;; f64 numbers in decimal format
(func $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 $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 $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 $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 $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)
(func (export "f64_dec.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 (export "f64_dec.negative_zero") (result i64) (i64.reinterpret/f64 (f64.const -0.0e0)))
(func (export "f64_dec.misc") (result i64) (i64.reinterpret/f64 (f64.const 6.28318530717958623)))
(func (export "f64_dec.min_positive") (result i64) (i64.reinterpret/f64 (f64.const 4.94066e-324)))
(func (export "f64_dec.min_normal") (result i64) (i64.reinterpret/f64 (f64.const 2.2250738585072012e-308)))
(func (export "f64_dec.max_subnormal") (result i64) (i64.reinterpret/f64 (f64.const 2.2250738585072011e-308)))
(func (export "f64_dec.max_finite") (result i64) (i64.reinterpret/f64 (f64.const 1.7976931348623157e+308)))
(func (export "f64_dec.trailing_dot") (result i64) (i64.reinterpret/f64 (f64.const 1.e100)))
)
(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.plain_nan") (i32.const 0x7fc00000))
(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_positive_nan") (i32.const 0x7fb04050))
(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.plain_nan") (i64.const 0x7ff8000000000000))
(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_positive_nan") (i64.const 0x7ff3040506070809))
(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.
(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)))
(export "f32.load" $f32.load)
(func $i32.load (result i32) (i32.load (i32.const 0)))
(export "i32.load" $i32.load)
(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)
(func (export "f32.load") (result f32) (f32.load (i32.const 0)))
(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 (export "i32.store") (i32.store (i32.const 0) (i32.const 0x7fa00000)))
(func (export "reset") (i32.store (i32.const 0) (i32.const 0)))
)
(assert_return (invoke "i32.load") (i32.const 0x7fa00000))
@ -37,22 +28,13 @@
(assert_return (invoke "f32.load") (f32.const nan:0x200000))
(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)))
(export "f64.load" $f64.load)
(func $i64.load (result i64) (i64.load (i32.const 0)))
(export "i64.load" $i64.load)
(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)
(func (export "f64.load") (result f64) (f64.load (i32.const 0)))
(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 (export "i64.store") (i64.store (i32.const 0) (i64.const 0x7ff4000000000000)))
(func (export "reset") (i64.store (i32.const 0) (i64.const 0)))
)
(assert_return (invoke "i64.load") (i64.const 0x7ff4000000000000))
@ -73,22 +55,13 @@
;; Test that unaligned load and store do not canonicalize NaNs.
(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)))
(export "f32.load" $f32.load)
(func $i32.load (result i32) (i32.load (i32.const 1)))
(export "i32.load" $i32.load)
(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)
(func (export "f32.load") (result f32) (f32.load (i32.const 1)))
(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 (export "i32.store") (i32.store (i32.const 1) (i32.const 0x7fa00000)))
(func (export "reset") (i32.store (i32.const 1) (i32.const 0)))
)
(assert_return (invoke "i32.load") (i32.const 0x7fa00000))
@ -107,22 +80,13 @@
(assert_return (invoke "f32.load") (f32.const nan:0x200000))
(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)))
(export "f64.load" $f64.load)
(func $i64.load (result i64) (i64.load (i32.const 1)))
(export "i64.load" $i64.load)
(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)
(func (export "f64.load") (result f64) (f64.load (i32.const 1)))
(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 (export "i64.store") (i64.store (i32.const 1) (i64.const 0x7ff4000000000000)))
(func (export "reset") (i64.store (i32.const 1) (i64.const 0)))
)
(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.
(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)))
(export "f32.load" $f32.load)
(func $i32.load (result i32) (i32.load (i32.const 0)))
(export "i32.load" $i32.load)
(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)
(func (export "f32.load") (result f32) (f32.load (i32.const 0)))
(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 (export "i32.store") (i32.store (i32.const 0) (i32.const 0x7fd00001)))
(func (export "reset") (i32.store (i32.const 0) (i32.const 0)))
)
(assert_return (invoke "i32.load") (i32.const 0x7fd00001))
@ -177,22 +132,13 @@
(assert_return (invoke "f32.load") (f32.const nan:0x500001))
(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)))
(export "f64.load" $f64.load)
(func $i64.load (result i64) (i64.load (i32.const 0)))
(export "i64.load" $i64.load)
(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)
(func (export "f64.load") (result f64) (f64.load (i32.const 0)))
(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 (export "i64.store") (i64.store (i32.const 0) (i64.const 0x7ffc000000000001)))
(func (export "reset") (i64.store (i32.const 0) (i64.const 0)))
)
(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
;; rather than something else entirely, (b) it's configured correctly for
;; WebAssembly (rounding direction, exception masks, precision level, subnormal
;; mode, etc.), and (c) the WebAssembly implementation doesn't perform any
;; common value-changing optimizations.
;; mode, etc.), (c) the WebAssembly implementation doesn't perform any common
;; 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
;; additional single-instruction tests covering additional miscellaneous
;; interesting cases.
(module
(func $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 $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 $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 $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 $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 $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 $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.add") (param $x f32) (param $y f32) (result f32) (f32.add (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 (export "f32.mul") (param $x f32) (param $y f32) (result f32) (f32.mul (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 (export "f32.sqrt") (param $x f32) (result f32) (f32.sqrt (get_local $x)))
(func (export "f32.abs") (param $x f32) (result f32) (f32.abs (get_local $x)))
(func (export "f32.neg") (param $x f32) (result f32) (f32.neg (get_local $x)))
(func (export "f32.copysign") (param $x f32) (param $y f32) (result f32) (f32.copysign (get_local $x) (get_local $y)))
(func (export "f32.ceil") (param $x f32) (result f32) (f32.ceil (get_local $x)))
(func (export "f32.floor") (param $x f32) (result f32) (f32.floor (get_local $x)))
(func (export "f32.trunc") (param $x f32) (result f32) (f32.trunc (get_local $x)))
(func (export "f32.nearest") (param $x f32) (result f32) (f32.nearest (get_local $x)))
(func (export "f32.min") (param $x f32) (param $y f32) (result f32) (f32.min (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 $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 $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 $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 $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 $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 $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 $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)
(func (export "f64.add") (param $x f64) (param $y f64) (result f64) (f64.add (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 (export "f64.mul") (param $x f64) (param $y f64) (result f64) (f64.mul (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 (export "f64.sqrt") (param $x f64) (result f64) (f64.sqrt (get_local $x)))
(func (export "f64.abs") (param $x f64) (result f64) (f64.abs (get_local $x)))
(func (export "f64.neg") (param $x f64) (result f64) (f64.neg (get_local $x)))
(func (export "f64.copysign") (param $x f64) (param $y f64) (result f64) (f64.copysign (get_local $x) (get_local $y)))
(func (export "f64.ceil") (param $x f64) (result f64) (f64.ceil (get_local $x)))
(func (export "f64.floor") (param $x f64) (result f64) (f64.floor (get_local $x)))
(func (export "f64.trunc") (param $x f64) (result f64) (f64.trunc (get_local $x)))
(func (export "f64.nearest") (param $x f64) (result f64) (f64.nearest (get_local $x)))
(func (export "f64.min") (param $x f64) (param $y f64) (result f64) (f64.min (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)))
)
;; Miscellaneous values.
(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
;; 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 0x1.000002p-24)) (f32.const 0x1.000002p+0))
;; 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 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))
;; 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 "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:
;; http://perso.ens-lyon.fr/jean-michel.muller/Handbook.html
;; 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))
;; Test a case that was "tricky" on MMIX.
;; 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))
;; 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.
(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 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))
;; 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 "f64.add" (f64.const -0x1.234a5a0412f41p+1023) (f64.const -0x1.53e9106c9367p+161)) (f64.const -0x1.234a5a0412f41p+1023))
(assert_return (invoke "f64.add" (f64.const -0x1.a86bdb66cbb32p+562) (f64.const 0x1.d10ff29e1d6e8p+1023)) (f64.const 0x1.d10ff29e1d6e8p+1023))
(assert_return (invoke "f64.add" (f64.const -0x1.dc295727a06e2p+1023) (f64.const 0x1.5e6979d7b24fp+485)) (f64.const -0x1.dc295727a06e2p+1023))
(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.2b91ap+116) (f32.const 0x1.cbcd52p+127)) (f32.const 0x1.cbf2c4p+127))
(assert_return (invoke "f32.add" (f32.const 0x1.96f392p+127) (f32.const -0x1.6b3fecp+107)) (f32.const 0x1.96f37cp+127))
(assert_return (invoke "f32.add" (f32.const 0x1.132f1cp+118) (f32.const -0x1.63d632p+127)) (f32.const -0x1.634c9ap+127))
(assert_return (invoke "f32.add" (f32.const -0x1.1dda64p+120) (f32.const -0x1.ef02ep+127)) (f32.const -0x1.f13e94p+127))
(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.
(assert_return (invoke "f64.add" (f64.const -0x0.2d2c9b631ae47p-1022) (f64.const -0x0.8e173a51d11a7p-1022)) (f64.const -0x0.bb43d5b4ebfeep-1022))
(assert_return (invoke "f64.add" (f64.const -0x0.ce7d534f2c7ep-1022) (f64.const -0x0.32f94dc4b7ee5p-1022)) (f64.const -0x1.0176a113e46c5p-1022))
(assert_return (invoke "f64.add" (f64.const -0x1.44d9fb78bf5d3p-1021) (f64.const -0x0.02766a20d263fp-1022)) (f64.const -0x1.46153089288f2p-1021))
(assert_return (invoke "f64.add" (f64.const 0x0.89e17f0fdc567p-1022) (f64.const -0x1.d9a93a01fd27dp-1021)) (f64.const -0x1.94b87a7a0efcap-1021))
(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.6a1a2p-127) (f32.const 0x1.378p-140)) (f32.const 0x1.6a23dcp-127))
(assert_return (invoke "f32.add" (f32.const 0x1.28p-144) (f32.const -0x1p-148)) (f32.const 0x1.18p-144))
(assert_return (invoke "f32.add" (f32.const -0x1p-146) (f32.const 0x1.c3cap-128)) (f32.const 0x1.c3c9cp-128))
(assert_return (invoke "f32.add" (f32.const -0x1.4p-145) (f32.const 0x1.424052p-122)) (f32.const 0x1.42405p-122))
(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.
(assert_return (invoke "f64.add" (f64.const nan:0x4000000000000) (f64.const 1.0)) (f64.const nan:0xc000000000000))
;; Test an add of the second-greatest finite value with the distance to greatest
;; 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.
;; 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))
;; 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))
;; 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 "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))
;; 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 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.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 1e20) (f32.const 1e20)) (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 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))
@ -264,10 +258,12 @@
;; 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))
(assert_return (invoke "f64.mul" (f64.const 1848874847.0) (f64.const 19954562207.0)) (f64.const 3.6893488147419111424e+19))
;; 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 77.1) (f64.const 850)) (f64.const 65534.99999999999272404))
;; 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.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 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.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 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 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))
;; 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 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 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))
;; 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 4195835) (f64.const 3145727)) (f64.const 0x1.557541c7c6b43p+0))
;; 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))
;; 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.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))
@ -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 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 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 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 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.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.
;; 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.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.
(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
(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.
(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))
@ -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.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.
(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 "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))
@ -515,7 +553,6 @@
(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 "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))
@ -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 "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.
(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))
;; 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 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.
(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))
;; 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 -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.
;; http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1
;; 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.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+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.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+105)) (f64.const 0x1.fffffffffffffp+105))
;; Nearest should not round halfway cases away from zero (as C's round(3) 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 -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.
(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))

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

@ -1,16 +1,13 @@
(module
(export "even" $even)
(export "odd" $odd)
(func $even (param $n i32) (result i32)
(if (i32.eq (get_local $n) (i32.const 0))
(func $even (export "even") (param $n i32) (result i32)
(if i32 (i32.eq (get_local $n) (i32.const 0))
(i32.const 1)
(call $odd (i32.sub (get_local $n) (i32.const 1)))
)
)
(func $odd (param $n i32) (result i32)
(if (i32.eq (get_local $n) (i32.const 0))
(func $odd (export "odd") (param $n i32) (result i32)
(if i32 (i32.eq (get_local $n) (i32.const 0))
(i32.const 0)
(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');

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

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

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

@ -1,2 +1,4 @@
// |jit-test| test-also-wasm-baseline
// TODO: new anyfunc table syntax
quit();
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"))

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