| 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 "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 } | 212 } |
| 213 | 213 |
| 214 | 214 |
| 215 // <Expression> :: BinaryOp { kind: Token::Kind | 215 // <Expression> :: BinaryOp { kind: Token::Kind |
| 216 // left: <Expression> | 216 // left: <Expression> |
| 217 // right: <Expression> } | 217 // right: <Expression> } |
| 218 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 218 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 219 // Operators "&&" and "||" cannot be overloaded therefore do not call | 219 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 220 // operator. | 220 // operator. |
| 221 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 221 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 222 // Implement short-circuit logic: do not evaluate right if evaluation | 222 // See ValueGraphVisitor::VisitBinaryOpNode. |
| 223 // of left is sufficient. | 223 TestGraphVisitor for_left(owner(), temp_index()); |
| 224 Bailout("EffectGraphVisitor::VisitBinaryOpNode AND/OR"); | 224 node->left()->Visit(&for_left); |
| 225 EffectGraphVisitor for_right(owner(), temp_index()); |
| 226 node->right()->Visit(&for_right); |
| 227 EffectGraphVisitor empty(owner(), temp_index()); |
| 228 if (node->kind() == Token::kAND) { |
| 229 Join(for_left, for_right, empty); |
| 230 } else { |
| 231 Join(for_left, empty, for_right); |
| 232 } |
| 233 return; |
| 225 } | 234 } |
| 226 ArgumentGraphVisitor for_left_value(owner(), temp_index()); | 235 ArgumentGraphVisitor for_left_value(owner(), temp_index()); |
| 227 node->left()->Visit(&for_left_value); | 236 node->left()->Visit(&for_left_value); |
| 228 Append(for_left_value); | 237 Append(for_left_value); |
| 229 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 238 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
| 230 node->right()->Visit(&for_right_value); | 239 node->right()->Visit(&for_right_value); |
| 231 Append(for_right_value); | 240 Append(for_right_value); |
| 232 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 241 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 233 arguments->Add(for_left_value.value()); | 242 arguments->Add(for_left_value.value()); |
| 234 arguments->Add(for_right_value.value()); | 243 arguments->Add(for_right_value.value()); |
| 235 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); | 244 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 236 InstanceCallComp* call = | 245 InstanceCallComp* call = |
| 237 new InstanceCallComp(node->id(), node->token_index(), name, | 246 new InstanceCallComp(node->id(), node->token_index(), name, |
| 238 arguments, Array::ZoneHandle(), 2); | 247 arguments, Array::ZoneHandle(), 2); |
| 239 ReturnComputation(call); | 248 ReturnComputation(call); |
| 240 } | 249 } |
| 241 | 250 |
| 242 | 251 |
| 252 // Special handling for AND/OR. |
| 253 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 254 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 255 // operator. |
| 256 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 257 // Implement short-circuit logic: do not evaluate right if evaluation |
| 258 // of left is sufficient. |
| 259 // AND: left ? right === true : false; |
| 260 // OR: left ? true : right === true; |
| 261 if (FLAG_enable_type_checks) { |
| 262 Bailout("GenerateConditionTypeCheck in kAND/kOR"); |
| 263 } |
| 264 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 265 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 266 |
| 267 TestGraphVisitor for_test(owner(), temp_index()); |
| 268 node->left()->Visit(&for_test); |
| 269 |
| 270 ValueGraphVisitor for_right(owner(), temp_index()); |
| 271 node->right()->Visit(&for_right); |
| 272 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, |
| 273 for_right.value(), new ConstantVal(bool_true)); |
| 274 for_right.AddInstruction(new BindInstr(temp_index(), comp)); |
| 275 |
| 276 if (node->kind() == Token::kAND) { |
| 277 ValueGraphVisitor for_false(owner(), temp_index()); |
| 278 for_false.AddInstruction( |
| 279 new BindInstr(temp_index(), new ConstantVal(bool_false))); |
| 280 Join(for_test, for_right, for_false); |
| 281 } else { |
| 282 ASSERT(node->kind() == Token::kOR); |
| 283 ValueGraphVisitor for_true(owner(), temp_index()); |
| 284 for_true.AddInstruction( |
| 285 new BindInstr(temp_index(), new ConstantVal(bool_true))); |
| 286 Join(for_test, for_true, for_right); |
| 287 } |
| 288 ReturnValue(new TempVal(AllocateTempIndex())); |
| 289 return; |
| 290 } |
| 291 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 292 } |
| 293 |
| 294 |
| 243 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) { | 295 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) { |
| 244 Bailout("EffectGraphVisitor::VisitStringConcatNode"); | 296 Bailout("EffectGraphVisitor::VisitStringConcatNode"); |
| 245 } | 297 } |
| 246 | 298 |
| 247 | 299 |
| 248 // <Expression> :: Comparison { kind: Token::Kind | 300 // <Expression> :: Comparison { kind: Token::Kind |
| 249 // left: <Expression> | 301 // left: <Expression> |
| 250 // right: <Expression> } | 302 // right: <Expression> } |
| 251 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 303 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 252 if (Token::IsInstanceofOperator(node->kind())) { | 304 if (Token::IsInstanceofOperator(node->kind())) { |
| (...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 char* chars = reinterpret_cast<char*>( | 1364 char* chars = reinterpret_cast<char*>( |
| 1313 Isolate::Current()->current_zone()->Allocate(len)); | 1365 Isolate::Current()->current_zone()->Allocate(len)); |
| 1314 OS::SNPrint(chars, len, kFormat, function_name, reason); | 1366 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 1315 const Error& error = Error::Handle( | 1367 const Error& error = Error::Handle( |
| 1316 LanguageError::New(String::Handle(String::New(chars)))); | 1368 LanguageError::New(String::Handle(String::New(chars)))); |
| 1317 Isolate::Current()->long_jump_base()->Jump(1, error); | 1369 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 1318 } | 1370 } |
| 1319 | 1371 |
| 1320 | 1372 |
| 1321 } // namespace dart | 1373 } // namespace dart |
| OLD | NEW |