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 17 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |