Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(904)

Side by Side Diff: src/typing-asm.cc

Issue 1473513004: Refactor VisitProperty, add starting point for SIMD.js support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: revision Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/typing-asm.h" 7 #include "src/typing-asm.h"
8 8
9 #include "src/ast.h" 9 #include "src/ast.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 20 matching lines...) Expand all
31 DCHECK(!HasStackOverflow()); \ 31 DCHECK(!HasStackOverflow()); \
32 call; \ 32 call; \
33 if (HasStackOverflow()) return; \ 33 if (HasStackOverflow()) return; \
34 if (!valid_) return; \ 34 if (!valid_) return; \
35 } while (false) 35 } while (false)
36 36
37 37
38 AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script, 38 AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script,
39 FunctionLiteral* root) 39 FunctionLiteral* root)
40 : zone_(zone), 40 : zone_(zone),
41 isolate_(isolate),
41 script_(script), 42 script_(script),
42 root_(root), 43 root_(root),
43 valid_(true), 44 valid_(true),
45 allow_simd_(false),
44 stdlib_types_(zone), 46 stdlib_types_(zone),
45 stdlib_heap_types_(zone), 47 stdlib_heap_types_(zone),
46 stdlib_math_types_(zone), 48 stdlib_math_types_(zone),
47 global_variable_type_(HashMap::PointersMatch, 49 #define V(NAME, Name, name, lane_count, lane_type) \
48 ZoneHashMap::kDefaultHashMapCapacity, 50 stdlib_simd_##name##_types_(zone),
49 ZoneAllocationPolicy(zone)), 51 SIMD128_TYPES(V)
52 #undef V
53 global_variable_type_(HashMap::PointersMatch,
54 ZoneHashMap::kDefaultHashMapCapacity,
55 ZoneAllocationPolicy(zone)),
50 local_variable_type_(HashMap::PointersMatch, 56 local_variable_type_(HashMap::PointersMatch,
51 ZoneHashMap::kDefaultHashMapCapacity, 57 ZoneHashMap::kDefaultHashMapCapacity,
52 ZoneAllocationPolicy(zone)), 58 ZoneAllocationPolicy(zone)),
53 in_function_(false), 59 in_function_(false),
54 building_function_tables_(false), 60 building_function_tables_(false),
55 cache_(TypeCache::Get()) { 61 cache_(TypeCache::Get()) {
56 InitializeAstVisitor(isolate); 62 InitializeAstVisitor(isolate);
57 InitializeStdlib(); 63 InitializeStdlib();
58 } 64 }
59 65
(...skipping 25 matching lines...) Expand all
85 // Validate global variables. 91 // Validate global variables.
86 RECURSE(VisitStatements(fun->body())); 92 RECURSE(VisitStatements(fun->body()));
87 93
88 // Validate function annotations. 94 // Validate function annotations.
89 for (int i = 0; i < decls->length(); ++i) { 95 for (int i = 0; i < decls->length(); ++i) {
90 FunctionDeclaration* decl = decls->at(i)->AsFunctionDeclaration(); 96 FunctionDeclaration* decl = decls->at(i)->AsFunctionDeclaration();
91 if (decl != NULL) { 97 if (decl != NULL) {
92 RECURSE(VisitFunctionAnnotation(decl->fun())); 98 RECURSE(VisitFunctionAnnotation(decl->fun()));
93 Variable* var = decl->proxy()->var(); 99 Variable* var = decl->proxy()->var();
94 DCHECK(GetType(var) == NULL); 100 DCHECK(GetType(var) == NULL);
101 if (property_info_ != NULL) {
102 SetVariableInfo(var, property_info_);
103 property_info_ = NULL;
104 }
95 SetType(var, computed_type_); 105 SetType(var, computed_type_);
96 DCHECK(GetType(var) != NULL); 106 DCHECK(GetType(var) != NULL);
97 } 107 }
98 } 108 }
99 109
100 // Build function tables. 110 // Build function tables.
101 building_function_tables_ = true; 111 building_function_tables_ = true;
102 RECURSE(VisitStatements(fun->body())); 112 RECURSE(VisitStatements(fun->body()));
103 building_function_tables_ = false; 113 building_function_tables_ = false;
104 114
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 Type* result_type = Type::Undefined(zone()); 158 Type* result_type = Type::Undefined(zone());
149 if (body->length() > 0) { 159 if (body->length() > 0) {
150 ReturnStatement* stmt = body->last()->AsReturnStatement(); 160 ReturnStatement* stmt = body->last()->AsReturnStatement();
151 if (stmt != NULL) { 161 if (stmt != NULL) {
152 Literal* literal = stmt->expression()->AsLiteral(); 162 Literal* literal = stmt->expression()->AsLiteral();
153 Type* old_expected = expected_type_; 163 Type* old_expected = expected_type_;
154 expected_type_ = Type::Any(); 164 expected_type_ = Type::Any();
155 if (literal) { 165 if (literal) {
156 RECURSE(VisitLiteral(literal, true)); 166 RECURSE(VisitLiteral(literal, true));
157 } else { 167 } else {
158 RECURSE(VisitExpressionAnnotation(stmt->expression(), true)); 168 RECURSE(VisitExpressionAnnotation(stmt->expression(), true, NULL));
159 } 169 }
160 expected_type_ = old_expected; 170 expected_type_ = old_expected;
161 result_type = computed_type_; 171 result_type = computed_type_;
162 } 172 }
163 } 173 }
164 Type::FunctionType* type = 174 Type::FunctionType* type =
165 Type::Function(result_type, Type::Any(), fun->parameter_count(), zone()) 175 Type::Function(result_type, Type::Any(), fun->parameter_count(), zone())
166 ->AsFunction(); 176 ->AsFunction();
167 177
168 // Extract parameter types. 178 // Extract parameter types.
169 bool good = true; 179 bool good = true;
170 for (int i = 0; i < fun->parameter_count(); ++i) { 180 for (int i = 0; i < fun->parameter_count(); ++i) {
171 good = false; 181 good = false;
172 if (i >= body->length()) break; 182 if (i >= body->length()) break;
173 ExpressionStatement* stmt = body->at(i)->AsExpressionStatement(); 183 ExpressionStatement* stmt = body->at(i)->AsExpressionStatement();
174 if (stmt == NULL) break; 184 if (stmt == NULL) break;
175 Assignment* expr = stmt->expression()->AsAssignment(); 185 Assignment* expr = stmt->expression()->AsAssignment();
176 if (expr == NULL || expr->is_compound()) break; 186 if (expr == NULL || expr->is_compound()) break;
177 VariableProxy* proxy = expr->target()->AsVariableProxy(); 187 VariableProxy* proxy = expr->target()->AsVariableProxy();
178 if (proxy == NULL) break; 188 if (proxy == NULL) break;
179 Variable* var = proxy->var(); 189 Variable* var = proxy->var();
180 if (var->location() != VariableLocation::PARAMETER || var->index() != i) 190 if (var->location() != VariableLocation::PARAMETER || var->index() != i)
181 break; 191 break;
182 RECURSE(VisitExpressionAnnotation(expr->value(), false)); 192 RECURSE(VisitExpressionAnnotation(expr->value(), false, var));
193 if (property_info_ != NULL) {
194 SetVariableInfo(var, property_info_);
195 property_info_ = NULL;
196 }
183 SetType(var, computed_type_); 197 SetType(var, computed_type_);
184 type->InitParameter(i, computed_type_); 198 type->InitParameter(i, computed_type_);
185 good = true; 199 good = true;
186 } 200 }
187 if (!good) FAIL(fun, "missing parameter type annotations"); 201 if (!good) FAIL(fun, "missing parameter type annotations");
188 202
189 SetResult(fun, type); 203 SetResult(fun, type);
190 } 204 }
191 205
192 206
193 void AsmTyper::VisitExpressionAnnotation(Expression* expr, bool is_return) { 207 void AsmTyper::VisitExpressionAnnotation(Expression* expr, bool is_return,
208 Variable* variable) {
194 // Normal +x or x|0 annotations. 209 // Normal +x or x|0 annotations.
195 BinaryOperation* bin = expr->AsBinaryOperation(); 210 BinaryOperation* bin = expr->AsBinaryOperation();
196 if (bin != NULL) { 211 if (bin != NULL) {
212 if (variable != NULL) {
213 VariableProxy* proxy = bin->left()->AsVariableProxy();
214 if (proxy == NULL) {
215 FAIL(bin->left(), "expected variable for type annotation");
216 }
217 if (proxy->var() != variable) {
218 FAIL(proxy, "annotation source doesn't match destination");
219 }
220 }
197 Literal* right = bin->right()->AsLiteral(); 221 Literal* right = bin->right()->AsLiteral();
198 if (right != NULL) { 222 if (right != NULL) {
199 switch (bin->op()) { 223 switch (bin->op()) {
200 case Token::MUL: // We encode +x as x*1.0 224 case Token::MUL: // We encode +x as x*1.0
201 if (right->raw_value()->ContainsDot() && 225 if (right->raw_value()->ContainsDot() &&
202 right->raw_value()->AsNumber() == 1.0) { 226 right->raw_value()->AsNumber() == 1.0) {
203 SetResult(expr, cache_.kAsmDouble); 227 SetResult(expr, cache_.kAsmDouble);
204 return; 228 return;
205 } 229 }
206 break; 230 break;
(...skipping 16 matching lines...) Expand all
223 } 247 }
224 248
225 // Numbers or the undefined literal (for empty returns). 249 // Numbers or the undefined literal (for empty returns).
226 if (expr->IsLiteral()) { 250 if (expr->IsLiteral()) {
227 RECURSE(VisitWithExpectation(expr, Type::Any(), "invalid literal")); 251 RECURSE(VisitWithExpectation(expr, Type::Any(), "invalid literal"));
228 return; 252 return;
229 } 253 }
230 254
231 Call* call = expr->AsCall(); 255 Call* call = expr->AsCall();
232 if (call != NULL) { 256 if (call != NULL) {
233 if (call->expression()->IsVariableProxy()) { 257 VariableProxy* proxy = call->expression()->AsVariableProxy();
234 RECURSE(VisitWithExpectation( 258 if (proxy != NULL) {
235 call->expression(), Type::Any(zone()), 259 VariableInfo* info = GetVariableInfo(proxy->var(), false);
236 "only fround allowed on expression annotations")); 260 if (!info ||
237 if (!computed_type_->Is( 261 (!info->is_check_function && !info->is_constructor_function)) {
238 Type::Function(cache_.kAsmFloat, Type::Number(zone()), zone()))) { 262 if (allow_simd_) {
239 FAIL(call->expression(), 263 FAIL(call->expression(),
240 "only fround allowed on expression annotations"); 264 "only fround/SIMD.checks allowed on expression annotations");
265 } else {
266 FAIL(call->expression(),
267 "only fround allowed on expression annotations");
268 }
241 } 269 }
242 if (call->arguments()->length() != 1) { 270 Type* type = info->type;
243 FAIL(call, "invalid argument count calling fround"); 271 DCHECK(type->IsFunction());
272 if (info->is_check_function) {
273 DCHECK(type->AsFunction()->Arity() == 1);
244 } 274 }
245 SetResult(expr, cache_.kAsmFloat); 275 if (call->arguments()->length() != type->AsFunction()->Arity()) {
276 FAIL(call, "invalid argument count calling function");
277 }
278 SetResult(expr, type->AsFunction()->Result());
246 return; 279 return;
247 } 280 }
248 } 281 }
249 282
250 FAIL(expr, "invalid type annotation"); 283 FAIL(expr, "invalid type annotation");
251 } 284 }
252 285
253 286
254 void AsmTyper::VisitStatements(ZoneList<Statement*>* stmts) { 287 void AsmTyper::VisitStatements(ZoneList<Statement*>* stmts) {
255 for (int i = 0; i < stmts->length(); ++i) { 288 for (int i = 0; i < stmts->length(); ++i) {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 if (!then_type->Is(else_type) || !else_type->Is(then_type)) { 514 if (!then_type->Is(else_type) || !else_type->Is(then_type)) {
482 FAIL(expr, "then and else expressions in ? must have the same type"); 515 FAIL(expr, "then and else expressions in ? must have the same type");
483 } 516 }
484 517
485 IntersectResult(expr, then_type); 518 IntersectResult(expr, then_type);
486 } 519 }
487 520
488 521
489 void AsmTyper::VisitVariableProxy(VariableProxy* expr) { 522 void AsmTyper::VisitVariableProxy(VariableProxy* expr) {
490 Variable* var = expr->var(); 523 Variable* var = expr->var();
491 if (GetType(var) == NULL) { 524 VariableInfo* info = GetVariableInfo(var, false);
525 if (info == NULL || info->type == NULL) {
492 FAIL(expr, "unbound variable"); 526 FAIL(expr, "unbound variable");
493 } 527 }
494 Type* type = Type::Intersect(GetType(var), expected_type_, zone()); 528 if (property_info_ != NULL) {
529 SetVariableInfo(var, property_info_);
530 property_info_ = NULL;
531 }
532 Type* type = Type::Intersect(info->type, expected_type_, zone());
495 if (type->Is(cache_.kAsmInt)) { 533 if (type->Is(cache_.kAsmInt)) {
496 type = cache_.kAsmInt; 534 type = cache_.kAsmInt;
497 } 535 }
498 SetType(var, type); 536 SetType(var, type);
499 intish_ = 0; 537 intish_ = 0;
500 IntersectResult(expr, type); 538 IntersectResult(expr, type);
501 } 539 }
502 540
503 541
504 void AsmTyper::VisitLiteral(Literal* expr, bool is_return) { 542 void AsmTyper::VisitLiteral(Literal* expr, bool is_return) {
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 if (expected_shift < 0 || n != expected_shift) { 719 if (expected_shift < 0 || n != expected_shift) {
682 FAIL(right, "heap access shift must match element size"); 720 FAIL(right, "heap access shift must match element size");
683 } 721 }
684 bin->set_bounds(Bounds(cache_.kAsmSigned)); 722 bin->set_bounds(Bounds(cache_.kAsmSigned));
685 } 723 }
686 } 724 }
687 IntersectResult(expr, type); 725 IntersectResult(expr, type);
688 } 726 }
689 727
690 728
729 bool AsmTyper::IsStdlibObject(Expression* expr) {
730 VariableProxy* proxy = expr->AsVariableProxy();
731 if (proxy == NULL) {
732 return false;
733 }
734 Variable* var = proxy->var();
735 if (var->location() != VariableLocation::PARAMETER || var->index() != 0) {
736 return false;
737 }
738 return true;
739 }
740
741
742 Expression* AsmTyper::AsPropertyObjectWithKey(Expression* expr,
titzer 2015/11/25 18:36:42 This basically returns the "obj" in "obj.name" by
bradn 2015/11/30 18:22:38 Done.
743 const char* name) {
744 Property* property = expr->AsProperty();
745 if (property == NULL) {
746 return NULL;
747 }
748 Literal* key = property->key()->AsLiteral();
749 if (key == NULL || !key->IsPropertyName() ||
750 !key->AsPropertyName()->IsUtf8EqualTo(CStrVector(name))) {
751 return NULL;
752 }
753 return property->obj();
754 }
755
756
757 bool AsmTyper::IsMathObject(Expression* expr) {
758 Expression* obj = AsPropertyObjectWithKey(expr, "Math");
759 return obj && IsStdlibObject(obj);
760 }
761
762
763 bool AsmTyper::IsSIMDObject(Expression* expr) {
764 Expression* obj = AsPropertyObjectWithKey(expr, "SIMD");
765 return obj && IsStdlibObject(obj);
766 }
767
768
769 bool AsmTyper::IsSIMDTypeObject(Expression* expr, const char* name) {
770 Expression* obj = AsPropertyObjectWithKey(expr, name);
771 return obj && IsSIMDObject(obj);
772 }
773
774
691 void AsmTyper::VisitProperty(Property* expr) { 775 void AsmTyper::VisitProperty(Property* expr) {
692 // stdlib.Math.x 776 if (IsMathObject(expr->obj())) {
693 Property* inner_prop = expr->obj()->AsProperty();
694 if (inner_prop != NULL) {
695 // Get property name.
696 Literal* key = expr->key()->AsLiteral(); 777 Literal* key = expr->key()->AsLiteral();
697 if (key == NULL || !key->IsPropertyName()) 778 if (key == NULL || !key->IsPropertyName())
698 FAIL(expr, "invalid type annotation on property 2"); 779 FAIL(expr, "invalid key used on Math object");
699 Handle<String> name = key->AsPropertyName(); 780 Handle<String> name = key->AsPropertyName();
700 781 VariableInfo* info = LibType(stdlib_math_types_, name);
701 // Check that inner property name is "Math". 782 if (info == NULL || info->type == NULL) FAIL(expr, "unknown Math function");
702 Literal* math_key = inner_prop->key()->AsLiteral(); 783 SetResult(expr, info->type);
703 if (math_key == NULL || !math_key->IsPropertyName() || 784 property_info_ = info;
704 !math_key->AsPropertyName()->IsUtf8EqualTo(CStrVector("Math")))
705 FAIL(expr, "invalid type annotation on stdlib (a1)");
706
707 // Check that object is stdlib.
708 VariableProxy* proxy = inner_prop->obj()->AsVariableProxy();
709 if (proxy == NULL) FAIL(expr, "invalid type annotation on stdlib (a2)");
710 Variable* var = proxy->var();
711 if (var->location() != VariableLocation::PARAMETER || var->index() != 0)
712 FAIL(expr, "invalid type annotation on stdlib (a3)");
713
714 // Look up library type.
715 Type* type = LibType(stdlib_math_types_, name);
716 if (type == NULL) FAIL(expr, "unknown standard function 3 ");
717 SetResult(expr, type);
718 return; 785 return;
719 } 786 }
787 #define V(NAME, Name, name, lane_count, lane_type) \
788 if (IsSIMDTypeObject(expr->obj(), #Name)) { \
789 Literal* key = expr->key()->AsLiteral(); \
790 if (key == NULL || !key->IsPropertyName()) \
791 FAIL(expr, "invalid key used on SIMD type object"); \
792 Handle<String> kname = key->AsPropertyName(); \
793 VariableInfo* info = LibType(stdlib_simd_##name##_types_, kname); \
794 if (info == NULL || info->type == NULL) \
795 FAIL(expr, "unknown Math function"); \
796 SetResult(expr, info->type); \
797 property_info_ = info; \
798 return; \
799 } \
800 if (IsSIMDTypeObject(expr, #Name)) { \
801 VariableInfo* info = stdlib_simd_##name##_constructor_type_; \
802 SetResult(expr, info->type); \
803 property_info_ = info; \
804 return; \
805 }
806 SIMD128_TYPES(V)
807 #undef V
808
809 property_info_ = NULL;
720 810
721 // Only recurse at this point so that we avoid needing 811 // Only recurse at this point so that we avoid needing
722 // stdlib.Math to have a real type. 812 // stdlib.Math to have a real type.
723 RECURSE(VisitWithExpectation(expr->obj(), Type::Any(), 813 RECURSE(VisitWithExpectation(expr->obj(), Type::Any(),
724 "property holder expected to be object")); 814 "property holder expected to be object"));
725 815
726 // For heap view or function table access. 816 // For heap view or function table access.
727 if (computed_type_->IsArray()) { 817 if (computed_type_->IsArray()) {
728 VisitHeapAccess(expr); 818 VisitHeapAccess(expr);
729 return; 819 return;
730 } 820 }
731 821
732 // Get property name. 822 // Get property name.
733 Literal* key = expr->key()->AsLiteral(); 823 Literal* key = expr->key()->AsLiteral();
734 if (key == NULL || !key->IsPropertyName()) 824 if (key == NULL || !key->IsPropertyName())
735 FAIL(expr, "invalid type annotation on property 3"); 825 FAIL(expr, "invalid type annotation on property");
736 Handle<String> name = key->AsPropertyName(); 826 Handle<String> name = key->AsPropertyName();
737 827
738 // stdlib.x or foreign.x 828 // stdlib.x or foreign.x
739 VariableProxy* proxy = expr->obj()->AsVariableProxy(); 829 VariableProxy* proxy = expr->obj()->AsVariableProxy();
740 if (proxy != NULL) { 830 if (proxy != NULL) {
741 Variable* var = proxy->var(); 831 Variable* var = proxy->var();
742 if (var->location() != VariableLocation::PARAMETER) { 832 if (var->location() != VariableLocation::PARAMETER) {
743 FAIL(expr, "invalid type annotation on variable"); 833 FAIL(expr, "invalid type annotation on variable");
744 } 834 }
745 switch (var->index()) { 835 switch (var->index()) {
746 case 0: { 836 case 0: {
747 // Object is stdlib, look up library type. 837 // Object is stdlib, look up library type.
748 Type* type = LibType(stdlib_types_, name); 838 VariableInfo* info = LibType(stdlib_types_, name);
749 if (type == NULL) { 839 if (info == NULL || info->type == NULL) {
750 FAIL(expr, "unknown standard function 4"); 840 FAIL(expr, "unknown standard function");
751 } 841 }
752 SetResult(expr, type); 842 SetResult(expr, info->type);
753 return; 843 return;
754 } 844 }
755 case 1: 845 case 1:
756 // Object is foreign lib. 846 // Object is foreign lib.
757 SetResult(expr, expected_type_); 847 SetResult(expr, expected_type_);
758 return; 848 return;
759 default: 849 default:
760 FAIL(expr, "invalid type annotation on parameter"); 850 FAIL(expr, "invalid type annotation on parameter");
761 } 851 }
762 } 852 }
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 void AsmTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) { 1170 void AsmTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {
1081 FAIL(expr, "super property reference not allowed"); 1171 FAIL(expr, "super property reference not allowed");
1082 } 1172 }
1083 1173
1084 1174
1085 void AsmTyper::VisitSuperCallReference(SuperCallReference* expr) { 1175 void AsmTyper::VisitSuperCallReference(SuperCallReference* expr) {
1086 FAIL(expr, "call reference not allowed"); 1176 FAIL(expr, "call reference not allowed");
1087 } 1177 }
1088 1178
1089 1179
1180 void AsmTyper::InitializeStdlibSIMD() {
1181 #define V(NAME, Name, name, lane_count, lane_type) \
1182 { \
1183 Type* type = Type::Function(Type::Name(isolate_, zone()), Type::Any(), \
1184 lane_count, zone()); \
1185 for (int i = 0; i < lane_count; ++i) { \
1186 type->AsFunction()->InitParameter(i, Type::Number()); \
1187 } \
1188 stdlib_simd_##name##_constructor_type_ = new (zone()) VariableInfo(type); \
1189 stdlib_simd_##name##_constructor_type_->is_constructor_function = true; \
1190 }
1191 SIMD128_TYPES(V)
1192 #undef V
1193 }
1194
1195
1090 void AsmTyper::InitializeStdlib() { 1196 void AsmTyper::InitializeStdlib() {
1197 if (allow_simd_) {
1198 InitializeStdlibSIMD();
1199 }
1091 Type* number_type = Type::Number(zone()); 1200 Type* number_type = Type::Number(zone());
1092 Type* double_type = cache_.kAsmDouble; 1201 Type* double_type = cache_.kAsmDouble;
1093 Type* double_fn1_type = Type::Function(double_type, double_type, zone()); 1202 Type* double_fn1_type = Type::Function(double_type, double_type, zone());
1094 Type* double_fn2_type = 1203 Type* double_fn2_type =
1095 Type::Function(double_type, double_type, double_type, zone()); 1204 Type::Function(double_type, double_type, double_type, zone());
1096 1205
1097 Type* fround_type = Type::Function(cache_.kAsmFloat, number_type, zone()); 1206 Type* fround_type = Type::Function(cache_.kAsmFloat, number_type, zone());
1098 Type* imul_type = 1207 Type* imul_type =
1099 Type::Function(cache_.kAsmSigned, cache_.kAsmInt, cache_.kAsmInt, zone()); 1208 Type::Function(cache_.kAsmSigned, cache_.kAsmInt, cache_.kAsmInt, zone());
1100 // TODO(bradnelson): currently only approximating the proper intersection type 1209 // TODO(bradnelson): currently only approximating the proper intersection type
(...skipping 13 matching lines...) Expand all
1114 {"imul", imul_type}, {"abs", abs_type}, 1223 {"imul", imul_type}, {"abs", abs_type},
1115 {"ceil", double_fn1_type}, {"floor", double_fn1_type}, 1224 {"ceil", double_fn1_type}, {"floor", double_fn1_type},
1116 {"fround", fround_type}, {"pow", double_fn2_type}, 1225 {"fround", fround_type}, {"pow", double_fn2_type},
1117 {"exp", double_fn1_type}, {"log", double_fn1_type}, 1226 {"exp", double_fn1_type}, {"log", double_fn1_type},
1118 {"min", double_fn2_type}, {"max", double_fn2_type}, 1227 {"min", double_fn2_type}, {"max", double_fn2_type},
1119 {"sqrt", double_fn1_type}, {"cos", double_fn1_type}, 1228 {"sqrt", double_fn1_type}, {"cos", double_fn1_type},
1120 {"sin", double_fn1_type}, {"tan", double_fn1_type}, 1229 {"sin", double_fn1_type}, {"tan", double_fn1_type},
1121 {"acos", double_fn1_type}, {"asin", double_fn1_type}, 1230 {"acos", double_fn1_type}, {"asin", double_fn1_type},
1122 {"atan", double_fn1_type}, {"atan2", double_fn2_type}}; 1231 {"atan", double_fn1_type}, {"atan2", double_fn2_type}};
1123 for (unsigned i = 0; i < arraysize(math); ++i) { 1232 for (unsigned i = 0; i < arraysize(math); ++i) {
1124 stdlib_math_types_[math[i].name] = math[i].type; 1233 stdlib_math_types_[math[i].name] = new (zone()) VariableInfo(math[i].type);
1125 } 1234 }
1235 stdlib_math_types_["fround"]->is_check_function = true;
1126 1236
1127 stdlib_types_["Infinity"] = double_type; 1237 stdlib_types_["Infinity"] = new (zone()) VariableInfo(double_type);
1128 stdlib_types_["NaN"] = double_type; 1238 stdlib_types_["NaN"] = new (zone()) VariableInfo(double_type);
1129 Type* buffer_type = Type::Any(zone()); 1239 Type* buffer_type = Type::Any(zone());
1130 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \ 1240 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \
1131 stdlib_types_[#TypeName "Array"] = \ 1241 stdlib_types_[#TypeName "Array"] = new (zone()) VariableInfo( \
1132 Type::Function(cache_.k##TypeName##Array, buffer_type, zone()); 1242 Type::Function(cache_.k##TypeName##Array, buffer_type, zone()));
1133 TYPED_ARRAYS(TYPED_ARRAY) 1243 TYPED_ARRAYS(TYPED_ARRAY)
1134 #undef TYPED_ARRAY 1244 #undef TYPED_ARRAY
1135 1245
1136 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \ 1246 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \
1137 stdlib_heap_types_[#TypeName "Array"] = \ 1247 stdlib_heap_types_[#TypeName "Array"] = new (zone()) VariableInfo( \
1138 Type::Function(cache_.k##TypeName##Array, buffer_type, zone()); 1248 Type::Function(cache_.k##TypeName##Array, buffer_type, zone()));
1139 TYPED_ARRAYS(TYPED_ARRAY) 1249 TYPED_ARRAYS(TYPED_ARRAY)
1140 #undef TYPED_ARRAY 1250 #undef TYPED_ARRAY
1141 } 1251 }
1142 1252
1143 1253
1144 Type* AsmTyper::LibType(ObjectTypeMap map, Handle<String> name) { 1254 AsmTyper::VariableInfo* AsmTyper::LibType(ObjectTypeMap map,
1255 Handle<String> name) {
1145 base::SmartArrayPointer<char> aname = name->ToCString(); 1256 base::SmartArrayPointer<char> aname = name->ToCString();
1146 ObjectTypeMap::iterator i = map.find(std::string(aname.get())); 1257 ObjectTypeMap::iterator i = map.find(std::string(aname.get()));
1147 if (i == map.end()) { 1258 if (i == map.end()) {
1148 return NULL; 1259 return NULL;
1149 } 1260 }
1150 return i->second; 1261 return i->second;
1151 } 1262 }
1152 1263
1153 1264
1154 void AsmTyper::SetType(Variable* variable, Type* type) { 1265 void AsmTyper::SetType(Variable* variable, Type* type) {
1155 ZoneHashMap::Entry* entry; 1266 VariableInfo* info = GetVariableInfo(variable, true);
1156 if (in_function_) { 1267 info->type = type;
1157 entry = local_variable_type_.LookupOrInsert(
1158 variable, ComputePointerHash(variable), ZoneAllocationPolicy(zone()));
1159 } else {
1160 entry = global_variable_type_.LookupOrInsert(
1161 variable, ComputePointerHash(variable), ZoneAllocationPolicy(zone()));
1162 }
1163 entry->value = reinterpret_cast<void*>(type);
1164 } 1268 }
1165 1269
1166 1270
1167 Type* AsmTyper::GetType(Variable* variable) { 1271 Type* AsmTyper::GetType(Variable* variable) {
1168 i::ZoneHashMap::Entry* entry = NULL; 1272 VariableInfo* info = GetVariableInfo(variable, false);
1169 if (in_function_) { 1273 if (!info) return NULL;
1170 entry = local_variable_type_.Lookup(variable, ComputePointerHash(variable)); 1274 return info->type;
1171 }
1172 if (entry == NULL) {
1173 entry =
1174 global_variable_type_.Lookup(variable, ComputePointerHash(variable));
1175 }
1176 if (entry == NULL) {
1177 return NULL;
1178 } else {
1179 return reinterpret_cast<Type*>(entry->value);
1180 }
1181 } 1275 }
1182 1276
1183 1277
1278 AsmTyper::VariableInfo* AsmTyper::GetVariableInfo(Variable* variable,
1279 bool setting) {
1280 ZoneHashMap::Entry* entry;
1281 ZoneHashMap* map;
1282 if (in_function_) {
1283 map = &local_variable_type_;
1284 } else {
1285 map = &global_variable_type_;
1286 }
1287 if (setting) {
1288 entry = map->LookupOrInsert(variable, ComputePointerHash(variable),
1289 ZoneAllocationPolicy(zone()));
1290 } else {
1291 entry = map->Lookup(variable, ComputePointerHash(variable));
1292 if (!entry && in_function_) {
1293 entry =
1294 global_variable_type_.Lookup(variable, ComputePointerHash(variable));
1295 }
1296 }
1297 if (!entry) return NULL;
1298 if (!entry->value) {
1299 if (!setting) return NULL;
1300 entry->value = new (zone()) VariableInfo;
1301 }
1302 return reinterpret_cast<VariableInfo*>(entry->value);
1303 }
1304
1305
1306 void AsmTyper::SetVariableInfo(Variable* variable, const VariableInfo* info) {
1307 VariableInfo* dest = GetVariableInfo(variable, true);
1308 dest->type = info->type;
1309 dest->is_check_function = info->is_check_function;
1310 dest->is_constructor_function = info->is_constructor_function;
1311 }
1312
1313
1184 void AsmTyper::SetResult(Expression* expr, Type* type) { 1314 void AsmTyper::SetResult(Expression* expr, Type* type) {
1185 computed_type_ = type; 1315 computed_type_ = type;
1186 expr->set_bounds(Bounds(computed_type_)); 1316 expr->set_bounds(Bounds(computed_type_));
1187 } 1317 }
1188 1318
1189 1319
1190 void AsmTyper::IntersectResult(Expression* expr, Type* type) { 1320 void AsmTyper::IntersectResult(Expression* expr, Type* type) {
1191 computed_type_ = type; 1321 computed_type_ = type;
1192 Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone()); 1322 Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone());
1193 expr->set_bounds(Bounds(bounded_type)); 1323 expr->set_bounds(Bounds(bounded_type));
(...skipping 12 matching lines...) Expand all
1206 computed_type_->Print(); 1336 computed_type_->Print();
1207 PrintF("Expected type: "); 1337 PrintF("Expected type: ");
1208 expected_type_->Print(); 1338 expected_type_->Print();
1209 #endif 1339 #endif
1210 FAIL(expr, msg); 1340 FAIL(expr, msg);
1211 } 1341 }
1212 expected_type_ = save; 1342 expected_type_ = save;
1213 } 1343 }
1214 } // namespace internal 1344 } // namespace internal
1215 } // namespace v8 1345 } // namespace v8
OLDNEW
« src/typing-asm.h ('K') | « src/typing-asm.h ('k') | test/cctest/test-asm-validator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698