Mercurial > hg > graal-compiler
annotate graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FixnumNodes.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 |
rev | line source |
---|---|
13514 | 1 /* |
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This | |
3 * code is released under a tri EPL/GPL/LGPL license. You can use it, | |
4 * redistribute it and/or modify it under the terms of the: | |
5 * | |
6 * Eclipse Public License version 1.0 | |
7 * GNU General Public License version 2 | |
8 * GNU Lesser General Public License version 2.1 | |
9 */ | |
10 package com.oracle.truffle.ruby.nodes.core; | |
11 | |
12 import java.math.*; | |
13 | |
14 import com.oracle.truffle.api.*; | |
15 import com.oracle.truffle.api.dsl.*; | |
16 import com.oracle.truffle.api.frame.*; | |
13556
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
17 import com.oracle.truffle.api.utilities.*; |
13514 | 18 import com.oracle.truffle.ruby.runtime.*; |
13556
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
19 import com.oracle.truffle.ruby.runtime.control.*; |
13514 | 20 import com.oracle.truffle.ruby.runtime.core.*; |
21 import com.oracle.truffle.ruby.runtime.core.array.*; | |
22 | |
23 @CoreClass(name = "Fixnum") | |
24 public abstract class FixnumNodes { | |
25 | |
26 @CoreMethod(names = "+@", maxArgs = 0) | |
27 public abstract static class PosNode extends CoreMethodNode { | |
28 | |
29 public PosNode(RubyContext context, SourceSection sourceSection) { | |
30 super(context, sourceSection); | |
31 } | |
32 | |
33 public PosNode(PosNode prev) { | |
34 super(prev); | |
35 } | |
36 | |
37 @Specialization | |
38 public int pos(int value) { | |
39 return value; | |
40 } | |
41 | |
42 } | |
43 | |
44 @CoreMethod(names = "-@", maxArgs = 0) | |
45 public abstract static class NegNode extends CoreMethodNode { | |
46 | |
47 public NegNode(RubyContext context, SourceSection sourceSection) { | |
48 super(context, sourceSection); | |
49 } | |
50 | |
51 public NegNode(NegNode prev) { | |
52 super(prev); | |
53 } | |
54 | |
55 @Specialization(rewriteOn = ArithmeticException.class) | |
56 public int neg(int value) { | |
57 return ExactMath.subtractExact(0, value); | |
58 } | |
59 | |
60 @Specialization | |
61 public BigInteger negWithOverflow(int value) { | |
62 return BigInteger.valueOf(value).negate(); | |
63 } | |
64 | |
65 } | |
66 | |
67 @CoreMethod(names = "+", minArgs = 1, maxArgs = 1) | |
68 public abstract static class AddNode extends CoreMethodNode { | |
69 | |
70 public AddNode(RubyContext context, SourceSection sourceSection) { | |
71 super(context, sourceSection); | |
72 } | |
73 | |
74 public AddNode(AddNode prev) { | |
75 super(prev); | |
76 } | |
77 | |
78 @Specialization(rewriteOn = ArithmeticException.class) | |
79 public int add(int a, int b) { | |
80 return ExactMath.addExact(a, b); | |
81 } | |
82 | |
83 @Specialization | |
84 public Object addWithOverflow(int a, int b) { | |
85 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).add(BigInteger.valueOf(b))); | |
86 } | |
87 | |
88 @Specialization | |
89 public double add(int a, double b) { | |
90 return a + b; | |
91 } | |
92 | |
93 @Specialization | |
94 public Object add(int a, BigInteger b) { | |
95 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).add(b)); | |
96 } | |
97 | |
98 } | |
99 | |
100 @CoreMethod(names = "-", minArgs = 1, maxArgs = 1) | |
101 public abstract static class SubNode extends CoreMethodNode { | |
102 | |
103 public SubNode(RubyContext context, SourceSection sourceSection) { | |
104 super(context, sourceSection); | |
105 } | |
106 | |
107 public SubNode(SubNode prev) { | |
108 super(prev); | |
109 } | |
110 | |
111 @Specialization(rewriteOn = ArithmeticException.class) | |
112 public int sub(int a, int b) { | |
113 return ExactMath.subtractExact(a, b); | |
114 } | |
115 | |
116 @Specialization | |
117 public Object subWithOverflow(int a, int b) { | |
118 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).subtract(BigInteger.valueOf(b))); | |
119 } | |
120 | |
121 @Specialization | |
122 public double sub(int a, double b) { | |
123 return a - b; | |
124 } | |
125 | |
126 @Specialization | |
127 public Object sub(int a, BigInteger b) { | |
128 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).subtract(b)); | |
129 } | |
130 | |
131 } | |
132 | |
133 @CoreMethod(names = "*", minArgs = 1, maxArgs = 1) | |
134 public abstract static class MulNode extends CoreMethodNode { | |
135 | |
136 public MulNode(RubyContext context, SourceSection sourceSection) { | |
137 super(context, sourceSection); | |
138 } | |
139 | |
140 public MulNode(MulNode prev) { | |
141 super(prev); | |
142 } | |
143 | |
144 @Specialization(rewriteOn = ArithmeticException.class) | |
145 public int mul(int a, int b) { | |
146 return ExactMath.multiplyExact(a, b); | |
147 } | |
148 | |
149 @Specialization | |
150 public Object mulWithOverflow(int a, int b) { | |
151 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).multiply(BigInteger.valueOf(b))); | |
152 } | |
153 | |
154 @Specialization | |
155 public double mul(int a, double b) { | |
156 return a * b; | |
157 } | |
158 | |
159 @Specialization | |
160 public Object mul(int a, BigInteger b) { | |
161 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).multiply(b)); | |
162 } | |
163 | |
164 } | |
165 | |
166 @CoreMethod(names = "**", minArgs = 1, maxArgs = 1) | |
167 public abstract static class PowNode extends CoreMethodNode { | |
168 | |
169 public PowNode(RubyContext context, SourceSection sourceSection) { | |
170 super(context, sourceSection); | |
171 } | |
172 | |
173 public PowNode(PowNode prev) { | |
174 super(prev); | |
175 } | |
176 | |
177 @Specialization | |
178 public Object pow(int a, int b) { | |
179 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).pow(b)); | |
180 } | |
181 | |
182 @Specialization | |
183 public double pow(int a, double b) { | |
184 return Math.pow(a, b); | |
185 } | |
186 | |
187 @Specialization | |
188 public Object pow(int a, BigInteger b) { | |
189 final BigInteger bigA = BigInteger.valueOf(a); | |
190 | |
191 BigInteger result = BigInteger.ONE; | |
192 | |
193 for (BigInteger n = BigInteger.ZERO; b.compareTo(b) < 0; n = n.add(BigInteger.ONE)) { | |
194 result = result.multiply(bigA); | |
195 } | |
196 | |
197 return result; | |
198 } | |
199 | |
200 } | |
201 | |
202 @CoreMethod(names = "/", minArgs = 1, maxArgs = 1) | |
203 public abstract static class DivNode extends CoreMethodNode { | |
204 | |
205 public DivNode(RubyContext context, SourceSection sourceSection) { | |
206 super(context, sourceSection); | |
207 } | |
208 | |
209 public DivNode(DivNode prev) { | |
210 super(prev); | |
211 } | |
212 | |
213 @Specialization | |
214 public int div(int a, int b) { | |
215 return a / b; | |
216 } | |
217 | |
218 @Specialization | |
219 public double div(int a, double b) { | |
220 return a / b; | |
221 } | |
222 | |
223 @Specialization | |
224 public int div(@SuppressWarnings("unused") int a, @SuppressWarnings("unused") BigInteger b) { | |
225 return 0; | |
226 } | |
227 } | |
228 | |
229 @CoreMethod(names = "%", minArgs = 1, maxArgs = 1) | |
230 public abstract static class ModNode extends CoreMethodNode { | |
231 | |
232 public ModNode(RubyContext context, SourceSection sourceSection) { | |
233 super(context, sourceSection); | |
234 } | |
235 | |
236 public ModNode(ModNode prev) { | |
237 super(prev); | |
238 } | |
239 | |
240 @Specialization | |
241 public int mod(int a, int b) { | |
242 return a % b; | |
243 } | |
244 | |
245 @Specialization | |
246 public double mod(@SuppressWarnings("unused") int a, @SuppressWarnings("unused") double b) { | |
247 throw new UnsupportedOperationException(); | |
248 } | |
249 | |
250 @Specialization | |
251 public BigInteger mod(@SuppressWarnings("unused") int a, BigInteger b) { | |
252 return b; | |
253 } | |
254 } | |
255 | |
256 @CoreMethod(names = "divmod", minArgs = 1, maxArgs = 1) | |
257 public abstract static class DivModNode extends CoreMethodNode { | |
258 | |
259 public DivModNode(RubyContext context, SourceSection sourceSection) { | |
260 super(context, sourceSection); | |
261 } | |
262 | |
263 public DivModNode(DivModNode prev) { | |
264 super(prev); | |
265 } | |
266 | |
267 @Specialization | |
268 public RubyArray divMod(int a, int b) { | |
269 int q; | |
270 | |
271 if (b < 0) { | |
272 if (a < 0) { | |
273 q = -a / -b; | |
274 } else { | |
275 q = -(a / -b); | |
276 } | |
277 } else { | |
278 if (a < 0) { | |
279 q = -(-a / b); | |
280 } else { | |
281 q = a / b; | |
282 } | |
283 } | |
284 | |
285 int r = a - q * b; | |
286 | |
287 if ((r < 0 && b > 0) || (r > 0 && b < 0)) { | |
288 r += b; | |
289 q -= 1; | |
290 } | |
291 | |
292 final FixnumImmutablePairArrayStore store = new FixnumImmutablePairArrayStore(q, r); | |
293 return new RubyArray(getContext().getCoreLibrary().getArrayClass(), store); | |
294 } | |
295 | |
296 @Specialization | |
297 public RubyArray divMod(@SuppressWarnings("unused") int a, @SuppressWarnings("unused") double b) { | |
298 throw new UnsupportedOperationException(); | |
299 } | |
300 | |
301 @Specialization | |
302 public RubyArray divMod(int a, BigInteger b) { | |
303 return RubyBignum.divMod(getContext(), BigInteger.valueOf(a), b); | |
304 } | |
305 } | |
306 | |
307 @CoreMethod(names = "<", minArgs = 1, maxArgs = 1) | |
308 public abstract static class LessNode extends CoreMethodNode { | |
309 | |
310 public LessNode(RubyContext context, SourceSection sourceSection) { | |
311 super(context, sourceSection); | |
312 } | |
313 | |
314 public LessNode(LessNode prev) { | |
315 super(prev); | |
316 } | |
317 | |
318 @Specialization | |
319 public boolean less(int a, int b) { | |
320 return a < b; | |
321 } | |
322 | |
323 @Specialization | |
324 public boolean less(int a, double b) { | |
325 return a < b; | |
326 } | |
327 | |
328 @Specialization | |
329 public boolean less(int a, BigInteger b) { | |
330 return BigInteger.valueOf(a).compareTo(b) < 0; | |
331 } | |
332 } | |
333 | |
334 @CoreMethod(names = "<=", minArgs = 1, maxArgs = 1) | |
335 public abstract static class LessEqualNode extends CoreMethodNode { | |
336 | |
337 public LessEqualNode(RubyContext context, SourceSection sourceSection) { | |
338 super(context, sourceSection); | |
339 } | |
340 | |
341 public LessEqualNode(LessEqualNode prev) { | |
342 super(prev); | |
343 } | |
344 | |
345 @Specialization | |
346 public boolean lessEqual(int a, int b) { | |
347 return a <= b; | |
348 } | |
349 | |
350 @Specialization | |
351 public boolean lessEqual(int a, double b) { | |
352 return a <= b; | |
353 } | |
354 | |
355 @Specialization | |
356 public boolean lessEqual(int a, BigInteger b) { | |
357 return BigInteger.valueOf(a).compareTo(b) <= 0; | |
358 } | |
359 } | |
360 | |
361 @CoreMethod(names = {"==", "==="}, minArgs = 1, maxArgs = 1) | |
362 public abstract static class EqualNode extends CoreMethodNode { | |
363 | |
364 public EqualNode(RubyContext context, SourceSection sourceSection) { | |
365 super(context, sourceSection); | |
366 } | |
367 | |
368 public EqualNode(EqualNode prev) { | |
369 super(prev); | |
370 } | |
371 | |
372 @Specialization | |
373 public boolean equal(int a, int b) { | |
374 return a == b; | |
375 } | |
376 | |
377 @Specialization | |
378 public boolean equal(int a, double b) { | |
379 return a == b; | |
380 } | |
381 | |
382 @Specialization | |
383 public boolean equal(int a, BigInteger b) { | |
384 return BigInteger.valueOf(a).compareTo(b) == 0; | |
385 } | |
386 } | |
387 | |
388 @CoreMethod(names = "<=>", minArgs = 1, maxArgs = 1) | |
389 public abstract static class CompareNode extends CoreMethodNode { | |
390 | |
391 public CompareNode(RubyContext context, SourceSection sourceSection) { | |
392 super(context, sourceSection); | |
393 } | |
394 | |
395 public CompareNode(CompareNode prev) { | |
396 super(prev); | |
397 } | |
398 | |
399 @Specialization | |
400 public int compare(int a, int b) { | |
401 return Integer.compare(a, b); | |
402 } | |
403 | |
404 @Specialization | |
405 public int compare(int a, double b) { | |
406 return Double.compare(a, b); | |
407 } | |
408 | |
409 @Specialization | |
410 public int compare(int a, BigInteger b) { | |
411 return BigInteger.valueOf(a).compareTo(b); | |
412 } | |
413 } | |
414 | |
415 @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1) | |
416 public abstract static class NotEqualNode extends CoreMethodNode { | |
417 | |
418 public NotEqualNode(RubyContext context, SourceSection sourceSection) { | |
419 super(context, sourceSection); | |
420 } | |
421 | |
422 public NotEqualNode(NotEqualNode prev) { | |
423 super(prev); | |
424 } | |
425 | |
426 @Specialization | |
427 public boolean notEqual(int a, int b) { | |
428 return a != b; | |
429 } | |
430 | |
431 @Specialization | |
432 public boolean notEqual(int a, double b) { | |
433 return a != b; | |
434 } | |
435 | |
436 @Specialization | |
437 public boolean notEqual(int a, BigInteger b) { | |
438 return BigInteger.valueOf(a).compareTo(b) != 0; | |
439 } | |
440 } | |
441 | |
442 @CoreMethod(names = ">=", minArgs = 1, maxArgs = 1) | |
443 public abstract static class GreaterEqualNode extends CoreMethodNode { | |
444 | |
445 public GreaterEqualNode(RubyContext context, SourceSection sourceSection) { | |
446 super(context, sourceSection); | |
447 } | |
448 | |
449 public GreaterEqualNode(GreaterEqualNode prev) { | |
450 super(prev); | |
451 } | |
452 | |
453 @Specialization | |
454 public boolean greaterEqual(int a, int b) { | |
455 return a >= b; | |
456 } | |
457 | |
458 @Specialization | |
459 public boolean greaterEqual(int a, double b) { | |
460 return a >= b; | |
461 } | |
462 | |
463 @Specialization | |
464 public boolean greaterEqual(int a, BigInteger b) { | |
465 return BigInteger.valueOf(a).compareTo(b) >= 0; | |
466 } | |
467 } | |
468 | |
469 @CoreMethod(names = ">", minArgs = 1, maxArgs = 1) | |
470 public abstract static class GreaterNode extends CoreMethodNode { | |
471 | |
472 public GreaterNode(RubyContext context, SourceSection sourceSection) { | |
473 super(context, sourceSection); | |
474 } | |
475 | |
476 public GreaterNode(GreaterNode prev) { | |
477 super(prev); | |
478 } | |
479 | |
480 @Specialization | |
481 public boolean equal(int a, int b) { | |
482 return a > b; | |
483 } | |
484 | |
485 @Specialization | |
486 public boolean equal(int a, double b) { | |
487 return a > b; | |
488 } | |
489 | |
490 @Specialization | |
491 public boolean equal(int a, BigInteger b) { | |
492 return BigInteger.valueOf(a).compareTo(b) > 0; | |
493 } | |
494 } | |
495 | |
496 @CoreMethod(names = "~", maxArgs = 0) | |
497 public abstract static class ComplementNode extends CoreMethodNode { | |
498 | |
499 public ComplementNode(RubyContext context, SourceSection sourceSection) { | |
500 super(context, sourceSection); | |
501 } | |
502 | |
503 public ComplementNode(ComplementNode prev) { | |
504 super(prev); | |
505 } | |
506 | |
507 @Specialization | |
508 public int complement(int n) { | |
509 return ~n; | |
510 } | |
511 | |
512 } | |
513 | |
514 @CoreMethod(names = "&", minArgs = 1, maxArgs = 1) | |
515 public abstract static class BitAndNode extends CoreMethodNode { | |
516 | |
517 public BitAndNode(RubyContext context, SourceSection sourceSection) { | |
518 super(context, sourceSection); | |
519 } | |
520 | |
521 public BitAndNode(BitAndNode prev) { | |
522 super(prev); | |
523 } | |
524 | |
525 @Specialization | |
526 public int bitAnd(int a, int b) { | |
527 return a & b; | |
528 } | |
529 | |
530 @Specialization | |
531 public Object bitAnd(int a, BigInteger b) { | |
532 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).and(b)); | |
533 } | |
534 } | |
535 | |
536 @CoreMethod(names = "|", minArgs = 1, maxArgs = 1) | |
537 public abstract static class BitOrNode extends CoreMethodNode { | |
538 | |
539 public BitOrNode(RubyContext context, SourceSection sourceSection) { | |
540 super(context, sourceSection); | |
541 } | |
542 | |
543 public BitOrNode(BitOrNode prev) { | |
544 super(prev); | |
545 } | |
546 | |
547 @Specialization | |
548 public int bitOr(int a, int b) { | |
549 return a | b; | |
550 } | |
551 | |
552 @Specialization | |
553 public Object bitOr(int a, BigInteger b) { | |
554 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).or(b)); | |
555 } | |
556 } | |
557 | |
558 @CoreMethod(names = "^", minArgs = 1, maxArgs = 1) | |
559 public abstract static class BitXOrNode extends CoreMethodNode { | |
560 | |
561 public BitXOrNode(RubyContext context, SourceSection sourceSection) { | |
562 super(context, sourceSection); | |
563 } | |
564 | |
565 public BitXOrNode(BitXOrNode prev) { | |
566 super(prev); | |
567 } | |
568 | |
569 @Specialization | |
570 public int bitXOr(int a, int b) { | |
571 return a ^ b; | |
572 } | |
573 | |
574 @Specialization | |
575 public Object bitXOr(int a, BigInteger b) { | |
576 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).xor(b)); | |
577 } | |
578 } | |
579 | |
580 @CoreMethod(names = "<<", minArgs = 1, maxArgs = 1) | |
581 public abstract static class LeftShiftNode extends CoreMethodNode { | |
582 | |
583 public LeftShiftNode(RubyContext context, SourceSection sourceSection) { | |
584 super(context, sourceSection); | |
585 } | |
586 | |
587 public LeftShiftNode(LeftShiftNode prev) { | |
588 super(prev); | |
589 } | |
590 | |
591 @Specialization | |
592 public Object leftShift(int a, int b) { | |
593 if (b > 0) { | |
594 if (RubyFixnum.SIZE - Integer.numberOfLeadingZeros(a) + b > RubyFixnum.SIZE - 1) { | |
595 return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).shiftLeft(b)); | |
596 } else { | |
597 return a << b; | |
598 } | |
599 } else { | |
600 if (-b >= Integer.SIZE) { | |
601 return 0; | |
602 } else { | |
603 return a >> -b; | |
604 } | |
605 } | |
606 } | |
607 | |
608 } | |
609 | |
610 @CoreMethod(names = ">>", minArgs = 1, maxArgs = 1) | |
611 public abstract static class RightShiftNode extends CoreMethodNode { | |
612 | |
613 public RightShiftNode(RubyContext context, SourceSection sourceSection) { | |
614 super(context, sourceSection); | |
615 } | |
616 | |
617 public RightShiftNode(RightShiftNode prev) { | |
618 super(prev); | |
619 } | |
620 | |
621 @Specialization | |
622 public int rightShift(int a, int b) { | |
623 if (b > 0) { | |
624 return a >> b; | |
625 } else { | |
626 if (-b >= RubyFixnum.SIZE) { | |
627 return 0; | |
628 } else { | |
629 return a >> -b; | |
630 } | |
631 } | |
632 } | |
633 | |
634 } | |
635 | |
636 @CoreMethod(names = "[]", minArgs = 1, maxArgs = 1) | |
637 public abstract static class GetIndexNode extends CoreMethodNode { | |
638 | |
639 public GetIndexNode(RubyContext context, SourceSection sourceSection) { | |
640 super(context, sourceSection); | |
641 } | |
642 | |
643 public GetIndexNode(GetIndexNode prev) { | |
644 super(prev); | |
645 } | |
646 | |
647 @Specialization | |
648 public int getIndex(int self, int index) { | |
649 if ((self & (1 << index)) == 0) { | |
650 return 0; | |
651 } else { | |
652 return 1; | |
653 } | |
654 } | |
655 | |
656 } | |
657 | |
658 @CoreMethod(names = "chr", maxArgs = 0) | |
659 public abstract static class ChrNode extends CoreMethodNode { | |
660 | |
661 public ChrNode(RubyContext context, SourceSection sourceSection) { | |
662 super(context, sourceSection); | |
663 } | |
664 | |
665 public ChrNode(ChrNode prev) { | |
666 super(prev); | |
667 } | |
668 | |
669 @Specialization | |
670 public RubyString chr(int n) { | |
671 // TODO(CS): not sure about encoding here | |
672 return getContext().makeString((char) n); | |
673 } | |
674 | |
675 } | |
676 | |
677 @CoreMethod(names = "inspect", maxArgs = 0) | |
678 public abstract static class InpsectNode extends CoreMethodNode { | |
679 | |
680 public InpsectNode(RubyContext context, SourceSection sourceSection) { | |
681 super(context, sourceSection); | |
682 } | |
683 | |
684 public InpsectNode(InpsectNode prev) { | |
685 super(prev); | |
686 } | |
687 | |
688 @Specialization | |
689 public RubyString inspect(int n) { | |
690 return getContext().makeString(Integer.toString(n)); | |
691 } | |
692 | |
693 } | |
694 | |
695 @CoreMethod(names = "nonzero?", maxArgs = 0) | |
696 public abstract static class NonZeroNode extends CoreMethodNode { | |
697 | |
698 public NonZeroNode(RubyContext context, SourceSection sourceSection) { | |
699 super(context, sourceSection); | |
700 } | |
701 | |
702 public NonZeroNode(NonZeroNode prev) { | |
703 super(prev); | |
704 } | |
705 | |
706 @Specialization | |
707 public Object nonZero(int value) { | |
708 if (value == 0) { | |
709 return false; | |
710 } else { | |
711 return value; | |
712 } | |
713 } | |
714 | |
715 } | |
716 | |
717 @CoreMethod(names = "size", needsSelf = false, maxArgs = 0) | |
718 public abstract static class SizeNode extends CoreMethodNode { | |
719 | |
720 public SizeNode(RubyContext context, SourceSection sourceSection) { | |
721 super(context, sourceSection); | |
722 } | |
723 | |
724 public SizeNode(SizeNode prev) { | |
725 super(prev); | |
726 } | |
727 | |
728 @Specialization | |
729 public int size() { | |
730 return Integer.SIZE / Byte.SIZE; | |
731 } | |
732 | |
733 } | |
734 | |
735 @CoreMethod(names = "step", needsBlock = true, minArgs = 2, maxArgs = 2) | |
736 public abstract static class StepNode extends YieldingCoreMethodNode { | |
737 | |
738 public StepNode(RubyContext context, SourceSection sourceSection) { | |
739 super(context, sourceSection); | |
740 } | |
741 | |
742 public StepNode(StepNode prev) { | |
743 super(prev); | |
744 } | |
745 | |
746 @Specialization | |
747 public NilPlaceholder step(VirtualFrame frame, int from, int to, int step, RubyProc block) { | |
748 for (int i = from; i <= to; i += step) { | |
749 yield(frame, block, i); | |
750 } | |
751 | |
752 return NilPlaceholder.INSTANCE; | |
753 } | |
754 | |
755 } | |
756 | |
757 @CoreMethod(names = "times", needsBlock = true, maxArgs = 0) | |
758 public abstract static class TimesNode extends YieldingCoreMethodNode { | |
759 | |
13556
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
760 private final BranchProfile breakProfile = new BranchProfile(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
761 private final BranchProfile nextProfile = new BranchProfile(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
762 private final BranchProfile redoProfile = new BranchProfile(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
763 |
13514 | 764 public TimesNode(RubyContext context, SourceSection sourceSection) { |
765 super(context, sourceSection); | |
766 } | |
767 | |
768 public TimesNode(TimesNode prev) { | |
769 super(prev); | |
770 } | |
771 | |
772 @Specialization | |
13556
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
773 public Object times(VirtualFrame frame, int n, RubyProc block) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
774 outer: for (int i = 0; i < n; i++) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
775 while (true) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
776 try { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
777 yield(frame, block, i); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
778 continue outer; |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
779 } catch (BreakException e) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
780 breakProfile.enter(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
781 return e.getResult(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
782 } catch (NextException e) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
783 nextProfile.enter(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
784 continue outer; |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
785 } catch (RedoException e) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
786 redoProfile.enter(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
787 } |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
788 } |
13514 | 789 } |
790 | |
791 return n; | |
792 } | |
793 | |
794 } | |
795 | |
796 @CoreMethod(names = {"to_i", "to_int"}, maxArgs = 0) | |
797 public abstract static class ToINode extends CoreMethodNode { | |
798 | |
799 public ToINode(RubyContext context, SourceSection sourceSection) { | |
800 super(context, sourceSection); | |
801 } | |
802 | |
803 public ToINode(ToINode prev) { | |
804 super(prev); | |
805 } | |
806 | |
807 @Specialization | |
808 public int toI(int n) { | |
809 return n; | |
810 } | |
811 | |
812 } | |
813 | |
814 @CoreMethod(names = "to_f", maxArgs = 0) | |
815 public abstract static class ToFNode extends CoreMethodNode { | |
816 | |
817 public ToFNode(RubyContext context, SourceSection sourceSection) { | |
818 super(context, sourceSection); | |
819 } | |
820 | |
821 public ToFNode(ToFNode prev) { | |
822 super(prev); | |
823 } | |
824 | |
825 @Specialization | |
826 public double toF(int n) { | |
827 return n; | |
828 } | |
829 | |
830 } | |
831 | |
832 @CoreMethod(names = "to_s", maxArgs = 0) | |
833 public abstract static class ToSNode extends CoreMethodNode { | |
834 | |
835 public ToSNode(RubyContext context, SourceSection sourceSection) { | |
836 super(context, sourceSection); | |
837 } | |
838 | |
839 public ToSNode(ToSNode prev) { | |
840 super(prev); | |
841 } | |
842 | |
843 @Specialization | |
844 public RubyString toS(int n) { | |
845 return getContext().makeString(Integer.toString(n)); | |
846 } | |
847 | |
848 } | |
849 | |
850 @CoreMethod(names = "upto", needsBlock = true, minArgs = 1, maxArgs = 1) | |
851 public abstract static class UpToNode extends YieldingCoreMethodNode { | |
852 | |
13556
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
853 private final BranchProfile breakProfile = new BranchProfile(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
854 private final BranchProfile nextProfile = new BranchProfile(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
855 private final BranchProfile redoProfile = new BranchProfile(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
856 |
13514 | 857 public UpToNode(RubyContext context, SourceSection sourceSection) { |
858 super(context, sourceSection); | |
859 } | |
860 | |
861 public UpToNode(UpToNode prev) { | |
862 super(prev); | |
863 } | |
864 | |
865 @Specialization | |
13556
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
866 public Object upto(VirtualFrame frame, int from, int to, RubyProc block) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
867 outer: for (int i = from; i <= to; i++) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
868 while (true) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
869 try { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
870 yield(frame, block, i); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
871 continue outer; |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
872 } catch (BreakException e) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
873 breakProfile.enter(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
874 return e.getResult(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
875 } catch (NextException e) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
876 nextProfile.enter(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
877 continue outer; |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
878 } catch (RedoException e) { |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
879 redoProfile.enter(); |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
880 } |
44288fe54352
Ruby: fix some ?break? semantics.
Chris Seaton <chris.seaton@oracle.com>
parents:
13514
diff
changeset
|
881 } |
13514 | 882 } |
883 | |
884 return NilPlaceholder.INSTANCE; | |
885 } | |
886 | |
887 } | |
888 | |
889 } |