Chromium Code Reviews| 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 |