OLD | NEW |
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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 ast_value_factory_(ast_value_factory), | 64 ast_value_factory_(ast_value_factory), |
65 script_(script), | 65 script_(script), |
66 typer_(typer), | 66 typer_(typer), |
67 typer_failed_(false), | 67 typer_failed_(false), |
68 breakable_blocks_(zone), | 68 breakable_blocks_(zone), |
69 foreign_variables_(zone), | 69 foreign_variables_(zone), |
70 init_function_(nullptr), | 70 init_function_(nullptr), |
71 foreign_init_function_(nullptr), | 71 foreign_init_function_(nullptr), |
72 function_tables_(ZoneHashMap::kDefaultHashMapCapacity, | 72 function_tables_(ZoneHashMap::kDefaultHashMapCapacity, |
73 ZoneAllocationPolicy(zone)), | 73 ZoneAllocationPolicy(zone)), |
74 imported_function_table_(this) { | 74 imported_function_table_(this), |
| 75 parent_binop_(nullptr) { |
75 InitializeAstVisitor(isolate); | 76 InitializeAstVisitor(isolate); |
76 } | 77 } |
77 | 78 |
78 void InitializeInitFunction() { | 79 void InitializeInitFunction() { |
79 FunctionSig::Builder b(zone(), 0, 0); | 80 FunctionSig::Builder b(zone(), 0, 0); |
80 init_function_ = builder_->AddFunction(b.Build()); | 81 init_function_ = builder_->AddFunction(b.Build()); |
81 builder_->MarkStartFunction(init_function_); | 82 builder_->MarkStartFunction(init_function_); |
82 } | 83 } |
83 | 84 |
84 void BuildForeignInitFunction() { | 85 void BuildForeignInitFunction() { |
(...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1391 Expression* arg = args->at(i); | 1392 Expression* arg = args->at(i); |
1392 RECURSE(Visit(arg)); | 1393 RECURSE(Visit(arg)); |
1393 } | 1394 } |
1394 } | 1395 } |
1395 | 1396 |
1396 void VisitCall(Call* expr) { VisitCallExpression(expr); } | 1397 void VisitCall(Call* expr) { VisitCallExpression(expr); } |
1397 | 1398 |
1398 bool VisitCallExpression(Call* expr) { | 1399 bool VisitCallExpression(Call* expr) { |
1399 Call::CallType call_type = expr->GetCallType(); | 1400 Call::CallType call_type = expr->GetCallType(); |
1400 bool returns_value = true; | 1401 bool returns_value = true; |
| 1402 |
| 1403 // Save the parent now, it might be overwritten in VisitCallArgs. |
| 1404 BinaryOperation* parent_binop = parent_binop_; |
| 1405 |
1401 switch (call_type) { | 1406 switch (call_type) { |
1402 case Call::OTHER_CALL: { | 1407 case Call::OTHER_CALL: { |
1403 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 1408 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
1404 if (proxy != nullptr) { | 1409 if (proxy != nullptr) { |
1405 DCHECK(kFuncScope == scope_ || | 1410 DCHECK(kFuncScope == scope_ || |
1406 typer_->VariableAsStandardMember(proxy->var()) == | 1411 typer_->VariableAsStandardMember(proxy->var()) == |
1407 AsmTyper::kMathFround); | 1412 AsmTyper::kMathFround); |
1408 if (VisitStdlibFunction(expr, proxy)) { | 1413 if (VisitStdlibFunction(expr, proxy)) { |
1409 return true; | 1414 return true; |
1410 } | 1415 } |
(...skipping 10 matching lines...) Expand all Loading... |
1421 sig.AddReturn(return_type); | 1426 sig.AddReturn(return_type); |
1422 } else { | 1427 } else { |
1423 returns_value = false; | 1428 returns_value = false; |
1424 } | 1429 } |
1425 for (int i = 0; i < args->length(); ++i) { | 1430 for (int i = 0; i < args->length(); ++i) { |
1426 sig.AddParam(TypeOf(args->at(i))); | 1431 sig.AddParam(TypeOf(args->at(i))); |
1427 } | 1432 } |
1428 uint32_t index = imported_function_table_.LookupOrInsertImportUse( | 1433 uint32_t index = imported_function_table_.LookupOrInsertImportUse( |
1429 vp->var(), sig.Build()); | 1434 vp->var(), sig.Build()); |
1430 VisitCallArgs(expr); | 1435 VisitCallArgs(expr); |
1431 current_function_builder_->AddAsmWasmOffset(expr->position()); | 1436 // For non-void functions, we must know the parent node. |
| 1437 DCHECK_IMPLIES(returns_value, parent_binop != nullptr); |
| 1438 DCHECK_IMPLIES(returns_value, parent_binop->left() == expr || |
| 1439 parent_binop->right() == expr); |
| 1440 int pos = expr->position(); |
| 1441 int parent_pos = returns_value ? parent_binop->position() : pos; |
| 1442 current_function_builder_->AddAsmWasmOffset(pos, parent_pos); |
1432 current_function_builder_->Emit(kExprCallFunction); | 1443 current_function_builder_->Emit(kExprCallFunction); |
1433 current_function_builder_->EmitVarInt(index); | 1444 current_function_builder_->EmitVarInt(index); |
1434 } else { | 1445 } else { |
1435 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var()); | 1446 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var()); |
1436 VisitCallArgs(expr); | 1447 VisitCallArgs(expr); |
1437 current_function_builder_->AddAsmWasmOffset(expr->position()); | 1448 current_function_builder_->AddAsmWasmOffset(expr->position(), |
| 1449 expr->position()); |
1438 current_function_builder_->Emit(kExprCallFunction); | 1450 current_function_builder_->Emit(kExprCallFunction); |
1439 current_function_builder_->EmitDirectCallIndex( | 1451 current_function_builder_->EmitDirectCallIndex( |
1440 function->func_index()); | 1452 function->func_index()); |
1441 returns_value = function->signature()->return_count() > 0; | 1453 returns_value = function->signature()->return_count() > 0; |
1442 } | 1454 } |
1443 break; | 1455 break; |
1444 } | 1456 } |
1445 case Call::KEYED_PROPERTY_CALL: { | 1457 case Call::KEYED_PROPERTY_CALL: { |
1446 DCHECK_EQ(kFuncScope, scope_); | 1458 DCHECK_EQ(kFuncScope, scope_); |
1447 Property* p = expr->expression()->AsProperty(); | 1459 Property* p = expr->expression()->AsProperty(); |
1448 DCHECK_NOT_NULL(p); | 1460 DCHECK_NOT_NULL(p); |
1449 VariableProxy* var = p->obj()->AsVariableProxy(); | 1461 VariableProxy* var = p->obj()->AsVariableProxy(); |
1450 DCHECK_NOT_NULL(var); | 1462 DCHECK_NOT_NULL(var); |
1451 FunctionTableIndices* indices = LookupOrAddFunctionTable(var, p); | 1463 FunctionTableIndices* indices = LookupOrAddFunctionTable(var, p); |
1452 Visit(p->key()); // TODO(titzer): should use RECURSE() | 1464 Visit(p->key()); // TODO(titzer): should use RECURSE() |
1453 | 1465 |
1454 // We have to use a temporary for the correct order of evaluation. | 1466 // We have to use a temporary for the correct order of evaluation. |
1455 current_function_builder_->EmitI32Const(indices->start_index); | 1467 current_function_builder_->EmitI32Const(indices->start_index); |
1456 current_function_builder_->Emit(kExprI32Add); | 1468 current_function_builder_->Emit(kExprI32Add); |
1457 WasmTemporary tmp(current_function_builder_, kAstI32); | 1469 WasmTemporary tmp(current_function_builder_, kAstI32); |
1458 current_function_builder_->EmitSetLocal(tmp.index()); | 1470 current_function_builder_->EmitSetLocal(tmp.index()); |
1459 | 1471 |
1460 VisitCallArgs(expr); | 1472 VisitCallArgs(expr); |
1461 | 1473 |
1462 current_function_builder_->EmitGetLocal(tmp.index()); | 1474 current_function_builder_->EmitGetLocal(tmp.index()); |
1463 current_function_builder_->AddAsmWasmOffset(expr->position()); | 1475 current_function_builder_->AddAsmWasmOffset(expr->position(), |
| 1476 expr->position()); |
1464 current_function_builder_->Emit(kExprCallIndirect); | 1477 current_function_builder_->Emit(kExprCallIndirect); |
1465 current_function_builder_->EmitVarInt(indices->signature_index); | 1478 current_function_builder_->EmitVarInt(indices->signature_index); |
1466 current_function_builder_->EmitVarInt(0); // table index | 1479 current_function_builder_->EmitVarInt(0); // table index |
1467 returns_value = | 1480 returns_value = |
1468 builder_->GetSignature(indices->signature_index)->return_count() > | 1481 builder_->GetSignature(indices->signature_index)->return_count() > |
1469 0; | 1482 0; |
1470 break; | 1483 break; |
1471 } | 1484 } |
1472 default: | 1485 default: |
1473 UNREACHABLE(); | 1486 UNREACHABLE(); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1625 if (expr->op() == Token::BIT_XOR) { | 1638 if (expr->op() == Token::BIT_XOR) { |
1626 return expr->left()->AsBinaryOperation()->left(); | 1639 return expr->left()->AsBinaryOperation()->left(); |
1627 } else { | 1640 } else { |
1628 return expr->left(); | 1641 return expr->left(); |
1629 } | 1642 } |
1630 } | 1643 } |
1631 | 1644 |
1632 void VisitBinaryOperation(BinaryOperation* expr) { | 1645 void VisitBinaryOperation(BinaryOperation* expr) { |
1633 ConvertOperation convertOperation = MatchBinaryOperation(expr); | 1646 ConvertOperation convertOperation = MatchBinaryOperation(expr); |
1634 static const bool kDontIgnoreSign = false; | 1647 static const bool kDontIgnoreSign = false; |
| 1648 parent_binop_ = expr; |
1635 if (convertOperation == kToDouble) { | 1649 if (convertOperation == kToDouble) { |
1636 RECURSE(Visit(expr->left())); | 1650 RECURSE(Visit(expr->left())); |
1637 TypeIndex type = TypeIndexOf(expr->left(), kDontIgnoreSign); | 1651 TypeIndex type = TypeIndexOf(expr->left(), kDontIgnoreSign); |
1638 if (type == kInt32 || type == kFixnum) { | 1652 if (type == kInt32 || type == kFixnum) { |
1639 current_function_builder_->Emit(kExprF64SConvertI32); | 1653 current_function_builder_->Emit(kExprF64SConvertI32); |
1640 } else if (type == kUint32) { | 1654 } else if (type == kUint32) { |
1641 current_function_builder_->Emit(kExprF64UConvertI32); | 1655 current_function_builder_->Emit(kExprF64UConvertI32); |
1642 } else if (type == kFloat32) { | 1656 } else if (type == kFloat32) { |
1643 current_function_builder_->Emit(kExprF64ConvertF32); | 1657 current_function_builder_->Emit(kExprF64ConvertF32); |
1644 } else { | 1658 } else { |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1928 Handle<Script> script_; | 1942 Handle<Script> script_; |
1929 AsmTyper* typer_; | 1943 AsmTyper* typer_; |
1930 bool typer_failed_; | 1944 bool typer_failed_; |
1931 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; | 1945 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; |
1932 ZoneVector<ForeignVariable> foreign_variables_; | 1946 ZoneVector<ForeignVariable> foreign_variables_; |
1933 WasmFunctionBuilder* init_function_; | 1947 WasmFunctionBuilder* init_function_; |
1934 WasmFunctionBuilder* foreign_init_function_; | 1948 WasmFunctionBuilder* foreign_init_function_; |
1935 uint32_t next_table_index_; | 1949 uint32_t next_table_index_; |
1936 ZoneHashMap function_tables_; | 1950 ZoneHashMap function_tables_; |
1937 ImportedFunctionTable imported_function_table_; | 1951 ImportedFunctionTable imported_function_table_; |
| 1952 // Remember the parent node for reporting the correct location for ToNumber |
| 1953 // conversions after calls. |
| 1954 BinaryOperation* parent_binop_; |
1938 | 1955 |
1939 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); | 1956 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |
1940 | 1957 |
1941 private: | 1958 private: |
1942 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); | 1959 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); |
1943 }; | 1960 }; |
1944 | 1961 |
1945 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, | 1962 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, |
1946 AstValueFactory* ast_value_factory, | 1963 AstValueFactory* ast_value_factory, |
1947 Handle<Script> script, FunctionLiteral* literal) | 1964 Handle<Script> script, FunctionLiteral* literal) |
(...skipping 17 matching lines...) Expand all Loading... |
1965 impl.builder_->WriteAsmJsOffsetTable(*asm_offsets_buffer); | 1982 impl.builder_->WriteAsmJsOffsetTable(*asm_offsets_buffer); |
1966 return {module_buffer, asm_offsets_buffer, success}; | 1983 return {module_buffer, asm_offsets_buffer, success}; |
1967 } | 1984 } |
1968 | 1985 |
1969 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__"; | 1986 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__"; |
1970 const char* AsmWasmBuilder::single_function_name = "__single_function__"; | 1987 const char* AsmWasmBuilder::single_function_name = "__single_function__"; |
1971 | 1988 |
1972 } // namespace wasm | 1989 } // namespace wasm |
1973 } // namespace internal | 1990 } // namespace internal |
1974 } // namespace v8 | 1991 } // namespace v8 |
OLD | NEW |