Chromium Code Reviews

Unified Diff: src/typing-asm.cc

Issue 1471073003: Make typing-asm match spec more closely around load/store, add more tests. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
« no previous file with comments | « src/typing-asm.h ('k') | test/cctest/expression-type-collector-macros.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/typing-asm.cc
diff --git a/src/typing-asm.cc b/src/typing-asm.cc
index da752418a63ba63e53b3c9e781c86817be7d60f0..3ebae9408aa13f9ec600af69a06bd97508b014bf 100644
--- a/src/typing-asm.cc
+++ b/src/typing-asm.cc
@@ -41,6 +41,8 @@ AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script,
script_(script),
root_(root),
valid_(true),
+ intish_(0),
+ assigning_(false),
stdlib_types_(zone),
stdlib_heap_types_(zone),
stdlib_math_types_(zone),
@@ -155,7 +157,7 @@ void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
if (literal) {
RECURSE(VisitLiteral(literal, true));
} else {
- RECURSE(VisitExpressionAnnotation(stmt->expression(), true));
+ RECURSE(VisitExpressionAnnotation(stmt->expression(), NULL, true));
}
expected_type_ = old_expected;
result_type = computed_type_;
@@ -179,7 +181,7 @@ void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
Variable* var = proxy->var();
if (var->location() != VariableLocation::PARAMETER || var->index() != i)
break;
- RECURSE(VisitExpressionAnnotation(expr->value(), false));
+ RECURSE(VisitExpressionAnnotation(expr->value(), var, false));
SetType(var, computed_type_);
type->InitParameter(i, computed_type_);
good = true;
@@ -190,10 +192,20 @@ void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
}
-void AsmTyper::VisitExpressionAnnotation(Expression* expr, bool is_return) {
+void AsmTyper::VisitExpressionAnnotation(Expression* expr, Variable* var,
+ bool is_return) {
// Normal +x or x|0 annotations.
BinaryOperation* bin = expr->AsBinaryOperation();
if (bin != NULL) {
+ if (var != NULL) {
+ VariableProxy* left = bin->left()->AsVariableProxy();
+ if (!left) {
+ FAIL(expr, "variable name expected in type annotation");
+ }
+ if (left->var() != var) {
+ FAIL(left, "variable type annotation references other variable");
+ }
+ }
Literal* right = bin->right()->AsLiteral();
if (right != NULL) {
switch (bin->op()) {
@@ -497,6 +509,7 @@ void AsmTyper::VisitVariableProxy(VariableProxy* expr) {
}
SetType(var, type);
intish_ = 0;
+ assigning_ = false;
IntersectResult(expr, type);
}
@@ -593,18 +606,14 @@ void AsmTyper::VisitAssignment(Assignment* expr) {
Type* type = expected_type_;
RECURSE(VisitWithExpectation(
expr->value(), type, "assignment value expected to match surrounding"));
+ Type* target_type = StorageType(computed_type_);
if (intish_ != 0) {
- FAIL(expr, "value still an intish");
- }
- Type* target_type = computed_type_;
- if (target_type->Is(cache_.kAsmInt)) {
- target_type = cache_.kAsmInt;
+ FAIL(expr, "intish or floatish assignment");
}
+ assigning_ = true;
titzer 2015/11/24 07:32:32 At first glance this follow a stack discipline, bu
bradn 2015/11/30 20:34:44 So it turns out the spec allows nested assignment,
RECURSE(VisitWithExpectation(expr->target(), target_type,
"assignment target expected to match value"));
- if (intish_ != 0) {
- FAIL(expr, "value still an intish");
- }
+ DCHECK(!assigning_);
IntersectResult(expr, computed_type_);
}
@@ -658,6 +667,7 @@ void AsmTyper::VisitHeapAccess(Property* expr) {
FAIL(right, "call mask must match function table");
}
bin->set_bounds(Bounds(cache_.kAsmSigned));
+ IntersectResult(expr, type);
} else {
Literal* literal = expr->key()->AsLiteral();
if (literal) {
@@ -683,8 +693,34 @@ void AsmTyper::VisitHeapAccess(Property* expr) {
}
bin->set_bounds(Bounds(cache_.kAsmSigned));
}
+ Type* result_type;
+ if (type->Is(cache_.kAsmIntArrayElement)) {
+ result_type = cache_.kAsmIntQ;
+ intish_ = kMaxUncombinedAdditiveSteps;
+ } else if (type->Is(cache_.kAsmFloat)) {
+ if (assigning_) {
+ result_type = cache_.kAsmFloatDoubleQ;
+ } else {
+ result_type = cache_.kAsmFloatQ;
+ }
+ intish_ = 0;
+ } else if (type->Is(cache_.kAsmDouble)) {
+ if (assigning_) {
+ result_type = cache_.kAsmFloatDoubleQ;
+ if (intish_ != 0) {
+ FAIL(expr, "Assignment of floatish to Float64Array");
+ }
+ } else {
+ result_type = cache_.kAsmDoubleQ;
+ }
+ intish_ = 0;
+ } else {
+ UNREACHABLE();
+ }
+ IntersectResult(expr, expected_type_);
+ IntersectResult(expr, result_type);
+ assigning_ = false;
}
- IntersectResult(expr, type);
}
@@ -780,6 +816,7 @@ void AsmTyper::VisitCall(Call* expr) {
arg, fun_type->Parameter(i),
"call argument expected to match callee parameter"));
}
+ intish_ = 0;
IntersectResult(expr, fun_type->Result());
} else if (computed_type_->Is(Type::Any())) {
// For foreign calls.
@@ -789,6 +826,7 @@ void AsmTyper::VisitCall(Call* expr) {
RECURSE(VisitWithExpectation(arg, Type::Any(),
"foreign call argument expected to be any"));
}
+ intish_ = kMaxUncombinedAdditiveSteps;
IntersectResult(expr, Type::Number());
} else {
FAIL(expr, "invalid callee");
@@ -994,13 +1032,17 @@ void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
IntersectResult(expr, cache_.kAsmInt);
return;
}
- } else if (expr->op() == Token::MUL && left_type->Is(cache_.kAsmInt) &&
+ } else if (expr->op() == Token::MUL && expr->right()->IsLiteral() &&
right_type->Is(cache_.kAsmDouble)) {
// For unary +, expressed as x * 1.0
IntersectResult(expr, cache_.kAsmDouble);
return;
} else if (type->Is(cache_.kAsmFloat) && expr->op() != Token::MOD) {
+ if (left_intish != 0 || right_intish != 0) {
+ FAIL(expr, "float operation before required fround");
+ }
IntersectResult(expr, cache_.kAsmFloat);
+ intish_ = 1;
return;
} else if (type->Is(cache_.kAsmDouble)) {
IntersectResult(expr, cache_.kAsmDouble);
« no previous file with comments | « src/typing-asm.h ('k') | test/cctest/expression-type-collector-macros.h » ('j') | no next file with comments »

Powered by Google App Engine