comparison graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayNodes.java @ 13556:44288fe54352

Ruby: fix some ?break? semantics.
author Chris Seaton <chris.seaton@oracle.com>
date Wed, 08 Jan 2014 17:42:10 +0000
parents 0fbee3eb71f0
children
comparison
equal deleted inserted replaced
13555:f70c894ae874 13556:44288fe54352
14 import com.oracle.truffle.api.CompilerDirectives.SlowPath; 14 import com.oracle.truffle.api.CompilerDirectives.SlowPath;
15 import com.oracle.truffle.api.*; 15 import com.oracle.truffle.api.*;
16 import com.oracle.truffle.api.dsl.*; 16 import com.oracle.truffle.api.dsl.*;
17 import com.oracle.truffle.api.frame.*; 17 import com.oracle.truffle.api.frame.*;
18 import com.oracle.truffle.api.nodes.*; 18 import com.oracle.truffle.api.nodes.*;
19 import com.oracle.truffle.api.utilities.*;
19 import com.oracle.truffle.ruby.runtime.*; 20 import com.oracle.truffle.ruby.runtime.*;
20 import com.oracle.truffle.ruby.runtime.control.*; 21 import com.oracle.truffle.ruby.runtime.control.*;
21 import com.oracle.truffle.ruby.runtime.core.*; 22 import com.oracle.truffle.ruby.runtime.core.*;
22 import com.oracle.truffle.ruby.runtime.core.array.*; 23 import com.oracle.truffle.ruby.runtime.core.array.*;
23 import com.oracle.truffle.ruby.runtime.core.range.*; 24 import com.oracle.truffle.ruby.runtime.core.range.*;
455 } 456 }
456 457
457 @CoreMethod(names = "each", needsBlock = true, maxArgs = 0) 458 @CoreMethod(names = "each", needsBlock = true, maxArgs = 0)
458 public abstract static class EachNode extends YieldingCoreMethodNode { 459 public abstract static class EachNode extends YieldingCoreMethodNode {
459 460
461 private final BranchProfile breakProfile = new BranchProfile();
462 private final BranchProfile nextProfile = new BranchProfile();
463 private final BranchProfile redoProfile = new BranchProfile();
464
460 public EachNode(RubyContext context, SourceSection sourceSection) { 465 public EachNode(RubyContext context, SourceSection sourceSection) {
461 super(context, sourceSection); 466 super(context, sourceSection);
462 } 467 }
463 468
464 public EachNode(EachNode prev) { 469 public EachNode(EachNode prev) {
465 super(prev); 470 super(prev);
466 } 471 }
467 472
468 @Specialization 473 @Specialization
469 public NilPlaceholder each(VirtualFrame frame, RubyArray array, RubyProc block) { 474 public Object each(VirtualFrame frame, RubyArray array, RubyProc block) {
470 for (int n = 0; n < array.size(); n++) { 475 outer: for (int n = 0; n < array.size(); n++) {
471 try { 476 while (true) {
472 yield(frame, block, array.get(n)); 477 try {
473 } catch (BreakException e) { 478 yield(frame, block, array.get(n));
474 break; 479 continue outer;
480 } catch (BreakException e) {
481 breakProfile.enter();
482 return e.getResult();
483 } catch (NextException e) {
484 nextProfile.enter();
485 continue outer;
486 } catch (RedoException e) {
487 redoProfile.enter();
488 }
475 } 489 }
476 } 490 }
477 491
478 return NilPlaceholder.INSTANCE; 492 return NilPlaceholder.INSTANCE;
479 } 493 }