Commit da632baa authored by bradnelson's avatar bradnelson Committed by Commit bot

Switch to using Function(Any) for foreign functions, label declarations.

As it turns out checking for bare Type::Function is problematic,
switching to use Type::Function(Type::Any())).

Also labeling the type on foreign function declarations.

BUG= https://code.google.com/p/v8/issues/detail?id=4203
TEST=test-asm-validator
R=aseemgarg@chromium.org
LOG=N

Review URL: https://codereview.chromium.org/1652963004

Cr-Commit-Position: refs/heads/master@{#33691}
parent 3c56400e
...@@ -908,13 +908,16 @@ void AsmTyper::VisitProperty(Property* expr) { ...@@ -908,13 +908,16 @@ void AsmTyper::VisitProperty(Property* expr) {
return; return;
} }
// stdlib.x or foreign.x
VariableProxy* proxy = expr->obj()->AsVariableProxy(); VariableProxy* proxy = expr->obj()->AsVariableProxy();
if (proxy != NULL) { if (proxy != NULL) {
Variable* var = proxy->var(); Variable* var = proxy->var();
if (var->location() == VariableLocation::PARAMETER && var->index() == 1) { if (var->location() == VariableLocation::PARAMETER && var->index() == 1) {
// foreign.x is ok. // foreign.x - Function represent as () -> Any
SetResult(expr, expected_type_); if (Type::Any()->Is(expected_type_)) {
SetResult(expr, Type::Function(Type::Any(), zone()));
} else {
SetResult(expr, expected_type_);
}
return; return;
} }
} }
...@@ -942,63 +945,66 @@ void AsmTyper::VisitCall(Call* expr) { ...@@ -942,63 +945,66 @@ void AsmTyper::VisitCall(Call* expr) {
FunctionType* fun_type = computed_type_->AsFunction(); FunctionType* fun_type = computed_type_->AsFunction();
Type* result_type = fun_type->Result(); Type* result_type = fun_type->Result();
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
if (fun_type->Arity() != args->length()) { if (Type::Any()->Is(result_type)) {
FAIL(expr, "call with wrong arity"); // For foreign calls.
} ZoneList<Expression*>* args = expr->arguments();
for (int i = 0; i < args->length(); ++i) { for (int i = 0; i < args->length(); ++i) {
Expression* arg = args->at(i); Expression* arg = args->at(i);
RECURSE(VisitWithExpectation( RECURSE(VisitWithExpectation(
arg, fun_type->Parameter(i), arg, Type::Any(), "foreign call argument expected to be any"));
"call argument expected to match callee parameter")); // Checking for asm extern types explicitly, as the type system
if (standard_member != kNone && standard_member != kMathFround && // doesn't correctly check their inheritance relationship.
i == 0) { if (!computed_type_->Is(cache_.kAsmSigned) &&
result_type = computed_type_; !computed_type_->Is(cache_.kAsmFixnum) &&
} !computed_type_->Is(cache_.kAsmDouble)) {
} FAIL(arg,
// Handle polymorphic stdlib functions specially. "foreign call argument expected to be int, double, or fixnum");
if (standard_member == kMathCeil || standard_member == kMathFloor || }
standard_member == kMathSqrt) {
if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) &&
!args->at(0)->bounds().upper->Is(cache_.kAsmDouble)) {
FAIL(expr, "illegal function argument type");
} }
} else if (standard_member == kMathAbs || standard_member == kMathMin || intish_ = 0;
standard_member == kMathMax) { expr->expression()->set_bounds(
if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) && Bounds(Type::Function(Type::Any(), zone())));
!args->at(0)->bounds().upper->Is(cache_.kAsmDouble) && IntersectResult(expr, expected_type);
!args->at(0)->bounds().upper->Is(cache_.kAsmSigned)) { } else {
FAIL(expr, "illegal function argument type"); if (fun_type->Arity() != args->length()) {
FAIL(expr, "call with wrong arity");
} }
if (args->length() > 1) { for (int i = 0; i < args->length(); ++i) {
Type* other = Type::Intersect(args->at(0)->bounds().upper, Expression* arg = args->at(i);
args->at(1)->bounds().upper, zone()); RECURSE(VisitWithExpectation(
if (!other->Is(cache_.kAsmFloat) && !other->Is(cache_.kAsmDouble) && arg, fun_type->Parameter(i),
!other->Is(cache_.kAsmSigned)) { "call argument expected to match callee parameter"));
FAIL(expr, "function arguments types don't match"); if (standard_member != kNone && standard_member != kMathFround &&
i == 0) {
result_type = computed_type_;
} }
} }
} // Handle polymorphic stdlib functions specially.
intish_ = 0; if (standard_member == kMathCeil || standard_member == kMathFloor ||
IntersectResult(expr, result_type); standard_member == kMathSqrt) {
} else if (computed_type_->Is(Type::Any())) { if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) &&
// For foreign calls. !args->at(0)->bounds().upper->Is(cache_.kAsmDouble)) {
ZoneList<Expression*>* args = expr->arguments(); FAIL(expr, "illegal function argument type");
for (int i = 0; i < args->length(); ++i) { }
Expression* arg = args->at(i); } else if (standard_member == kMathAbs || standard_member == kMathMin ||
RECURSE(VisitWithExpectation(arg, Type::Any(), standard_member == kMathMax) {
"foreign call argument expected to be any")); if (!args->at(0)->bounds().upper->Is(cache_.kAsmFloat) &&
// Checking for asm extern types explicitly, as the type system !args->at(0)->bounds().upper->Is(cache_.kAsmDouble) &&
// doesn't correctly check their inheritance relationship. !args->at(0)->bounds().upper->Is(cache_.kAsmSigned)) {
if (!computed_type_->Is(cache_.kAsmSigned) && FAIL(expr, "illegal function argument type");
!computed_type_->Is(cache_.kAsmFixnum) && }
!computed_type_->Is(cache_.kAsmDouble)) { if (args->length() > 1) {
FAIL(arg, Type* other = Type::Intersect(args->at(0)->bounds().upper,
"foreign call argument expected to be int, double, or fixnum"); args->at(1)->bounds().upper, zone());
if (!other->Is(cache_.kAsmFloat) && !other->Is(cache_.kAsmDouble) &&
!other->Is(cache_.kAsmSigned)) {
FAIL(expr, "function arguments types don't match");
}
}
} }
intish_ = 0;
IntersectResult(expr, result_type);
} }
intish_ = kMaxUncombinedAdditiveSteps;
expr->expression()->set_bounds(Bounds(Type::Function()));
IntersectResult(expr, expected_type);
} else { } else {
FAIL(expr, "invalid callee"); FAIL(expr, "invalid callee");
} }
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "test/cctest/expression-type-collector-macros.h" #include "test/cctest/expression-type-collector-macros.h"
// Macros for function types. // Macros for function types.
#define FUNC_BARE_TYPE Bounds(Type::Function()) #define FUNC_FOREIGN_TYPE Bounds(Type::Function(Type::Any(), zone))
#define FUNC_V_TYPE Bounds(Type::Function(Type::Undefined(), zone)) #define FUNC_V_TYPE Bounds(Type::Function(Type::Undefined(), zone))
#define FUNC_I_TYPE Bounds(Type::Function(cache.kAsmSigned, zone)) #define FUNC_I_TYPE Bounds(Type::Function(cache.kAsmSigned, zone))
#define FUNC_F_TYPE Bounds(Type::Function(cache.kAsmFloat, zone)) #define FUNC_F_TYPE Bounds(Type::Function(cache.kAsmFloat, zone))
...@@ -1726,7 +1726,7 @@ TEST(ForeignFunction) { ...@@ -1726,7 +1726,7 @@ TEST(ForeignFunction) {
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) { CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
CHECK_VAR(baz, FUNC_BARE_TYPE); CHECK_VAR(baz, FUNC_FOREIGN_TYPE);
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
} }
...@@ -1740,9 +1740,9 @@ TEST(ForeignFunction) { ...@@ -1740,9 +1740,9 @@ TEST(ForeignFunction) {
} }
} }
CHECK_FUNC_TYPES_END_1() CHECK_FUNC_TYPES_END_1()
CHECK_EXPR(Assignment, Bounds(Type::Any())) { CHECK_EXPR(Assignment, Bounds(FUNC_FOREIGN_TYPE)) {
CHECK_VAR(baz, Bounds(Type::Any())); CHECK_VAR(baz, Bounds(FUNC_FOREIGN_TYPE));
CHECK_EXPR(Property, Bounds(Type::Any())) { CHECK_EXPR(Property, Bounds(FUNC_FOREIGN_TYPE)) {
CHECK_VAR(foreign, Bounds::Unbounded()); CHECK_VAR(foreign, Bounds::Unbounded());
CHECK_EXPR(Literal, Bounds::Unbounded()); CHECK_EXPR(Literal, Bounds::Unbounded());
} }
...@@ -2127,7 +2127,7 @@ TEST(Imports) { ...@@ -2127,7 +2127,7 @@ TEST(Imports) {
CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) {
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) { CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) {
CHECK_VAR(ffunc, FUNC_BARE_TYPE); CHECK_VAR(ffunc, FUNC_FOREIGN_TYPE);
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
CHECK_VAR(fint, Bounds(cache.kAsmInt)); CHECK_VAR(fint, Bounds(cache.kAsmInt));
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
...@@ -2141,7 +2141,7 @@ TEST(Imports) { ...@@ -2141,7 +2141,7 @@ TEST(Imports) {
CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) { CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) {
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) { CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) {
CHECK_VAR(ffunc, FUNC_BARE_TYPE); CHECK_VAR(ffunc, FUNC_FOREIGN_TYPE);
CHECK_VAR(fdouble, Bounds(cache.kAsmDouble)); CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
CHECK_VAR(fint, Bounds(cache.kAsmInt)); CHECK_VAR(fint, Bounds(cache.kAsmInt));
...@@ -2154,9 +2154,9 @@ TEST(Imports) { ...@@ -2154,9 +2154,9 @@ TEST(Imports) {
// "use asm"; // "use asm";
CHECK_EXPR(Literal, Bounds(Type::String())); CHECK_EXPR(Literal, Bounds(Type::String()));
// var func = foreign.foo; // var func = foreign.foo;
CHECK_EXPR(Assignment, Bounds(Type::Any())) { CHECK_EXPR(Assignment, Bounds(FUNC_FOREIGN_TYPE)) {
CHECK_VAR(ffunc, Bounds(Type::Any())); CHECK_VAR(ffunc, Bounds(FUNC_FOREIGN_TYPE));
CHECK_EXPR(Property, Bounds(Type::Any())) { CHECK_EXPR(Property, Bounds(FUNC_FOREIGN_TYPE)) {
CHECK_VAR(foreign, Bounds::Unbounded()); CHECK_VAR(foreign, Bounds::Unbounded());
CHECK_EXPR(Literal, Bounds::Unbounded()); CHECK_EXPR(Literal, Bounds::Unbounded());
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment