| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| 11 #include "vm/exceptions.h" | 11 #include "vm/exceptions.h" |
| 12 #include "vm/flags.h" | 12 #include "vm/flags.h" |
| 13 #include "vm/flow_graph.h" | 13 #include "vm/flow_graph.h" |
| 14 #include "vm/flow_graph_compiler.h" | 14 #include "vm/flow_graph_compiler.h" |
| 15 #include "vm/heap.h" | 15 #include "vm/heap.h" |
| 16 #include "vm/il_printer.h" | 16 #include "vm/il_printer.h" |
| 17 #include "vm/intermediate_language.h" | 17 #include "vm/intermediate_language.h" |
| 18 #include "vm/isolate.h" | 18 #include "vm/isolate.h" |
| 19 #include "vm/longjump.h" | |
| 20 #include "vm/object.h" | 19 #include "vm/object.h" |
| 21 #include "vm/object_store.h" | 20 #include "vm/object_store.h" |
| 22 #include "vm/os.h" | 21 #include "vm/os.h" |
| 23 #include "vm/parser.h" | 22 #include "vm/parser.h" |
| 23 #include "vm/report.h" |
| 24 #include "vm/resolver.h" | 24 #include "vm/resolver.h" |
| 25 #include "vm/scopes.h" | 25 #include "vm/scopes.h" |
| 26 #include "vm/stack_frame.h" | 26 #include "vm/stack_frame.h" |
| 27 #include "vm/stub_code.h" | 27 #include "vm/stub_code.h" |
| 28 #include "vm/symbols.h" | 28 #include "vm/symbols.h" |
| 29 #include "vm/token.h" | 29 #include "vm/token.h" |
| 30 #include "vm/zone.h" | 30 #include "vm/zone.h" |
| 31 | 31 |
| 32 namespace dart { | 32 namespace dart { |
| 33 | 33 |
| 34 DEFINE_FLAG(bool, eliminate_type_checks, true, | 34 DEFINE_FLAG(bool, eliminate_type_checks, true, |
| 35 "Eliminate type checks when allowed by static type analysis."); | 35 "Eliminate type checks when allowed by static type analysis."); |
| 36 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); | 36 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); |
| 37 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); | 37 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); |
| 38 DEFINE_FLAG(bool, trace_type_check_elimination, false, | 38 DEFINE_FLAG(bool, trace_type_check_elimination, false, |
| 39 "Trace type check elimination at compile time."); | 39 "Trace type check elimination at compile time."); |
| 40 DEFINE_FLAG(bool, warn_on_javascript_compatibility, false, | |
| 41 "Warn on incompatibilities between vm and dart2js."); | |
| 42 | 40 |
| 43 DECLARE_FLAG(bool, enable_debugger); | 41 DECLARE_FLAG(bool, enable_debugger); |
| 44 DECLARE_FLAG(bool, enable_type_checks); | 42 DECLARE_FLAG(bool, enable_type_checks); |
| 45 DECLARE_FLAG(int, optimization_counter_threshold); | 43 DECLARE_FLAG(int, optimization_counter_threshold); |
| 46 DECLARE_FLAG(bool, silent_warnings); | 44 DECLARE_FLAG(bool, silent_warnings); |
| 45 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 47 DECLARE_FLAG(bool, warning_as_error); | 46 DECLARE_FLAG(bool, warning_as_error); |
| 48 | 47 |
| 49 // Quick access to the locally defined isolate() method. | 48 // Quick access to the locally defined isolate() method. |
| 50 #define I (isolate()) | 49 #define I (isolate()) |
| 51 | 50 |
| 52 // TODO(srdjan): Allow compiler to add constants as they are encountered in | 51 // TODO(srdjan): Allow compiler to add constants as they are encountered in |
| 53 // the compilation. | 52 // the compilation. |
| 54 const double kCommonDoubleConstants[] = | 53 const double kCommonDoubleConstants[] = |
| 55 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, | 54 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, |
| 56 10.0, 20.0, 30.0, 64.0, 255.0, NAN, | 55 10.0, 20.0, 30.0, 64.0, 255.0, NAN, |
| (...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1427 } | 1426 } |
| 1428 if (!(node->IsLiteralNode() && (type.IsIntType() || type.IsDoubleType()))) { | 1427 if (!(node->IsLiteralNode() && (type.IsIntType() || type.IsDoubleType()))) { |
| 1429 return; | 1428 return; |
| 1430 } | 1429 } |
| 1431 const Instance& instance = node->AsLiteralNode()->literal(); | 1430 const Instance& instance = node->AsLiteralNode()->literal(); |
| 1432 if (type.IsIntType()) { | 1431 if (type.IsIntType()) { |
| 1433 if (instance.IsDouble()) { | 1432 if (instance.IsDouble()) { |
| 1434 const Double& double_instance = Double::Cast(instance); | 1433 const Double& double_instance = Double::Cast(instance); |
| 1435 double value = double_instance.value(); | 1434 double value = double_instance.value(); |
| 1436 if (floor(value) == value) { | 1435 if (floor(value) == value) { |
| 1437 Warning(node->token_pos(), | 1436 JSWarning(node->token_pos(), |
| 1438 "javascript compatibility warning: integral value of type " | 1437 "integral value of type 'double' is also considered " |
| 1439 "'double' is also considered to be of type 'int'"); | 1438 "to be of type 'int'"); |
| 1440 } | 1439 } |
| 1441 } | 1440 } |
| 1442 } else { | 1441 } else { |
| 1443 ASSERT(type.IsDoubleType()); | 1442 ASSERT(type.IsDoubleType()); |
| 1444 if (instance.IsInteger()) { | 1443 if (instance.IsInteger()) { |
| 1445 Warning(node->token_pos(), | 1444 JSWarning(node->token_pos(), |
| 1446 "javascript compatibility warning: integer value is also " | 1445 "integer value is also considered to be of type 'double'"); |
| 1447 "considered to be of type 'double'"); | |
| 1448 } | 1446 } |
| 1449 } | 1447 } |
| 1450 } | 1448 } |
| 1451 | 1449 |
| 1452 | 1450 |
| 1453 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 1451 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 1454 ASSERT(Token::IsTypeTestOperator(node->kind())); | 1452 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 1455 const AbstractType& type = node->right()->AsTypeNode()->type(); | 1453 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1456 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); | 1454 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); |
| 1457 const bool negate_result = (node->kind() == Token::kISNOT); | 1455 const bool negate_result = (node->kind() == Token::kISNOT); |
| (...skipping 2497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3955 | 3953 |
| 3956 void FlowGraphBuilder::PruneUnreachable() { | 3954 void FlowGraphBuilder::PruneUnreachable() { |
| 3957 ASSERT(osr_id_ != Isolate::kNoDeoptId); | 3955 ASSERT(osr_id_ != Isolate::kNoDeoptId); |
| 3958 BitVector* block_marks = new BitVector(last_used_block_id_ + 1); | 3956 BitVector* block_marks = new BitVector(last_used_block_id_ + 1); |
| 3959 bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_, | 3957 bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_, |
| 3960 block_marks); | 3958 block_marks); |
| 3961 ASSERT(found); | 3959 ASSERT(found); |
| 3962 } | 3960 } |
| 3963 | 3961 |
| 3964 | 3962 |
| 3965 void FlowGraphBuilder::Warning(intptr_t token_pos, | 3963 void FlowGraphBuilder::JSWarning(intptr_t token_pos, const char* msg) const { |
| 3966 const char* format, ...) const { | 3964 const Script& script = Script::Handle(parsed_function_->function().script()); |
| 3967 if (FLAG_silent_warnings) return; | |
| 3968 const Function& function = parsed_function_->function(); | |
| 3969 va_list args; | |
| 3970 va_start(args, format); | |
| 3971 const Script& script = Script::Handle(I, function.script()); | |
| 3972 const Error& error = Error::Handle( | |
| 3973 I, | |
| 3974 LanguageError::NewFormattedV( | |
| 3975 Error::Handle(I, Error::null()), // No previous error. | |
| 3976 script, token_pos, LanguageError::kWarning, | |
| 3977 Heap::kNew, format, args)); | |
| 3978 va_end(args); | |
| 3979 if (FLAG_warning_as_error) { | 3965 if (FLAG_warning_as_error) { |
| 3980 I->long_jump_base()->Jump(1, error); | 3966 // Report::kJSWarning would result in a JavascriptCompatibilityError, but we |
| 3967 // want a compile-time error. |
| 3968 // TODO(regis): Should we change the expection and make the tests work with |
| 3969 // a JavascriptCompatibilityError? |
| 3970 Report::MessageF(Report::kWarning, script, token_pos, "%s", msg); |
| 3981 UNREACHABLE(); | 3971 UNREACHABLE(); |
| 3982 } else { | |
| 3983 OS::Print("%s", error.ToErrorCString()); | |
| 3984 va_start(args, format); | |
| 3985 Exceptions::TraceJSWarningV(script, token_pos, format, args); | |
| 3986 va_end(args); | |
| 3987 } | 3972 } |
| 3973 Report::MessageF(Report::kJSWarning, script, token_pos, "%s", msg); |
| 3988 } | 3974 } |
| 3989 | 3975 |
| 3990 | 3976 |
| 3991 void FlowGraphBuilder::Bailout(const char* reason) const { | 3977 void FlowGraphBuilder::Bailout(const char* reason) const { |
| 3992 const Function& function = parsed_function_->function(); | 3978 const Function& function = parsed_function_->function(); |
| 3993 const Error& error = Error::Handle( | 3979 Report::MessageF(Report::kBailout, |
| 3994 I, | 3980 Script::Handle(function.script()), |
| 3995 LanguageError::NewFormatted( | 3981 function.token_pos(), |
| 3996 Error::Handle(I, Error::null()), // No previous error. | 3982 "FlowGraphBuilder Bailout: %s %s", |
| 3997 Script::Handle(I, function.script()), | 3983 String::Handle(function.name()).ToCString(), |
| 3998 function.token_pos(), | 3984 reason); |
| 3999 LanguageError::kBailout, | |
| 4000 Heap::kNew, | |
| 4001 "FlowGraphBuilder Bailout: %s %s", | |
| 4002 String::Handle(I, function.name()).ToCString(), | |
| 4003 reason)); | |
| 4004 I->long_jump_base()->Jump(1, error); | |
| 4005 UNREACHABLE(); | 3985 UNREACHABLE(); |
| 4006 } | 3986 } |
| 4007 | 3987 |
| 4008 } // namespace dart | 3988 } // namespace dart |
| OLD | NEW |