зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
903b01d434
Коммит
28d57ea0f3
|
@ -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)
|
||||
{
|
||||
Type ignored;
|
||||
if (expr->isKind(PNK_CALL))
|
||||
if (expr->isKind(PNK_CALL)) {
|
||||
Type ignored;
|
||||
return CheckCoercedCall(f, expr, Type::Void, &ignored);
|
||||
return CheckExpr(f, expr, &ignored);
|
||||
}
|
||||
|
||||
Type resultType;
|
||||
if (!CheckExpr(f, expr, &resultType))
|
||||
return false;
|
||||
|
||||
if (!resultType.isVoid()) {
|
||||
if (!f.encoder().writeExpr(Expr::Drop))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -6403,10 +6432,12 @@ 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
|
||||
// (brIf $after_loop (i32.eq 0 #cond))
|
||||
// #body
|
||||
// (br $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,11 +6476,13 @@ 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)
|
||||
// (brIf $after (eq 0 #cond))
|
||||
// (block $after_body #body) // depth X+3
|
||||
// #inc
|
||||
// (br $loop_top)
|
||||
// (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.
|
||||
|
@ -6506,9 +6539,11 @@ 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 #body) // depth X+2
|
||||
// (brIf #cond $top)
|
||||
// (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.
|
||||
|
@ -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)
|
||||
|
@ -505,8 +555,8 @@ class AstBranchTable : public AstExpr
|
|||
public:
|
||||
static const AstExprKind Kind = AstExprKind::BranchTable;
|
||||
explicit AstBranchTable(AstExpr& index, AstRef def, AstRefVector&& table,
|
||||
AstExpr* maybeValue)
|
||||
: AstExpr(Kind),
|
||||
AstExpr* maybeValue)
|
||||
: 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)
|
||||
return false;
|
||||
if (idSize != IdSize || !!memcmp(cur_, id, IdSize))
|
||||
goto backup;
|
||||
cur_ += 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;
|
||||
beforeId = cur_;
|
||||
if (!readVarU32(&idValue))
|
||||
goto backup;
|
||||
}
|
||||
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;
|
||||
|
||||
// "User sections" do not cause validation errors unless the error is in
|
||||
// the user-defined section header itself.
|
||||
|
||||
MOZ_MUST_USE bool startUserDefinedSection(const char* expectedId,
|
||||
size_t expectedIdSize,
|
||||
uint32_t* sectionStart,
|
||||
uint32_t* sectionSize)
|
||||
{
|
||||
const uint8_t* const before = cur_;
|
||||
while (true) {
|
||||
if (!startSection(SectionId::UserDefined, sectionStart, sectionSize, "user-defined"))
|
||||
return false;
|
||||
if (*sectionStart == NotStarted) {
|
||||
cur_ = before;
|
||||
return true;
|
||||
}
|
||||
uint32_t idSize;
|
||||
if (!readVarU32(&idSize))
|
||||
goto fail;
|
||||
if (idSize > bytesRemain() || currentOffset() + idSize > *sectionStart + *sectionSize)
|
||||
goto fail;
|
||||
if (expectedId && (expectedIdSize != idSize || !!memcmp(cur_, expectedId, idSize))) {
|
||||
finishUserDefinedSection(*sectionStart, *sectionSize);
|
||||
continue;
|
||||
}
|
||||
cur_ += idSize;
|
||||
return true;
|
||||
}
|
||||
MOZ_CRASH("unreachable");
|
||||
fail:
|
||||
return fail("failed to start user-defined section");
|
||||
}
|
||||
template <size_t IdSizeWith0>
|
||||
MOZ_MUST_USE bool startUserDefinedSection(const char (&id)[IdSizeWith0],
|
||||
uint32_t* sectionStart,
|
||||
uint32_t* sectionSize)
|
||||
{
|
||||
MOZ_ASSERT(id[IdSizeWith0 - 1] == '\0');
|
||||
return startUserDefinedSection(id, IdSizeWith0 - 1, sectionStart, sectionSize);
|
||||
}
|
||||
void finishUserDefinedSection(uint32_t sectionStart, uint32_t sectionSize) {
|
||||
MOZ_ASSERT(cur_ >= beg_);
|
||||
MOZ_ASSERT(cur_ <= end_);
|
||||
cur_ = (beg_ + sectionStart) + sectionSize;
|
||||
MOZ_ASSERT(cur_ <= end_);
|
||||
clearError();
|
||||
}
|
||||
MOZ_MUST_USE bool skipSection() {
|
||||
uint32_t idSize;
|
||||
if (!readVarU32(&idSize) || bytesRemain() < idSize)
|
||||
MOZ_MUST_USE bool skipUserDefinedSection() {
|
||||
uint32_t sectionStart, sectionSize;
|
||||
if (!startUserDefinedSection(nullptr, 0, §ionStart, §ionSize))
|
||||
return false;
|
||||
cur_ += idSize;
|
||||
uint32_t size;
|
||||
if (!readVarU32(&size) || bytesRemain() < size)
|
||||
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,15 +655,18 @@ 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])))
|
||||
return false;
|
||||
skip = 1;
|
||||
if (block.exprs().length() == 1 && block.breakName().empty()) {
|
||||
// Special case to resolve ambiguity in parsing of optional end block label.
|
||||
if (!PrintIndent(c))
|
||||
return false;
|
||||
if (!c.buffer.append("$exit$:\n"))
|
||||
return false;
|
||||
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.name().empty()) {
|
||||
// Special case to resolve ambiguity in parsing of optional end block label.
|
||||
if (!PrintIndent(c))
|
||||
return false;
|
||||
if (!c.buffer.append("$exit$:\n"))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,8 +676,10 @@ PrintBlock(WasmPrintContext& c, AstBlock& block)
|
|||
c.indent--;
|
||||
c.currentPrecedence = lastPrecedence;
|
||||
|
||||
if (!PrintBlockName(c, block.breakName()))
|
||||
return false;
|
||||
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,29 +357,52 @@ 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;
|
||||
}
|
||||
|
||||
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 (!RenderIndent(c))
|
||||
return false;
|
||||
|
||||
if (block.expr() == Expr::Block) {
|
||||
if (!c.buffer.append("(block "))
|
||||
return false;
|
||||
if (!RenderName(c, block.breakName()))
|
||||
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,14 +473,17 @@ 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("("))
|
||||
return false;
|
||||
if (!RenderExpr(c, *op.op()))
|
||||
return false;
|
||||
|
||||
if (!RenderIndent(c))
|
||||
return false;
|
||||
|
||||
const char* opStr;
|
||||
switch (op.expr()) {
|
||||
|
@ -449,20 +512,19 @@ 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("("))
|
||||
return false;
|
||||
if (!RenderExpr(c, *op.lhs()))
|
||||
return false;
|
||||
if (!RenderExpr(c, *op.rhs()))
|
||||
return false;
|
||||
|
||||
if (!RenderIndent(c))
|
||||
return false;
|
||||
|
||||
const char* opStr;
|
||||
switch (op.expr()) {
|
||||
|
@ -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,8 +608,13 @@ RenderTernaryOperator(WasmRenderContext& c, AstTernaryOperator& op)
|
|||
static bool
|
||||
RenderComparisonOperator(WasmRenderContext& c, AstComparisonOperator& op)
|
||||
{
|
||||
if (!c.buffer.append("("))
|
||||
return false;
|
||||
if (!RenderExpr(c, *op.lhs()))
|
||||
return false;
|
||||
if (!RenderExpr(c, *op.rhs()))
|
||||
return false;
|
||||
|
||||
if (!RenderIndent(c))
|
||||
return false;
|
||||
|
||||
const char* opStr;
|
||||
switch (op.expr()) {
|
||||
|
@ -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,8 +664,11 @@ RenderComparisonOperator(WasmRenderContext& c, AstComparisonOperator& op)
|
|||
static bool
|
||||
RenderConversionOperator(WasmRenderContext& c, AstConversionOperator& op)
|
||||
{
|
||||
if (!c.buffer.append("("))
|
||||
return false;
|
||||
if (!RenderExpr(c, *op.op()))
|
||||
return false;
|
||||
|
||||
if (!RenderIndent(c))
|
||||
return false;
|
||||
|
||||
const char* opStr;
|
||||
switch (op.expr()) {
|
||||
|
@ -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,8 +137,7 @@ ModuleGenerator::init(UniqueModuleGeneratorData shared, const CompileArgs& args,
|
|||
numSigs_ = shared_->sigs.length();
|
||||
numTables_ = shared_->tables.length();
|
||||
|
||||
if (args.assumptions.newFormat)
|
||||
shared_->firstFuncDefIndex = shared_->funcImports.length();
|
||||
shared_->firstFuncDefIndex = shared_->funcImports.length();
|
||||
|
||||
for (FuncImportGenDesc& funcImport : shared_->funcImports) {
|
||||
MOZ_ASSERT(!funcImport.globalDataOffset);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
f.iter().setResult(def);
|
||||
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))
|
||||
return false;
|
||||
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))
|
||||
return false;
|
||||
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));
|
||||
|
||||
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,10 +361,12 @@ 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
|
||||
ReportOutOfMemory(cx);
|
||||
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,10 +597,12 @@ 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
|
||||
ReportOutOfMemory(cx);
|
||||
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());
|
||||
val = ObjectValue(*memoryObj);
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
mod.test();
|
||||
}).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 (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, /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 Block = 0x01;
|
||||
const End = 0x0f;
|
||||
const CallImport = 0x18;
|
||||
const Unreachable = 0x00;
|
||||
const Block = 0x01;
|
||||
const End = 0x0f;
|
||||
const I32Const = 0x10;
|
||||
const I64Const = 0x11;
|
||||
const F64Const = 0x12;
|
||||
const F32Const = 0x13;
|
||||
const Call = 0x16;
|
||||
|
||||
// DefinitionKind
|
||||
const FunctionCode = 0x00;
|
||||
const TableCode = 0x01;
|
||||
const MemoryCode = 0x02;
|
||||
const GlobalCode = 0x03;
|
||||
|
||||
// ResizableFlags
|
||||
const DefaultFlag = 0x1;
|
||||
const HasMaximumFlag = 0x2;
|
||||
|
||||
function toU8(array) {
|
||||
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
|
||||
(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)
|
||||
(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
|
||||
(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)))
|
||||
(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
|
||||
(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)))
|
||||
)
|
||||
(get_local 0)
|
||||
(i32.eq (get_local 0) (i32.const -14))
|
||||
)
|
||||
|
||||
(export "empty" $empty)
|
||||
(export "singular" $singular)
|
||||
(export "multi" $multi)
|
||||
(export "effects" $effects)
|
||||
)
|
||||
|
||||
(invoke "empty")
|
||||
(assert_return (invoke "empty"))
|
||||
(assert_return (invoke "singular") (i32.const 7))
|
||||
(assert_return (invoke "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,64 +1,68 @@
|
|||
(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))
|
||||
(loop
|
||||
(if
|
||||
(i64.eq (get_local 1) (i64.const 0))
|
||||
(br 2)
|
||||
(block
|
||||
(set_local 2 (i64.mul (get_local 1) (get_local 2)))
|
||||
(set_local 1 (i64.sub (get_local 1) (i64.const 1)))
|
||||
(block
|
||||
(loop
|
||||
(if
|
||||
(i64.eq (get_local 1) (i64.const 0))
|
||||
(br 2)
|
||||
(block
|
||||
(set_local 2 (i64.mul (get_local 1) (get_local 2)))
|
||||
(set_local 1 (i64.sub (get_local 1) (i64.const 1)))
|
||||
)
|
||||
)
|
||||
(br 0)
|
||||
)
|
||||
(br 0)
|
||||
)
|
||||
(get_local 2)
|
||||
)
|
||||
|
||||
;; 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
|
||||
(if
|
||||
(i64.eq (get_local $i) (i64.const 0))
|
||||
(br $done)
|
||||
(block
|
||||
(set_local $res (i64.mul (get_local $i) (get_local $res)))
|
||||
(set_local $i (i64.sub (get_local $i) (i64.const 1)))
|
||||
(block $done
|
||||
(loop $loop
|
||||
(if
|
||||
(i64.eq (get_local $i) (i64.const 0))
|
||||
(br $done)
|
||||
(block
|
||||
(set_local $res (i64.mul (get_local $i) (get_local $res)))
|
||||
(set_local $i (i64.sub (get_local $i) (i64.const 1)))
|
||||
)
|
||||
)
|
||||
(br $loop)
|
||||
)
|
||||
(br $loop)
|
||||
)
|
||||
(get_local $res)
|
||||
)
|
||||
|
||||
;; 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');
|
|
@ -1,58 +1,70 @@
|
|||
(module
|
||||
(type (func)) ;; 0: void -> void
|
||||
(type $S (func)) ;; 1: void -> void
|
||||
(type (func (param))) ;; 2: void -> void
|
||||
(type (func (result i32))) ;; 3: void -> i32
|
||||
(type (func (param) (result i32))) ;; 4: void -> i32
|
||||
(type $T (func (param i32) (result i32))) ;; 5: i32 -> i32
|
||||
(type $U (func (param i32))) ;; 6: i32 -> void
|
||||
(type (func)) ;; 0: void -> void
|
||||
(type $S (func)) ;; 1: void -> void
|
||||
(type (func (param))) ;; 2: void -> void
|
||||
(type (func (result i32))) ;; 3: void -> i32
|
||||
(type (func (param) (result i32))) ;; 4: void -> i32
|
||||
(type $T (func (param i32) (result i32))) ;; 5: i32 -> i32
|
||||
(type $U (func (param i32))) ;; 6: i32 -> void
|
||||
|
||||
(func (type 0))
|
||||
(func (type $S))
|
||||
(func $print (import "spectest" "print") (type 6))
|
||||
|
||||
(func $one (type 4) (i32.const 13))
|
||||
(export "one" $one)
|
||||
(func (type 0))
|
||||
(func (type $S))
|
||||
|
||||
(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)
|
||||
;; Both signature and parameters are allowed (and required to match)
|
||||
;; since this allows the naming of parameters.
|
||||
(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)
|
||||
(type $T (func (param) (result i32)))
|
||||
(type $U (func (param) (result i32)))
|
||||
(table anyfunc (elem $t1 $t2 $t3 $u1 $u2 $t1 $t3))
|
||||
|
||||
(func $t1 (type $T) (i32.const 1))
|
||||
(func $t2 (type $T) (i32.const 2))
|
||||
(func $t3 (type $T) (i32.const 3))
|
||||
(func $u1 (type $U) (i32.const 4))
|
||||
(func $u2 (type $U) (i32.const 5))
|
||||
(func $t1 (type $T) (i32.const 1))
|
||||
(func $t2 (type $T) (i32.const 2))
|
||||
(func $t3 (type $T) (i32.const 3))
|
||||
(func $u1 (type $U) (i32.const 4))
|
||||
(func $u2 (type $U) (i32.const 5))
|
||||
|
||||
(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))
|
||||
)
|
||||
|
||||
(func $callu (param $i i32) (result i32)
|
||||
(call_indirect $U (get_local $i))
|
||||
)
|
||||
(export "callu" $callu)
|
||||
(func (export "callu") (param $i i32) (result i32)
|
||||
(call_indirect $U (get_local $i))
|
||||
)
|
||||
)
|
||||
|
||||
(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)
|
||||
(type $T (func (result i32)))
|
||||
(table anyfunc (elem 0 1))
|
||||
|
||||
(import $print_i32 "spectest" "print" (param i32))
|
||||
(func $t1 (type $T) (i32.const 1))
|
||||
(func $t2 (type $T) (i32.const 2))
|
||||
|
||||
(func $t1 (type $T) (i32.const 1))
|
||||
(func $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"))
|
||||
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче