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

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

Issue 2057403003: Hooking up asm-wasm conversion. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 4 years, 5 months 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/asmjs/typing-asm.h ('k') | src/bootstrapper.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/typing-asm.h" 5 #include "src/asmjs/typing-asm.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
11 #include "src/ast/ast.h" 11 #include "src/ast/ast.h"
12 #include "src/ast/scopes.h" 12 #include "src/ast/scopes.h"
13 #include "src/codegen.h" 13 #include "src/codegen.h"
14 #include "src/type-cache.h" 14 #include "src/type-cache.h"
15 15
(...skipping 20 matching lines...) Expand all
36 } while (false) 36 } while (false)
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 isolate_(isolate),
42 script_(script), 42 script_(script),
43 root_(root), 43 root_(root),
44 valid_(true), 44 valid_(true),
45 allow_simd_(false), 45 allow_simd_(false),
46 fixed_signature_(false),
46 property_info_(nullptr), 47 property_info_(nullptr),
47 intish_(0), 48 intish_(0),
48 stdlib_types_(zone), 49 stdlib_types_(zone),
49 stdlib_heap_types_(zone), 50 stdlib_heap_types_(zone),
50 stdlib_math_types_(zone), 51 stdlib_math_types_(zone),
51 #define V(NAME, Name, name, lane_count, lane_type) \ 52 #define V(NAME, Name, name, lane_count, lane_type) \
52 stdlib_simd_##name##_types_(zone), 53 stdlib_simd_##name##_types_(zone),
53 SIMD128_TYPES(V) 54 SIMD128_TYPES(V)
54 #undef V 55 #undef V
55 global_variable_type_(base::HashMap::PointersMatch, 56 global_variable_type_(base::HashMap::PointersMatch,
56 ZoneHashMap::kDefaultHashMapCapacity, 57 ZoneHashMap::kDefaultHashMapCapacity,
57 ZoneAllocationPolicy(zone)), 58 ZoneAllocationPolicy(zone)),
58 local_variable_type_(base::HashMap::PointersMatch, 59 local_variable_type_(base::HashMap::PointersMatch,
59 ZoneHashMap::kDefaultHashMapCapacity, 60 ZoneHashMap::kDefaultHashMapCapacity,
60 ZoneAllocationPolicy(zone)), 61 ZoneAllocationPolicy(zone)),
61 in_function_(false), 62 in_function_(false),
62 building_function_tables_(false), 63 building_function_tables_(false),
63 visiting_exports_(false), 64 visiting_exports_(false),
64 cache_(TypeCache::Get()), 65 cache_(TypeCache::Get()),
65 bounds_(zone) { 66 bounds_(zone) {
66 InitializeAstVisitor(isolate); 67 InitializeAstVisitor(isolate);
67 InitializeStdlib(); 68 InitializeStdlib();
68 } 69 }
69 70
70
71 bool AsmTyper::Validate() { 71 bool AsmTyper::Validate() {
72 VisitAsmModule(root_); 72 VisitAsmModule(root_);
73 return valid_ && !HasStackOverflow(); 73 return valid_ && !HasStackOverflow();
74 } 74 }
75 75
76
77 void AsmTyper::VisitAsmModule(FunctionLiteral* fun) { 76 void AsmTyper::VisitAsmModule(FunctionLiteral* fun) {
78 Scope* scope = fun->scope(); 77 Scope* scope = fun->scope();
79 if (!scope->is_function_scope()) FAIL(fun, "not at function scope"); 78 if (!scope->is_function_scope()) FAIL(fun, "not at function scope");
80 79
81 ExpressionStatement* use_asm = fun->body()->first()->AsExpressionStatement(); 80 ExpressionStatement* use_asm = fun->body()->first()->AsExpressionStatement();
82 if (use_asm == nullptr) FAIL(fun, "missing \"use asm\""); 81 if (use_asm == nullptr) FAIL(fun, "missing \"use asm\"");
83 Literal* use_asm_literal = use_asm->expression()->AsLiteral(); 82 Literal* use_asm_literal = use_asm->expression()->AsLiteral();
84 if (use_asm_literal == nullptr) FAIL(fun, "missing \"use asm\""); 83 if (use_asm_literal == nullptr) FAIL(fun, "missing \"use asm\"");
85 if (!use_asm_literal->raw_value()->AsString()->IsOneByteEqualTo("use asm")) 84 if (!use_asm_literal->raw_value()->AsString()->IsOneByteEqualTo("use asm"))
86 FAIL(fun, "missing \"use asm\""); 85 FAIL(fun, "missing \"use asm\"");
87 86
87 // TODO(bradnelson): Generalize this.
88 if (fixed_signature_ && scope->num_parameters() != 3) {
89 FAIL(fun,
90 "only asm modules with (stdlib, foreign, heap) "
91 "parameters currently supported");
92 }
93
88 // Module parameters. 94 // Module parameters.
89 for (int i = 0; i < scope->num_parameters(); ++i) { 95 for (int i = 0; i < scope->num_parameters(); ++i) {
90 Variable* param = scope->parameter(i); 96 Variable* param = scope->parameter(i);
91 DCHECK(GetType(param) == nullptr); 97 DCHECK(GetType(param) == nullptr);
92 SetType(param, Type::None()); 98 SetType(param, Type::None());
93 } 99 }
94 100
95 ZoneList<Declaration*>* decls = scope->declarations(); 101 ZoneList<Declaration*>* decls = scope->declarations();
96 102
97 // Set all globals to type Any. 103 // Set all globals to type Any.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 // Validate exports. 142 // Validate exports.
137 visiting_exports_ = true; 143 visiting_exports_ = true;
138 ReturnStatement* stmt = fun->body()->last()->AsReturnStatement(); 144 ReturnStatement* stmt = fun->body()->last()->AsReturnStatement();
139 if (stmt == nullptr) { 145 if (stmt == nullptr) {
140 FAIL(fun->body()->last(), "last statement in module is not a return"); 146 FAIL(fun->body()->last(), "last statement in module is not a return");
141 } 147 }
142 RECURSE(VisitWithExpectation(stmt->expression(), Type::Object(), 148 RECURSE(VisitWithExpectation(stmt->expression(), Type::Object(),
143 "expected object export")); 149 "expected object export"));
144 } 150 }
145 151
146
147 void AsmTyper::VisitVariableDeclaration(VariableDeclaration* decl) { 152 void AsmTyper::VisitVariableDeclaration(VariableDeclaration* decl) {
148 Variable* var = decl->proxy()->var(); 153 Variable* var = decl->proxy()->var();
149 if (var->location() != VariableLocation::PARAMETER) { 154 if (var->location() != VariableLocation::PARAMETER) {
150 if (GetType(var) == nullptr) { 155 if (GetType(var) == nullptr) {
151 SetType(var, Type::Any()); 156 SetType(var, Type::Any());
152 } else { 157 } else {
153 DCHECK(!GetType(var)->IsFunction()); 158 DCHECK(!GetType(var)->IsFunction());
154 } 159 }
155 } 160 }
156 DCHECK(GetType(var) != nullptr); 161 DCHECK(GetType(var) != nullptr);
157 intish_ = 0; 162 intish_ = 0;
158 } 163 }
159 164
160
161 void AsmTyper::VisitFunctionDeclaration(FunctionDeclaration* decl) { 165 void AsmTyper::VisitFunctionDeclaration(FunctionDeclaration* decl) {
162 if (in_function_) { 166 if (in_function_) {
163 FAIL(decl, "function declared inside another"); 167 FAIL(decl, "function declared inside another");
164 } 168 }
165 // Set function type so global references to functions have some type 169 // Set function type so global references to functions have some type
166 // (so they can give a more useful error). 170 // (so they can give a more useful error).
167 Variable* var = decl->proxy()->var(); 171 Variable* var = decl->proxy()->var();
168 if (GetVariableInfo(var)) { 172 if (GetVariableInfo(var)) {
169 // Detect previously-seen functions. 173 // Detect previously-seen functions.
170 FAIL(decl->fun(), "function repeated in module"); 174 FAIL(decl->fun(), "function repeated in module");
171 } 175 }
172 SetType(var, Type::Function()); 176 SetType(var, Type::Function());
173 } 177 }
174 178
175
176 void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) { 179 void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
177 // Extract result type. 180 // Extract result type.
178 ZoneList<Statement*>* body = fun->body(); 181 ZoneList<Statement*>* body = fun->body();
179 Type* result_type = Type::Undefined(); 182 Type* result_type = Type::Undefined();
180 if (body->length() > 0) { 183 if (body->length() > 0) {
181 ReturnStatement* stmt = body->last()->AsReturnStatement(); 184 ReturnStatement* stmt = body->last()->AsReturnStatement();
182 if (stmt != nullptr) { 185 if (stmt != nullptr) {
183 Literal* literal = stmt->expression()->AsLiteral(); 186 Literal* literal = stmt->expression()->AsLiteral();
184 Type* old_expected = expected_type_; 187 Type* old_expected = expected_type_;
185 expected_type_ = Type::Any(); 188 expected_type_ = Type::Any();
(...skipping 30 matching lines...) Expand all
216 } 219 }
217 SetType(var, computed_type_); 220 SetType(var, computed_type_);
218 type->AsFunction()->InitParameter(i, computed_type_); 221 type->AsFunction()->InitParameter(i, computed_type_);
219 good = true; 222 good = true;
220 } 223 }
221 if (!good) FAIL(fun, "missing parameter type annotations"); 224 if (!good) FAIL(fun, "missing parameter type annotations");
222 225
223 SetResult(fun, type); 226 SetResult(fun, type);
224 } 227 }
225 228
226
227 void AsmTyper::VisitExpressionAnnotation(Expression* expr, Variable* var, 229 void AsmTyper::VisitExpressionAnnotation(Expression* expr, Variable* var,
228 bool is_return) { 230 bool is_return) {
229 // Normal +x or x|0 annotations. 231 // Normal +x or x|0 annotations.
230 BinaryOperation* bin = expr->AsBinaryOperation(); 232 BinaryOperation* bin = expr->AsBinaryOperation();
231 if (bin != nullptr) { 233 if (bin != nullptr) {
232 if (var != nullptr) { 234 if (var != nullptr) {
233 VariableProxy* proxy = bin->left()->AsVariableProxy(); 235 VariableProxy* proxy = bin->left()->AsVariableProxy();
234 if (proxy == nullptr) { 236 if (proxy == nullptr) {
235 FAIL(bin->left(), "expected variable for type annotation"); 237 FAIL(bin->left(), "expected variable for type annotation");
236 } 238 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 FAIL(call, "invalid argument count calling function"); 298 FAIL(call, "invalid argument count calling function");
297 } 299 }
298 SetResult(expr, type->AsFunction()->Result()); 300 SetResult(expr, type->AsFunction()->Result());
299 return; 301 return;
300 } 302 }
301 } 303 }
302 304
303 FAIL(expr, "invalid type annotation"); 305 FAIL(expr, "invalid type annotation");
304 } 306 }
305 307
306
307 void AsmTyper::VisitStatements(ZoneList<Statement*>* stmts) { 308 void AsmTyper::VisitStatements(ZoneList<Statement*>* stmts) {
308 for (int i = 0; i < stmts->length(); ++i) { 309 for (int i = 0; i < stmts->length(); ++i) {
309 Statement* stmt = stmts->at(i); 310 Statement* stmt = stmts->at(i);
310 RECURSE(Visit(stmt)); 311 RECURSE(Visit(stmt));
311 } 312 }
312 } 313 }
313 314
314
315 void AsmTyper::VisitBlock(Block* stmt) { 315 void AsmTyper::VisitBlock(Block* stmt) {
316 RECURSE(VisitStatements(stmt->statements())); 316 RECURSE(VisitStatements(stmt->statements()));
317 } 317 }
318 318
319
320 void AsmTyper::VisitExpressionStatement(ExpressionStatement* stmt) { 319 void AsmTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
321 RECURSE(VisitWithExpectation(stmt->expression(), Type::Any(), 320 RECURSE(VisitWithExpectation(stmt->expression(), Type::Any(),
322 "expression statement expected to be any")); 321 "expression statement expected to be any"));
323 } 322 }
324 323
325
326 void AsmTyper::VisitEmptyStatement(EmptyStatement* stmt) {} 324 void AsmTyper::VisitEmptyStatement(EmptyStatement* stmt) {}
327 325
328
329 void AsmTyper::VisitSloppyBlockFunctionStatement( 326 void AsmTyper::VisitSloppyBlockFunctionStatement(
330 SloppyBlockFunctionStatement* stmt) { 327 SloppyBlockFunctionStatement* stmt) {
331 Visit(stmt->statement()); 328 Visit(stmt->statement());
332 } 329 }
333 330
334
335 void AsmTyper::VisitEmptyParentheses(EmptyParentheses* expr) { UNREACHABLE(); } 331 void AsmTyper::VisitEmptyParentheses(EmptyParentheses* expr) { UNREACHABLE(); }
336 332
337
338 void AsmTyper::VisitIfStatement(IfStatement* stmt) { 333 void AsmTyper::VisitIfStatement(IfStatement* stmt) {
339 if (!in_function_) { 334 if (!in_function_) {
340 FAIL(stmt, "if statement inside module body"); 335 FAIL(stmt, "if statement inside module body");
341 } 336 }
342 RECURSE(VisitWithExpectation(stmt->condition(), cache_.kAsmInt, 337 RECURSE(VisitWithExpectation(stmt->condition(), cache_.kAsmInt,
343 "if condition expected to be integer")); 338 "if condition expected to be integer"));
344 if (intish_ != 0) { 339 if (intish_ != 0) {
345 FAIL(stmt, "if condition expected to be signed or unsigned"); 340 FAIL(stmt, "if condition expected to be signed or unsigned");
346 } 341 }
347 RECURSE(Visit(stmt->then_statement())); 342 RECURSE(Visit(stmt->then_statement()));
348 RECURSE(Visit(stmt->else_statement())); 343 RECURSE(Visit(stmt->else_statement()));
349 } 344 }
350 345
351
352 void AsmTyper::VisitContinueStatement(ContinueStatement* stmt) { 346 void AsmTyper::VisitContinueStatement(ContinueStatement* stmt) {
353 if (!in_function_) { 347 if (!in_function_) {
354 FAIL(stmt, "continue statement inside module body"); 348 FAIL(stmt, "continue statement inside module body");
355 } 349 }
356 } 350 }
357 351
358
359 void AsmTyper::VisitBreakStatement(BreakStatement* stmt) { 352 void AsmTyper::VisitBreakStatement(BreakStatement* stmt) {
360 if (!in_function_) { 353 if (!in_function_) {
361 FAIL(stmt, "continue statement inside module body"); 354 FAIL(stmt, "continue statement inside module body");
362 } 355 }
363 } 356 }
364 357
365
366 void AsmTyper::VisitReturnStatement(ReturnStatement* stmt) { 358 void AsmTyper::VisitReturnStatement(ReturnStatement* stmt) {
367 // Handle module return statement in VisitAsmModule. 359 // Handle module return statement in VisitAsmModule.
368 if (!in_function_) { 360 if (!in_function_) {
369 return; 361 return;
370 } 362 }
371 Literal* literal = stmt->expression()->AsLiteral(); 363 Literal* literal = stmt->expression()->AsLiteral();
372 if (literal) { 364 if (literal) {
373 VisitLiteral(literal, true); 365 VisitLiteral(literal, true);
374 } else { 366 } else {
375 RECURSE( 367 RECURSE(
376 VisitWithExpectation(stmt->expression(), Type::Any(), 368 VisitWithExpectation(stmt->expression(), Type::Any(),
377 "return expression expected to have return type")); 369 "return expression expected to have return type"));
378 } 370 }
379 if (!computed_type_->Is(return_type_) || !return_type_->Is(computed_type_)) { 371 if (!computed_type_->Is(return_type_) || !return_type_->Is(computed_type_)) {
380 FAIL(stmt->expression(), "return type does not match function signature"); 372 FAIL(stmt->expression(), "return type does not match function signature");
381 } 373 }
382 } 374 }
383 375
384
385 void AsmTyper::VisitWithStatement(WithStatement* stmt) { 376 void AsmTyper::VisitWithStatement(WithStatement* stmt) {
386 FAIL(stmt, "bad with statement"); 377 FAIL(stmt, "bad with statement");
387 } 378 }
388 379
389
390 void AsmTyper::VisitSwitchStatement(SwitchStatement* stmt) { 380 void AsmTyper::VisitSwitchStatement(SwitchStatement* stmt) {
391 if (!in_function_) { 381 if (!in_function_) {
392 FAIL(stmt, "switch statement inside module body"); 382 FAIL(stmt, "switch statement inside module body");
393 } 383 }
394 RECURSE(VisitWithExpectation(stmt->tag(), cache_.kAsmSigned, 384 RECURSE(VisitWithExpectation(stmt->tag(), cache_.kAsmSigned,
395 "switch expression non-integer")); 385 "switch expression non-integer"));
396 ZoneList<CaseClause*>* clauses = stmt->cases(); 386 ZoneList<CaseClause*>* clauses = stmt->cases();
397 ZoneSet<int32_t> cases(zone()); 387 ZoneSet<int32_t> cases(zone());
398 for (int i = 0; i < clauses->length(); ++i) { 388 for (int i = 0; i < clauses->length(); ++i) {
399 CaseClause* clause = clauses->at(i); 389 CaseClause* clause = clauses->at(i);
(...skipping 20 matching lines...) Expand all
420 } 410 }
421 if (cases.size() > 0) { 411 if (cases.size() > 0) {
422 int64_t min_case = *cases.begin(); 412 int64_t min_case = *cases.begin();
423 int64_t max_case = *cases.rbegin(); 413 int64_t max_case = *cases.rbegin();
424 if (max_case - min_case > std::numeric_limits<int32_t>::max()) { 414 if (max_case - min_case > std::numeric_limits<int32_t>::max()) {
425 FAIL(stmt, "case range too large"); 415 FAIL(stmt, "case range too large");
426 } 416 }
427 } 417 }
428 } 418 }
429 419
430
431 void AsmTyper::VisitCaseClause(CaseClause* clause) { UNREACHABLE(); } 420 void AsmTyper::VisitCaseClause(CaseClause* clause) { UNREACHABLE(); }
432 421
433
434 void AsmTyper::VisitDoWhileStatement(DoWhileStatement* stmt) { 422 void AsmTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
435 if (!in_function_) { 423 if (!in_function_) {
436 FAIL(stmt, "do statement inside module body"); 424 FAIL(stmt, "do statement inside module body");
437 } 425 }
438 RECURSE(Visit(stmt->body())); 426 RECURSE(Visit(stmt->body()));
439 RECURSE(VisitWithExpectation(stmt->cond(), cache_.kAsmInt, 427 RECURSE(VisitWithExpectation(stmt->cond(), cache_.kAsmInt,
440 "do condition expected to be integer")); 428 "do condition expected to be integer"));
441 if (intish_ != 0) { 429 if (intish_ != 0) {
442 FAIL(stmt, "do condition expected to be signed or unsigned"); 430 FAIL(stmt, "do condition expected to be signed or unsigned");
443 } 431 }
444 } 432 }
445 433
446
447 void AsmTyper::VisitWhileStatement(WhileStatement* stmt) { 434 void AsmTyper::VisitWhileStatement(WhileStatement* stmt) {
448 if (!in_function_) { 435 if (!in_function_) {
449 FAIL(stmt, "while statement inside module body"); 436 FAIL(stmt, "while statement inside module body");
450 } 437 }
451 RECURSE(VisitWithExpectation(stmt->cond(), cache_.kAsmInt, 438 RECURSE(VisitWithExpectation(stmt->cond(), cache_.kAsmInt,
452 "while condition expected to be integer")); 439 "while condition expected to be integer"));
453 if (intish_ != 0) { 440 if (intish_ != 0) {
454 FAIL(stmt, "while condition expected to be signed or unsigned"); 441 FAIL(stmt, "while condition expected to be signed or unsigned");
455 } 442 }
456 RECURSE(Visit(stmt->body())); 443 RECURSE(Visit(stmt->body()));
457 } 444 }
458 445
459
460 void AsmTyper::VisitForStatement(ForStatement* stmt) { 446 void AsmTyper::VisitForStatement(ForStatement* stmt) {
461 if (!in_function_) { 447 if (!in_function_) {
462 FAIL(stmt, "for statement inside module body"); 448 FAIL(stmt, "for statement inside module body");
463 } 449 }
464 if (stmt->init() != nullptr) { 450 if (stmt->init() != nullptr) {
465 RECURSE(Visit(stmt->init())); 451 RECURSE(Visit(stmt->init()));
466 } 452 }
467 if (stmt->cond() != nullptr) { 453 if (stmt->cond() != nullptr) {
468 RECURSE(VisitWithExpectation(stmt->cond(), cache_.kAsmInt, 454 RECURSE(VisitWithExpectation(stmt->cond(), cache_.kAsmInt,
469 "for condition expected to be integer")); 455 "for condition expected to be integer"));
470 } 456 }
471 if (intish_ != 0) { 457 if (intish_ != 0) {
472 FAIL(stmt, "for condition expected to be signed or unsigned"); 458 FAIL(stmt, "for condition expected to be signed or unsigned");
473 } 459 }
474 if (stmt->next() != nullptr) { 460 if (stmt->next() != nullptr) {
475 RECURSE(Visit(stmt->next())); 461 RECURSE(Visit(stmt->next()));
476 } 462 }
477 RECURSE(Visit(stmt->body())); 463 RECURSE(Visit(stmt->body()));
478 } 464 }
479 465
480
481 void AsmTyper::VisitForInStatement(ForInStatement* stmt) { 466 void AsmTyper::VisitForInStatement(ForInStatement* stmt) {
482 FAIL(stmt, "for-in statement encountered"); 467 FAIL(stmt, "for-in statement encountered");
483 } 468 }
484 469
485
486 void AsmTyper::VisitForOfStatement(ForOfStatement* stmt) { 470 void AsmTyper::VisitForOfStatement(ForOfStatement* stmt) {
487 FAIL(stmt, "for-of statement encountered"); 471 FAIL(stmt, "for-of statement encountered");
488 } 472 }
489 473
490
491 void AsmTyper::VisitTryCatchStatement(TryCatchStatement* stmt) { 474 void AsmTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
492 FAIL(stmt, "try statement encountered"); 475 FAIL(stmt, "try statement encountered");
493 } 476 }
494 477
495
496 void AsmTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 478 void AsmTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
497 FAIL(stmt, "try statement encountered"); 479 FAIL(stmt, "try statement encountered");
498 } 480 }
499 481
500
501 void AsmTyper::VisitDebuggerStatement(DebuggerStatement* stmt) { 482 void AsmTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
502 FAIL(stmt, "debugger statement encountered"); 483 FAIL(stmt, "debugger statement encountered");
503 } 484 }
504 485
505
506 void AsmTyper::VisitFunctionLiteral(FunctionLiteral* expr) { 486 void AsmTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
507 if (in_function_) { 487 if (in_function_) {
508 FAIL(expr, "invalid nested function"); 488 FAIL(expr, "invalid nested function");
509 } 489 }
510 Scope* scope = expr->scope(); 490 Scope* scope = expr->scope();
511 DCHECK(scope->is_function_scope()); 491 DCHECK(scope->is_function_scope());
512 492
513 if (!bounds_.get(expr).upper->IsFunction()) { 493 if (!bounds_.get(expr).upper->IsFunction()) {
514 FAIL(expr, "invalid function literal"); 494 FAIL(expr, "invalid function literal");
515 } 495 }
516 496
517 Type* type = bounds_.get(expr).upper; 497 Type* type = bounds_.get(expr).upper;
518 Type* save_return_type = return_type_; 498 Type* save_return_type = return_type_;
519 return_type_ = type->AsFunction()->Result(); 499 return_type_ = type->AsFunction()->Result();
520 in_function_ = true; 500 in_function_ = true;
521 local_variable_type_.Clear(); 501 local_variable_type_.Clear();
522 RECURSE(VisitDeclarations(scope->declarations())); 502 RECURSE(VisitDeclarations(scope->declarations()));
523 RECURSE(VisitStatements(expr->body())); 503 RECURSE(VisitStatements(expr->body()));
524 in_function_ = false; 504 in_function_ = false;
525 return_type_ = save_return_type; 505 return_type_ = save_return_type;
526 RECURSE(IntersectResult(expr, type)); 506 RECURSE(IntersectResult(expr, type));
527 } 507 }
528 508
529
530 void AsmTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 509 void AsmTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
531 FAIL(expr, "function info literal encountered"); 510 FAIL(expr, "function info literal encountered");
532 } 511 }
533 512
534
535 void AsmTyper::VisitDoExpression(DoExpression* expr) { 513 void AsmTyper::VisitDoExpression(DoExpression* expr) {
536 FAIL(expr, "do-expression encountered"); 514 FAIL(expr, "do-expression encountered");
537 } 515 }
538 516
539
540 void AsmTyper::VisitConditional(Conditional* expr) { 517 void AsmTyper::VisitConditional(Conditional* expr) {
541 if (!in_function_) { 518 if (!in_function_) {
542 FAIL(expr, "ternary operator inside module body"); 519 FAIL(expr, "ternary operator inside module body");
543 } 520 }
544 RECURSE(VisitWithExpectation(expr->condition(), Type::Number(), 521 RECURSE(VisitWithExpectation(expr->condition(), Type::Number(),
545 "condition expected to be integer")); 522 "condition expected to be integer"));
546 if (!computed_type_->Is(cache_.kAsmInt)) { 523 if (!computed_type_->Is(cache_.kAsmInt)) {
547 FAIL(expr->condition(), "condition must be of type int"); 524 FAIL(expr->condition(), "condition must be of type int");
548 } 525 }
549 526
(...skipping 15 matching lines...) Expand all
565 (then_type->Is(cache_.kAsmDouble) && 542 (then_type->Is(cache_.kAsmDouble) &&
566 else_type->Is(cache_.kAsmDouble)))) { 543 else_type->Is(cache_.kAsmDouble)))) {
567 FAIL(expr, 544 FAIL(expr,
568 "then and else expressions in ? must have the same type " 545 "then and else expressions in ? must have the same type "
569 "and be int, float, or double"); 546 "and be int, float, or double");
570 } 547 }
571 548
572 RECURSE(IntersectResult(expr, then_type)); 549 RECURSE(IntersectResult(expr, then_type));
573 } 550 }
574 551
575
576 void AsmTyper::VisitVariableProxy(VariableProxy* expr) { 552 void AsmTyper::VisitVariableProxy(VariableProxy* expr) {
577 Variable* var = expr->var(); 553 Variable* var = expr->var();
578 VariableInfo* info = GetVariableInfo(var); 554 VariableInfo* info = GetVariableInfo(var);
579 if (!in_function_ && !building_function_tables_ && !visiting_exports_) { 555 if (!in_function_ && !building_function_tables_ && !visiting_exports_) {
580 if (var->location() != VariableLocation::PARAMETER || var->index() >= 3) { 556 if (var->location() != VariableLocation::PARAMETER || var->index() >= 3) {
581 FAIL(expr, "illegal variable reference in module body"); 557 FAIL(expr, "illegal variable reference in module body");
582 } 558 }
583 } 559 }
584 if (info == nullptr || info->type == nullptr) { 560 if (info == nullptr || info->type == nullptr) {
585 if (var->mode() == TEMPORARY) { 561 if (var->mode() == TEMPORARY) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 } 596 }
621 } else if (!is_return && value->IsString()) { 597 } else if (!is_return && value->IsString()) {
622 RECURSE(IntersectResult(expr, Type::String())); 598 RECURSE(IntersectResult(expr, Type::String()));
623 } else if (value->IsUndefined(isolate_)) { 599 } else if (value->IsUndefined(isolate_)) {
624 RECURSE(IntersectResult(expr, Type::Undefined())); 600 RECURSE(IntersectResult(expr, Type::Undefined()));
625 } else { 601 } else {
626 FAIL(expr, "illegal literal"); 602 FAIL(expr, "illegal literal");
627 } 603 }
628 } 604 }
629 605
630
631 void AsmTyper::VisitLiteral(Literal* expr) { VisitLiteral(expr, false); } 606 void AsmTyper::VisitLiteral(Literal* expr) { VisitLiteral(expr, false); }
632 607
633
634 void AsmTyper::VisitRegExpLiteral(RegExpLiteral* expr) { 608 void AsmTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
635 FAIL(expr, "regular expression encountered"); 609 FAIL(expr, "regular expression encountered");
636 } 610 }
637 611
638
639 void AsmTyper::VisitObjectLiteral(ObjectLiteral* expr) { 612 void AsmTyper::VisitObjectLiteral(ObjectLiteral* expr) {
640 if (in_function_) { 613 if (in_function_) {
641 FAIL(expr, "object literal in function"); 614 FAIL(expr, "object literal in function");
642 } 615 }
643 // Allowed for asm module's export declaration. 616 // Allowed for asm module's export declaration.
644 ZoneList<ObjectLiteralProperty*>* props = expr->properties(); 617 ZoneList<ObjectLiteralProperty*>* props = expr->properties();
645 for (int i = 0; i < props->length(); ++i) { 618 for (int i = 0; i < props->length(); ++i) {
646 ObjectLiteralProperty* prop = props->at(i); 619 ObjectLiteralProperty* prop = props->at(i);
647 RECURSE(VisitWithExpectation(prop->value(), Type::Any(), 620 RECURSE(VisitWithExpectation(prop->value(), Type::Any(),
648 "object property expected to be a function")); 621 "object property expected to be a function"));
649 if (!computed_type_->IsFunction()) { 622 if (!computed_type_->IsFunction()) {
650 FAIL(prop->value(), "non-function in function table"); 623 FAIL(prop->value(), "non-function in function table");
651 } 624 }
652 } 625 }
653 RECURSE(IntersectResult(expr, Type::Object())); 626 RECURSE(IntersectResult(expr, Type::Object()));
654 } 627 }
655 628
656
657 void AsmTyper::VisitArrayLiteral(ArrayLiteral* expr) { 629 void AsmTyper::VisitArrayLiteral(ArrayLiteral* expr) {
658 if (in_function_) { 630 if (in_function_) {
659 FAIL(expr, "array literal inside a function"); 631 FAIL(expr, "array literal inside a function");
660 } 632 }
661 // Allowed for function tables. 633 // Allowed for function tables.
662 ZoneList<Expression*>* values = expr->values(); 634 ZoneList<Expression*>* values = expr->values();
663 Type* elem_type = Type::None(); 635 Type* elem_type = Type::None();
664 for (int i = 0; i < values->length(); ++i) { 636 for (int i = 0; i < values->length(); ++i) {
665 Expression* value = values->at(i); 637 Expression* value = values->at(i);
666 RECURSE(VisitWithExpectation(value, Type::Any(), "UNREACHABLE")); 638 RECURSE(VisitWithExpectation(value, Type::Any(), "UNREACHABLE"));
667 if (!computed_type_->IsFunction()) { 639 if (!computed_type_->IsFunction()) {
668 FAIL(value, "array component expected to be a function"); 640 FAIL(value, "array component expected to be a function");
669 } 641 }
670 elem_type = Type::Union(elem_type, computed_type_, zone()); 642 elem_type = Type::Union(elem_type, computed_type_, zone());
671 } 643 }
672 array_size_ = values->length(); 644 array_size_ = values->length();
673 RECURSE(IntersectResult(expr, Type::Array(elem_type, zone()))); 645 RECURSE(IntersectResult(expr, Type::Array(elem_type, zone())));
674 } 646 }
675 647
676
677 void AsmTyper::VisitAssignment(Assignment* expr) { 648 void AsmTyper::VisitAssignment(Assignment* expr) {
678 // Handle function tables and everything else in different passes. 649 // Handle function tables and everything else in different passes.
679 if (!in_function_) { 650 if (!in_function_) {
680 if (expr->value()->IsArrayLiteral()) { 651 if (expr->value()->IsArrayLiteral()) {
681 if (!building_function_tables_) { 652 if (!building_function_tables_) {
682 return; 653 return;
683 } 654 }
684 } else { 655 } else {
685 if (building_function_tables_) { 656 if (building_function_tables_) {
686 return; 657 return;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 FAIL(property->obj(), "array expected"); 703 FAIL(property->obj(), "array expected");
733 } 704 }
734 if (value_intish != 0 && computed_type_->Is(cache_.kFloat64Array)) { 705 if (value_intish != 0 && computed_type_->Is(cache_.kFloat64Array)) {
735 FAIL(expr, "floatish assignment to double array"); 706 FAIL(expr, "floatish assignment to double array");
736 } 707 }
737 VisitHeapAccess(property, true, target_type); 708 VisitHeapAccess(property, true, target_type);
738 } 709 }
739 RECURSE(IntersectResult(expr, target_type)); 710 RECURSE(IntersectResult(expr, target_type));
740 } 711 }
741 712
742
743 void AsmTyper::VisitYield(Yield* expr) { 713 void AsmTyper::VisitYield(Yield* expr) {
744 FAIL(expr, "yield expression encountered"); 714 FAIL(expr, "yield expression encountered");
745 } 715 }
746 716
747
748 void AsmTyper::VisitThrow(Throw* expr) { 717 void AsmTyper::VisitThrow(Throw* expr) {
749 FAIL(expr, "throw statement encountered"); 718 FAIL(expr, "throw statement encountered");
750 } 719 }
751 720
752
753 int AsmTyper::ElementShiftSize(Type* type) { 721 int AsmTyper::ElementShiftSize(Type* type) {
754 if (type->Is(cache_.kAsmSize8)) return 0; 722 if (type->Is(cache_.kAsmSize8)) return 0;
755 if (type->Is(cache_.kAsmSize16)) return 1; 723 if (type->Is(cache_.kAsmSize16)) return 1;
756 if (type->Is(cache_.kAsmSize32)) return 2; 724 if (type->Is(cache_.kAsmSize32)) return 2;
757 if (type->Is(cache_.kAsmSize64)) return 3; 725 if (type->Is(cache_.kAsmSize64)) return 3;
758 return -1; 726 return -1;
759 } 727 }
760 728
761
762 Type* AsmTyper::StorageType(Type* type) { 729 Type* AsmTyper::StorageType(Type* type) {
763 if (type->Is(cache_.kAsmInt)) { 730 if (type->Is(cache_.kAsmInt)) {
764 return cache_.kAsmInt; 731 return cache_.kAsmInt;
765 } else { 732 } else {
766 return type; 733 return type;
767 } 734 }
768 } 735 }
769 736
770
771 void AsmTyper::VisitHeapAccess(Property* expr, bool assigning, 737 void AsmTyper::VisitHeapAccess(Property* expr, bool assigning,
772 Type* assignment_type) { 738 Type* assignment_type) {
773 ArrayType* array_type = computed_type_->AsArray(); 739 ArrayType* array_type = computed_type_->AsArray();
774 // size_t size = array_size_; 740 // size_t size = array_size_;
775 Type* type = array_type->Element(); 741 Type* type = array_type->Element();
776 if (type->IsFunction()) { 742 if (type->IsFunction()) {
777 if (assigning) { 743 if (assigning) {
778 FAIL(expr, "assigning to function table is illegal"); 744 FAIL(expr, "assigning to function table is illegal");
779 } 745 }
780 // TODO(bradnelson): Fix the parser and then un-comment this part 746 // TODO(bradnelson): Fix the parser and then un-comment this part
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 if (!assignment_type->Is(result_type)) { 820 if (!assignment_type->Is(result_type)) {
855 FAIL(expr, "illegal type in assignment"); 821 FAIL(expr, "illegal type in assignment");
856 } 822 }
857 } else { 823 } else {
858 RECURSE(IntersectResult(expr, expected_type_)); 824 RECURSE(IntersectResult(expr, expected_type_));
859 RECURSE(IntersectResult(expr, result_type)); 825 RECURSE(IntersectResult(expr, result_type));
860 } 826 }
861 } 827 }
862 } 828 }
863 829
864
865 bool AsmTyper::IsStdlibObject(Expression* expr) { 830 bool AsmTyper::IsStdlibObject(Expression* expr) {
866 VariableProxy* proxy = expr->AsVariableProxy(); 831 VariableProxy* proxy = expr->AsVariableProxy();
867 if (proxy == nullptr) { 832 if (proxy == nullptr) {
868 return false; 833 return false;
869 } 834 }
870 Variable* var = proxy->var(); 835 Variable* var = proxy->var();
871 VariableInfo* info = GetVariableInfo(var); 836 VariableInfo* info = GetVariableInfo(var);
872 if (info) { 837 if (info) {
873 if (info->standard_member == kStdlib) return true; 838 if (info->standard_member == kStdlib) return true;
874 } 839 }
875 if (var->location() != VariableLocation::PARAMETER || var->index() != 0) { 840 if (var->location() != VariableLocation::PARAMETER || var->index() != 0) {
876 return false; 841 return false;
877 } 842 }
878 info = MakeVariableInfo(var); 843 info = MakeVariableInfo(var);
879 info->type = Type::Object(); 844 info->type = Type::Object();
880 info->standard_member = kStdlib; 845 info->standard_member = kStdlib;
881 return true; 846 return true;
882 } 847 }
883 848
884
885 Expression* AsmTyper::GetReceiverOfPropertyAccess(Expression* expr, 849 Expression* AsmTyper::GetReceiverOfPropertyAccess(Expression* expr,
886 const char* name) { 850 const char* name) {
887 Property* property = expr->AsProperty(); 851 Property* property = expr->AsProperty();
888 if (property == nullptr) { 852 if (property == nullptr) {
889 return nullptr; 853 return nullptr;
890 } 854 }
891 Literal* key = property->key()->AsLiteral(); 855 Literal* key = property->key()->AsLiteral();
892 if (key == nullptr || !key->IsPropertyName() || 856 if (key == nullptr || !key->IsPropertyName() ||
893 !key->AsPropertyName()->IsUtf8EqualTo(CStrVector(name))) { 857 !key->AsPropertyName()->IsUtf8EqualTo(CStrVector(name))) {
894 return nullptr; 858 return nullptr;
895 } 859 }
896 return property->obj(); 860 return property->obj();
897 } 861 }
898 862
899
900 bool AsmTyper::IsMathObject(Expression* expr) { 863 bool AsmTyper::IsMathObject(Expression* expr) {
901 Expression* obj = GetReceiverOfPropertyAccess(expr, "Math"); 864 Expression* obj = GetReceiverOfPropertyAccess(expr, "Math");
902 return obj && IsStdlibObject(obj); 865 return obj && IsStdlibObject(obj);
903 } 866 }
904 867
905
906 bool AsmTyper::IsSIMDObject(Expression* expr) { 868 bool AsmTyper::IsSIMDObject(Expression* expr) {
907 Expression* obj = GetReceiverOfPropertyAccess(expr, "SIMD"); 869 Expression* obj = GetReceiverOfPropertyAccess(expr, "SIMD");
908 return obj && IsStdlibObject(obj); 870 return obj && IsStdlibObject(obj);
909 } 871 }
910 872
911
912 bool AsmTyper::IsSIMDTypeObject(Expression* expr, const char* name) { 873 bool AsmTyper::IsSIMDTypeObject(Expression* expr, const char* name) {
913 Expression* obj = GetReceiverOfPropertyAccess(expr, name); 874 Expression* obj = GetReceiverOfPropertyAccess(expr, name);
914 return obj && IsSIMDObject(obj); 875 return obj && IsSIMDObject(obj);
915 } 876 }
916 877
917
918 void AsmTyper::VisitProperty(Property* expr) { 878 void AsmTyper::VisitProperty(Property* expr) {
919 if (IsMathObject(expr->obj())) { 879 if (IsMathObject(expr->obj())) {
920 VisitLibraryAccess(&stdlib_math_types_, expr); 880 VisitLibraryAccess(&stdlib_math_types_, expr);
921 return; 881 return;
922 } 882 }
923 #define V(NAME, Name, name, lane_count, lane_type) \ 883 #define V(NAME, Name, name, lane_count, lane_type) \
924 if (IsSIMDTypeObject(expr->obj(), #Name)) { \ 884 if (IsSIMDTypeObject(expr->obj(), #Name)) { \
925 VisitLibraryAccess(&stdlib_simd_##name##_types_, expr); \ 885 VisitLibraryAccess(&stdlib_simd_##name##_types_, expr); \
926 return; \ 886 return; \
927 } \ 887 } \
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 } 1031 }
1072 RECURSE(CheckPolymorphicStdlibArguments(standard_member, args)); 1032 RECURSE(CheckPolymorphicStdlibArguments(standard_member, args));
1073 intish_ = 0; 1033 intish_ = 0;
1074 RECURSE(IntersectResult(expr, result_type)); 1034 RECURSE(IntersectResult(expr, result_type));
1075 } 1035 }
1076 } else { 1036 } else {
1077 FAIL(expr, "invalid callee"); 1037 FAIL(expr, "invalid callee");
1078 } 1038 }
1079 } 1039 }
1080 1040
1081
1082 void AsmTyper::VisitCallNew(CallNew* expr) { 1041 void AsmTyper::VisitCallNew(CallNew* expr) {
1083 if (in_function_) { 1042 if (in_function_) {
1084 FAIL(expr, "new not allowed in module function"); 1043 FAIL(expr, "new not allowed in module function");
1085 } 1044 }
1086 RECURSE(VisitWithExpectation(expr->expression(), Type::Any(), 1045 RECURSE(VisitWithExpectation(expr->expression(), Type::Any(),
1087 "expected stdlib function")); 1046 "expected stdlib function"));
1088 if (computed_type_->IsFunction()) { 1047 if (computed_type_->IsFunction()) {
1089 FunctionType* fun_type = computed_type_->AsFunction(); 1048 FunctionType* fun_type = computed_type_->AsFunction();
1090 ZoneList<Expression*>* args = expr->arguments(); 1049 ZoneList<Expression*>* args = expr->arguments();
1091 if (fun_type->Arity() != args->length()) 1050 if (fun_type->Arity() != args->length())
1092 FAIL(expr, "call with wrong arity"); 1051 FAIL(expr, "call with wrong arity");
1093 for (int i = 0; i < args->length(); ++i) { 1052 for (int i = 0; i < args->length(); ++i) {
1094 Expression* arg = args->at(i); 1053 Expression* arg = args->at(i);
1095 RECURSE(VisitWithExpectation( 1054 RECURSE(VisitWithExpectation(
1096 arg, fun_type->Parameter(i), 1055 arg, fun_type->Parameter(i),
1097 "constructor argument expected to match callee parameter")); 1056 "constructor argument expected to match callee parameter"));
1098 } 1057 }
1099 RECURSE(IntersectResult(expr, fun_type->Result())); 1058 RECURSE(IntersectResult(expr, fun_type->Result()));
1100 return; 1059 return;
1101 } 1060 }
1102 1061
1103 FAIL(expr, "ill-typed new operator"); 1062 FAIL(expr, "ill-typed new operator");
1104 } 1063 }
1105 1064
1106
1107 void AsmTyper::VisitCallRuntime(CallRuntime* expr) { 1065 void AsmTyper::VisitCallRuntime(CallRuntime* expr) {
1108 FAIL(expr, "runtime call not allowed"); 1066 FAIL(expr, "runtime call not allowed");
1109 } 1067 }
1110 1068
1111
1112 void AsmTyper::VisitUnaryOperation(UnaryOperation* expr) { 1069 void AsmTyper::VisitUnaryOperation(UnaryOperation* expr) {
1113 if (!in_function_) { 1070 if (!in_function_) {
1114 FAIL(expr, "unary operator inside module body"); 1071 FAIL(expr, "unary operator inside module body");
1115 } 1072 }
1116 switch (expr->op()) { 1073 switch (expr->op()) {
1117 case Token::NOT: // Used to encode != and !== 1074 case Token::NOT: // Used to encode != and !==
1118 RECURSE(VisitWithExpectation(expr->expression(), cache_.kAsmInt, 1075 RECURSE(VisitWithExpectation(expr->expression(), cache_.kAsmInt,
1119 "operand expected to be integer")); 1076 "operand expected to be integer"));
1120 RECURSE(IntersectResult(expr, cache_.kAsmSigned)); 1077 RECURSE(IntersectResult(expr, cache_.kAsmSigned));
1121 return; 1078 return;
1122 case Token::DELETE: 1079 case Token::DELETE:
1123 FAIL(expr, "delete operator encountered"); 1080 FAIL(expr, "delete operator encountered");
1124 case Token::VOID: 1081 case Token::VOID:
1125 FAIL(expr, "void operator encountered"); 1082 FAIL(expr, "void operator encountered");
1126 case Token::TYPEOF: 1083 case Token::TYPEOF:
1127 FAIL(expr, "typeof operator encountered"); 1084 FAIL(expr, "typeof operator encountered");
1128 default: 1085 default:
1129 UNREACHABLE(); 1086 UNREACHABLE();
1130 } 1087 }
1131 } 1088 }
1132 1089
1133
1134 void AsmTyper::VisitCountOperation(CountOperation* expr) { 1090 void AsmTyper::VisitCountOperation(CountOperation* expr) {
1135 FAIL(expr, "increment or decrement operator encountered"); 1091 FAIL(expr, "increment or decrement operator encountered");
1136 } 1092 }
1137 1093
1138
1139 void AsmTyper::VisitIntegerBitwiseOperator(BinaryOperation* expr, 1094 void AsmTyper::VisitIntegerBitwiseOperator(BinaryOperation* expr,
1140 Type* left_expected, 1095 Type* left_expected,
1141 Type* right_expected, 1096 Type* right_expected,
1142 Type* result_type, bool conversion) { 1097 Type* result_type, bool conversion) {
1143 RECURSE(VisitWithExpectation(expr->left(), Type::Number(), 1098 RECURSE(VisitWithExpectation(expr->left(), Type::Number(),
1144 "left bitwise operand expected to be a number")); 1099 "left bitwise operand expected to be a number"));
1145 int32_t left_intish = intish_; 1100 int32_t left_intish = intish_;
1146 Type* left_type = computed_type_; 1101 Type* left_type = computed_type_;
1147 if (!left_type->Is(left_expected)) { 1102 if (!left_type->Is(left_expected)) {
1148 FAIL(expr->left(), "left bitwise operand expected to be an integer"); 1103 FAIL(expr->left(), "left bitwise operand expected to be an integer");
(...skipping 23 matching lines...) Expand all
1172 right_type = left_type; 1127 right_type = left_type;
1173 } 1128 }
1174 if (!conversion) { 1129 if (!conversion) {
1175 if (!left_type->Is(cache_.kAsmIntQ) || !right_type->Is(cache_.kAsmIntQ)) { 1130 if (!left_type->Is(cache_.kAsmIntQ) || !right_type->Is(cache_.kAsmIntQ)) {
1176 FAIL(expr, "ill-typed bitwise operation"); 1131 FAIL(expr, "ill-typed bitwise operation");
1177 } 1132 }
1178 } 1133 }
1179 RECURSE(IntersectResult(expr, result_type)); 1134 RECURSE(IntersectResult(expr, result_type));
1180 } 1135 }
1181 1136
1182
1183 void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) { 1137 void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
1184 if (!in_function_) { 1138 if (!in_function_) {
1185 if (expr->op() != Token::BIT_OR && expr->op() != Token::MUL) { 1139 if (expr->op() != Token::BIT_OR && expr->op() != Token::MUL) {
1186 FAIL(expr, "illegal binary operator inside module body"); 1140 FAIL(expr, "illegal binary operator inside module body");
1187 } 1141 }
1188 if (!(expr->left()->IsProperty() || expr->left()->IsVariableProxy()) || 1142 if (!(expr->left()->IsProperty() || expr->left()->IsVariableProxy()) ||
1189 !expr->right()->IsLiteral()) { 1143 !expr->right()->IsLiteral()) {
1190 FAIL(expr, "illegal computation inside module body"); 1144 FAIL(expr, "illegal computation inside module body");
1191 } 1145 }
1192 DCHECK(expr->right()->AsLiteral() != nullptr); 1146 DCHECK(expr->right()->AsLiteral() != nullptr);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 return; 1324 return;
1371 } else { 1325 } else {
1372 FAIL(expr, "ill-typed arithmetic operation"); 1326 FAIL(expr, "ill-typed arithmetic operation");
1373 } 1327 }
1374 } 1328 }
1375 default: 1329 default:
1376 UNREACHABLE(); 1330 UNREACHABLE();
1377 } 1331 }
1378 } 1332 }
1379 1333
1380
1381 void AsmTyper::VisitCompareOperation(CompareOperation* expr) { 1334 void AsmTyper::VisitCompareOperation(CompareOperation* expr) {
1382 if (!in_function_) { 1335 if (!in_function_) {
1383 FAIL(expr, "comparison inside module body"); 1336 FAIL(expr, "comparison inside module body");
1384 } 1337 }
1385 Token::Value op = expr->op(); 1338 Token::Value op = expr->op();
1386 if (op != Token::EQ && op != Token::NE && op != Token::LT && 1339 if (op != Token::EQ && op != Token::NE && op != Token::LT &&
1387 op != Token::LTE && op != Token::GT && op != Token::GTE) { 1340 op != Token::LTE && op != Token::GT && op != Token::GTE) {
1388 FAIL(expr, "illegal comparison operator"); 1341 FAIL(expr, "illegal comparison operator");
1389 } 1342 }
1390 1343
(...skipping 18 matching lines...) Expand all
1409 (left_type->Is(cache_.kAsmDouble) && 1362 (left_type->Is(cache_.kAsmDouble) &&
1410 right_type->Is(cache_.kAsmDouble)))) { 1363 right_type->Is(cache_.kAsmDouble)))) {
1411 FAIL(expr, 1364 FAIL(expr,
1412 "left and right side of comparison must match type " 1365 "left and right side of comparison must match type "
1413 "and be signed, unsigned, float, or double"); 1366 "and be signed, unsigned, float, or double");
1414 } 1367 }
1415 1368
1416 RECURSE(IntersectResult(expr, cache_.kAsmSigned)); 1369 RECURSE(IntersectResult(expr, cache_.kAsmSigned));
1417 } 1370 }
1418 1371
1419
1420 void AsmTyper::VisitThisFunction(ThisFunction* expr) { 1372 void AsmTyper::VisitThisFunction(ThisFunction* expr) {
1421 FAIL(expr, "this function not allowed"); 1373 FAIL(expr, "this function not allowed");
1422 } 1374 }
1423 1375
1424
1425 void AsmTyper::VisitDeclarations(ZoneList<Declaration*>* decls) { 1376 void AsmTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
1426 for (int i = 0; i < decls->length(); ++i) { 1377 for (int i = 0; i < decls->length(); ++i) {
1427 Declaration* decl = decls->at(i); 1378 Declaration* decl = decls->at(i);
1428 RECURSE(Visit(decl)); 1379 RECURSE(Visit(decl));
1429 } 1380 }
1430 } 1381 }
1431 1382
1432
1433 void AsmTyper::VisitImportDeclaration(ImportDeclaration* decl) { 1383 void AsmTyper::VisitImportDeclaration(ImportDeclaration* decl) {
1434 FAIL(decl, "import declaration encountered"); 1384 FAIL(decl, "import declaration encountered");
1435 } 1385 }
1436 1386
1437
1438 void AsmTyper::VisitClassLiteral(ClassLiteral* expr) { 1387 void AsmTyper::VisitClassLiteral(ClassLiteral* expr) {
1439 FAIL(expr, "class literal not allowed"); 1388 FAIL(expr, "class literal not allowed");
1440 } 1389 }
1441 1390
1442
1443 void AsmTyper::VisitSpread(Spread* expr) { FAIL(expr, "spread not allowed"); } 1391 void AsmTyper::VisitSpread(Spread* expr) { FAIL(expr, "spread not allowed"); }
1444 1392
1445
1446 void AsmTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) { 1393 void AsmTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {
1447 FAIL(expr, "super property reference not allowed"); 1394 FAIL(expr, "super property reference not allowed");
1448 } 1395 }
1449 1396
1450
1451 void AsmTyper::VisitSuperCallReference(SuperCallReference* expr) { 1397 void AsmTyper::VisitSuperCallReference(SuperCallReference* expr) {
1452 FAIL(expr, "call reference not allowed"); 1398 FAIL(expr, "call reference not allowed");
1453 } 1399 }
1454 1400
1455
1456 void AsmTyper::InitializeStdlibSIMD() { 1401 void AsmTyper::InitializeStdlibSIMD() {
1457 #define V(NAME, Name, name, lane_count, lane_type) \ 1402 #define V(NAME, Name, name, lane_count, lane_type) \
1458 { \ 1403 { \
1459 Type* type = Type::Function(Type::Name(isolate_, zone()), Type::Any(), \ 1404 Type* type = Type::Function(Type::Name(isolate_, zone()), Type::Any(), \
1460 lane_count, zone()); \ 1405 lane_count, zone()); \
1461 for (int i = 0; i < lane_count; ++i) { \ 1406 for (int i = 0; i < lane_count; ++i) { \
1462 type->AsFunction()->InitParameter(i, Type::Number()); \ 1407 type->AsFunction()->InitParameter(i, Type::Number()); \
1463 } \ 1408 } \
1464 stdlib_simd_##name##_constructor_type_ = new (zone()) VariableInfo(type); \ 1409 stdlib_simd_##name##_constructor_type_ = new (zone()) VariableInfo(type); \
1465 stdlib_simd_##name##_constructor_type_->is_constructor_function = true; \ 1410 stdlib_simd_##name##_constructor_type_->is_constructor_function = true; \
1466 } 1411 }
1467 SIMD128_TYPES(V) 1412 SIMD128_TYPES(V)
1468 #undef V 1413 #undef V
1469 } 1414 }
1470 1415
1471
1472 void AsmTyper::InitializeStdlib() { 1416 void AsmTyper::InitializeStdlib() {
1473 if (allow_simd_) { 1417 if (allow_simd_) {
1474 InitializeStdlibSIMD(); 1418 InitializeStdlibSIMD();
1475 } 1419 }
1476 Type* number_type = Type::Number(); 1420 Type* number_type = Type::Number();
1477 Type* double_type = cache_.kAsmDouble; 1421 Type* double_type = cache_.kAsmDouble;
1478 Type* double_fn1_type = Type::Function(double_type, double_type, zone()); 1422 Type* double_fn1_type = Type::Function(double_type, double_type, zone());
1479 Type* double_fn2_type = 1423 Type* double_fn2_type =
1480 Type::Function(double_type, double_type, double_type, zone()); 1424 Type::Function(double_type, double_type, double_type, zone());
1481 1425
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 TYPED_ARRAYS(TYPED_ARRAY) 1481 TYPED_ARRAYS(TYPED_ARRAY)
1538 #undef TYPED_ARRAY 1482 #undef TYPED_ARRAY
1539 1483
1540 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \ 1484 #define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \
1541 stdlib_heap_types_[#TypeName "Array"] = new (zone()) VariableInfo( \ 1485 stdlib_heap_types_[#TypeName "Array"] = new (zone()) VariableInfo( \
1542 Type::Function(cache_.k##TypeName##Array, buffer_type, zone())); 1486 Type::Function(cache_.k##TypeName##Array, buffer_type, zone()));
1543 TYPED_ARRAYS(TYPED_ARRAY) 1487 TYPED_ARRAYS(TYPED_ARRAY)
1544 #undef TYPED_ARRAY 1488 #undef TYPED_ARRAY
1545 } 1489 }
1546 1490
1547
1548 void AsmTyper::VisitLibraryAccess(ObjectTypeMap* map, Property* expr) { 1491 void AsmTyper::VisitLibraryAccess(ObjectTypeMap* map, Property* expr) {
1549 Literal* key = expr->key()->AsLiteral(); 1492 Literal* key = expr->key()->AsLiteral();
1550 if (key == nullptr || !key->IsPropertyName()) 1493 if (key == nullptr || !key->IsPropertyName())
1551 FAIL(expr, "invalid key used on stdlib member"); 1494 FAIL(expr, "invalid key used on stdlib member");
1552 Handle<String> name = key->AsPropertyName(); 1495 Handle<String> name = key->AsPropertyName();
1553 VariableInfo* info = LibType(map, name); 1496 VariableInfo* info = LibType(map, name);
1554 if (info == nullptr || info->type == nullptr) 1497 if (info == nullptr || info->type == nullptr)
1555 FAIL(expr, "unknown stdlib function"); 1498 FAIL(expr, "unknown stdlib function");
1556 SetResult(expr, info->type); 1499 SetResult(expr, info->type);
1557 property_info_ = info; 1500 property_info_ = info;
1558 } 1501 }
1559 1502
1560
1561 AsmTyper::VariableInfo* AsmTyper::LibType(ObjectTypeMap* map, 1503 AsmTyper::VariableInfo* AsmTyper::LibType(ObjectTypeMap* map,
1562 Handle<String> name) { 1504 Handle<String> name) {
1563 base::SmartArrayPointer<char> aname = name->ToCString(); 1505 base::SmartArrayPointer<char> aname = name->ToCString();
1564 ObjectTypeMap::iterator i = map->find(std::string(aname.get())); 1506 ObjectTypeMap::iterator i = map->find(std::string(aname.get()));
1565 if (i == map->end()) { 1507 if (i == map->end()) {
1566 return nullptr; 1508 return nullptr;
1567 } 1509 }
1568 return i->second; 1510 return i->second;
1569 } 1511 }
1570 1512
1571
1572 void AsmTyper::SetType(Variable* variable, Type* type) { 1513 void AsmTyper::SetType(Variable* variable, Type* type) {
1573 VariableInfo* info = MakeVariableInfo(variable); 1514 VariableInfo* info = MakeVariableInfo(variable);
1574 info->type = type; 1515 info->type = type;
1575 } 1516 }
1576 1517
1577
1578 Type* AsmTyper::GetType(Variable* variable) { 1518 Type* AsmTyper::GetType(Variable* variable) {
1579 VariableInfo* info = GetVariableInfo(variable); 1519 VariableInfo* info = GetVariableInfo(variable);
1580 if (!info) return nullptr; 1520 if (!info) return nullptr;
1581 return info->type; 1521 return info->type;
1582 } 1522 }
1583 1523
1584 AsmTyper::VariableInfo* AsmTyper::GetVariableInfo(Variable* variable) { 1524 AsmTyper::VariableInfo* AsmTyper::GetVariableInfo(Variable* variable) {
1585 ZoneHashMap* map = 1525 ZoneHashMap* map =
1586 in_function_ ? &local_variable_type_ : &global_variable_type_; 1526 in_function_ ? &local_variable_type_ : &global_variable_type_;
1587 ZoneHashMap::Entry* entry = 1527 ZoneHashMap::Entry* entry =
(...skipping 15 matching lines...) Expand all
1603 } 1543 }
1604 1544
1605 void AsmTyper::SetVariableInfo(Variable* variable, const VariableInfo* info) { 1545 void AsmTyper::SetVariableInfo(Variable* variable, const VariableInfo* info) {
1606 VariableInfo* dest = MakeVariableInfo(variable); 1546 VariableInfo* dest = MakeVariableInfo(variable);
1607 dest->type = info->type; 1547 dest->type = info->type;
1608 dest->is_check_function = info->is_check_function; 1548 dest->is_check_function = info->is_check_function;
1609 dest->is_constructor_function = info->is_constructor_function; 1549 dest->is_constructor_function = info->is_constructor_function;
1610 dest->standard_member = info->standard_member; 1550 dest->standard_member = info->standard_member;
1611 } 1551 }
1612 1552
1613
1614 AsmTyper::StandardMember AsmTyper::VariableAsStandardMember( 1553 AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(
1615 Variable* variable) { 1554 Variable* variable) {
1616 VariableInfo* info = GetVariableInfo(variable); 1555 VariableInfo* info = GetVariableInfo(variable);
1617 if (!info) return kNone; 1556 if (!info) return kNone;
1618 return info->standard_member; 1557 return info->standard_member;
1619 } 1558 }
1620 1559
1621
1622 void AsmTyper::SetResult(Expression* expr, Type* type) { 1560 void AsmTyper::SetResult(Expression* expr, Type* type) {
1623 computed_type_ = type; 1561 computed_type_ = type;
1624 bounds_.set(expr, Bounds(computed_type_)); 1562 bounds_.set(expr, Bounds(computed_type_));
1625 } 1563 }
1626 1564
1627
1628 void AsmTyper::IntersectResult(Expression* expr, Type* type) { 1565 void AsmTyper::IntersectResult(Expression* expr, Type* type) {
1629 computed_type_ = type; 1566 computed_type_ = type;
1630 Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone()); 1567 Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone());
1631 if (Type::Representation(bounded_type, zone())->Is(Type::None())) { 1568 if (Type::Representation(bounded_type, zone())->Is(Type::None())) {
1632 #ifdef DEBUG 1569 #ifdef DEBUG
1633 PrintF("Computed type: "); 1570 PrintF("Computed type: ");
1634 computed_type_->Print(); 1571 computed_type_->Print();
1635 PrintF("Expected type: "); 1572 PrintF("Expected type: ");
1636 expected_type_->Print(); 1573 expected_type_->Print();
1637 #endif 1574 #endif
1638 FAIL(expr, "type mismatch"); 1575 FAIL(expr, "type mismatch");
1639 } 1576 }
1640 bounds_.set(expr, Bounds(bounded_type)); 1577 bounds_.set(expr, Bounds(bounded_type));
1641 } 1578 }
1642 1579
1643
1644 void AsmTyper::VisitWithExpectation(Expression* expr, Type* expected_type, 1580 void AsmTyper::VisitWithExpectation(Expression* expr, Type* expected_type,
1645 const char* msg) { 1581 const char* msg) {
1646 Type* save = expected_type_; 1582 Type* save = expected_type_;
1647 expected_type_ = expected_type; 1583 expected_type_ = expected_type;
1648 RECURSE(Visit(expr)); 1584 RECURSE(Visit(expr));
1649 Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone()); 1585 Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone());
1650 if (Type::Representation(bounded_type, zone())->Is(Type::None())) { 1586 if (Type::Representation(bounded_type, zone())->Is(Type::None())) {
1651 #ifdef DEBUG 1587 #ifdef DEBUG
1652 PrintF("Computed type: "); 1588 PrintF("Computed type: ");
1653 computed_type_->Print(); 1589 computed_type_->Print();
1654 PrintF("Expected type: "); 1590 PrintF("Expected type: ");
1655 expected_type_->Print(); 1591 expected_type_->Print();
1656 #endif 1592 #endif
1657 FAIL(expr, msg); 1593 FAIL(expr, msg);
1658 } 1594 }
1659 expected_type_ = save; 1595 expected_type_ = save;
1660 } 1596 }
1661 1597
1662
1663 void AsmTyper::VisitRewritableExpression(RewritableExpression* expr) { 1598 void AsmTyper::VisitRewritableExpression(RewritableExpression* expr) {
1664 RECURSE(Visit(expr->expression())); 1599 RECURSE(Visit(expr->expression()));
1665 } 1600 }
1666 1601
1667
1668 } // namespace internal 1602 } // namespace internal
1669 } // namespace v8 1603 } // namespace v8
OLDNEW
« no previous file with comments | « src/asmjs/typing-asm.h ('k') | src/bootstrapper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698