| OLD | NEW |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 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/asmjs/asm-parser.h" | 5 #include "src/asmjs/asm-parser.h" |
| 6 | 6 |
| 7 // Required to get M_E etc. for MSVC. | 7 // Required to get M_E etc. for MSVC. |
| 8 // References from STDLIB_MATH_VALUE_LIST in asm-names.h | 8 // References from STDLIB_MATH_VALUE_LIST in asm-names.h |
| 9 #if defined(_WIN32) | 9 #if defined(_WIN32) |
| 10 #define _USE_MATH_DEFINES | 10 #define _USE_MATH_DEFINES |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 scanner_.Next(); \ | 64 scanner_.Next(); \ |
| 65 } while (false); | 65 } while (false); |
| 66 #endif | 66 #endif |
| 67 | 67 |
| 68 #define EXPECT_TOKEN(token) EXPECT_TOKEN_OR_RETURN(, token) | 68 #define EXPECT_TOKEN(token) EXPECT_TOKEN_OR_RETURN(, token) |
| 69 #define EXPECT_TOKENn(token) EXPECT_TOKEN_OR_RETURN(nullptr, token) | 69 #define EXPECT_TOKENn(token) EXPECT_TOKEN_OR_RETURN(nullptr, token) |
| 70 #define EXPECT_TOKENf(token) EXPECT_TOKEN_OR_RETURN(false, token) | 70 #define EXPECT_TOKENf(token) EXPECT_TOKEN_OR_RETURN(false, token) |
| 71 | 71 |
| 72 #define RECURSE_OR_RETURN(ret, call) \ | 72 #define RECURSE_OR_RETURN(ret, call) \ |
| 73 do { \ | 73 do { \ |
| 74 DCHECK(GetCurrentStackPosition() >= stack_limit_); \ | |
| 75 DCHECK(!failed_); \ | 74 DCHECK(!failed_); \ |
| 76 call; \ | |
| 77 if (GetCurrentStackPosition() < stack_limit_) { \ | 75 if (GetCurrentStackPosition() < stack_limit_) { \ |
| 78 FAIL_AND_RETURN(ret, "Stack overflow while parsing asm.js module."); \ | 76 FAIL_AND_RETURN(ret, "Stack overflow while parsing asm.js module."); \ |
| 79 } \ | 77 } \ |
| 78 call; \ |
| 80 if (failed_) return ret; \ | 79 if (failed_) return ret; \ |
| 81 } while (false); | 80 } while (false); |
| 82 | 81 |
| 83 #define RECURSE(call) RECURSE_OR_RETURN(, call) | 82 #define RECURSE(call) RECURSE_OR_RETURN(, call) |
| 84 #define RECURSEn(call) RECURSE_OR_RETURN(nullptr, call) | 83 #define RECURSEn(call) RECURSE_OR_RETURN(nullptr, call) |
| 85 #define RECURSEf(call) RECURSE_OR_RETURN(false, call) | 84 #define RECURSEf(call) RECURSE_OR_RETURN(false, call) |
| 86 | 85 |
| 87 #define TOK(name) AsmJsScanner::kToken_##name | 86 #define TOK(name) AsmJsScanner::kToken_##name |
| 88 | 87 |
| 89 AsmJsParser::AsmJsParser(Isolate* isolate, Zone* zone, Handle<Script> script, | 88 AsmJsParser::AsmJsParser(Isolate* isolate, Zone* zone, Handle<Script> script, |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 if (info->import != nullptr) { | 230 if (info->import != nullptr) { |
| 232 return info->index; | 231 return info->index; |
| 233 } else { | 232 } else { |
| 234 return info->index + static_cast<uint32_t>(global_imports_.size()); | 233 return info->index + static_cast<uint32_t>(global_imports_.size()); |
| 235 } | 234 } |
| 236 } | 235 } |
| 237 | 236 |
| 238 void AsmJsParser::AddGlobalImport(std::string name, AsmType* type, | 237 void AsmJsParser::AddGlobalImport(std::string name, AsmType* type, |
| 239 ValueType vtype, bool mutable_variable, | 238 ValueType vtype, bool mutable_variable, |
| 240 VarInfo* info) { | 239 VarInfo* info) { |
| 240 // TODO(bradnelson): Refactor memory management here. |
| 241 // AsmModuleBuilder should really own import names. |
| 242 char* name_data = zone()->NewArray<char>(name.size()); |
| 243 memcpy(name_data, name.data(), name.size()); |
| 241 if (mutable_variable) { | 244 if (mutable_variable) { |
| 242 // Allocate a separate variable for the import. | 245 // Allocate a separate variable for the import. |
| 243 DeclareGlobal(info, true, type, vtype); | 246 DeclareGlobal(info, true, type, vtype); |
| 244 // Record the need to initialize the global from the import. | 247 // Record the need to initialize the global from the import. |
| 245 global_imports_.push_back({name, 0, info->index, true}); | 248 global_imports_.push_back({name_data, name.size(), 0, info->index, true}); |
| 246 } else { | 249 } else { |
| 247 // Just use the import directly. | 250 // Just use the import directly. |
| 248 global_imports_.push_back({name, 0, info->index, false}); | 251 global_imports_.push_back({name_data, name.size(), 0, info->index, false}); |
| 249 } | 252 } |
| 250 GlobalImport& gi = global_imports_.back(); | 253 GlobalImport& gi = global_imports_.back(); |
| 251 // TODO(bradnelson): Reuse parse buffer memory / make wasm-module-builder | 254 // TODO(bradnelson): Reuse parse buffer memory / make wasm-module-builder |
| 252 // managed the memory for the import name (currently have to keep our | 255 // managed the memory for the import name (currently have to keep our |
| 253 // own memory for it). | 256 // own memory for it). |
| 254 gi.import_index = module_builder_->AddGlobalImport( | 257 gi.import_index = module_builder_->AddGlobalImport( |
| 255 name.data(), static_cast<int>(name.size()), vtype); | 258 name_data, static_cast<int>(name.size()), vtype); |
| 256 if (!mutable_variable) { | 259 if (!mutable_variable) { |
| 257 info->DeclareGlobalImport(type, gi.import_index); | 260 info->DeclareGlobalImport(type, gi.import_index); |
| 258 } | 261 } |
| 259 } | 262 } |
| 260 | 263 |
| 261 void AsmJsParser::VarInfo::DeclareGlobalImport(AsmType* type, uint32_t index) { | 264 void AsmJsParser::VarInfo::DeclareGlobalImport(AsmType* type, uint32_t index) { |
| 262 kind = VarKind::kGlobal; | 265 kind = VarKind::kGlobal; |
| 263 this->type = type; | 266 this->type = type; |
| 264 this->index = index; | 267 this->index = index; |
| 265 mutable_variable = false; | 268 mutable_variable = false; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 SkipSemicolon(); | 358 SkipSemicolon(); |
| 356 RECURSE(ValidateModuleVars()); | 359 RECURSE(ValidateModuleVars()); |
| 357 while (Peek(TOK(function))) { | 360 while (Peek(TOK(function))) { |
| 358 RECURSE(ValidateFunction()); | 361 RECURSE(ValidateFunction()); |
| 359 } | 362 } |
| 360 while (Peek(TOK(var))) { | 363 while (Peek(TOK(var))) { |
| 361 RECURSE(ValidateFunctionTable()); | 364 RECURSE(ValidateFunctionTable()); |
| 362 } | 365 } |
| 363 RECURSE(ValidateExport()); | 366 RECURSE(ValidateExport()); |
| 364 | 367 |
| 368 // Check that all functions were eventually defined. |
| 369 for (auto info : global_var_info_) { |
| 370 if (info.kind != VarKind::kFunction) { |
| 371 continue; |
| 372 } |
| 373 if (!info.function_defined) { |
| 374 FAIL("Undefined function"); |
| 375 } |
| 376 } |
| 377 |
| 365 // Add start function to init things. | 378 // Add start function to init things. |
| 366 WasmFunctionBuilder* start = module_builder_->AddFunction(); | 379 WasmFunctionBuilder* start = module_builder_->AddFunction(); |
| 367 module_builder_->MarkStartFunction(start); | 380 module_builder_->MarkStartFunction(start); |
| 368 for (auto global_import : global_imports_) { | 381 for (auto global_import : global_imports_) { |
| 369 if (global_import.needs_init) { | 382 if (global_import.needs_init) { |
| 370 start->EmitWithVarInt(kExprGetGlobal, global_import.import_index); | 383 start->EmitWithVarInt(kExprGetGlobal, global_import.import_index); |
| 371 start->EmitWithVarInt(kExprSetGlobal, | 384 start->EmitWithVarInt(kExprSetGlobal, |
| 372 static_cast<uint32_t>(global_import.global_index + | 385 static_cast<uint32_t>(global_import.global_index + |
| 373 global_imports_.size())); | 386 global_imports_.size())); |
| 374 } | 387 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 EXPECT_TOKEN('='); | 453 EXPECT_TOKEN('='); |
| 441 double dvalue = 0.0; | 454 double dvalue = 0.0; |
| 442 uint64_t uvalue = 0; | 455 uint64_t uvalue = 0; |
| 443 if (CheckForDouble(&dvalue)) { | 456 if (CheckForDouble(&dvalue)) { |
| 444 DeclareGlobal(info, mutable_variable, AsmType::Double(), kWasmF64, | 457 DeclareGlobal(info, mutable_variable, AsmType::Double(), kWasmF64, |
| 445 WasmInitExpr(dvalue)); | 458 WasmInitExpr(dvalue)); |
| 446 } else if (CheckForUnsigned(&uvalue)) { | 459 } else if (CheckForUnsigned(&uvalue)) { |
| 447 if (uvalue > 0x7fffffff) { | 460 if (uvalue > 0x7fffffff) { |
| 448 FAIL("Numeric literal out of range"); | 461 FAIL("Numeric literal out of range"); |
| 449 } | 462 } |
| 450 DeclareGlobal(info, mutable_variable, AsmType::Int(), kWasmI32, | 463 DeclareGlobal(info, mutable_variable, |
| 451 WasmInitExpr(static_cast<int32_t>(uvalue))); | 464 mutable_variable ? AsmType::Int() : AsmType::Signed(), |
| 465 kWasmI32, WasmInitExpr(static_cast<int32_t>(uvalue))); |
| 452 } else if (Check('-')) { | 466 } else if (Check('-')) { |
| 453 if (CheckForDouble(&dvalue)) { | 467 if (CheckForDouble(&dvalue)) { |
| 454 DeclareGlobal(info, mutable_variable, AsmType::Double(), kWasmF64, | 468 DeclareGlobal(info, mutable_variable, AsmType::Double(), kWasmF64, |
| 455 WasmInitExpr(-dvalue)); | 469 WasmInitExpr(-dvalue)); |
| 456 } else if (CheckForUnsigned(&uvalue)) { | 470 } else if (CheckForUnsigned(&uvalue)) { |
| 457 if (uvalue > 0x7fffffff) { | 471 if (uvalue > 0x7fffffff) { |
| 458 FAIL("Numeric literal out of range"); | 472 FAIL("Numeric literal out of range"); |
| 459 } | 473 } |
| 460 DeclareGlobal(info, mutable_variable, AsmType::Int(), kWasmI32, | 474 DeclareGlobal(info, mutable_variable, |
| 461 WasmInitExpr(-static_cast<int32_t>(uvalue))); | 475 mutable_variable ? AsmType::Int() : AsmType::Signed(), |
| 476 kWasmI32, WasmInitExpr(-static_cast<int32_t>(uvalue))); |
| 462 } else { | 477 } else { |
| 463 FAIL("Expected numeric literal"); | 478 FAIL("Expected numeric literal"); |
| 464 } | 479 } |
| 465 } else if (Check(TOK(new))) { | 480 } else if (Check(TOK(new))) { |
| 466 RECURSE(ValidateModuleVarNewStdlib(info)); | 481 RECURSE(ValidateModuleVarNewStdlib(info)); |
| 467 } else if (Check(stdlib_name_)) { | 482 } else if (Check(stdlib_name_)) { |
| 468 EXPECT_TOKEN('.'); | 483 EXPECT_TOKEN('.'); |
| 469 RECURSE(ValidateModuleVarStdlib(info)); | 484 RECURSE(ValidateModuleVarStdlib(info)); |
| 470 } else if (ValidateModuleVarImport(info, mutable_variable)) { | 485 } else if (ValidateModuleVarImport(info, mutable_variable)) { |
| 471 // Handled inside. | 486 // Handled inside. |
| 472 } else if (scanner_.IsGlobal()) { | 487 } else if (scanner_.IsGlobal()) { |
| 473 RECURSE(ValidateModuleVarFloat(info, mutable_variable)); | 488 RECURSE(ValidateModuleVarFromGlobal(info, mutable_variable)); |
| 474 } else { | 489 } else { |
| 475 FAIL("Bad variable declaration"); | 490 FAIL("Bad variable declaration"); |
| 476 } | 491 } |
| 477 } | 492 } |
| 478 | 493 |
| 479 // 6.1 ValidateModule - global float declaration | 494 // 6.1 ValidateModule - global float declaration |
| 480 void AsmJsParser::ValidateModuleVarFloat(VarInfo* info, bool mutable_variable) { | 495 void AsmJsParser::ValidateModuleVarFromGlobal(VarInfo* info, |
| 481 if (!GetVarInfo(Consume())->type->IsA(stdlib_fround_)) { | 496 bool mutable_variable) { |
| 482 FAIL("Expected fround"); | 497 VarInfo* src_info = GetVarInfo(Consume()); |
| 498 if (!src_info->type->IsA(stdlib_fround_)) { |
| 499 if (src_info->mutable_variable) { |
| 500 FAIL("Can only use immutable variables in global definition"); |
| 501 } |
| 502 if (mutable_variable) { |
| 503 FAIL("Can only define immutable variables with other immutables"); |
| 504 } |
| 505 if (!src_info->type->IsA(AsmType::Int()) && |
| 506 !src_info->type->IsA(AsmType::Float()) && |
| 507 !src_info->type->IsA(AsmType::Double())) { |
| 508 FAIL("Expected int, float, double, or fround for global definition"); |
| 509 } |
| 510 info->kind = VarKind::kGlobal; |
| 511 info->type = src_info->type; |
| 512 info->index = src_info->index; |
| 513 info->mutable_variable = false; |
| 514 return; |
| 483 } | 515 } |
| 484 EXPECT_TOKEN('('); | 516 EXPECT_TOKEN('('); |
| 485 bool negate = false; | 517 bool negate = false; |
| 486 if (Check('-')) { | 518 if (Check('-')) { |
| 487 negate = true; | 519 negate = true; |
| 488 } | 520 } |
| 489 double dvalue = 0.0; | 521 double dvalue = 0.0; |
| 490 uint64_t uvalue = 0; | 522 uint64_t uvalue = 0; |
| 491 if (CheckForDouble(&dvalue)) { | 523 if (CheckForDouble(&dvalue)) { |
| 492 if (negate) { | 524 if (negate) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 if (!CheckForZero()) { | 557 if (!CheckForZero()) { |
| 526 FAILf("Expected |0 type annotation for foreign integer import"); | 558 FAILf("Expected |0 type annotation for foreign integer import"); |
| 527 } | 559 } |
| 528 AddGlobalImport(import_name, AsmType::Int(), kWasmI32, mutable_variable, | 560 AddGlobalImport(import_name, AsmType::Int(), kWasmI32, mutable_variable, |
| 529 info); | 561 info); |
| 530 return true; | 562 return true; |
| 531 } | 563 } |
| 532 info->kind = VarKind::kImportedFunction; | 564 info->kind = VarKind::kImportedFunction; |
| 533 function_import_info_.resize(function_import_info_.size() + 1); | 565 function_import_info_.resize(function_import_info_.size() + 1); |
| 534 info->import = &function_import_info_.back(); | 566 info->import = &function_import_info_.back(); |
| 535 info->import->name = import_name; | 567 // TODO(bradnelson): Refactor memory management here. |
| 568 // AsmModuleBuilder should really own import names. |
| 569 info->import->function_name = zone()->NewArray<char>(import_name.size()); |
| 570 memcpy(info->import->function_name, import_name.data(), import_name.size()); |
| 571 info->import->function_name_size = import_name.size(); |
| 536 return true; | 572 return true; |
| 537 } | 573 } |
| 538 return false; | 574 return false; |
| 539 } | 575 } |
| 540 | 576 |
| 541 // 6.1 ValidateModule - one variable | 577 // 6.1 ValidateModule - one variable |
| 542 // 9 - Standard Library - heap types | 578 // 9 - Standard Library - heap types |
| 543 void AsmJsParser::ValidateModuleVarNewStdlib(VarInfo* info) { | 579 void AsmJsParser::ValidateModuleVarNewStdlib(VarInfo* info) { |
| 544 EXPECT_TOKEN(stdlib_name_); | 580 EXPECT_TOKEN(stdlib_name_); |
| 545 EXPECT_TOKEN('.'); | 581 EXPECT_TOKEN('.'); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 562 // 6.1 ValidateModule - one variable | 598 // 6.1 ValidateModule - one variable |
| 563 // 9 - Standard Library | 599 // 9 - Standard Library |
| 564 void AsmJsParser::ValidateModuleVarStdlib(VarInfo* info) { | 600 void AsmJsParser::ValidateModuleVarStdlib(VarInfo* info) { |
| 565 if (Check(TOK(Math))) { | 601 if (Check(TOK(Math))) { |
| 566 EXPECT_TOKEN('.'); | 602 EXPECT_TOKEN('.'); |
| 567 switch (Consume()) { | 603 switch (Consume()) { |
| 568 #define V(name) \ | 604 #define V(name) \ |
| 569 case TOK(name): \ | 605 case TOK(name): \ |
| 570 DeclareGlobal(info, false, AsmType::Double(), kWasmF64, \ | 606 DeclareGlobal(info, false, AsmType::Double(), kWasmF64, \ |
| 571 WasmInitExpr(M_##name)); \ | 607 WasmInitExpr(M_##name)); \ |
| 608 stdlib_uses_.insert(AsmTyper::kMath##name); \ |
| 572 break; | 609 break; |
| 573 STDLIB_MATH_VALUE_LIST(V) | 610 STDLIB_MATH_VALUE_LIST(V) |
| 574 #undef V | 611 #undef V |
| 575 #define V(name, Name, op, sig) \ | 612 #define V(name, Name, op, sig) \ |
| 576 case TOK(name): \ | 613 case TOK(name): \ |
| 577 info->DeclareStdlibFunc(VarKind::kMath##Name, stdlib_##sig##_); \ | 614 info->DeclareStdlibFunc(VarKind::kMath##Name, stdlib_##sig##_); \ |
| 578 stdlib_uses_.insert(AsmTyper::kMath##Name); \ | 615 stdlib_uses_.insert(AsmTyper::kMath##Name); \ |
| 579 break; | 616 break; |
| 580 STDLIB_MATH_FUNCTION_LIST(V) | 617 STDLIB_MATH_FUNCTION_LIST(V) |
| 581 #undef V | 618 #undef V |
| 582 default: | 619 default: |
| 583 FAIL("Invalid member of stdlib.Math"); | 620 FAIL("Invalid member of stdlib.Math"); |
| 584 } | 621 } |
| 585 } else if (Check(TOK(Infinity))) { | 622 } else if (Check(TOK(Infinity))) { |
| 586 DeclareGlobal(info, false, AsmType::Double(), kWasmF64, | 623 DeclareGlobal(info, false, AsmType::Double(), kWasmF64, |
| 587 WasmInitExpr(std::numeric_limits<double>::infinity())); | 624 WasmInitExpr(std::numeric_limits<double>::infinity())); |
| 625 stdlib_uses_.insert(AsmTyper::kInfinity); |
| 588 } else if (Check(TOK(NaN))) { | 626 } else if (Check(TOK(NaN))) { |
| 589 DeclareGlobal(info, false, AsmType::Double(), kWasmF64, | 627 DeclareGlobal(info, false, AsmType::Double(), kWasmF64, |
| 590 WasmInitExpr(std::numeric_limits<double>::quiet_NaN())); | 628 WasmInitExpr(std::numeric_limits<double>::quiet_NaN())); |
| 629 stdlib_uses_.insert(AsmTyper::kNaN); |
| 591 } else { | 630 } else { |
| 592 FAIL("Invalid member of stdlib"); | 631 FAIL("Invalid member of stdlib"); |
| 593 } | 632 } |
| 594 } | 633 } |
| 595 | 634 |
| 596 // 6.2 ValidateExport | 635 // 6.2 ValidateExport |
| 597 void AsmJsParser::ValidateExport() { | 636 void AsmJsParser::ValidateExport() { |
| 598 // clang-format off | 637 // clang-format off |
| 599 EXPECT_TOKEN(TOK(return)); | 638 EXPECT_TOKEN(TOK(return)); |
| 600 // clang format on | 639 // clang format on |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 if (!scanner_.IsGlobal()) { | 727 if (!scanner_.IsGlobal()) { |
| 689 FAIL("Expected function name"); | 728 FAIL("Expected function name"); |
| 690 } | 729 } |
| 691 | 730 |
| 692 std::string function_name_raw = scanner_.GetIdentifierString(); | 731 std::string function_name_raw = scanner_.GetIdentifierString(); |
| 693 AsmJsScanner::token_t function_name = Consume(); | 732 AsmJsScanner::token_t function_name = Consume(); |
| 694 VarInfo* function_info = GetVarInfo(function_name); | 733 VarInfo* function_info = GetVarInfo(function_name); |
| 695 if (function_info->kind == VarKind::kUnused) { | 734 if (function_info->kind == VarKind::kUnused) { |
| 696 function_info->kind = VarKind::kFunction; | 735 function_info->kind = VarKind::kFunction; |
| 697 function_info->function_builder = module_builder_->AddFunction(); | 736 function_info->function_builder = module_builder_->AddFunction(); |
| 737 // TODO(bradnelson): Cleanup memory management here. |
| 738 // WasmModuleBuilder should own these. |
| 739 char* function_name = zone()->NewArray<char>(function_name_raw.size()); |
| 740 memcpy(function_name, function_name_raw.data(), function_name_raw.size()); |
| 698 function_info->function_builder->SetName( | 741 function_info->function_builder->SetName( |
| 699 {function_name_raw.c_str(), | 742 {function_name, static_cast<int>(function_name_raw.size())}); |
| 700 static_cast<int>(function_name_raw.size())}); | |
| 701 function_info->index = function_info->function_builder->func_index(); | 743 function_info->index = function_info->function_builder->func_index(); |
| 702 function_info->function_defined = true; | 744 function_info->function_defined = true; |
| 703 } else if (function_info->function_defined) { | 745 } else if (function_info->function_defined) { |
| 704 FAIL("Function redefined"); | 746 FAIL("Function redefined"); |
| 747 } else { |
| 748 function_info->function_defined = true; |
| 705 } | 749 } |
| 706 current_function_builder_ = function_info->function_builder; | 750 current_function_builder_ = function_info->function_builder; |
| 707 return_type_ = nullptr; | 751 return_type_ = nullptr; |
| 708 | 752 |
| 709 // Record start of the function, used as position for the stack check. | 753 // Record start of the function, used as position for the stack check. |
| 710 current_function_builder_->SetAsmFunctionStartPosition(start_position); | 754 current_function_builder_->SetAsmFunctionStartPosition(start_position); |
| 711 | 755 |
| 712 std::vector<AsmType*> params; | 756 std::vector<AsmType*> params; |
| 713 ValidateFunctionParams(¶ms); | 757 ValidateFunctionParams(¶ms); |
| 714 std::vector<ValueType> locals; | 758 std::vector<ValueType> locals; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 // Store types. | 892 // Store types. |
| 849 EXPECT_TOKEN('='); | 893 EXPECT_TOKEN('='); |
| 850 double dvalue = 0.0; | 894 double dvalue = 0.0; |
| 851 uint64_t uvalue = 0; | 895 uint64_t uvalue = 0; |
| 852 if (Check('-')) { | 896 if (Check('-')) { |
| 853 if (CheckForDouble(&dvalue)) { | 897 if (CheckForDouble(&dvalue)) { |
| 854 info->kind = VarKind::kLocal; | 898 info->kind = VarKind::kLocal; |
| 855 info->type = AsmType::Double(); | 899 info->type = AsmType::Double(); |
| 856 info->index = static_cast<uint32_t>(param_count + locals->size()); | 900 info->index = static_cast<uint32_t>(param_count + locals->size()); |
| 857 locals->push_back(kWasmF64); | 901 locals->push_back(kWasmF64); |
| 858 byte code[] = {WASM_F64(dvalue)}; | 902 byte code[] = {WASM_F64(-dvalue)}; |
| 859 current_function_builder_->EmitCode(code, sizeof(code)); | 903 current_function_builder_->EmitCode(code, sizeof(code)); |
| 860 current_function_builder_->EmitSetLocal(info->index); | 904 current_function_builder_->EmitSetLocal(info->index); |
| 861 } else if (CheckForUnsigned(&uvalue)) { | 905 } else if (CheckForUnsigned(&uvalue)) { |
| 862 if (uvalue > 0x7fffffff) { | 906 if (uvalue > 0x7fffffff) { |
| 863 FAIL("Numeric literal out of range"); | 907 FAIL("Numeric literal out of range"); |
| 864 } | 908 } |
| 865 info->kind = VarKind::kLocal; | 909 info->kind = VarKind::kLocal; |
| 866 info->type = AsmType::Int(); | 910 info->type = AsmType::Int(); |
| 867 info->index = static_cast<uint32_t>(param_count + locals->size()); | 911 info->index = static_cast<uint32_t>(param_count + locals->size()); |
| 868 locals->push_back(kWasmI32); | 912 locals->push_back(kWasmI32); |
| (...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2056 } | 2100 } |
| 2057 if (return_type->IsA(AsmType::Float())) { | 2101 if (return_type->IsA(AsmType::Float())) { |
| 2058 FAILn("Imported function can't be called as float"); | 2102 FAILn("Imported function can't be called as float"); |
| 2059 } | 2103 } |
| 2060 DCHECK(function_info->import != nullptr); | 2104 DCHECK(function_info->import != nullptr); |
| 2061 // TODO(bradnelson): Factor out. | 2105 // TODO(bradnelson): Factor out. |
| 2062 uint32_t cache_index = function_info->import->cache.FindOrInsert(sig); | 2106 uint32_t cache_index = function_info->import->cache.FindOrInsert(sig); |
| 2063 uint32_t index; | 2107 uint32_t index; |
| 2064 if (cache_index >= function_info->import->cache_index.size()) { | 2108 if (cache_index >= function_info->import->cache_index.size()) { |
| 2065 index = module_builder_->AddImport( | 2109 index = module_builder_->AddImport( |
| 2066 function_info->import->name.data(), | 2110 function_info->import->function_name, |
| 2067 static_cast<uint32_t>(function_info->import->name.size()), sig); | 2111 static_cast<uint32_t>(function_info->import->function_name_size), |
| 2112 sig); |
| 2068 function_info->import->cache_index.push_back(index); | 2113 function_info->import->cache_index.push_back(index); |
| 2069 } else { | 2114 } else { |
| 2070 index = function_info->import->cache_index[cache_index]; | 2115 index = function_info->import->cache_index[cache_index]; |
| 2071 } | 2116 } |
| 2072 current_function_builder_->Emit(kExprCallFunction); | 2117 current_function_builder_->Emit(kExprCallFunction); |
| 2073 current_function_builder_->EmitVarUint(index); | 2118 current_function_builder_->EmitVarUint(index); |
| 2074 } else if (function_info->type->IsA(AsmType::None())) { | 2119 } else if (function_info->type->IsA(AsmType::None())) { |
| 2075 function_info->type = function_type; | 2120 function_info->type = function_type; |
| 2076 if (function_info->kind == VarKind::kTable) { | 2121 if (function_info->kind == VarKind::kTable) { |
| 2077 current_function_builder_->EmitGetLocal(tmp); | 2122 current_function_builder_->EmitGetLocal(tmp); |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2366 break; | 2411 break; |
| 2367 } | 2412 } |
| 2368 scanner_.Next(); | 2413 scanner_.Next(); |
| 2369 } | 2414 } |
| 2370 scanner_.Seek(start); | 2415 scanner_.Seek(start); |
| 2371 } | 2416 } |
| 2372 | 2417 |
| 2373 } // namespace wasm | 2418 } // namespace wasm |
| 2374 } // namespace internal | 2419 } // namespace internal |
| 2375 } // namespace v8 | 2420 } // namespace v8 |
| OLD | NEW |