Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 9649012: Implement logical AND/OR. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698