2015-09-01 18:30:34 +00:00
|
|
|
// Copyright 2015 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "src/v8.h"
|
|
|
|
|
2015-11-26 16:22:34 +00:00
|
|
|
#include "src/ast/ast.h"
|
|
|
|
#include "src/ast/ast-expression-visitor.h"
|
|
|
|
#include "src/ast/scopes.h"
|
|
|
|
#include "src/parsing/parser.h"
|
|
|
|
#include "src/parsing/rewriter.h"
|
2015-10-28 13:31:10 +00:00
|
|
|
#include "src/type-cache.h"
|
2015-09-01 18:30:34 +00:00
|
|
|
#include "src/typing-asm.h"
|
|
|
|
#include "test/cctest/cctest.h"
|
|
|
|
#include "test/cctest/expression-type-collector.h"
|
|
|
|
#include "test/cctest/expression-type-collector-macros.h"
|
|
|
|
|
|
|
|
// Macros for function types.
|
2016-02-03 01:20:22 +00:00
|
|
|
#define FUNC_FOREIGN_TYPE Bounds(Type::Function(Type::Any(), zone))
|
2016-02-02 07:25:30 +00:00
|
|
|
#define FUNC_V_TYPE Bounds(Type::Function(Type::Undefined(), zone))
|
2015-11-17 19:42:01 +00:00
|
|
|
#define FUNC_I_TYPE Bounds(Type::Function(cache.kAsmSigned, zone))
|
|
|
|
#define FUNC_F_TYPE Bounds(Type::Function(cache.kAsmFloat, zone))
|
|
|
|
#define FUNC_D_TYPE Bounds(Type::Function(cache.kAsmDouble, zone))
|
2015-09-01 18:30:34 +00:00
|
|
|
#define FUNC_D2D_TYPE \
|
2015-11-17 19:42:01 +00:00
|
|
|
Bounds(Type::Function(cache.kAsmDouble, cache.kAsmDouble, zone))
|
2015-09-01 18:30:34 +00:00
|
|
|
#define FUNC_N2F_TYPE \
|
2016-02-02 07:25:30 +00:00
|
|
|
Bounds(Type::Function(cache.kAsmFloat, Type::Number(), zone))
|
2015-11-17 19:42:01 +00:00
|
|
|
#define FUNC_I2I_TYPE \
|
|
|
|
Bounds(Type::Function(cache.kAsmSigned, cache.kAsmInt, zone))
|
2015-09-01 18:30:34 +00:00
|
|
|
#define FUNC_II2D_TYPE \
|
2015-11-17 19:42:01 +00:00
|
|
|
Bounds(Type::Function(cache.kAsmDouble, cache.kAsmInt, cache.kAsmInt, zone))
|
2015-09-01 18:30:34 +00:00
|
|
|
#define FUNC_II2I_TYPE \
|
2015-11-17 19:42:01 +00:00
|
|
|
Bounds(Type::Function(cache.kAsmSigned, cache.kAsmInt, cache.kAsmInt, zone))
|
|
|
|
#define FUNC_DD2D_TYPE \
|
|
|
|
Bounds(Type::Function(cache.kAsmDouble, cache.kAsmDouble, cache.kAsmDouble, \
|
|
|
|
zone))
|
2016-02-02 07:25:30 +00:00
|
|
|
#define FUNC_NN2N_TYPE \
|
|
|
|
Bounds(Type::Function(Type::Number(), Type::Number(), Type::Number(), zone))
|
2015-09-01 18:30:34 +00:00
|
|
|
#define FUNC_N2N_TYPE \
|
2016-02-02 07:25:30 +00:00
|
|
|
Bounds(Type::Function(Type::Number(), Type::Number(), zone))
|
2015-09-01 18:30:34 +00:00
|
|
|
|
|
|
|
// Macros for array types.
|
2015-11-17 19:42:01 +00:00
|
|
|
#define FLOAT64_ARRAY_TYPE Bounds(Type::Array(cache.kAsmDouble, zone))
|
|
|
|
#define FUNC_I2I_ARRAY_TYPE \
|
|
|
|
Bounds(Type::Array(Type::Function(cache.kAsmSigned, cache.kAsmInt, zone), \
|
|
|
|
zone))
|
2015-09-01 18:30:34 +00:00
|
|
|
|
|
|
|
using namespace v8::internal;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
std::string Validate(Zone* zone, const char* source,
|
|
|
|
ZoneVector<ExpressionTypeEntry>* types) {
|
|
|
|
i::Isolate* isolate = CcTest::i_isolate();
|
|
|
|
i::Factory* factory = isolate->factory();
|
|
|
|
|
|
|
|
i::Handle<i::String> source_code =
|
|
|
|
factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked();
|
|
|
|
|
|
|
|
i::Handle<i::Script> script = factory->NewScript(source_code);
|
|
|
|
|
|
|
|
i::ParseInfo info(zone, script);
|
|
|
|
i::Parser parser(&info);
|
|
|
|
info.set_global();
|
|
|
|
info.set_lazy(false);
|
|
|
|
info.set_allow_lazy_parsing(false);
|
|
|
|
info.set_toplevel(true);
|
|
|
|
|
|
|
|
CHECK(i::Compiler::ParseAndAnalyze(&info));
|
|
|
|
|
2015-09-01 23:06:29 +00:00
|
|
|
FunctionLiteral* root =
|
|
|
|
info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun();
|
|
|
|
AsmTyper typer(isolate, zone, *script, root);
|
2015-09-01 18:30:34 +00:00
|
|
|
if (typer.Validate()) {
|
Remove Expression::bounds_, in order to conserve memory during parsing.
Expression::bounds_ is used only by a subset of compile passes, but the
data structure occupies space for every Expression node ever parsed. This
unneccessarily increases memory consumption. Particularly, peak memory
consumption during startup, which may cause out-of-memory errors.
This CL
- removes Expression::bounds_;
- introduces an AstTypeBounds container, which mappes Expression* to Bounds;
- modifies the code that actually requires bounds information, namely
Crankshaft compile and AsmWasmBuilder, to instantiate such an AstTypeBounds
container before typing and to pass it to the code that consumes this
information; and
- modifies all accesses to Expression::bounds_ to instead access the bounds
via the container instead.
Additionally, this rewrites test-ast-expression-visitor. The reason is that
this code attempted to test AstExpressionVisitor but did so exclusively
through its subclass ExpressionTypeCollector, meaning that the test dealt
almost exclusively with type bounds despite the class-under-test having
no knowledge or functionality related to it. Worse, the test was written
in a way to assume that type bounds were available outside & after
compilation, which is something this change changes.
BUG=v8:4947
Review-Url: https://codereview.chromium.org/1968383002
Cr-Commit-Position: refs/heads/master@{#36222}
2016-05-12 22:24:03 +00:00
|
|
|
ExpressionTypeCollector(isolate, root, typer.bounds(), types).Run();
|
2015-09-01 18:30:34 +00:00
|
|
|
return "";
|
|
|
|
} else {
|
|
|
|
return typer.error_message();
|
|
|
|
}
|
|
|
|
}
|
2015-09-30 13:46:56 +00:00
|
|
|
|
|
|
|
} // namespace
|
2015-09-01 18:30:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
TEST(ValidateMinimum) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function GeometricMean(stdlib, foreign, buffer) {\n"
|
|
|
|
" \"use asm\";\n"
|
|
|
|
"\n"
|
|
|
|
" var exp = stdlib.Math.exp;\n"
|
|
|
|
" var log = stdlib.Math.log;\n"
|
|
|
|
" var values = new stdlib.Float64Array(buffer);\n"
|
|
|
|
"\n"
|
|
|
|
" function logSum(start, end) {\n"
|
|
|
|
" start = start|0;\n"
|
|
|
|
" end = end|0;\n"
|
|
|
|
"\n"
|
|
|
|
" var sum = 0.0, p = 0, q = 0;\n"
|
|
|
|
"\n"
|
|
|
|
" // asm.js forces byte addressing of the heap by requiring shifting "
|
|
|
|
"by 3\n"
|
|
|
|
" for (p = start << 3, q = end << 3; (p|0) < (q|0); p = (p + 8)|0) {\n"
|
|
|
|
" sum = sum + +log(values[p>>3]);\n"
|
|
|
|
" }\n"
|
|
|
|
"\n"
|
|
|
|
" return +sum;\n"
|
|
|
|
" }\n"
|
|
|
|
"\n"
|
|
|
|
" function geometricMean(start, end) {\n"
|
|
|
|
" start = start|0;\n"
|
|
|
|
" end = end|0;\n"
|
|
|
|
"\n"
|
|
|
|
" return +exp(+logSum(start, end) / +((end - start)|0));\n"
|
|
|
|
" }\n"
|
|
|
|
"\n"
|
|
|
|
" return { geometricMean: geometricMean };\n"
|
|
|
|
"}\n";
|
|
|
|
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("", Validate(zone, test_function, &types));
|
2015-10-28 13:31:10 +00:00
|
|
|
TypeCache cache;
|
2015-09-01 18:30:34 +00:00
|
|
|
|
|
|
|
CHECK_TYPES_BEGIN {
|
|
|
|
// Module.
|
|
|
|
CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
|
|
|
|
// function logSum
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_II2D_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(start, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(start, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(end, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(end, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(sum, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(p, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(q, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
// for (p = start << 3, q = end << 3;
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(p, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(start, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(q, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(end, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// (p|0) < (q|0);
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(p, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(q, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2016-03-18 23:14:17 +00:00
|
|
|
// p = (p + 8)|0) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(p, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(p, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// sum = sum + +log(values[p>>3]);
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(sum, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(sum, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR(log, FUNC_D2D_TYPE);
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Property, Bounds(cache.kAsmDouble)) {
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR(values, FLOAT64_ARRAY_TYPE);
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(p, Bounds(cache.kAsmSigned));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// return +sum;
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(sum, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// function geometricMean
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_II2D_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(start, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(start, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(end, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(end, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// return +exp(+logSum(start, end) / +((end - start)|0));
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR(exp, FUNC_D2D_TYPE);
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR(logSum, FUNC_II2D_TYPE);
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_VAR(start, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_VAR(end, Bounds(cache.kAsmInt));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(end, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_VAR(start, Bounds(cache.kAsmInt));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// "use asm";
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(Type::String()));
|
2015-09-01 18:30:34 +00:00
|
|
|
// var exp = stdlib.Math.exp;
|
|
|
|
CHECK_EXPR(Assignment, FUNC_D2D_TYPE) {
|
|
|
|
CHECK_VAR(exp, FUNC_D2D_TYPE);
|
|
|
|
CHECK_EXPR(Property, FUNC_D2D_TYPE) {
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(stdlib, Bounds::Unbounded());
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded());
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// var log = stdlib.Math.log;
|
|
|
|
CHECK_EXPR(Assignment, FUNC_D2D_TYPE) {
|
|
|
|
CHECK_VAR(log, FUNC_D2D_TYPE);
|
|
|
|
CHECK_EXPR(Property, FUNC_D2D_TYPE) {
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(stdlib, Bounds::Unbounded());
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded());
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// var values = new stdlib.Float64Array(buffer);
|
|
|
|
CHECK_EXPR(Assignment, FLOAT64_ARRAY_TYPE) {
|
|
|
|
CHECK_VAR(values, FLOAT64_ARRAY_TYPE);
|
|
|
|
CHECK_EXPR(CallNew, FLOAT64_ARRAY_TYPE) {
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(stdlib, Bounds::Unbounded());
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded());
|
|
|
|
}
|
|
|
|
CHECK_VAR(buffer, Bounds::Unbounded());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// return { geometricMean: geometricMean };
|
|
|
|
CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(geometricMean, FUNC_II2D_TYPE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-01-11 12:26:53 +00:00
|
|
|
TEST(MissingUseAsm) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function foo() {\n"
|
|
|
|
" function bar() {}\n"
|
|
|
|
" return { bar: bar };\n"
|
|
|
|
"}\n";
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("asm: line 1: missing \"use asm\"\n",
|
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(WrongUseAsm) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function foo() {\n"
|
|
|
|
" \"use wasm\"\n"
|
|
|
|
" function bar() {}\n"
|
|
|
|
" return { bar: bar };\n"
|
|
|
|
"}\n";
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("asm: line 1: missing \"use asm\"\n",
|
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(MissingReturnExports) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function foo() {\n"
|
|
|
|
" \"use asm\"\n"
|
|
|
|
" function bar() {}\n"
|
|
|
|
"}\n";
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("asm: line 2: last statement in module is not a return\n",
|
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
|
|
|
|
2016-03-18 23:14:17 +00:00
|
|
|
#define HARNESS_STDLIB() \
|
|
|
|
"var Infinity = stdlib.Infinity; " \
|
|
|
|
"var NaN = stdlib.NaN; " \
|
|
|
|
"var acos = stdlib.Math.acos; " \
|
|
|
|
"var asin = stdlib.Math.asin; " \
|
|
|
|
"var atan = stdlib.Math.atan; " \
|
|
|
|
"var cos = stdlib.Math.cos; " \
|
|
|
|
"var sin = stdlib.Math.sin; " \
|
|
|
|
"var tan = stdlib.Math.tan; " \
|
|
|
|
"var exp = stdlib.Math.exp; " \
|
|
|
|
"var log = stdlib.Math.log; " \
|
|
|
|
"var ceil = stdlib.Math.ceil; " \
|
|
|
|
"var floor = stdlib.Math.floor; " \
|
|
|
|
"var sqrt = stdlib.Math.sqrt; " \
|
|
|
|
"var min = stdlib.Math.min; " \
|
|
|
|
"var max = stdlib.Math.max; " \
|
|
|
|
"var atan2 = stdlib.Math.atan2; " \
|
|
|
|
"var pow = stdlib.Math.pow; " \
|
|
|
|
"var abs = stdlib.Math.abs; " \
|
|
|
|
"var imul = stdlib.Math.imul; " \
|
|
|
|
"var fround = stdlib.Math.fround; " \
|
|
|
|
"var E = stdlib.Math.E; " \
|
|
|
|
"var LN10 = stdlib.Math.LN10; " \
|
|
|
|
"var LN2 = stdlib.Math.LN2; " \
|
|
|
|
"var LOG2E = stdlib.Math.LOG2E; " \
|
|
|
|
"var LOG10E = stdlib.Math.LOG10E; " \
|
|
|
|
"var PI = stdlib.Math.PI; " \
|
|
|
|
"var SQRT1_2 = stdlib.Math.SQRT1_2; " \
|
|
|
|
"var SQRT2 = stdlib.Math.SQRT2; "
|
|
|
|
|
|
|
|
#define HARNESS_HEAP() \
|
|
|
|
"var u8 = new stdlib.Uint8Array(buffer); " \
|
|
|
|
"var i8 = new stdlib.Int8Array(buffer); " \
|
|
|
|
"var u16 = new stdlib.Uint16Array(buffer); " \
|
|
|
|
"var i16 = new stdlib.Int16Array(buffer); " \
|
|
|
|
"var u32 = new stdlib.Uint32Array(buffer); " \
|
|
|
|
"var i32 = new stdlib.Int32Array(buffer); " \
|
|
|
|
"var f32 = new stdlib.Float32Array(buffer); " \
|
|
|
|
"var f64 = new stdlib.Float64Array(buffer); "
|
|
|
|
|
|
|
|
#define HARNESS_PREAMBLE() \
|
|
|
|
const char test_function[] = \
|
|
|
|
"function Module(stdlib, foreign, buffer) { " \
|
|
|
|
"\"use asm\"; " HARNESS_STDLIB() HARNESS_HEAP()
|
2015-09-01 18:30:34 +00:00
|
|
|
|
|
|
|
#define HARNESS_POSTAMBLE() \
|
2016-03-18 23:14:17 +00:00
|
|
|
"return { foo: foo }; " \
|
|
|
|
"} ";
|
2015-09-01 18:30:34 +00:00
|
|
|
|
|
|
|
#define CHECK_VAR_MATH_SHORTCUT(name, type) \
|
|
|
|
CHECK_EXPR(Assignment, type) { \
|
|
|
|
CHECK_VAR(name, type); \
|
|
|
|
CHECK_EXPR(Property, type) { \
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) { \
|
|
|
|
CHECK_VAR(stdlib, Bounds::Unbounded()); \
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded()); \
|
|
|
|
} \
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded()); \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define CHECK_VAR_SHORTCUT(name, type) \
|
|
|
|
CHECK_EXPR(Assignment, type) { \
|
|
|
|
CHECK_VAR(name, type); \
|
|
|
|
CHECK_EXPR(Property, type) { \
|
|
|
|
CHECK_VAR(stdlib, Bounds::Unbounded()); \
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded()); \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define CHECK_VAR_NEW_SHORTCUT(name, type) \
|
|
|
|
CHECK_EXPR(Assignment, type) { \
|
|
|
|
CHECK_VAR(name, type); \
|
|
|
|
CHECK_EXPR(CallNew, type) { \
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) { \
|
|
|
|
CHECK_VAR(stdlib, Bounds::Unbounded()); \
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded()); \
|
|
|
|
} \
|
|
|
|
CHECK_VAR(buffer, Bounds::Unbounded()); \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2015-12-03 16:46:54 +00:00
|
|
|
void CheckStdlibShortcuts1(Zone* zone, ZoneVector<ExpressionTypeEntry>& types,
|
|
|
|
size_t& index, int& depth, TypeCache& cache) {
|
2015-12-09 04:27:51 +00:00
|
|
|
// var exp = stdlib.*;
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_VAR_SHORTCUT(Infinity, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_VAR_SHORTCUT(NaN, Bounds(cache.kAsmDouble));
|
2015-12-09 04:27:51 +00:00
|
|
|
// var x = stdlib.Math.x;
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR_MATH_SHORTCUT(acos, FUNC_D2D_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(asin, FUNC_D2D_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(atan, FUNC_D2D_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(cos, FUNC_D2D_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(sin, FUNC_D2D_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(tan, FUNC_D2D_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(exp, FUNC_D2D_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(log, FUNC_D2D_TYPE);
|
2015-12-09 04:27:51 +00:00
|
|
|
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(ceil, FUNC_N2N_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(floor, FUNC_N2N_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(sqrt, FUNC_N2N_TYPE);
|
|
|
|
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(min, FUNC_NN2N_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(max, FUNC_NN2N_TYPE);
|
|
|
|
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR_MATH_SHORTCUT(atan2, FUNC_DD2D_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(pow, FUNC_DD2D_TYPE);
|
2015-12-09 04:27:51 +00:00
|
|
|
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR_MATH_SHORTCUT(abs, FUNC_N2N_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(imul, FUNC_II2I_TYPE);
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(fround, FUNC_N2F_TYPE);
|
2015-12-03 16:46:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CheckStdlibShortcuts2(Zone* zone, ZoneVector<ExpressionTypeEntry>& types,
|
|
|
|
size_t& index, int& depth, TypeCache& cache) {
|
2015-09-01 18:30:34 +00:00
|
|
|
// var exp = stdlib.Math.*; (D * 12)
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_VAR_MATH_SHORTCUT(E, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(LN10, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(LN2, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(LOG2E, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(LOG10E, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(PI, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(SQRT1_2, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_VAR_MATH_SHORTCUT(SQRT2, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
// var values = new stdlib.*Array(buffer);
|
|
|
|
CHECK_VAR_NEW_SHORTCUT(u8, Bounds(cache.kUint8Array));
|
|
|
|
CHECK_VAR_NEW_SHORTCUT(i8, Bounds(cache.kInt8Array));
|
|
|
|
CHECK_VAR_NEW_SHORTCUT(u16, Bounds(cache.kUint16Array));
|
|
|
|
CHECK_VAR_NEW_SHORTCUT(i16, Bounds(cache.kInt16Array));
|
|
|
|
CHECK_VAR_NEW_SHORTCUT(u32, Bounds(cache.kUint32Array));
|
|
|
|
CHECK_VAR_NEW_SHORTCUT(i32, Bounds(cache.kInt32Array));
|
|
|
|
CHECK_VAR_NEW_SHORTCUT(f32, Bounds(cache.kFloat32Array));
|
|
|
|
CHECK_VAR_NEW_SHORTCUT(f64, Bounds(cache.kFloat64Array));
|
|
|
|
}
|
2015-09-30 13:46:56 +00:00
|
|
|
|
|
|
|
} // namespace
|
2015-09-01 18:30:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
#define CHECK_FUNC_TYPES_BEGIN(func) \
|
|
|
|
HARNESS_PREAMBLE() \
|
|
|
|
func "\n" HARNESS_POSTAMBLE(); \
|
|
|
|
\
|
|
|
|
v8::V8::Initialize(); \
|
|
|
|
HandleAndZoneScope handles; \
|
|
|
|
Zone* zone = handles.main_zone(); \
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone); \
|
|
|
|
CHECK_EQ("", Validate(zone, test_function, &types)); \
|
2015-10-28 13:31:10 +00:00
|
|
|
TypeCache cache; \
|
2015-09-01 18:30:34 +00:00
|
|
|
\
|
|
|
|
CHECK_TYPES_BEGIN { \
|
|
|
|
/* Module. */ \
|
|
|
|
CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
|
2015-12-03 16:46:54 +00:00
|
|
|
#define CHECK_FUNC_TYPES_END_1() \
|
|
|
|
/* "use asm"; */ \
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(Type::String())); \
|
2015-12-03 16:46:54 +00:00
|
|
|
/* stdlib shortcuts. */ \
|
|
|
|
CheckStdlibShortcuts1(zone, types, index, depth, cache); \
|
|
|
|
CheckStdlibShortcuts2(zone, types, index, depth, cache);
|
2015-09-01 18:30:34 +00:00
|
|
|
|
|
|
|
#define CHECK_FUNC_TYPES_END_2() \
|
|
|
|
/* return { foo: foo }; */ \
|
|
|
|
CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) { \
|
|
|
|
CHECK_VAR(foo, FUNC_V_TYPE); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
CHECK_TYPES_END
|
|
|
|
|
|
|
|
|
|
|
|
#define CHECK_FUNC_TYPES_END \
|
|
|
|
CHECK_FUNC_TYPES_END_1(); \
|
|
|
|
CHECK_FUNC_TYPES_END_2();
|
|
|
|
|
|
|
|
|
|
|
|
#define CHECK_FUNC_ERROR(func, message) \
|
|
|
|
HARNESS_PREAMBLE() \
|
|
|
|
func "\n" HARNESS_POSTAMBLE(); \
|
|
|
|
\
|
|
|
|
v8::V8::Initialize(); \
|
|
|
|
HandleAndZoneScope handles; \
|
|
|
|
Zone* zone = handles.main_zone(); \
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone); \
|
|
|
|
CHECK_EQ(message, Validate(zone, test_function, &types));
|
|
|
|
|
|
|
|
|
|
|
|
TEST(BareHarness) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN("function foo() {}") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(ReturnVoid) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { return; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
// return undefined;
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(Type::Undefined()));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(Type::Undefined())) {
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR(bar, FUNC_V_TYPE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-03 00:29:15 +00:00
|
|
|
TEST(EmptyBody) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE);
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(Type::Undefined())) {
|
2015-11-03 00:29:15 +00:00
|
|
|
CHECK_VAR(bar, FUNC_V_TYPE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(DoesNothing) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1.0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(Type::Undefined())) {
|
2015-11-03 00:29:15 +00:00
|
|
|
CHECK_VAR(bar, FUNC_V_TYPE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-01 18:30:34 +00:00
|
|
|
TEST(ReturnInt32Literal) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { return 1; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
|
|
|
// return 1;
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(bar, FUNC_I_TYPE);
|
|
|
|
}
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(ReturnFloat64Literal) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { return 1.0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
|
|
|
|
// return 1.0;
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(bar, FUNC_D_TYPE);
|
|
|
|
}
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(ReturnFloat32Literal) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { return fround(1.0); }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) {
|
|
|
|
// return fround(1.0);
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { CHECK_VAR(bar, FUNC_F_TYPE); }
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(ReturnFloat64Var) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1.0; return +x; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
|
|
|
|
// return 1.0;
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
// return 1.0;
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(bar, FUNC_D_TYPE);
|
|
|
|
}
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(Addition2) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 2; return (x+y)|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-17 19:42:01 +00:00
|
|
|
#define TEST_COMPARE_OP(name, op) \
|
|
|
|
TEST(name) { \
|
|
|
|
CHECK_FUNC_TYPES_BEGIN("function bar() { return (0 " op \
|
|
|
|
" 0)|0; }\n" \
|
|
|
|
"function foo() { bar(); }") { \
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { \
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { \
|
|
|
|
CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { \
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
|
|
|
|
} \
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
CHECK_SKIP(); \
|
|
|
|
} \
|
|
|
|
CHECK_FUNC_TYPES_END \
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST_COMPARE_OP(EqOperator, "==")
|
|
|
|
TEST_COMPARE_OP(LtOperator, "<")
|
|
|
|
TEST_COMPARE_OP(LteOperator, "<=")
|
|
|
|
TEST_COMPARE_OP(GtOperator, ">")
|
|
|
|
TEST_COMPARE_OP(GteOperator, ">=")
|
|
|
|
|
|
|
|
|
|
|
|
TEST(NeqOperator) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { return (0 != 0)|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(UnaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(NotOperator) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 0; return (!x)|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(UnaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(InvertOperator) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 0; return (~x)|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(InvertConversion) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 0.0; return (~~x)|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(Ternary) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 1; return (x?y:5)|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(Conditional, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define TEST_INT_BIN_OP(name, op) \
|
|
|
|
TEST(name) { \
|
|
|
|
CHECK_FUNC_TYPES_BEGIN("function bar() { var x = 0; return (x " op \
|
|
|
|
" 123)|0; }\n" \
|
|
|
|
"function foo() { bar(); }") { \
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { \
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { \
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt)); \
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
|
2015-11-11 22:34:13 +00:00
|
|
|
} \
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { \
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { \
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt)); \
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
|
2015-11-11 22:34:13 +00:00
|
|
|
} \
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \
|
2015-11-11 22:34:13 +00:00
|
|
|
} \
|
|
|
|
} \
|
|
|
|
CHECK_SKIP(); \
|
|
|
|
} \
|
|
|
|
CHECK_FUNC_TYPES_END \
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST_INT_BIN_OP(AndOperator, "&")
|
|
|
|
TEST_INT_BIN_OP(OrOperator, "|")
|
|
|
|
TEST_INT_BIN_OP(XorOperator, "^")
|
|
|
|
|
|
|
|
|
2015-11-30 21:11:35 +00:00
|
|
|
TEST(SignedCompare) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 1; return ((x|0) < (y|0))|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(SignedCompareConst) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 1; return ((x|0) < (1<<31))|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-03 00:29:15 +00:00
|
|
|
TEST(UnsignedCompare) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 1; return ((x>>>0) < (y>>>0))|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-30 21:11:35 +00:00
|
|
|
TEST(UnsignedCompareConst0) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 1; return ((x>>>0) < (0>>>0))|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(UnsignedCompareConst1) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 1; return ((x>>>0) < "
|
|
|
|
"(0xffffffff>>>0))|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmUnsigned));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-03 00:29:15 +00:00
|
|
|
TEST(UnsignedDivide) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 1; return ((x>>>0) / (y>>>0))|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(Type::None(), Type::Any())) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-03 22:46:40 +00:00
|
|
|
TEST(UnsignedFromFloat64) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1.0; return (x>>>0)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: left bitwise operand expected to be an integer\n");
|
2015-11-17 19:42:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(AndFloat64) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1.0; return (x&0)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: left bitwise operand expected to be an integer\n");
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(TypeMismatchAddInt32Float64) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1.0; var y = 0; return (x + y)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: ill-typed arithmetic operation\n");
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(TypeMismatchSubInt32Float64) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1.0; var y = 0; return (x - y)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: ill-typed arithmetic operation\n");
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(TypeMismatchDivInt32Float64) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1.0; var y = 0; return (x / y)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: ill-typed arithmetic operation\n");
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(TypeMismatchModInt32Float64) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1.0; var y = 0; return (x % y)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: ill-typed arithmetic operation\n");
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(ModFloat32) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = fround(1.0); return (x % x)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: ill-typed arithmetic operation\n");
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(TernaryMismatchInt32Float64) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1; var y = 0.0; return (1 ? x : y)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: then and else expressions in ? must have the same type\n");
|
2015-11-17 19:42:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(TernaryMismatchIntish) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1; var y = 0; return (1 ? x + x : y)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: invalid type in ? then expression\n");
|
2015-11-17 19:42:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(TernaryMismatchInt32Float32) {
|
|
|
|
CHECK_FUNC_ERROR(
|
Fix conversion to float32, typing issue, split apart asm-wasm tests.
Add missing conversions from other types to f32 in fround.
Restrict fround() to only float, double, signed, unsigned (no unions / intish).
Restrict Bitwise operations to intish, particularly |0, when not applied to a foreign function.
Adding more exhaustive tests of stdlib Math, move to a separate file.
Adding tests of interesting values for the stdlib asm.js functions.
BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
TEST=test-asm-validator,asm-wasm
R=titzer@chromium.org,rossberg@chromium.org
LOG=N
Review URL: https://codereview.chromium.org/1804243003
Cr-Commit-Position: refs/heads/master@{#34967}
2016-03-21 20:33:52 +00:00
|
|
|
"function bar() { var x = 1; var y = 2.0; return (x?fround(y):x)|0; }\n"
|
2015-11-17 19:42:01 +00:00
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: then and else expressions in ? must have the same type\n");
|
2015-11-17 19:42:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(TernaryBadCondition) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1; var y = 2.0; return (y?x:1)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: condition must be of type int\n");
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
|
|
|
|
2016-02-23 19:03:50 +00:00
|
|
|
TEST(BadIntishMultiply) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1; return ((x + x) * 4) | 0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: intish not allowed in multiply\n");
|
2016-02-23 19:03:50 +00:00
|
|
|
}
|
2015-11-03 22:46:40 +00:00
|
|
|
|
Fix conversion to float32, typing issue, split apart asm-wasm tests.
Add missing conversions from other types to f32 in fround.
Restrict fround() to only float, double, signed, unsigned (no unions / intish).
Restrict Bitwise operations to intish, particularly |0, when not applied to a foreign function.
Adding more exhaustive tests of stdlib Math, move to a separate file.
Adding tests of interesting values for the stdlib asm.js functions.
BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
TEST=test-asm-validator,asm-wasm
R=titzer@chromium.org,rossberg@chromium.org
LOG=N
Review URL: https://codereview.chromium.org/1804243003
Cr-Commit-Position: refs/heads/master@{#34967}
2016-03-21 20:33:52 +00:00
|
|
|
TEST(IntToFloat32) {
|
|
|
|
CHECK_FUNC_ERROR(
|
2015-11-03 00:29:15 +00:00
|
|
|
"function bar() { var x = 1; return fround(x); }\n"
|
Fix conversion to float32, typing issue, split apart asm-wasm tests.
Add missing conversions from other types to f32 in fround.
Restrict fround() to only float, double, signed, unsigned (no unions / intish).
Restrict Bitwise operations to intish, particularly |0, when not applied to a foreign function.
Adding more exhaustive tests of stdlib Math, move to a separate file.
Adding tests of interesting values for the stdlib asm.js functions.
BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
TEST=test-asm-validator,asm-wasm
R=titzer@chromium.org,rossberg@chromium.org
LOG=N
Review URL: https://codereview.chromium.org/1804243003
Cr-Commit-Position: refs/heads/master@{#34967}
2016-03-21 20:33:52 +00:00
|
|
|
"function foo() { bar(); }",
|
|
|
|
"asm: line 1: illegal function argument type\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Int32ToFloat32) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; return fround(x|0); }\n"
|
2015-11-03 00:29:15 +00:00
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
2015-11-03 00:29:15 +00:00
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
Fix conversion to float32, typing issue, split apart asm-wasm tests.
Add missing conversions from other types to f32 in fround.
Restrict fround() to only float, double, signed, unsigned (no unions / intish).
Restrict Bitwise operations to intish, particularly |0, when not applied to a foreign function.
Adding more exhaustive tests of stdlib Math, move to a separate file.
Adding tests of interesting values for the stdlib asm.js functions.
BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
TEST=test-asm-validator,asm-wasm
R=titzer@chromium.org,rossberg@chromium.org
LOG=N
Review URL: https://codereview.chromium.org/1804243003
Cr-Commit-Position: refs/heads/master@{#34967}
2016-03-21 20:33:52 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Uint32ToFloat32) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; return fround(x>>>0); }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
Fix conversion to float32, typing issue, split apart asm-wasm tests.
Add missing conversions from other types to f32 in fround.
Restrict fround() to only float, double, signed, unsigned (no unions / intish).
Restrict Bitwise operations to intish, particularly |0, when not applied to a foreign function.
Adding more exhaustive tests of stdlib Math, move to a separate file.
Adding tests of interesting values for the stdlib asm.js functions.
BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
TEST=test-asm-validator,asm-wasm
R=titzer@chromium.org,rossberg@chromium.org
LOG=N
Review URL: https://codereview.chromium.org/1804243003
Cr-Commit-Position: refs/heads/master@{#34967}
2016-03-21 20:33:52 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
Fix conversion to float32, typing issue, split apart asm-wasm tests.
Add missing conversions from other types to f32 in fround.
Restrict fround() to only float, double, signed, unsigned (no unions / intish).
Restrict Bitwise operations to intish, particularly |0, when not applied to a foreign function.
Adding more exhaustive tests of stdlib Math, move to a separate file.
Adding tests of interesting values for the stdlib asm.js functions.
BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
TEST=test-asm-validator,asm-wasm
R=titzer@chromium.org,rossberg@chromium.org
LOG=N
Review URL: https://codereview.chromium.org/1804243003
Cr-Commit-Position: refs/heads/master@{#34967}
2016-03-21 20:33:52 +00:00
|
|
|
TEST(Float64ToFloat32) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1.0; return fround(x); }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Int32ToFloat32ToInt32) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; return ~~fround(x|0) | 0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
2015-11-03 00:29:15 +00:00
|
|
|
|
2015-09-01 18:30:34 +00:00
|
|
|
TEST(Addition4) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 2; return (x+y+x+y)|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(Multiplication2) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1; var y = 2; return (x*y)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: multiply must be by an integer literal\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(Division4) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1; var y = 2; return (x/y/x/y)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: too many consecutive multiplicative ops\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-17 19:42:01 +00:00
|
|
|
TEST(CompareToStringLeft) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1; return ('hi' > x)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: bad type on left side of comparison\n");
|
2015-11-17 19:42:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(CompareToStringRight) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1; return (x < 'hi')|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: bad type on right side of comparison\n");
|
2015-11-17 19:42:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-03 00:29:15 +00:00
|
|
|
TEST(CompareMismatchInt32Float64) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1; var y = 2.0; return (x < y)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: left and right side of comparison must match\n");
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(CompareMismatchInt32Uint32) {
|
|
|
|
CHECK_FUNC_ERROR(
|
2015-11-17 19:42:01 +00:00
|
|
|
"function bar() { var x = 1; var y = 2; return ((x|0) < (y>>>0))|0; }\n"
|
2015-11-03 00:29:15 +00:00
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: left and right side of comparison must match\n");
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(CompareMismatchInt32Float32) {
|
|
|
|
CHECK_FUNC_ERROR(
|
Fix conversion to float32, typing issue, split apart asm-wasm tests.
Add missing conversions from other types to f32 in fround.
Restrict fround() to only float, double, signed, unsigned (no unions / intish).
Restrict Bitwise operations to intish, particularly |0, when not applied to a foreign function.
Adding more exhaustive tests of stdlib Math, move to a separate file.
Adding tests of interesting values for the stdlib asm.js functions.
BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
TEST=test-asm-validator,asm-wasm
R=titzer@chromium.org,rossberg@chromium.org
LOG=N
Review URL: https://codereview.chromium.org/1804243003
Cr-Commit-Position: refs/heads/master@{#34967}
2016-03-21 20:33:52 +00:00
|
|
|
"function bar() { var x = 1; var y = 2.0; return (x < fround(y))|0; }\n"
|
2015-11-03 00:29:15 +00:00
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: left and right side of comparison must match\n");
|
2015-11-03 00:29:15 +00:00
|
|
|
}
|
|
|
|
|
2016-06-06 13:40:11 +00:00
|
|
|
TEST(FunctionRepeated) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function foo() { return 0; }\n"
|
|
|
|
"function foo() { return 0; }",
|
|
|
|
"asm: line 2: function repeated in module\n");
|
|
|
|
}
|
2015-11-03 00:29:15 +00:00
|
|
|
|
2015-11-03 22:46:40 +00:00
|
|
|
TEST(Float64ToInt32) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 0.0; x = ~~y; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
2015-11-03 22:46:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-01 18:30:34 +00:00
|
|
|
TEST(Load1) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = i8[x>>0]|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
2015-11-30 21:11:35 +00:00
|
|
|
CHECK_EXPR(Property, Bounds(cache.kAsmInt)) {
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR(i8, Bounds(cache.kInt8Array));
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
2016-02-13 06:20:56 +00:00
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-30 21:11:35 +00:00
|
|
|
TEST(LoadDouble) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 0.0; y = +f64[x>>3]; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_EXPR(Property, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(f64, Bounds(cache.kFloat64Array));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmSigned));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(Store1) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; i8[x>>0] = 0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(i8, Bounds(cache.kInt8Array));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
2016-02-13 06:20:56 +00:00
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
2015-11-30 21:11:35 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(StoreFloat) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = fround(1.0); "
|
|
|
|
"f32[0] = fround(x + fround(1.0)); }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmFloat));
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(f32, Bounds(cache.kFloat32Array));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmFloat));
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
2016-02-23 06:18:37 +00:00
|
|
|
TEST(StoreIntish) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = 1; i32[0] = x + y; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(i32, Bounds(cache.kInt32Array));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(StoreFloatish) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { "
|
|
|
|
"var x = fround(1.0); "
|
|
|
|
"var y = fround(1.0); f32[0] = x + y; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmFloat));
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmFloat));
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(f32, Bounds(cache.kFloat32Array));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmFloat));
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmFloat));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
2015-11-30 21:11:35 +00:00
|
|
|
|
2015-11-10 01:59:42 +00:00
|
|
|
TEST(Load1Constant) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 1; var y = i8[5]|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-10 01:59:42 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
2015-11-30 21:11:35 +00:00
|
|
|
CHECK_EXPR(Property, Bounds(cache.kAsmInt)) {
|
2015-11-10 01:59:42 +00:00
|
|
|
CHECK_VAR(i8, Bounds(cache.kInt8Array));
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-10 01:59:42 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-11-10 01:59:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-01 18:30:34 +00:00
|
|
|
TEST(FunctionTables) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function func1(x) { x = x | 0; return (x * 5) | 0; }\n"
|
|
|
|
"function func2(x) { x = x | 0; return (x * 25) | 0; }\n"
|
|
|
|
"var table1 = [func1, func2];\n"
|
|
|
|
"function bar(x, y) { x = x | 0; y = y | 0;\n"
|
|
|
|
" return table1[x & 1](y)|0; }\n"
|
|
|
|
"function foo() { bar(1, 2); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_II2I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_EXPR(Property, FUNC_I2I_TYPE) {
|
|
|
|
CHECK_VAR(table1, FUNC_I2I_ARRAY_TYPE);
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
2016-01-20 23:36:42 +00:00
|
|
|
// TODO(bradnelson): revert this
|
|
|
|
// CHECK_VAR(x, Bounds(cache.kAsmSigned));
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_VAR(y, Bounds(cache.kAsmInt));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END_1();
|
|
|
|
CHECK_EXPR(Assignment, FUNC_I2I_ARRAY_TYPE) {
|
|
|
|
CHECK_VAR(table1, FUNC_I2I_ARRAY_TYPE);
|
|
|
|
CHECK_EXPR(ArrayLiteral, FUNC_I2I_ARRAY_TYPE) {
|
|
|
|
CHECK_VAR(func1, FUNC_I2I_TYPE);
|
|
|
|
CHECK_VAR(func2, FUNC_I2I_TYPE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END_2();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(BadFunctionTable) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function func1(x) { x = x | 0; return (x * 5) | 0; }\n"
|
|
|
|
"var table1 = [func1, 1];\n"
|
|
|
|
"function bar(x, y) { x = x | 0; y = y | 0;\n"
|
|
|
|
" return table1[x & 1](y)|0; }\n"
|
|
|
|
"function foo() { bar(1, 2); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 2: array component expected to be a function\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(MissingParameterTypes) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar(x) { var y = 1; }\n"
|
|
|
|
"function foo() { bar(2); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: missing parameter type annotations\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(InvalidTypeAnnotationBinaryOpDiv) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar(x) { x = x / 4; }\n"
|
|
|
|
"function foo() { bar(2); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: invalid type annotation on binary op\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(InvalidTypeAnnotationBinaryOpMul) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar(x) { x = x * 4.0; }\n"
|
|
|
|
"function foo() { bar(2); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: invalid type annotation on binary op\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(InvalidArgumentCount) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar(x) { return fround(4, 5); }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: invalid argument count calling function\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(InvalidTypeAnnotationArity) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar(x) { x = max(x); }\n"
|
|
|
|
"function foo() { bar(3); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: only fround allowed on expression annotations\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(InvalidTypeAnnotationOnlyFround) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar(x) { x = sin(x); }\n"
|
|
|
|
"function foo() { bar(3); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: only fround allowed on expression annotations\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(InvalidTypeAnnotation) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar(x) { x = (x+x)(x); }\n"
|
|
|
|
"function foo() { bar(3); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: invalid type annotation\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(WithStatement) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 0; with (x) { x = x + 1; } }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: bad with statement\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(NestedFunction) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { function x() { return 1; } }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: function declared inside another\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(UnboundVariable) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = y; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: unbound variable\n");
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-11 22:34:13 +00:00
|
|
|
TEST(EqStrict) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { return (0 === 0)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: illegal comparison operator\n");
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(NeStrict) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { return (0 !== 0)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: illegal comparison operator\n");
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(InstanceOf) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { return (0 instanceof 0)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-05-17 11:23:59 +00:00
|
|
|
"asm: line 1: illegal comparison operator\n");
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(InOperator) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { return (0 in 0)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: illegal comparison operator\n");
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(LogicalAndOperator) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { return (0 && 0)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: illegal logical operator\n");
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(LogicalOrOperator) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { return (0 || 0)|0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: illegal logical operator\n");
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
|
Fix conversion to float32, typing issue, split apart asm-wasm tests.
Add missing conversions from other types to f32 in fround.
Restrict fround() to only float, double, signed, unsigned (no unions / intish).
Restrict Bitwise operations to intish, particularly |0, when not applied to a foreign function.
Adding more exhaustive tests of stdlib Math, move to a separate file.
Adding tests of interesting values for the stdlib asm.js functions.
BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
TEST=test-asm-validator,asm-wasm
R=titzer@chromium.org,rossberg@chromium.org
LOG=N
Review URL: https://codereview.chromium.org/1804243003
Cr-Commit-Position: refs/heads/master@{#34967}
2016-03-21 20:33:52 +00:00
|
|
|
TEST(BitOrDouble) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1.0; return x | 0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
|
|
|
"asm: line 1: intish required\n");
|
|
|
|
}
|
2015-11-11 22:34:13 +00:00
|
|
|
|
|
|
|
TEST(BadLiteral) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { return true | 0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: illegal literal\n");
|
2015-11-11 22:34:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-18 19:47:21 +00:00
|
|
|
TEST(MismatchedReturnTypeLiteral) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { if(1) { return 1; } return 1.0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: return type does not match function signature\n");
|
2015-11-18 19:47:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(MismatchedReturnTypeExpression) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() {\n"
|
|
|
|
" var x = 1; var y = 1.0; if(1) { return x; } return +y; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 2: return type does not match function signature\n");
|
2015-11-18 19:47:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-30 21:11:35 +00:00
|
|
|
TEST(AssignToFloatishToF64) {
|
|
|
|
CHECK_FUNC_ERROR(
|
2016-02-23 06:18:37 +00:00
|
|
|
"function bar() { var v = fround(1.0); f64[0] = v + fround(1.0); }\n"
|
2015-11-30 21:11:35 +00:00
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: floatish assignment to double array\n");
|
2015-11-30 21:11:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-01 18:30:34 +00:00
|
|
|
TEST(ForeignFunction) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"var baz = foreign.baz;\n"
|
|
|
|
"function bar() { return baz(1, 2)|0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
2016-01-29 22:32:38 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
|
2016-02-03 01:20:22 +00:00
|
|
|
CHECK_VAR(baz, FUNC_FOREIGN_TYPE);
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(bar, FUNC_I_TYPE);
|
|
|
|
}
|
2015-09-01 18:30:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END_1()
|
2016-02-03 01:20:22 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(FUNC_FOREIGN_TYPE)) {
|
|
|
|
CHECK_VAR(baz, Bounds(FUNC_FOREIGN_TYPE));
|
|
|
|
CHECK_EXPR(Property, Bounds(FUNC_FOREIGN_TYPE)) {
|
2015-09-01 18:30:34 +00:00
|
|
|
CHECK_VAR(foreign, Bounds::Unbounded());
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END_2()
|
|
|
|
}
|
|
|
|
|
2016-02-13 06:20:56 +00:00
|
|
|
TEST(ByteArray) {
|
|
|
|
// Forbidden by asm.js spec, present in embenchen.
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 0; i8[x] = 2; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(i8, Bounds(cache.kInt8Array));
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmSigned));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
2015-09-01 18:30:34 +00:00
|
|
|
|
|
|
|
TEST(BadExports) {
|
|
|
|
HARNESS_PREAMBLE()
|
|
|
|
"function foo() {};\n"
|
|
|
|
"return {foo: foo, bar: 1};"
|
|
|
|
"}\n";
|
|
|
|
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
2016-03-18 23:14:17 +00:00
|
|
|
CHECK_EQ("asm: line 2: non-function in function table\n",
|
2015-09-01 18:30:34 +00:00
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
2015-11-17 19:42:01 +00:00
|
|
|
|
|
|
|
|
2015-11-30 21:11:35 +00:00
|
|
|
TEST(NestedHeapAssignment) {
|
|
|
|
CHECK_FUNC_ERROR(
|
2016-02-13 06:20:56 +00:00
|
|
|
"function bar() { var x = 0; i16[x = 1] = 2; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: expected >> in heap access\n");
|
2016-02-13 06:20:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(BadOperatorHeapAssignment) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 0; i16[x & 1] = 2; }\n"
|
2015-11-30 21:11:35 +00:00
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: expected >> in heap access\n");
|
2015-11-30 21:11:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(BadArrayAssignment) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { i8[0] = 0.0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: illegal type in assignment\n");
|
2015-11-30 21:11:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-12-09 04:27:51 +00:00
|
|
|
TEST(BadStandardFunctionCallOutside) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"var s0 = sin(0);\n"
|
|
|
|
"function bar() { }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: illegal variable reference in module body\n");
|
2015-12-09 04:27:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(BadFunctionCallOutside) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { return 0.0; }\n"
|
|
|
|
"var s0 = bar(0);\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 2: illegal variable reference in module body\n");
|
2015-12-09 04:27:51 +00:00
|
|
|
}
|
|
|
|
|
2016-03-23 23:19:54 +00:00
|
|
|
TEST(UnaryPlusOnIntForbidden) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 1; return +x; }\n"
|
|
|
|
"function foo() { bar(); }",
|
|
|
|
"asm: line 1: "
|
|
|
|
"unary + only allowed on signed, unsigned, float?, or double?\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MultiplyNon1ConvertForbidden) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { var x = 0.0; return x * 2.0; }\n"
|
|
|
|
"function foo() { bar(); }",
|
|
|
|
"asm: line 1: invalid type annotation on binary op\n");
|
|
|
|
}
|
2015-12-09 04:27:51 +00:00
|
|
|
|
2015-11-30 21:11:35 +00:00
|
|
|
TEST(NestedVariableAssignment) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 0; x = x = 4; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(NestedAssignmentInHeap) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 0; i8[(x = 1) >> 0] = 2; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(i8, Bounds(cache.kInt8Array));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
2016-01-29 22:32:38 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
2015-11-30 21:11:35 +00:00
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-12-03 18:14:08 +00:00
|
|
|
TEST(NegativeDouble) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = -123.2; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(NegativeInteger) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = -123; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-12-09 04:27:51 +00:00
|
|
|
TEST(AbsFunction) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = -123.0; x = abs(x); }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(abs, FUNC_N2N_TYPE);
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(CeilFloat) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = fround(3.1); x = ceil(x); }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmFloat));
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmFloat));
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(ceil, FUNC_N2N_TYPE);
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmFloat));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
|
|
|
|
2016-03-14 17:29:08 +00:00
|
|
|
TEST(FloatReturnAsDouble) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = fround(3.1); return +fround(x); }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmFloat));
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) {
|
|
|
|
CHECK_VAR(fround, FUNC_N2F_TYPE);
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmFloat));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
2015-12-09 04:27:51 +00:00
|
|
|
|
2015-11-17 19:42:01 +00:00
|
|
|
TEST(TypeConsistency) {
|
|
|
|
v8::V8::Initialize();
|
|
|
|
TypeCache cache;
|
2015-11-18 19:47:21 +00:00
|
|
|
// Check the consistency of each of the main Asm.js types.
|
|
|
|
CHECK(cache.kAsmFixnum->Is(cache.kAsmFixnum));
|
|
|
|
CHECK(cache.kAsmFixnum->Is(cache.kAsmSigned));
|
|
|
|
CHECK(cache.kAsmFixnum->Is(cache.kAsmUnsigned));
|
|
|
|
CHECK(cache.kAsmFixnum->Is(cache.kAsmInt));
|
|
|
|
CHECK(!cache.kAsmFixnum->Is(cache.kAsmFloat));
|
|
|
|
CHECK(!cache.kAsmFixnum->Is(cache.kAsmDouble));
|
|
|
|
|
|
|
|
CHECK(cache.kAsmSigned->Is(cache.kAsmSigned));
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK(cache.kAsmSigned->Is(cache.kAsmInt));
|
2015-11-18 19:47:21 +00:00
|
|
|
CHECK(!cache.kAsmSigned->Is(cache.kAsmFixnum));
|
|
|
|
CHECK(!cache.kAsmSigned->Is(cache.kAsmUnsigned));
|
|
|
|
CHECK(!cache.kAsmSigned->Is(cache.kAsmFloat));
|
2015-11-17 19:42:01 +00:00
|
|
|
CHECK(!cache.kAsmSigned->Is(cache.kAsmDouble));
|
2015-11-18 19:47:21 +00:00
|
|
|
|
|
|
|
CHECK(cache.kAsmUnsigned->Is(cache.kAsmUnsigned));
|
|
|
|
CHECK(cache.kAsmUnsigned->Is(cache.kAsmInt));
|
|
|
|
CHECK(!cache.kAsmUnsigned->Is(cache.kAsmSigned));
|
|
|
|
CHECK(!cache.kAsmUnsigned->Is(cache.kAsmFixnum));
|
|
|
|
CHECK(!cache.kAsmUnsigned->Is(cache.kAsmFloat));
|
|
|
|
CHECK(!cache.kAsmUnsigned->Is(cache.kAsmDouble));
|
|
|
|
|
|
|
|
CHECK(cache.kAsmInt->Is(cache.kAsmInt));
|
|
|
|
CHECK(!cache.kAsmInt->Is(cache.kAsmUnsigned));
|
|
|
|
CHECK(!cache.kAsmInt->Is(cache.kAsmSigned));
|
|
|
|
CHECK(!cache.kAsmInt->Is(cache.kAsmFixnum));
|
|
|
|
CHECK(!cache.kAsmInt->Is(cache.kAsmFloat));
|
|
|
|
CHECK(!cache.kAsmInt->Is(cache.kAsmDouble));
|
|
|
|
|
|
|
|
CHECK(cache.kAsmFloat->Is(cache.kAsmFloat));
|
|
|
|
CHECK(!cache.kAsmFloat->Is(cache.kAsmInt));
|
|
|
|
CHECK(!cache.kAsmFloat->Is(cache.kAsmUnsigned));
|
|
|
|
CHECK(!cache.kAsmFloat->Is(cache.kAsmSigned));
|
|
|
|
CHECK(!cache.kAsmFloat->Is(cache.kAsmFixnum));
|
|
|
|
CHECK(!cache.kAsmFloat->Is(cache.kAsmDouble));
|
|
|
|
|
|
|
|
CHECK(cache.kAsmDouble->Is(cache.kAsmDouble));
|
|
|
|
CHECK(!cache.kAsmDouble->Is(cache.kAsmInt));
|
|
|
|
CHECK(!cache.kAsmDouble->Is(cache.kAsmUnsigned));
|
|
|
|
CHECK(!cache.kAsmDouble->Is(cache.kAsmSigned));
|
|
|
|
CHECK(!cache.kAsmDouble->Is(cache.kAsmFixnum));
|
|
|
|
CHECK(!cache.kAsmDouble->Is(cache.kAsmFloat));
|
2015-11-17 19:42:01 +00:00
|
|
|
}
|
2016-01-11 20:36:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
TEST(SwitchTest) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function switcher(x) {\n"
|
|
|
|
" x = x|0;\n"
|
|
|
|
" switch (x|0) {\n"
|
|
|
|
" case 1: return 23;\n"
|
|
|
|
" case 2: return 43;\n"
|
|
|
|
" default: return 66;\n"
|
|
|
|
" }\n"
|
|
|
|
" return 0;\n"
|
|
|
|
"}\n"
|
|
|
|
"function foo() { switcher(1); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(.switch_tag, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(Type::Undefined()));
|
2016-01-11 20:36:25 +00:00
|
|
|
CHECK_VAR(.switch_tag, Bounds(cache.kAsmSigned));
|
|
|
|
// case 1: return 23;
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
|
|
|
// case 2: return 43;
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
|
|
|
// default: return 66;
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
|
|
|
// return 0;
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmSigned));
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
2016-01-12 02:09:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
TEST(BadSwitchRange) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { switch (1) { case -1: case 0x7fffffff: } }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: case range too large\n");
|
2016-01-12 02:09:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(DuplicateSwitchCase) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { switch (1) { case 0: case 0: } }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: duplicate case value\n");
|
2016-01-12 02:09:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(BadSwitchOrder) {
|
|
|
|
CHECK_FUNC_ERROR(
|
|
|
|
"function bar() { switch (1) { default: case 0: } }\n"
|
|
|
|
"function foo() { bar(); }",
|
2016-03-18 23:14:17 +00:00
|
|
|
"asm: line 1: default case out of order\n");
|
2016-01-12 02:09:33 +00:00
|
|
|
}
|
2016-01-29 22:32:38 +00:00
|
|
|
|
|
|
|
TEST(BadForeignCall) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function TestModule(stdlib, foreign, buffer) {\n"
|
|
|
|
" \"use asm\";\n"
|
|
|
|
" var ffunc = foreign.foo;\n"
|
|
|
|
" function test1() { var x = 0; ffunc(x); }\n"
|
|
|
|
" return { testFunc1: test1 };\n"
|
|
|
|
"}\n";
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ(
|
|
|
|
"asm: line 4: foreign call argument expected to be int, double, or "
|
|
|
|
"fixnum\n",
|
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(BadImports) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function TestModule(stdlib, foreign, buffer) {\n"
|
|
|
|
" \"use asm\";\n"
|
|
|
|
" var fint = (foreign.bar | 0) | 0;\n"
|
|
|
|
" function test1() {}\n"
|
|
|
|
" return { testFunc1: test1 };\n"
|
|
|
|
"}\n";
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("asm: line 3: illegal computation inside module body\n",
|
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(BadVariableReference) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function TestModule(stdlib, foreign, buffer) {\n"
|
|
|
|
" \"use asm\";\n"
|
|
|
|
" var x = 0;\n"
|
|
|
|
" var y = x;\n"
|
|
|
|
" function test1() {}\n"
|
|
|
|
" return { testFunc1: test1 };\n"
|
|
|
|
"}\n";
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("asm: line 4: illegal variable reference in module body\n",
|
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
|
|
|
|
2016-02-12 01:50:18 +00:00
|
|
|
TEST(BadForeignVariableReferenceValueOr) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function TestModule(stdlib, foreign, buffer) {\n"
|
|
|
|
" \"use asm\";\n"
|
|
|
|
" var fint = foreign.bar | 1;\n"
|
|
|
|
"}\n";
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("asm: line 3: illegal integer annotation value\n",
|
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(BadForeignVariableReferenceValueOrDot) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function TestModule(stdlib, foreign, buffer) {\n"
|
|
|
|
" \"use asm\";\n"
|
|
|
|
" var fint = foreign.bar | 1.0;\n"
|
|
|
|
"}\n";
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("asm: line 3: illegal integer annotation value\n",
|
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(BadForeignVariableReferenceValueMul) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function TestModule(stdlib, foreign, buffer) {\n"
|
|
|
|
" \"use asm\";\n"
|
|
|
|
" var fint = foreign.bar * 2.0;\n"
|
|
|
|
"}\n";
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("asm: line 3: illegal double annotation value\n",
|
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(BadForeignVariableReferenceValueMulNoDot) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function TestModule(stdlib, foreign, buffer) {\n"
|
|
|
|
" \"use asm\";\n"
|
|
|
|
" var fint = foreign.bar * 1;\n"
|
|
|
|
"}\n";
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("asm: line 3: ill-typed arithmetic operation\n",
|
|
|
|
Validate(zone, test_function, &types));
|
|
|
|
}
|
|
|
|
|
2016-01-29 22:32:38 +00:00
|
|
|
TEST(Imports) {
|
|
|
|
const char test_function[] =
|
|
|
|
"function TestModule(stdlib, foreign, buffer) {\n"
|
|
|
|
" \"use asm\";\n"
|
|
|
|
" var ffunc = foreign.foo;\n"
|
|
|
|
" var fint = foreign.bar | 0;\n"
|
|
|
|
" var fdouble = +foreign.baz;\n"
|
|
|
|
" function test1() { return ffunc(fint|0, fdouble) | 0; }\n"
|
|
|
|
" function test2() { return +ffunc(fdouble, fint|0); }\n"
|
|
|
|
" return { testFunc1: test1, testFunc2: test2 };\n"
|
|
|
|
"}\n";
|
|
|
|
|
|
|
|
v8::V8::Initialize();
|
|
|
|
HandleAndZoneScope handles;
|
|
|
|
Zone* zone = handles.main_zone();
|
|
|
|
ZoneVector<ExpressionTypeEntry> types(zone);
|
|
|
|
CHECK_EQ("", Validate(zone, test_function, &types));
|
|
|
|
TypeCache cache;
|
|
|
|
|
|
|
|
CHECK_TYPES_BEGIN {
|
|
|
|
// Module.
|
|
|
|
CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
|
|
|
|
// function test1
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
|
2016-02-03 01:20:22 +00:00
|
|
|
CHECK_VAR(ffunc, FUNC_FOREIGN_TYPE);
|
2016-01-29 22:32:38 +00:00
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(fint, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// function test2
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
|
2016-02-03 01:20:22 +00:00
|
|
|
CHECK_VAR(ffunc, FUNC_FOREIGN_TYPE);
|
2016-01-29 22:32:38 +00:00
|
|
|
CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
|
|
|
CHECK_VAR(fint, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// "use asm";
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(Literal, Bounds(Type::String()));
|
2016-01-29 22:32:38 +00:00
|
|
|
// var func = foreign.foo;
|
2016-02-03 01:20:22 +00:00
|
|
|
CHECK_EXPR(Assignment, Bounds(FUNC_FOREIGN_TYPE)) {
|
|
|
|
CHECK_VAR(ffunc, Bounds(FUNC_FOREIGN_TYPE));
|
|
|
|
CHECK_EXPR(Property, Bounds(FUNC_FOREIGN_TYPE)) {
|
2016-01-29 22:32:38 +00:00
|
|
|
CHECK_VAR(foreign, Bounds::Unbounded());
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// var fint = foreign.bar | 0;
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
|
|
|
CHECK_VAR(fint, Bounds(cache.kAsmInt));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(Property, Bounds(Type::Number())) {
|
2016-01-29 22:32:38 +00:00
|
|
|
CHECK_VAR(foreign, Bounds::Unbounded());
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded());
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// var fdouble = +foreign.baz;
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
2016-02-02 07:25:30 +00:00
|
|
|
CHECK_EXPR(Property, Bounds(Type::Number())) {
|
2016-01-29 22:32:38 +00:00
|
|
|
CHECK_VAR(foreign, Bounds::Unbounded());
|
|
|
|
CHECK_EXPR(Literal, Bounds::Unbounded());
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// return { testFunc1: test1, testFunc2: test2 };
|
|
|
|
CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(test1, FUNC_I_TYPE);
|
|
|
|
CHECK_VAR(test2, FUNC_D_TYPE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_TYPES_END
|
|
|
|
}
|
2016-03-01 18:06:23 +00:00
|
|
|
|
|
|
|
TEST(StoreFloatFromDouble) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { f32[0] = 0.0; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_EXPR(Property, Bounds::Unbounded()) {
|
|
|
|
CHECK_VAR(f32, Bounds(cache.kFloat32Array));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|
2016-03-02 23:43:29 +00:00
|
|
|
|
|
|
|
TEST(NegateDouble) {
|
|
|
|
CHECK_FUNC_TYPES_BEGIN(
|
|
|
|
"function bar() { var x = 0.0; x = -x; }\n"
|
|
|
|
"function foo() { bar(); }") {
|
|
|
|
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
|
|
|
CHECK_VAR(x, Bounds(cache.kAsmDouble));
|
|
|
|
CHECK_EXPR(Literal, Bounds(cache.kAsmDouble));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CHECK_SKIP();
|
|
|
|
}
|
|
|
|
CHECK_FUNC_TYPES_END
|
|
|
|
}
|