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

Side by Side Diff: src/asmjs/asm-wasm-builder.cc

Issue 2555243002: [wasm] Fix location for error in asm.js ToNumber conversion (Closed)
Patch Set: No need to store parent in VisitCall Created 4 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 | « no previous file | src/compiler/pipeline.h » ('j') | src/wasm/wasm-objects.cc » ('J')
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 // Required to get M_E etc. in MSVC. 7 // Required to get M_E etc. in MSVC.
8 #if defined(_WIN32) 8 #if defined(_WIN32)
9 #define _USE_MATH_DEFINES 9 #define _USE_MATH_DEFINES
10 #endif 10 #endif
(...skipping 17 matching lines...) Expand all
28 namespace internal { 28 namespace internal {
29 namespace wasm { 29 namespace wasm {
30 30
31 #define RECURSE(call) \ 31 #define RECURSE(call) \
32 do { \ 32 do { \
33 DCHECK(!HasStackOverflow()); \ 33 DCHECK(!HasStackOverflow()); \
34 call; \ 34 call; \
35 if (HasStackOverflow()) return; \ 35 if (HasStackOverflow()) return; \
36 } while (false) 36 } while (false)
37 37
38 #ifdef DEBUG
39 namespace {
40 bool IsChild(Expression* parent, Expression* child) {
bradnelson 2016/12/07 19:19:06 IsBinOpChild ?
Clemens Hammacher 2016/12/08 10:50:23 I just removed the function completely :) By stori
41 DCHECK_NOT_NULL(parent);
42 if (parent->IsBinaryOperation()) {
43 BinaryOperation* bin_op = static_cast<BinaryOperation*>(parent);
44 return bin_op->left() == child || bin_op->right() == child;
45 }
46 UNREACHABLE();
47 return false;
48 }
49 } // namespace
50 #endif
51
38 enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope }; 52 enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope };
39 enum ValueFate { kDrop, kLeaveOnStack }; 53 enum ValueFate { kDrop, kLeaveOnStack };
40 54
41 struct ForeignVariable { 55 struct ForeignVariable {
42 Handle<Name> name; 56 Handle<Name> name;
43 Variable* var; 57 Variable* var;
44 LocalType type; 58 LocalType type;
45 }; 59 };
46 60
47 class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> { 61 class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
(...skipping 16 matching lines...) Expand all
64 ast_value_factory_(ast_value_factory), 78 ast_value_factory_(ast_value_factory),
65 script_(script), 79 script_(script),
66 typer_(typer), 80 typer_(typer),
67 typer_failed_(false), 81 typer_failed_(false),
68 breakable_blocks_(zone), 82 breakable_blocks_(zone),
69 foreign_variables_(zone), 83 foreign_variables_(zone),
70 init_function_(nullptr), 84 init_function_(nullptr),
71 foreign_init_function_(nullptr), 85 foreign_init_function_(nullptr),
72 function_tables_(ZoneHashMap::kDefaultHashMapCapacity, 86 function_tables_(ZoneHashMap::kDefaultHashMapCapacity,
73 ZoneAllocationPolicy(zone)), 87 ZoneAllocationPolicy(zone)),
74 imported_function_table_(this) { 88 imported_function_table_(this),
89 parent_(nullptr) {
75 InitializeAstVisitor(isolate); 90 InitializeAstVisitor(isolate);
76 } 91 }
77 92
78 void InitializeInitFunction() { 93 void InitializeInitFunction() {
79 FunctionSig::Builder b(zone(), 0, 0); 94 FunctionSig::Builder b(zone(), 0, 0);
80 init_function_ = builder_->AddFunction(b.Build()); 95 init_function_ = builder_->AddFunction(b.Build());
81 builder_->MarkStartFunction(init_function_); 96 builder_->MarkStartFunction(init_function_);
82 } 97 }
83 98
84 void BuildForeignInitFunction() { 99 void BuildForeignInitFunction() {
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 Expression* arg = args->at(i); 1404 Expression* arg = args->at(i);
1390 RECURSE(Visit(arg)); 1405 RECURSE(Visit(arg));
1391 } 1406 }
1392 } 1407 }
1393 1408
1394 void VisitCall(Call* expr) { VisitCallExpression(expr); } 1409 void VisitCall(Call* expr) { VisitCallExpression(expr); }
1395 1410
1396 bool VisitCallExpression(Call* expr) { 1411 bool VisitCallExpression(Call* expr) {
1397 Call::CallType call_type = expr->GetCallType(); 1412 Call::CallType call_type = expr->GetCallType();
1398 bool returns_value = true; 1413 bool returns_value = true;
1414
1415 // Save the parent now, it might be overwritten in VisitCallArgs.
1416 Expression* this_parent = parent_;
1417
1399 switch (call_type) { 1418 switch (call_type) {
1400 case Call::OTHER_CALL: { 1419 case Call::OTHER_CALL: {
1401 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 1420 VariableProxy* proxy = expr->expression()->AsVariableProxy();
1402 if (proxy != nullptr) { 1421 if (proxy != nullptr) {
1403 DCHECK(kFuncScope == scope_ || 1422 DCHECK(kFuncScope == scope_ ||
1404 typer_->VariableAsStandardMember(proxy->var()) == 1423 typer_->VariableAsStandardMember(proxy->var()) ==
1405 AsmTyper::kMathFround); 1424 AsmTyper::kMathFround);
1406 if (VisitStdlibFunction(expr, proxy)) { 1425 if (VisitStdlibFunction(expr, proxy)) {
1407 return true; 1426 return true;
1408 } 1427 }
(...skipping 10 matching lines...) Expand all
1419 sig.AddReturn(return_type); 1438 sig.AddReturn(return_type);
1420 } else { 1439 } else {
1421 returns_value = false; 1440 returns_value = false;
1422 } 1441 }
1423 for (int i = 0; i < args->length(); ++i) { 1442 for (int i = 0; i < args->length(); ++i) {
1424 sig.AddParam(TypeOf(args->at(i))); 1443 sig.AddParam(TypeOf(args->at(i)));
1425 } 1444 }
1426 uint32_t index = imported_function_table_.LookupOrInsertImportUse( 1445 uint32_t index = imported_function_table_.LookupOrInsertImportUse(
1427 vp->var(), sig.Build()); 1446 vp->var(), sig.Build());
1428 VisitCallArgs(expr); 1447 VisitCallArgs(expr);
1429 current_function_builder_->AddAsmWasmOffset(expr->position()); 1448 // For non-void functions, we must know the parent node.
1449 DCHECK_IMPLIES(returns_value, IsChild(this_parent, expr));
1450 int pos = expr->position();
1451 int parent_pos = returns_value ? this_parent->position() : pos;
1452 current_function_builder_->AddAsmWasmOffset(pos, parent_pos);
1430 current_function_builder_->Emit(kExprCallFunction); 1453 current_function_builder_->Emit(kExprCallFunction);
1431 current_function_builder_->EmitVarInt(index); 1454 current_function_builder_->EmitVarInt(index);
1432 } else { 1455 } else {
1433 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var()); 1456 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var());
1434 VisitCallArgs(expr); 1457 VisitCallArgs(expr);
1435 current_function_builder_->AddAsmWasmOffset(expr->position()); 1458 current_function_builder_->AddAsmWasmOffset(expr->position(),
1459 expr->position());
1436 current_function_builder_->Emit(kExprCallFunction); 1460 current_function_builder_->Emit(kExprCallFunction);
1437 current_function_builder_->EmitDirectCallIndex( 1461 current_function_builder_->EmitDirectCallIndex(
1438 function->func_index()); 1462 function->func_index());
1439 returns_value = function->signature()->return_count() > 0; 1463 returns_value = function->signature()->return_count() > 0;
1440 } 1464 }
1441 break; 1465 break;
1442 } 1466 }
1443 case Call::KEYED_PROPERTY_CALL: { 1467 case Call::KEYED_PROPERTY_CALL: {
1444 DCHECK_EQ(kFuncScope, scope_); 1468 DCHECK_EQ(kFuncScope, scope_);
1445 Property* p = expr->expression()->AsProperty(); 1469 Property* p = expr->expression()->AsProperty();
1446 DCHECK_NOT_NULL(p); 1470 DCHECK_NOT_NULL(p);
1447 VariableProxy* var = p->obj()->AsVariableProxy(); 1471 VariableProxy* var = p->obj()->AsVariableProxy();
1448 DCHECK_NOT_NULL(var); 1472 DCHECK_NOT_NULL(var);
1449 FunctionTableIndices* indices = LookupOrAddFunctionTable(var, p); 1473 FunctionTableIndices* indices = LookupOrAddFunctionTable(var, p);
1450 Visit(p->key()); // TODO(titzer): should use RECURSE() 1474 Visit(p->key()); // TODO(titzer): should use RECURSE()
1451 1475
1452 // We have to use a temporary for the correct order of evaluation. 1476 // We have to use a temporary for the correct order of evaluation.
1453 current_function_builder_->EmitI32Const(indices->start_index); 1477 current_function_builder_->EmitI32Const(indices->start_index);
1454 current_function_builder_->Emit(kExprI32Add); 1478 current_function_builder_->Emit(kExprI32Add);
1455 WasmTemporary tmp(current_function_builder_, kAstI32); 1479 WasmTemporary tmp(current_function_builder_, kAstI32);
1456 current_function_builder_->EmitSetLocal(tmp.index()); 1480 current_function_builder_->EmitSetLocal(tmp.index());
1457 1481
1458 VisitCallArgs(expr); 1482 VisitCallArgs(expr);
1459 1483
1460 current_function_builder_->EmitGetLocal(tmp.index()); 1484 current_function_builder_->EmitGetLocal(tmp.index());
1461 current_function_builder_->AddAsmWasmOffset(expr->position()); 1485 current_function_builder_->AddAsmWasmOffset(expr->position(),
1486 expr->position());
1462 current_function_builder_->Emit(kExprCallIndirect); 1487 current_function_builder_->Emit(kExprCallIndirect);
1463 current_function_builder_->EmitVarInt(indices->signature_index); 1488 current_function_builder_->EmitVarInt(indices->signature_index);
1464 current_function_builder_->EmitVarInt(0); // table index 1489 current_function_builder_->EmitVarInt(0); // table index
1465 returns_value = 1490 returns_value =
1466 builder_->GetSignature(indices->signature_index)->return_count() > 1491 builder_->GetSignature(indices->signature_index)->return_count() >
1467 0; 1492 0;
1468 break; 1493 break;
1469 } 1494 }
1470 default: 1495 default:
1471 UNREACHABLE(); 1496 UNREACHABLE();
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1623 if (expr->op() == Token::BIT_XOR) { 1648 if (expr->op() == Token::BIT_XOR) {
1624 return expr->left()->AsBinaryOperation()->left(); 1649 return expr->left()->AsBinaryOperation()->left();
1625 } else { 1650 } else {
1626 return expr->left(); 1651 return expr->left();
1627 } 1652 }
1628 } 1653 }
1629 1654
1630 void VisitBinaryOperation(BinaryOperation* expr) { 1655 void VisitBinaryOperation(BinaryOperation* expr) {
1631 ConvertOperation convertOperation = MatchBinaryOperation(expr); 1656 ConvertOperation convertOperation = MatchBinaryOperation(expr);
1632 static const bool kDontIgnoreSign = false; 1657 static const bool kDontIgnoreSign = false;
1658 parent_ = expr;
1633 if (convertOperation == kToDouble) { 1659 if (convertOperation == kToDouble) {
1634 RECURSE(Visit(expr->left())); 1660 RECURSE(Visit(expr->left()));
1635 TypeIndex type = TypeIndexOf(expr->left(), kDontIgnoreSign); 1661 TypeIndex type = TypeIndexOf(expr->left(), kDontIgnoreSign);
1636 if (type == kInt32 || type == kFixnum) { 1662 if (type == kInt32 || type == kFixnum) {
1637 current_function_builder_->Emit(kExprF64SConvertI32); 1663 current_function_builder_->Emit(kExprF64SConvertI32);
1638 } else if (type == kUint32) { 1664 } else if (type == kUint32) {
1639 current_function_builder_->Emit(kExprF64UConvertI32); 1665 current_function_builder_->Emit(kExprF64UConvertI32);
1640 } else if (type == kFloat32) { 1666 } else if (type == kFloat32) {
1641 current_function_builder_->Emit(kExprF64ConvertF32); 1667 current_function_builder_->Emit(kExprF64ConvertF32);
1642 } else { 1668 } else {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1926 Handle<Script> script_; 1952 Handle<Script> script_;
1927 AsmTyper* typer_; 1953 AsmTyper* typer_;
1928 bool typer_failed_; 1954 bool typer_failed_;
1929 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; 1955 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
1930 ZoneVector<ForeignVariable> foreign_variables_; 1956 ZoneVector<ForeignVariable> foreign_variables_;
1931 WasmFunctionBuilder* init_function_; 1957 WasmFunctionBuilder* init_function_;
1932 WasmFunctionBuilder* foreign_init_function_; 1958 WasmFunctionBuilder* foreign_init_function_;
1933 uint32_t next_table_index_; 1959 uint32_t next_table_index_;
1934 ZoneHashMap function_tables_; 1960 ZoneHashMap function_tables_;
1935 ImportedFunctionTable imported_function_table_; 1961 ImportedFunctionTable imported_function_table_;
1962 // Remember the parent node for reporting the correct location for ToNumber
1963 // conversions after calls.
1964 Expression* parent_;
1936 1965
1937 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 1966 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
1938 1967
1939 private: 1968 private:
1940 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); 1969 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl);
1941 }; 1970 };
1942 1971
1943 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, 1972 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone,
1944 AstValueFactory* ast_value_factory, 1973 AstValueFactory* ast_value_factory,
1945 Handle<Script> script, FunctionLiteral* literal) 1974 Handle<Script> script, FunctionLiteral* literal)
(...skipping 17 matching lines...) Expand all
1963 impl.builder_->WriteAsmJsOffsetTable(*asm_offsets_buffer); 1992 impl.builder_->WriteAsmJsOffsetTable(*asm_offsets_buffer);
1964 return {module_buffer, asm_offsets_buffer, success}; 1993 return {module_buffer, asm_offsets_buffer, success};
1965 } 1994 }
1966 1995
1967 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__"; 1996 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__";
1968 const char* AsmWasmBuilder::single_function_name = "__single_function__"; 1997 const char* AsmWasmBuilder::single_function_name = "__single_function__";
1969 1998
1970 } // namespace wasm 1999 } // namespace wasm
1971 } // namespace internal 2000 } // namespace internal
1972 } // namespace v8 2001 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/pipeline.h » ('j') | src/wasm/wasm-objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698