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

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: fixes 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
« no previous file with comments | « src/typing-asm.h ('k') | test/cctest/test-asm-validator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/ast.h" 9 #include "src/ast/ast.h"
10 #include "src/ast/scopes.h" 10 #include "src/ast/scopes.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 VariableInfo* info = GetVariableInfo(var, false);
736 if (info) {
737 if (info->is_stdlib) return info->is_stdlib;
738 }
739 if (var->location() != VariableLocation::PARAMETER || var->index() != 0) {
740 return false;
741 }
742 info = GetVariableInfo(var, true);
743 info->type = Type::Object();
744 info->is_stdlib = true;
745 return true;
746 }
747
748
749 Expression* AsmTyper::GetReceiverOfPropertyAccess(Expression* expr,
750 const char* name) {
751 Property* property = expr->AsProperty();
752 if (property == NULL) {
753 return NULL;
754 }
755 Literal* key = property->key()->AsLiteral();
756 if (key == NULL || !key->IsPropertyName() ||
757 !key->AsPropertyName()->IsUtf8EqualTo(CStrVector(name))) {
758 return NULL;
759 }
760 return property->obj();
761 }
762
763
764 bool AsmTyper::IsMathObject(Expression* expr) {
765 Expression* obj = GetReceiverOfPropertyAccess(expr, "Math");
766 return obj && IsStdlibObject(obj);
767 }
768
769
770 bool AsmTyper::IsSIMDObject(Expression* expr) {
771 Expression* obj = GetReceiverOfPropertyAccess(expr, "SIMD");
772 return obj && IsStdlibObject(obj);
773 }
774
775
776 bool AsmTyper::IsSIMDTypeObject(Expression* expr, const char* name) {
777 Expression* obj = GetReceiverOfPropertyAccess(expr, name);
778 return obj && IsSIMDObject(obj);
779 }
780
781
691 void AsmTyper::VisitProperty(Property* expr) { 782 void AsmTyper::VisitProperty(Property* expr) {
692 // stdlib.Math.x 783 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(); 784 Literal* key = expr->key()->AsLiteral();
697 if (key == NULL || !key->IsPropertyName()) 785 if (key == NULL || !key->IsPropertyName())
698 FAIL(expr, "invalid type annotation on property 2"); 786 FAIL(expr, "invalid key used on Math object");
699 Handle<String> name = key->AsPropertyName(); 787 Handle<String> name = key->AsPropertyName();
700 788 VariableInfo* info = LibType(stdlib_math_types_, name);
701 // Check that inner property name is "Math". 789 if (info == NULL || info->type == NULL) FAIL(expr, "unknown Math function");
702 Literal* math_key = inner_prop->key()->AsLiteral(); 790 SetResult(expr, info->type);
703 if (math_key == NULL || !math_key->IsPropertyName() || 791 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; 792 return;
719 } 793 }
794 #define V(NAME, Name, name, lane_count, lane_type) \
titzer 2015/11/30 20:40:14 That's a big hunk of code. Not sure how many types
bradn 2015/11/30 21:10:50 Done.
795 if (IsSIMDTypeObject(expr->obj(), #Name)) { \
796 Literal* key = expr->key()->AsLiteral(); \
797 if (key == NULL || !key->IsPropertyName()) \
798 FAIL(expr, "invalid key used on SIMD type object"); \
799 Handle<String> kname = key->AsPropertyName(); \
800 VariableInfo* info = LibType(stdlib_simd_##name##_types_, kname); \
801 if (info == NULL || info->type == NULL) \
802 FAIL(expr, "unknown Math function"); \
803 SetResult(expr, info->type); \
804 property_info_ = info; \
805 return; \
806 } \
807 if (IsSIMDTypeObject(expr, #Name)) { \
808 VariableInfo* info = stdlib_simd_##name##_constructor_type_; \
809 SetResult(expr, info->type); \
810 property_info_ = info; \
811 return; \
812 }
813 SIMD128_TYPES(V)
814 #undef V
815 if (IsStdlibObject(expr->obj())) {
816 Literal* key = expr->key()->AsLiteral();
817 if (key == NULL || !key->IsPropertyName())
818 FAIL(expr, "invalid key used on stdlib object");
819 Handle<String> name = key->AsPropertyName();
820 VariableInfo* info = LibType(stdlib_types_, name);
821 if (info == NULL || info->type == NULL)
822 FAIL(expr, "unknown standard function");
823 SetResult(expr, info->type);
824 property_info_ = info;
825 return;
826 }
827
828 property_info_ = NULL;
720 829
721 // Only recurse at this point so that we avoid needing 830 // Only recurse at this point so that we avoid needing
722 // stdlib.Math to have a real type. 831 // stdlib.Math to have a real type.
723 RECURSE(VisitWithExpectation(expr->obj(), Type::Any(), 832 RECURSE(VisitWithExpectation(expr->obj(), Type::Any(),
724 "property holder expected to be object")); 833 "property holder expected to be object"));
725 834
726 // For heap view or function table access. 835 // For heap view or function table access.
727 if (computed_type_->IsArray()) { 836 if (computed_type_->IsArray()) {
728 VisitHeapAccess(expr); 837 VisitHeapAccess(expr);
729 return; 838 return;
730 } 839 }
731 840
732 // Get property name.
733 Literal* key = expr->key()->AsLiteral();
734 if (key == NULL || !key->IsPropertyName())
735 FAIL(expr, "invalid type annotation on property 3");
736 Handle<String> name = key->AsPropertyName();
737
738 // stdlib.x or foreign.x 841 // stdlib.x or foreign.x
739 VariableProxy* proxy = expr->obj()->AsVariableProxy(); 842 VariableProxy* proxy = expr->obj()->AsVariableProxy();
740 if (proxy != NULL) { 843 if (proxy != NULL) {
741 Variable* var = proxy->var(); 844 Variable* var = proxy->var();
742 if (var->location() != VariableLocation::PARAMETER) { 845 if (var->location() == VariableLocation::PARAMETER && var->index() == 1) {
743 FAIL(expr, "invalid type annotation on variable"); 846 // foreign.x is ok.
744 } 847 SetResult(expr, expected_type_);
745 switch (var->index()) { 848 return;
746 case 0: {
747 // Object is stdlib, look up library type.
748 Type* type = LibType(stdlib_types_, name);
749 if (type == NULL) {
750 FAIL(expr, "unknown standard function 4");
751 }
752 SetResult(expr, type);
753 return;
754 }
755 case 1:
756 // Object is foreign lib.
757 SetResult(expr, expected_type_);
758 return;
759 default:
760 FAIL(expr, "invalid type annotation on parameter");
761 } 849 }
762 } 850 }
763 851
764 FAIL(expr, "invalid property access"); 852 FAIL(expr, "invalid property access");
765 } 853 }
766 854
767 855
768 void AsmTyper::VisitCall(Call* expr) { 856 void AsmTyper::VisitCall(Call* expr) {
769 RECURSE(VisitWithExpectation(expr->expression(), Type::Any(), 857 RECURSE(VisitWithExpectation(expr->expression(), Type::Any(),
770 "callee expected to be any")); 858 "callee expected to be any"));
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 void AsmTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) { 1168 void AsmTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {
1081 FAIL(expr, "super property reference not allowed"); 1169 FAIL(expr, "super property reference not allowed");
1082 } 1170 }
1083 1171
1084 1172
1085 void AsmTyper::VisitSuperCallReference(SuperCallReference* expr) { 1173 void AsmTyper::VisitSuperCallReference(SuperCallReference* expr) {
1086 FAIL(expr, "call reference not allowed"); 1174 FAIL(expr, "call reference not allowed");
1087 } 1175 }
1088 1176
1089 1177
1178 void AsmTyper::InitializeStdlibSIMD() {
1179 #define V(NAME, Name, name, lane_count, lane_type) \
1180 { \
1181 Type* type = Type::Function(Type::Name(isolate_, zone()), Type::Any(), \
1182 lane_count, zone()); \
1183 for (int i = 0; i < lane_count; ++i) { \
1184 type->AsFunction()->InitParameter(i, Type::Number()); \
1185 } \
1186 stdlib_simd_##name##_constructor_type_ = new (zone()) VariableInfo(type); \
1187 stdlib_simd_##name##_constructor_type_->is_constructor_function = true; \
1188 }
1189 SIMD128_TYPES(V)
1190 #undef V
1191 }
1192
1193
1090 void AsmTyper::InitializeStdlib() { 1194 void AsmTyper::InitializeStdlib() {
1195 if (allow_simd_) {
1196 InitializeStdlibSIMD();
1197 }
1091 Type* number_type = Type::Number(zone()); 1198 Type* number_type = Type::Number(zone());
1092 Type* double_type = cache_.kAsmDouble; 1199 Type* double_type = cache_.kAsmDouble;
1093 Type* double_fn1_type = Type::Function(double_type, double_type, zone()); 1200 Type* double_fn1_type = Type::Function(double_type, double_type, zone());
1094 Type* double_fn2_type = 1201 Type* double_fn2_type =
1095 Type::Function(double_type, double_type, double_type, zone()); 1202 Type::Function(double_type, double_type, double_type, zone());
1096 1203
1097 Type* fround_type = Type::Function(cache_.kAsmFloat, number_type, zone()); 1204 Type* fround_type = Type::Function(cache_.kAsmFloat, number_type, zone());
1098 Type* imul_type = 1205 Type* imul_type =
1099 Type::Function(cache_.kAsmSigned, cache_.kAsmInt, cache_.kAsmInt, zone()); 1206 Type::Function(cache_.kAsmSigned, cache_.kAsmInt, cache_.kAsmInt, zone());
1100 // TODO(bradnelson): currently only approximating the proper intersection type 1207 // TODO(bradnelson): currently only approximating the proper intersection type
(...skipping 13 matching lines...) Expand all
1114 {"imul", imul_type}, {"abs", abs_type}, 1221 {"imul", imul_type}, {"abs", abs_type},
1115 {"ceil", double_fn1_type}, {"floor", double_fn1_type}, 1222 {"ceil", double_fn1_type}, {"floor", double_fn1_type},
1116 {"fround", fround_type}, {"pow", double_fn2_type}, 1223 {"fround", fround_type}, {"pow", double_fn2_type},
1117 {"exp", double_fn1_type}, {"log", double_fn1_type}, 1224 {"exp", double_fn1_type}, {"log", double_fn1_type},
1118 {"min", double_fn2_type}, {"max", double_fn2_type}, 1225 {"min", double_fn2_type}, {"max", double_fn2_type},
1119 {"sqrt", double_fn1_type}, {"cos", double_fn1_type}, 1226 {"sqrt", double_fn1_type}, {"cos", double_fn1_type},
1120 {"sin", double_fn1_type}, {"tan", double_fn1_type}, 1227 {"sin", double_fn1_type}, {"tan", double_fn1_type},
1121 {"acos", double_fn1_type}, {"asin", double_fn1_type}, 1228 {"acos", double_fn1_type}, {"asin", double_fn1_type},
1122 {"atan", double_fn1_type}, {"atan2", double_fn2_type}}; 1229 {"atan", double_fn1_type}, {"atan2", double_fn2_type}};
1123 for (unsigned i = 0; i < arraysize(math); ++i) { 1230 for (unsigned i = 0; i < arraysize(math); ++i) {
1124 stdlib_math_types_[math[i].name] = math[i].type; 1231 stdlib_math_types_[math[i].name] = new (zone()) VariableInfo(math[i].type);
1125 } 1232 }
1233 stdlib_math_types_["fround"]->is_check_function = true;
1126 1234
1127 stdlib_types_["Infinity"] = double_type; 1235 stdlib_types_["Infinity"] = new (zone()) VariableInfo(double_type);
1128 stdlib_types_["NaN"] = double_type; 1236 stdlib_types_["NaN"] = new (zone()) VariableInfo(double_type);
1129 Type* buffer_type = Type::Any(zone()); 1237 Type* buffer_type = Type::Any(zone());
1130 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \ 1238 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \
1131 stdlib_types_[#TypeName "Array"] = \ 1239 stdlib_types_[#TypeName "Array"] = new (zone()) VariableInfo( \
1132 Type::Function(cache_.k##TypeName##Array, buffer_type, zone()); 1240 Type::Function(cache_.k##TypeName##Array, buffer_type, zone()));
1133 TYPED_ARRAYS(TYPED_ARRAY) 1241 TYPED_ARRAYS(TYPED_ARRAY)
1134 #undef TYPED_ARRAY 1242 #undef TYPED_ARRAY
1135 1243
1136 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \ 1244 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \
1137 stdlib_heap_types_[#TypeName "Array"] = \ 1245 stdlib_heap_types_[#TypeName "Array"] = new (zone()) VariableInfo( \
1138 Type::Function(cache_.k##TypeName##Array, buffer_type, zone()); 1246 Type::Function(cache_.k##TypeName##Array, buffer_type, zone()));
1139 TYPED_ARRAYS(TYPED_ARRAY) 1247 TYPED_ARRAYS(TYPED_ARRAY)
1140 #undef TYPED_ARRAY 1248 #undef TYPED_ARRAY
1141 } 1249 }
1142 1250
1143 1251
1144 Type* AsmTyper::LibType(ObjectTypeMap map, Handle<String> name) { 1252 AsmTyper::VariableInfo* AsmTyper::LibType(ObjectTypeMap map,
1253 Handle<String> name) {
1145 base::SmartArrayPointer<char> aname = name->ToCString(); 1254 base::SmartArrayPointer<char> aname = name->ToCString();
1146 ObjectTypeMap::iterator i = map.find(std::string(aname.get())); 1255 ObjectTypeMap::iterator i = map.find(std::string(aname.get()));
1147 if (i == map.end()) { 1256 if (i == map.end()) {
1148 return NULL; 1257 return NULL;
1149 } 1258 }
1150 return i->second; 1259 return i->second;
1151 } 1260 }
1152 1261
1153 1262
1154 void AsmTyper::SetType(Variable* variable, Type* type) { 1263 void AsmTyper::SetType(Variable* variable, Type* type) {
1155 ZoneHashMap::Entry* entry; 1264 VariableInfo* info = GetVariableInfo(variable, true);
1156 if (in_function_) { 1265 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 } 1266 }
1165 1267
1166 1268
1167 Type* AsmTyper::GetType(Variable* variable) { 1269 Type* AsmTyper::GetType(Variable* variable) {
1168 i::ZoneHashMap::Entry* entry = NULL; 1270 VariableInfo* info = GetVariableInfo(variable, false);
1169 if (in_function_) { 1271 if (!info) return NULL;
1170 entry = local_variable_type_.Lookup(variable, ComputePointerHash(variable)); 1272 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 } 1273 }
1182 1274
1183 1275
1276 AsmTyper::VariableInfo* AsmTyper::GetVariableInfo(Variable* variable,
1277 bool setting) {
1278 ZoneHashMap::Entry* entry;
1279 ZoneHashMap* map;
1280 if (in_function_) {
1281 map = &local_variable_type_;
1282 } else {
1283 map = &global_variable_type_;
1284 }
1285 if (setting) {
1286 entry = map->LookupOrInsert(variable, ComputePointerHash(variable),
1287 ZoneAllocationPolicy(zone()));
1288 } else {
1289 entry = map->Lookup(variable, ComputePointerHash(variable));
1290 if (!entry && in_function_) {
1291 entry =
1292 global_variable_type_.Lookup(variable, ComputePointerHash(variable));
1293 }
1294 }
1295 if (!entry) return NULL;
1296 if (!entry->value) {
1297 if (!setting) return NULL;
1298 entry->value = new (zone()) VariableInfo;
1299 }
1300 return reinterpret_cast<VariableInfo*>(entry->value);
1301 }
1302
1303
1304 void AsmTyper::SetVariableInfo(Variable* variable, const VariableInfo* info) {
titzer 2015/11/30 20:40:14 You probably need to initialize is_stdlib_object h
bradn 2015/11/30 21:10:50 Done.
1305 VariableInfo* dest = GetVariableInfo(variable, true);
1306 dest->type = info->type;
1307 dest->is_check_function = info->is_check_function;
1308 dest->is_constructor_function = info->is_constructor_function;
1309 }
1310
1311
1184 void AsmTyper::SetResult(Expression* expr, Type* type) { 1312 void AsmTyper::SetResult(Expression* expr, Type* type) {
1185 computed_type_ = type; 1313 computed_type_ = type;
1186 expr->set_bounds(Bounds(computed_type_)); 1314 expr->set_bounds(Bounds(computed_type_));
1187 } 1315 }
1188 1316
1189 1317
1190 void AsmTyper::IntersectResult(Expression* expr, Type* type) { 1318 void AsmTyper::IntersectResult(Expression* expr, Type* type) {
1191 computed_type_ = type; 1319 computed_type_ = type;
1192 Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone()); 1320 Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone());
1193 expr->set_bounds(Bounds(bounded_type)); 1321 expr->set_bounds(Bounds(bounded_type));
(...skipping 12 matching lines...) Expand all
1206 computed_type_->Print(); 1334 computed_type_->Print();
1207 PrintF("Expected type: "); 1335 PrintF("Expected type: ");
1208 expected_type_->Print(); 1336 expected_type_->Print();
1209 #endif 1337 #endif
1210 FAIL(expr, msg); 1338 FAIL(expr, msg);
1211 } 1339 }
1212 expected_type_ = save; 1340 expected_type_ = save;
1213 } 1341 }
1214 } // namespace internal 1342 } // namespace internal
1215 } // namespace v8 1343 } // namespace v8
OLDNEW
« no previous file with comments | « 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