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

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') | runtime/vm/intermediate_language.cc » ('j') | 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_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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698