Chromium Code Reviews| 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_test(owner(), temp_index()); |
| 224 Bailout("EffectGraphVisitor::VisitBinaryOpNode AND/OR"); | 224 node->left()->Visit(&for_test); |
| 225 if (node->kind() == Token::kAND) { | |
|
Kevin Millikin (Google)
2012/03/09 12:29:14
Maybe too cute is to write:
EffectGraphVisitor fo
srdjan
2012/03/09 19:47:41
Done.
| |
| 226 EffectGraphVisitor for_true(owner(), temp_index()); | |
| 227 node->right()->Visit(&for_true); | |
| 228 EffectGraphVisitor for_false(owner(), temp_index()); | |
| 229 Join(for_test, for_true, for_false); | |
| 230 } else { | |
| 231 EffectGraphVisitor for_true(owner(), temp_index()); | |
| 232 EffectGraphVisitor for_false(owner(), temp_index()); | |
| 233 node->right()->Visit(&for_false); | |
| 234 Join(for_test, for_true, for_false); | |
| 235 } | |
| 236 return; | |
| 225 } | 237 } |
| 226 ArgumentGraphVisitor for_left_value(owner(), temp_index()); | 238 ArgumentGraphVisitor for_left_value(owner(), temp_index()); |
| 227 node->left()->Visit(&for_left_value); | 239 node->left()->Visit(&for_left_value); |
| 228 Append(for_left_value); | 240 Append(for_left_value); |
| 229 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); | 241 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); |
| 230 node->right()->Visit(&for_right_value); | 242 node->right()->Visit(&for_right_value); |
| 231 Append(for_right_value); | 243 Append(for_right_value); |
| 232 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 244 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 233 arguments->Add(for_left_value.value()); | 245 arguments->Add(for_left_value.value()); |
| 234 arguments->Add(for_right_value.value()); | 246 arguments->Add(for_right_value.value()); |
| 235 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); | 247 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |
| 236 InstanceCallComp* call = | 248 InstanceCallComp* call = |
| 237 new InstanceCallComp(node->id(), node->token_index(), name, | 249 new InstanceCallComp(node->id(), node->token_index(), name, |
| 238 arguments, Array::ZoneHandle(), 2); | 250 arguments, Array::ZoneHandle(), 2); |
| 239 ReturnComputation(call); | 251 ReturnComputation(call); |
| 240 } | 252 } |
| 241 | 253 |
| 242 | 254 |
| 255 // Special handling for AND/OR. | |
| 256 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | |
| 257 // Operators "&&" and "||" cannot be overloaded therefore do not call | |
| 258 // operator. | |
| 259 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | |
| 260 // Implement short-circuit logic: do not evaluate right if evaluation | |
| 261 // of left is sufficient. | |
| 262 // AND: left ? right : false; | |
|
Kevin Millikin (Google)
2012/03/09 12:29:14
right needs a conversion to boolean (e.g., right =
srdjan
2012/03/09 19:47:41
Thanks for catching it. Added tests (separate CL).
| |
| 263 // OR: left ? true : right; | |
| 264 if (FLAG_enable_type_checks) { | |
| 265 Bailout("GenerateConditionTypeCheck in kAND/kOR"); | |
| 266 } | |
| 267 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 268 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 269 | |
| 270 TestGraphVisitor for_test(owner(), temp_index()); | |
| 271 node->left()->Visit(&for_test); | |
| 272 | |
| 273 if (node->kind() == Token::kAND) { | |
| 274 ValueGraphVisitor for_true(owner(), temp_index()); | |
| 275 node->right()->Visit(&for_true); | |
| 276 if (for_true.value()->IsTemp()) { | |
| 277 ASSERT(for_true.value()->AsTemp()->index() == temp_index()); | |
| 278 } else { | |
| 279 for_true.AddInstruction( | |
| 280 new BindInstr(temp_index(), for_true.value())); | |
| 281 } | |
| 282 | |
| 283 ValueGraphVisitor for_false(owner(), temp_index()); | |
| 284 for_false.AddInstruction( | |
| 285 new BindInstr(temp_index(), new ConstantVal(bool_false))); | |
| 286 | |
| 287 Join(for_test, for_true, for_false); | |
| 288 ReturnValue(new TempVal(AllocateTempIndex())); | |
| 289 } else { | |
| 290 ASSERT(node->kind() == Token::kOR); | |
| 291 ValueGraphVisitor for_true(owner(), temp_index()); | |
| 292 for_true.AddInstruction( | |
| 293 new BindInstr(temp_index(), new ConstantVal(bool_true))); | |
| 294 | |
| 295 ValueGraphVisitor for_false(owner(), temp_index()); | |
| 296 node->right()->Visit(&for_false); | |
| 297 if (for_false.value()->IsTemp()) { | |
| 298 ASSERT(for_false.value()->AsTemp()->index() == temp_index()); | |
| 299 } else { | |
| 300 for_false.AddInstruction( | |
| 301 new BindInstr(temp_index(), for_false.value())); | |
| 302 } | |
| 303 | |
| 304 Join(for_test, for_true, for_false); | |
| 305 ReturnValue(new TempVal(AllocateTempIndex())); | |
| 306 } | |
| 307 return; | |
| 308 } | |
| 309 EffectGraphVisitor::VisitBinaryOpNode(node); | |
| 310 } | |
| 311 | |
| 312 | |
| 243 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) { | 313 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) { |
| 244 Bailout("EffectGraphVisitor::VisitStringConcatNode"); | 314 Bailout("EffectGraphVisitor::VisitStringConcatNode"); |
| 245 } | 315 } |
| 246 | 316 |
| 247 | 317 |
| 248 // <Expression> :: Comparison { kind: Token::Kind | 318 // <Expression> :: Comparison { kind: Token::Kind |
| 249 // left: <Expression> | 319 // left: <Expression> |
| 250 // right: <Expression> } | 320 // right: <Expression> } |
| 251 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 321 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 252 if (Token::IsInstanceofOperator(node->kind())) { | 322 if (Token::IsInstanceofOperator(node->kind())) { |
| (...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1176 char* chars = reinterpret_cast<char*>( | 1246 char* chars = reinterpret_cast<char*>( |
| 1177 Isolate::Current()->current_zone()->Allocate(len)); | 1247 Isolate::Current()->current_zone()->Allocate(len)); |
| 1178 OS::SNPrint(chars, len, kFormat, function_name, reason); | 1248 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 1179 const Error& error = Error::Handle( | 1249 const Error& error = Error::Handle( |
| 1180 LanguageError::New(String::Handle(String::New(chars)))); | 1250 LanguageError::New(String::Handle(String::New(chars)))); |
| 1181 Isolate::Current()->long_jump_base()->Jump(1, error); | 1251 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 1182 } | 1252 } |
| 1183 | 1253 |
| 1184 | 1254 |
| 1185 } // namespace dart | 1255 } // namespace dart |
| OLD | NEW |