Index: src/typing-asm.cc |
diff --git a/src/typing-asm.cc b/src/typing-asm.cc |
index 771d255b81a5ba81eb1865ac49cff3e370f8b8f0..9a8cf8f1bf3b9c55314ba5218638c64052a3ba15 100644 |
--- a/src/typing-asm.cc |
+++ b/src/typing-asm.cc |
@@ -44,7 +44,7 @@ AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script, |
root_(root), |
valid_(true), |
allow_simd_(false), |
- property_info_(NULL), |
+ property_info_(nullptr), |
intish_(0), |
stdlib_types_(zone), |
stdlib_heap_types_(zone), |
@@ -79,16 +79,16 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) { |
if (!scope->is_function_scope()) FAIL(fun, "not at function scope"); |
ExpressionStatement* use_asm = fun->body()->first()->AsExpressionStatement(); |
- if (use_asm == NULL) FAIL(fun, "missing \"use asm\""); |
+ if (use_asm == nullptr) FAIL(fun, "missing \"use asm\""); |
Literal* use_asm_literal = use_asm->expression()->AsLiteral(); |
- if (use_asm_literal == NULL) FAIL(fun, "missing \"use asm\""); |
+ if (use_asm_literal == nullptr) FAIL(fun, "missing \"use asm\""); |
if (!use_asm_literal->raw_value()->AsString()->IsOneByteEqualTo("use asm")) |
FAIL(fun, "missing \"use asm\""); |
// Module parameters. |
for (int i = 0; i < scope->num_parameters(); ++i) { |
Variable* param = scope->parameter(i); |
- DCHECK(GetType(param) == NULL); |
+ DCHECK(GetType(param) == nullptr); |
SetType(param, Type::None()); |
} |
@@ -96,7 +96,7 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) { |
// Set all globals to type Any. |
VariableDeclaration* decl = scope->function(); |
- if (decl != NULL) SetType(decl->proxy()->var(), Type::None()); |
+ if (decl != nullptr) SetType(decl->proxy()->var(), Type::None()); |
RECURSE(VisitDeclarations(scope->declarations())); |
// Validate global variables. |
@@ -105,15 +105,15 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) { |
// Validate function annotations. |
for (int i = 0; i < decls->length(); ++i) { |
FunctionDeclaration* decl = decls->at(i)->AsFunctionDeclaration(); |
- if (decl != NULL) { |
+ if (decl != nullptr) { |
RECURSE(VisitFunctionAnnotation(decl->fun())); |
Variable* var = decl->proxy()->var(); |
- if (property_info_ != NULL) { |
+ if (property_info_ != nullptr) { |
SetVariableInfo(var, property_info_); |
- property_info_ = NULL; |
+ property_info_ = nullptr; |
} |
SetType(var, computed_type_); |
- DCHECK(GetType(var) != NULL); |
+ DCHECK(GetType(var) != nullptr); |
} |
} |
@@ -125,7 +125,7 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) { |
// Validate function bodies. |
for (int i = 0; i < decls->length(); ++i) { |
FunctionDeclaration* decl = decls->at(i)->AsFunctionDeclaration(); |
- if (decl != NULL) { |
+ if (decl != nullptr) { |
RECURSE(VisitWithExpectation(decl->fun(), Type::Any(), "UNREACHABLE")); |
if (!computed_type_->IsFunction()) { |
FAIL(decl->fun(), "function literal expected to be a function"); |
@@ -147,13 +147,13 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) { |
void AsmTyper::VisitVariableDeclaration(VariableDeclaration* decl) { |
Variable* var = decl->proxy()->var(); |
if (var->location() != VariableLocation::PARAMETER) { |
- if (GetType(var) == NULL) { |
+ if (GetType(var) == nullptr) { |
SetType(var, Type::Any()); |
} else { |
DCHECK(!GetType(var)->IsFunction()); |
} |
} |
- DCHECK(GetType(var) != NULL); |
+ DCHECK(GetType(var) != nullptr); |
intish_ = 0; |
} |
@@ -175,14 +175,14 @@ void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) { |
Type* result_type = Type::Undefined(); |
if (body->length() > 0) { |
ReturnStatement* stmt = body->last()->AsReturnStatement(); |
- if (stmt != NULL) { |
+ if (stmt != nullptr) { |
Literal* literal = stmt->expression()->AsLiteral(); |
Type* old_expected = expected_type_; |
expected_type_ = Type::Any(); |
if (literal) { |
RECURSE(VisitLiteral(literal, true)); |
} else { |
- RECURSE(VisitExpressionAnnotation(stmt->expression(), NULL, true)); |
+ RECURSE(VisitExpressionAnnotation(stmt->expression(), nullptr, true)); |
} |
expected_type_ = old_expected; |
result_type = computed_type_; |
@@ -197,18 +197,18 @@ void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) { |
good = false; |
if (i >= body->length()) break; |
ExpressionStatement* stmt = body->at(i)->AsExpressionStatement(); |
- if (stmt == NULL) break; |
+ if (stmt == nullptr) break; |
Assignment* expr = stmt->expression()->AsAssignment(); |
- if (expr == NULL || expr->is_compound()) break; |
+ if (expr == nullptr || expr->is_compound()) break; |
VariableProxy* proxy = expr->target()->AsVariableProxy(); |
- if (proxy == NULL) break; |
+ if (proxy == nullptr) break; |
Variable* var = proxy->var(); |
if (var->location() != VariableLocation::PARAMETER || var->index() != i) |
break; |
RECURSE(VisitExpressionAnnotation(expr->value(), var, false)); |
- if (property_info_ != NULL) { |
+ if (property_info_ != nullptr) { |
SetVariableInfo(var, property_info_); |
- property_info_ = NULL; |
+ property_info_ = nullptr; |
} |
SetType(var, computed_type_); |
type->AsFunction()->InitParameter(i, computed_type_); |
@@ -224,10 +224,10 @@ 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) { |
+ if (bin != nullptr) { |
+ if (var != nullptr) { |
VariableProxy* proxy = bin->left()->AsVariableProxy(); |
- if (proxy == NULL) { |
+ if (proxy == nullptr) { |
FAIL(bin->left(), "expected variable for type annotation"); |
} |
if (proxy->var() != var) { |
@@ -235,7 +235,7 @@ void AsmTyper::VisitExpressionAnnotation(Expression* expr, Variable* var, |
} |
} |
Literal* right = bin->right()->AsLiteral(); |
- if (right != NULL) { |
+ if (right != nullptr) { |
switch (bin->op()) { |
case Token::MUL: // We encode +x as x*1.0 |
if (right->raw_value()->ContainsDot() && |
@@ -269,10 +269,10 @@ void AsmTyper::VisitExpressionAnnotation(Expression* expr, Variable* var, |
} |
Call* call = expr->AsCall(); |
- if (call != NULL) { |
+ if (call != nullptr) { |
VariableProxy* proxy = call->expression()->AsVariableProxy(); |
- if (proxy != NULL) { |
- VariableInfo* info = GetVariableInfo(proxy->var(), false); |
+ if (proxy != nullptr) { |
+ VariableInfo* info = GetVariableInfo(proxy->var()); |
if (!info || |
(!info->is_check_function && !info->is_constructor_function)) { |
if (allow_simd_) { |
@@ -448,14 +448,14 @@ void AsmTyper::VisitForStatement(ForStatement* stmt) { |
if (!in_function_) { |
FAIL(stmt, "for statement inside module body"); |
} |
- if (stmt->init() != NULL) { |
+ if (stmt->init() != nullptr) { |
RECURSE(Visit(stmt->init())); |
} |
- if (stmt->cond() != NULL) { |
+ if (stmt->cond() != nullptr) { |
RECURSE(VisitWithExpectation(stmt->cond(), cache_.kAsmSigned, |
"for condition expected to be integer")); |
} |
- if (stmt->next() != NULL) { |
+ if (stmt->next() != nullptr) { |
RECURSE(Visit(stmt->next())); |
} |
RECURSE(Visit(stmt->body())); |
@@ -556,40 +556,31 @@ void AsmTyper::VisitConditional(Conditional* expr) { |
void AsmTyper::VisitVariableProxy(VariableProxy* expr) { |
- VisitVariableProxy(expr, false); |
-} |
- |
-void AsmTyper::VisitVariableProxy(VariableProxy* expr, bool assignment) { |
Variable* var = expr->var(); |
- VariableInfo* info = GetVariableInfo(var, false); |
- if (!assignment && !in_function_ && !building_function_tables_ && |
- !visiting_exports_) { |
+ VariableInfo* info = GetVariableInfo(var); |
+ if (!in_function_ && !building_function_tables_ && !visiting_exports_) { |
if (var->location() != VariableLocation::PARAMETER || var->index() >= 3) { |
FAIL(expr, "illegal variable reference in module body"); |
} |
} |
- if (info == NULL || info->type == NULL) { |
+ if (info == nullptr || info->type == nullptr) { |
if (var->mode() == TEMPORARY) { |
SetType(var, Type::Any()); |
- info = GetVariableInfo(var, false); |
+ info = GetVariableInfo(var); |
} else { |
FAIL(expr, "unbound variable"); |
} |
} |
- if (property_info_ != NULL) { |
+ if (property_info_ != nullptr) { |
SetVariableInfo(var, property_info_); |
- property_info_ = NULL; |
+ property_info_ = nullptr; |
} |
Type* type = Type::Intersect(info->type, expected_type_, zone()); |
- if (type->Is(cache_.kAsmInt)) { |
- type = cache_.kAsmInt; |
- } |
- info->type = type; |
+ if (type->Is(cache_.kAsmInt)) type = cache_.kAsmInt; |
intish_ = 0; |
IntersectResult(expr, type); |
} |
- |
void AsmTyper::VisitLiteral(Literal* expr, bool is_return) { |
intish_ = 0; |
Handle<Object> value = expr->value(); |
@@ -683,13 +674,35 @@ void AsmTyper::VisitAssignment(Assignment* expr) { |
RECURSE(VisitWithExpectation( |
expr->value(), type, "assignment value expected to match surrounding")); |
Type* target_type = StorageType(computed_type_); |
+ |
if (expr->target()->IsVariableProxy()) { |
+ // Assignment to a local or context variable. |
+ VariableProxy* proxy = expr->target()->AsVariableProxy(); |
if (intish_ != 0) { |
FAIL(expr, "intish or floatish assignment"); |
} |
expected_type_ = target_type; |
- VisitVariableProxy(expr->target()->AsVariableProxy(), true); |
+ Variable* var = proxy->var(); |
+ VariableInfo* info = GetVariableInfo(var); |
+ if (info == nullptr || info->type == nullptr) { |
bradnelson
2016/05/05 04:21:58
Structurally equivalent, but probably can be reduc
|
+ if (var->mode() == TEMPORARY) { |
+ SetType(var, Type::Any()); |
+ info = GetVariableInfo(var); |
+ } else { |
+ FAIL(proxy, "unbound variable"); |
+ } |
+ } |
+ if (property_info_ != nullptr) { |
+ SetVariableInfo(var, property_info_); |
+ property_info_ = nullptr; |
+ } |
+ Type* type = Type::Intersect(info->type, expected_type_, zone()); |
+ if (type->Is(cache_.kAsmInt)) type = cache_.kAsmInt; |
+ info->type = type; |
+ intish_ = 0; |
+ IntersectResult(proxy, type); |
} else if (expr->target()->IsProperty()) { |
+ // Assignment to a property: should be a heap assignment {H[x] = y}. |
int32_t value_intish = intish_; |
Property* property = expr->target()->AsProperty(); |
RECURSE(VisitWithExpectation(property->obj(), Type::Any(), |
@@ -745,13 +758,13 @@ void AsmTyper::VisitHeapAccess(Property* expr, bool assigning, |
} |
// TODO(bradnelson): Fix the parser and then un-comment this part |
// BinaryOperation* bin = expr->key()->AsBinaryOperation(); |
- // if (bin == NULL || bin->op() != Token::BIT_AND) { |
+ // if (bin == nullptr || bin->op() != Token::BIT_AND) { |
// FAIL(expr->key(), "expected & in call"); |
// } |
// RECURSE(VisitWithExpectation(bin->left(), cache_.kAsmSigned, |
// "array index expected to be integer")); |
// Literal* right = bin->right()->AsLiteral(); |
- // if (right == NULL || right->raw_value()->ContainsDot()) { |
+ // if (right == nullptr || right->raw_value()->ContainsDot()) { |
// FAIL(right, "call mask must be integer"); |
// } |
// RECURSE(VisitWithExpectation(bin->right(), cache_.kAsmSigned, |
@@ -774,13 +787,13 @@ void AsmTyper::VisitHeapAccess(Property* expr, bool assigning, |
RECURSE(Visit(expr->key())); |
} else { |
BinaryOperation* bin = expr->key()->AsBinaryOperation(); |
- if (bin == NULL || bin->op() != Token::SAR) { |
+ if (bin == nullptr || bin->op() != Token::SAR) { |
FAIL(expr->key(), "expected >> in heap access"); |
} |
RECURSE(VisitWithExpectation(bin->left(), cache_.kAsmSigned, |
"array index expected to be integer")); |
Literal* right = bin->right()->AsLiteral(); |
- if (right == NULL || right->raw_value()->ContainsDot()) { |
+ if (right == nullptr || right->raw_value()->ContainsDot()) { |
FAIL(bin->right(), "heap access shift must be integer"); |
} |
RECURSE(VisitWithExpectation(bin->right(), cache_.kAsmSigned, |
@@ -830,18 +843,18 @@ void AsmTyper::VisitHeapAccess(Property* expr, bool assigning, |
bool AsmTyper::IsStdlibObject(Expression* expr) { |
VariableProxy* proxy = expr->AsVariableProxy(); |
- if (proxy == NULL) { |
+ if (proxy == nullptr) { |
return false; |
} |
Variable* var = proxy->var(); |
- VariableInfo* info = GetVariableInfo(var, false); |
+ VariableInfo* info = GetVariableInfo(var); |
if (info) { |
if (info->standard_member == kStdlib) return true; |
} |
if (var->location() != VariableLocation::PARAMETER || var->index() != 0) { |
return false; |
} |
- info = GetVariableInfo(var, true); |
+ info = MakeVariableInfo(var); |
info->type = Type::Object(); |
info->standard_member = kStdlib; |
return true; |
@@ -851,13 +864,13 @@ bool AsmTyper::IsStdlibObject(Expression* expr) { |
Expression* AsmTyper::GetReceiverOfPropertyAccess(Expression* expr, |
const char* name) { |
Property* property = expr->AsProperty(); |
- if (property == NULL) { |
- return NULL; |
+ if (property == nullptr) { |
+ return nullptr; |
} |
Literal* key = property->key()->AsLiteral(); |
- if (key == NULL || !key->IsPropertyName() || |
+ if (key == nullptr || !key->IsPropertyName() || |
!key->AsPropertyName()->IsUtf8EqualTo(CStrVector(name))) { |
- return NULL; |
+ return nullptr; |
} |
return property->obj(); |
} |
@@ -904,7 +917,7 @@ void AsmTyper::VisitProperty(Property* expr) { |
return; |
} |
- property_info_ = NULL; |
+ property_info_ = nullptr; |
// Only recurse at this point so that we avoid needing |
// stdlib.Math to have a real type. |
@@ -913,12 +926,12 @@ void AsmTyper::VisitProperty(Property* expr) { |
// For heap view or function table access. |
if (computed_type_->IsArray()) { |
- VisitHeapAccess(expr, false, NULL); |
+ VisitHeapAccess(expr, false, nullptr); |
return; |
} |
VariableProxy* proxy = expr->obj()->AsVariableProxy(); |
- if (proxy != NULL) { |
+ if (proxy != nullptr) { |
Variable* var = proxy->var(); |
if (var->location() == VariableLocation::PARAMETER && var->index() == 1) { |
// foreign.x - Function represent as () -> Any |
@@ -992,10 +1005,10 @@ void AsmTyper::VisitCall(Call* expr) { |
if (proxy) { |
standard_member = VariableAsStandardMember(proxy->var()); |
} |
- if (!in_function_ && (proxy == NULL || standard_member != kMathFround)) { |
+ if (!in_function_ && (proxy == nullptr || standard_member != kMathFround)) { |
FAIL(expr, "calls forbidden outside function bodies"); |
} |
- if (proxy == NULL && !expr->expression()->IsProperty()) { |
+ if (proxy == nullptr && !expr->expression()->IsProperty()) { |
FAIL(expr, "calls must be to bound variables or function tables"); |
} |
if (computed_type_->IsFunction()) { |
@@ -1502,11 +1515,12 @@ void AsmTyper::InitializeStdlib() { |
void AsmTyper::VisitLibraryAccess(ObjectTypeMap* map, Property* expr) { |
Literal* key = expr->key()->AsLiteral(); |
- if (key == NULL || !key->IsPropertyName()) |
+ if (key == nullptr || !key->IsPropertyName()) |
FAIL(expr, "invalid key used on stdlib member"); |
Handle<String> name = key->AsPropertyName(); |
VariableInfo* info = LibType(map, name); |
- if (info == NULL || info->type == NULL) FAIL(expr, "unknown stdlib function"); |
+ if (info == nullptr || info->type == nullptr) |
+ FAIL(expr, "unknown stdlib function"); |
SetResult(expr, info->type); |
property_info_ = info; |
} |
@@ -1517,57 +1531,47 @@ AsmTyper::VariableInfo* AsmTyper::LibType(ObjectTypeMap* map, |
base::SmartArrayPointer<char> aname = name->ToCString(); |
ObjectTypeMap::iterator i = map->find(std::string(aname.get())); |
if (i == map->end()) { |
- return NULL; |
+ return nullptr; |
} |
return i->second; |
} |
void AsmTyper::SetType(Variable* variable, Type* type) { |
- VariableInfo* info = GetVariableInfo(variable, true); |
+ VariableInfo* info = MakeVariableInfo(variable); |
info->type = type; |
} |
Type* AsmTyper::GetType(Variable* variable) { |
- VariableInfo* info = GetVariableInfo(variable, false); |
- if (!info) return NULL; |
+ VariableInfo* info = GetVariableInfo(variable); |
+ if (!info) return nullptr; |
return info->type; |
} |
- |
-AsmTyper::VariableInfo* AsmTyper::GetVariableInfo(Variable* variable, |
- bool setting) { |
- ZoneHashMap::Entry* entry; |
- ZoneHashMap* map; |
- if (in_function_) { |
- map = &local_variable_type_; |
- } else { |
- map = &global_variable_type_; |
- } |
- if (setting) { |
- entry = map->LookupOrInsert(variable, ComputePointerHash(variable), |
- ZoneAllocationPolicy(zone())); |
- } else { |
- entry = map->Lookup(variable, ComputePointerHash(variable)); |
- if (!entry && in_function_) { |
- entry = |
- global_variable_type_.Lookup(variable, ComputePointerHash(variable)); |
- if (entry && entry->value) { |
- } |
- } |
- } |
- if (!entry) return NULL; |
- if (!entry->value) { |
- if (!setting) return NULL; |
- entry->value = new (zone()) VariableInfo; |
+AsmTyper::VariableInfo* AsmTyper::GetVariableInfo(Variable* variable) { |
+ ZoneHashMap* map = |
+ in_function_ ? &local_variable_type_ : &global_variable_type_; |
+ ZoneHashMap::Entry* entry = |
+ map->Lookup(variable, ComputePointerHash(variable)); |
+ if (!entry && in_function_) { |
+ entry = |
+ global_variable_type_.Lookup(variable, ComputePointerHash(variable)); |
} |
- return reinterpret_cast<VariableInfo*>(entry->value); |
+ return entry ? reinterpret_cast<VariableInfo*>(entry->value) : nullptr; |
} |
+AsmTyper::VariableInfo* AsmTyper::MakeVariableInfo(Variable* variable) { |
+ ZoneHashMap* map = |
+ in_function_ ? &local_variable_type_ : &global_variable_type_; |
+ ZoneHashMap::Entry* entry = map->LookupOrInsert( |
+ variable, ComputePointerHash(variable), ZoneAllocationPolicy(zone())); |
+ if (!entry->value) entry->value = new (zone()) VariableInfo; |
+ return reinterpret_cast<VariableInfo*>(entry->value); |
+} |
void AsmTyper::SetVariableInfo(Variable* variable, const VariableInfo* info) { |
- VariableInfo* dest = GetVariableInfo(variable, true); |
+ VariableInfo* dest = MakeVariableInfo(variable); |
dest->type = info->type; |
dest->is_check_function = info->is_check_function; |
dest->is_constructor_function = info->is_constructor_function; |
@@ -1577,7 +1581,7 @@ void AsmTyper::SetVariableInfo(Variable* variable, const VariableInfo* info) { |
AsmTyper::StandardMember AsmTyper::VariableAsStandardMember( |
Variable* variable) { |
- VariableInfo* info = GetVariableInfo(variable, false); |
+ VariableInfo* info = GetVariableInfo(variable); |
if (!info) return kNone; |
return info->standard_member; |
} |