Implemented a resizable heap abstraction over mmap(). Allows us to
[panda.git] / src / st-primitives.c
blob7ae5fa279cae9e7dbd1deabdfff287d3e95d75f8
1 /*
2 * st-primitives.c
4 * Copyright (C) 2008 Vincent Geddes
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
25 #include "st-primitives.h"
26 #include "st-processor.h"
27 #include "st-array.h"
28 #include "st-word-array.h"
29 #include "st-byte-array.h"
30 #include "st-large-integer.h"
31 #include "st-float.h"
32 #include "st-float-array.h"
33 #include "st-object.h"
34 #include "st-behavior.h"
35 #include "st-context.h"
36 #include "st-method.h"
37 #include "st-symbol.h"
38 #include "st-character.h"
39 #include "st-unicode.h"
41 #include <math.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <setjmp.h>
46 #define ST_PRIMITIVE_FAIL(pr) \
47 pr->success = false
50 static inline void
51 set_success (st_processor *pr, bool success)
53 pr->success = pr->success && success;
56 static inline st_smi
57 pop_integer (st_processor *pr)
59 st_oop object = ST_STACK_POP (pr);
61 if (ST_LIKELY (st_object_is_smi (object)))
62 return st_smi_value (object);
64 ST_PRIMITIVE_FAIL (pr);
65 return 0;
68 static inline st_smi
69 pop_integer32 (st_processor *pr)
71 st_oop object = ST_STACK_POP (pr);
73 if (ST_LIKELY (st_object_is_smi (object)))
74 return st_smi_value (object);
75 else if (st_object_class (object) == st_large_integer_class)
76 return (st_smi) mp_get_int (st_large_integer_value (object));
78 ST_PRIMITIVE_FAIL (pr);
79 return 0;
82 static void
83 SmallInteger_add (st_processor *pr)
85 st_smi y = pop_integer (pr);
86 st_smi x = pop_integer (pr);
87 st_oop result;
89 if (ST_LIKELY (pr->success)) {
90 result = st_smi_new (x + y);
91 ST_STACK_PUSH (pr, result);
92 return;
95 ST_STACK_UNPOP (pr, 2);
98 static void
99 SmallInteger_sub (st_processor *pr)
101 st_smi y = pop_integer (pr);
102 st_smi x = pop_integer (pr);
103 st_oop result;
105 if (ST_LIKELY (pr->success)) {
106 result = st_smi_new (x - y);
107 ST_STACK_PUSH (pr, result);
108 return;
111 ST_STACK_UNPOP (pr, 2);
114 static void
115 SmallInteger_lt (st_processor *pr)
117 st_smi y = pop_integer (pr);
118 st_smi x = pop_integer (pr);
119 st_oop result;
121 if (ST_LIKELY (pr->success)) {
122 result = (x < y) ? st_true : st_false;
123 ST_STACK_PUSH (pr, result);
124 return;
127 ST_STACK_UNPOP (pr, 2);
130 static void
131 SmallInteger_gt (st_processor *pr)
133 st_smi y = pop_integer (pr);
134 st_smi x = pop_integer (pr);
135 st_oop result;
137 if (ST_LIKELY (pr->success)) {
138 result = (x > y) ? st_true : st_false;
139 ST_STACK_PUSH (pr, result);
140 return;
143 ST_STACK_UNPOP (pr, 2);
146 static void
147 SmallInteger_le (st_processor *pr)
149 st_smi y = pop_integer (pr);
150 st_smi x = pop_integer (pr);
151 st_oop result;
153 if (ST_LIKELY (pr->success)) {
154 result = (x <= y) ? st_true : st_false;
155 ST_STACK_PUSH (pr, result);
156 return;
159 ST_STACK_UNPOP (pr, 2);
162 static void
163 SmallInteger_ge (st_processor *pr)
165 st_smi y = pop_integer (pr);
166 st_smi x = pop_integer (pr);
167 st_oop result;
169 if (ST_LIKELY (pr->success)) {
170 result = (x >= y) ? st_true : st_false;
171 ST_STACK_PUSH (pr, result);
172 return;
175 ST_STACK_UNPOP (pr, 2);
178 static void
179 SmallInteger_eq (st_processor *pr)
181 st_smi y = pop_integer (pr);
182 st_smi x = pop_integer (pr);
183 st_oop result;
185 if (ST_LIKELY (pr->success)) {
186 result = (x == y) ? st_true : st_false;
187 ST_STACK_PUSH (pr, result);
188 return;
191 ST_STACK_UNPOP (pr, 2);
194 static void
195 SmallInteger_ne (st_processor *pr)
197 st_smi y = pop_integer (pr);
198 st_smi x = pop_integer (pr);
199 st_oop result;
201 if (ST_LIKELY (pr->success)) {
202 result = (x != y) ? st_true : st_false;
203 ST_STACK_PUSH (pr, result);
204 return;
207 ST_STACK_UNPOP (pr, 2);
210 static void
211 SmallInteger_mul (st_processor *pr)
213 st_smi y = pop_integer (pr);
214 st_smi x = pop_integer (pr);
215 st_oop result;
217 if (ST_LIKELY (pr->success)) {
218 result = st_smi_new (x * y);
219 ST_STACK_PUSH (pr, result);
220 return;
223 ST_STACK_UNPOP (pr, 2);
226 /* selector: / */
227 static void
228 SmallInteger_div (st_processor *pr)
230 st_smi y = pop_integer (pr);
231 st_smi x = pop_integer (pr);
232 st_oop result;
234 if (ST_LIKELY (pr->success)) {
236 if (y != 0 && x % y == 0) {
237 result = st_smi_new (x / y);
238 ST_STACK_PUSH (pr, result);
239 return;
240 } else {
241 ST_PRIMITIVE_FAIL (pr);
245 ST_STACK_UNPOP (pr, 2);
248 static void
249 SmallInteger_intDiv (st_processor *pr)
251 st_smi y = pop_integer (pr);
252 st_smi x = pop_integer (pr);
253 st_oop result;
255 if (ST_LIKELY (pr->success)) {
257 if (y != 0) {
258 result = st_smi_new (x / y);
259 ST_STACK_PUSH (pr, result);
260 return;
261 } else {
262 ST_PRIMITIVE_FAIL (pr);
266 ST_STACK_UNPOP (pr, 2);
269 static void
270 SmallInteger_mod (st_processor *pr)
272 st_smi y = pop_integer (pr);
273 st_smi x = pop_integer (pr);
274 st_oop result;
276 if (ST_LIKELY (pr->success)) {
277 result = st_smi_new (x % y);
278 ST_STACK_PUSH (pr, result);
279 return;
282 ST_STACK_UNPOP (pr, 2);
285 static void
286 SmallInteger_bitOr (st_processor *pr)
288 st_smi y = pop_integer (pr);
289 st_smi x = pop_integer (pr);
290 st_oop result = st_nil;
292 if (ST_LIKELY (pr->success)) {
293 result = st_smi_new (x | y);
294 ST_STACK_PUSH (pr, result);
295 return;
298 ST_STACK_UNPOP (pr, 2);
301 static void
302 SmallInteger_bitXor (st_processor *pr)
304 st_smi y = pop_integer (pr);
305 st_smi x = pop_integer (pr);
306 st_oop result;
308 if (ST_LIKELY (pr->success)) {
309 result = st_smi_new (x ^ y);
310 ST_STACK_PUSH (pr, result);
311 return;
314 ST_STACK_UNPOP (pr, 2);
317 static void
318 SmallInteger_bitAnd (st_processor *pr)
320 st_smi y = pop_integer (pr);
321 st_smi x = pop_integer (pr);
322 st_oop result = st_nil;
324 if (ST_LIKELY (pr->success)) {
325 result = st_smi_new (x & y);
326 ST_STACK_PUSH (pr, result);
327 return;
330 ST_STACK_UNPOP (pr, 2);
333 static void
334 SmallInteger_bitShift (st_processor *pr)
336 st_smi y = pop_integer (pr);
337 st_smi x = pop_integer (pr);
338 st_oop result = st_nil;
340 if (ST_LIKELY (pr->success)) {
341 if (y > 0)
342 result = st_smi_new (x << y);
343 else if (y < 0)
344 result = st_smi_new (x >> (-y));
345 else
346 result = st_smi_new (x);
348 ST_STACK_PUSH (pr, result);
349 return;
352 ST_STACK_UNPOP (pr, 2);
355 static void
356 SmallInteger_asFloat (st_processor *pr)
358 st_smi x = pop_integer (pr);
359 st_oop result = st_nil;
361 if (ST_LIKELY (pr->success)) {
362 result = st_float_new ((double) x);
363 ST_STACK_PUSH (pr, result);
364 return;
367 ST_STACK_UNPOP (pr, 1);
370 static void
371 SmallInteger_asLargeInteger (st_processor *pr)
373 st_smi receiver = pop_integer (pr);
374 mp_int value;
375 st_oop result;
377 mp_init_set (&value, abs (receiver));
379 if (receiver < 0)
380 mp_neg (&value, &value);
382 result = st_large_integer_new (&value);
383 ST_STACK_PUSH (pr, result);
386 #define VALUE(oop) (&(ST_LARGE_INTEGER(oop)->value))
388 /* useful macros to avoid duplication of error-handling code */
390 #define OP_PROLOGUE \
391 mp_int value; \
392 mp_init (&value);
395 #define BINARY_OP(op, a, b) \
396 OP_PROLOGUE \
397 result = op (VALUE (a), VALUE (b), &value);
399 #define BINARY_DIV_OP(op, a, b) \
400 OP_PROLOGUE \
401 result = op (VALUE (a), VALUE (b), &value, NULL);
403 #define UNARY_OP(op, a) \
404 OP_PROLOGUE \
405 result = op (VALUE (a), &value);
408 static inline st_oop
409 pop_large_integer (st_processor *pr)
411 st_oop object = ST_STACK_POP (pr);
413 set_success (pr, st_object_class (object) == st_large_integer_class);
415 return object;
418 static void
419 LargeInteger_add (st_processor *pr)
421 st_oop b = pop_large_integer (pr);
422 st_oop a = pop_large_integer (pr);
423 st_oop result;
425 if (!pr->success) {
426 ST_STACK_UNPOP (pr, 2);
427 return;
430 BINARY_OP (mp_add, a, b);
432 result = st_large_integer_new (&value);
433 ST_STACK_PUSH (pr, result);
436 static void
437 LargeInteger_sub (st_processor *pr)
439 st_oop b = pop_large_integer (pr);
440 st_oop a = pop_large_integer (pr);
441 st_oop result;
443 if (!pr->success) {
444 ST_STACK_UNPOP (pr, 2);
445 return;
448 BINARY_OP (mp_sub, a, b);
450 result = st_large_integer_new (&value);
451 ST_STACK_PUSH (pr, result);
454 static void
455 LargeInteger_mul (st_processor *pr)
457 st_oop b = pop_large_integer (pr);
458 st_oop a = pop_large_integer (pr);
459 st_oop result;
461 if (!pr->success) {
462 ST_STACK_UNPOP (pr, 2);
463 return;
466 BINARY_OP (mp_mul, a, b);
468 result = st_large_integer_new (&value);
469 ST_STACK_PUSH (pr, result);
472 static void
473 LargeInteger_div (st_processor *pr)
475 st_oop b = pop_large_integer (pr);
476 st_oop a = pop_large_integer (pr);
477 mp_int quotient, remainder;
478 st_oop result;
480 if (!pr->success) {
481 ST_STACK_UNPOP (pr, 2);
482 return;
485 mp_init_multi (&quotient, &remainder, NULL);
486 mp_div (VALUE (a), VALUE (b), &quotient, &remainder);
488 int size;
489 char *str;
491 mp_radix_size (&remainder, 10, &size);
492 str = st_malloc (size);
493 mp_toradix (&remainder, str, 10);
495 if (mp_cmp_d (&remainder, 0) == MP_EQ) {
496 result = st_large_integer_new (&quotient);
497 ST_STACK_PUSH (pr, result);
498 mp_clear (&remainder);
499 } else {
500 set_success (pr, false);
501 ST_STACK_UNPOP (pr, 2);
502 mp_clear_multi (&quotient, &remainder, NULL);
506 static void
507 LargeInteger_intDiv (st_processor *pr)
509 st_oop b = pop_large_integer (pr);
510 st_oop a = pop_large_integer (pr);
511 st_oop result;
513 if (!pr->success) {
514 ST_STACK_UNPOP (pr, 2);
515 return;
518 BINARY_DIV_OP (mp_div, a, b);
520 result = st_large_integer_new (&value);
521 ST_STACK_PUSH (pr, result);
524 static void
525 LargeInteger_mod (st_processor *pr)
527 st_oop b = pop_large_integer (pr);
528 st_oop a = pop_large_integer (pr);
529 st_oop result;
531 if (!pr->success) {
532 ST_STACK_UNPOP (pr, 2);
533 return;
536 BINARY_OP (mp_mod, a, b);
538 result = st_large_integer_new (&value);
539 ST_STACK_PUSH (pr, result);
542 static void
543 LargeInteger_gcd (st_processor *pr)
545 st_oop b = pop_large_integer (pr);
546 st_oop a = pop_large_integer (pr);
547 st_oop result;
549 if (!pr->success) {
550 ST_STACK_UNPOP (pr, 2);
551 return;
554 BINARY_OP (mp_gcd, a, b);
556 result = st_large_integer_new (&value);
557 ST_STACK_PUSH (pr, result);
560 static void
561 LargeInteger_lcm (st_processor *pr)
563 st_oop b = pop_large_integer (pr);
564 st_oop a = pop_large_integer (pr);
565 st_oop result;
567 if (!pr->success) {
568 ST_STACK_UNPOP (pr, 2);
569 return;
572 BINARY_OP (mp_lcm, a, b);
574 result = st_large_integer_new (&value);
575 ST_STACK_PUSH (pr, result);
578 static void
579 LargeInteger_eq (st_processor *pr)
581 st_oop b = pop_large_integer (pr);
582 st_oop a = pop_large_integer (pr);
583 st_oop result;
584 int relation;
586 if (!pr->success) {
587 ST_STACK_UNPOP (pr, 2);
588 return;
591 relation = mp_cmp (VALUE (a), VALUE (b));
592 result = (relation == MP_EQ) ? st_true : st_false;
593 ST_STACK_PUSH (pr, result);
596 static void
597 LargeInteger_ne (st_processor *pr)
599 st_oop b = pop_large_integer (pr);
600 st_oop a = pop_large_integer (pr);
601 st_oop result;
602 int relation;
604 if (!pr->success) {
605 ST_STACK_UNPOP (pr, 2);
606 return;
609 relation = mp_cmp (VALUE (a), VALUE (b));
610 result = (relation == MP_EQ) ? st_false : st_true;
611 ST_STACK_PUSH (pr, result);
614 static void
615 LargeInteger_lt (st_processor *pr)
617 st_oop b = pop_large_integer (pr);
618 st_oop a = pop_large_integer (pr);
619 st_oop result;
620 int relation;
622 if (!pr->success) {
623 ST_STACK_UNPOP (pr, 2);
624 return;
627 relation = mp_cmp (VALUE (a), VALUE (b));
628 result = (relation == MP_LT) ? st_true : st_false;
629 ST_STACK_PUSH (pr, result);
632 static void
633 LargeInteger_gt (st_processor *pr)
635 st_oop b = pop_large_integer (pr);
636 st_oop a = pop_large_integer (pr);
638 st_oop result;
639 int relation;
641 if (!pr->success) {
642 ST_STACK_UNPOP (pr, 2);
643 return;
646 relation = mp_cmp (VALUE (a), VALUE (b));
647 result = (relation == MP_GT) ? st_true : st_false;
648 ST_STACK_PUSH (pr, result);
651 static void
652 LargeInteger_le (st_processor *pr)
654 st_oop b = pop_large_integer (pr);
655 st_oop a = pop_large_integer (pr);
656 st_oop result;
657 int relation;
659 if (!pr->success) {
660 ST_STACK_UNPOP (pr, 2);
661 return;
664 relation = mp_cmp (VALUE (a), VALUE (b));
665 result = (relation == MP_LT || relation == MP_EQ) ? st_true : st_false;
666 ST_STACK_PUSH (pr, result);
669 static void
670 LargeInteger_ge (st_processor *pr)
672 st_oop b = pop_large_integer (pr);
673 st_oop a = pop_large_integer (pr);
674 st_oop result;
675 int relation;
677 if (!pr->success) {
678 ST_STACK_UNPOP (pr, 2);
679 return;
682 relation = mp_cmp (VALUE (a), VALUE (b));
683 result = (relation == MP_GT || relation == MP_EQ) ? st_true : st_false;
684 ST_STACK_PUSH (pr, result);
687 static void
688 LargeInteger_squared (st_processor *pr)
690 st_oop receiver = pop_large_integer (pr);
691 st_oop result;
693 if (!pr->success) {
694 ST_STACK_UNPOP (pr, 1);
695 return;
698 UNARY_OP (mp_sqr, receiver);
700 result = st_large_integer_new (&value);
701 ST_STACK_PUSH (pr, result);
704 static void
705 LargeInteger_bitOr (st_processor *pr)
707 st_oop b = pop_large_integer (pr);
708 st_oop a = pop_large_integer (pr);
709 st_oop result;
711 if (!pr->success) {
712 ST_STACK_UNPOP (pr, 2);
713 return;
716 BINARY_OP (mp_or, a, b);
718 result = st_large_integer_new (&value);
719 ST_STACK_PUSH (pr, result);
722 static void
723 LargeInteger_bitAnd (st_processor *pr)
725 st_oop b = pop_large_integer (pr);
726 st_oop a = pop_large_integer (pr);
727 st_oop result;
729 if (!pr->success) {
730 ST_STACK_UNPOP (pr, 2);
731 return;
734 BINARY_OP (mp_and, a, b);
736 result = st_large_integer_new (&value);
737 ST_STACK_PUSH (pr, result);
740 static void
741 LargeInteger_bitXor (st_processor *pr)
743 st_oop b = pop_large_integer (pr);
744 st_oop a = pop_large_integer (pr);
745 st_oop result;
747 if (!pr->success) {
748 ST_STACK_UNPOP (pr, 2);
749 return;
752 BINARY_OP (mp_xor, a, b);
754 result = st_large_integer_new (&value);
755 ST_STACK_PUSH (pr, result);
758 static void
759 LargeInteger_bitShift (st_processor *pr)
761 st_smi displacement = pop_integer32 (pr);
762 st_oop receiver = pop_large_integer (pr);
763 st_oop result;
764 mp_int value;
766 if (!pr->success) {
767 ST_STACK_UNPOP (pr, 2);
768 return;
771 mp_init (&value);
773 if (displacement >= 0)
774 mp_mul_2d (VALUE (receiver), displacement, &value);
775 else
776 mp_div_2d (VALUE (receiver), abs (displacement), &value, NULL);
778 result = st_large_integer_new (&value);
779 ST_STACK_PUSH (pr, result);
782 static void
783 LargeInteger_asFloat (st_processor *pr)
785 st_oop receiver = pop_large_integer (pr);
786 char *string;
787 double dblval;
789 string = st_large_integer_to_string (receiver, 10);
791 dblval = strtod (string, NULL);
792 st_free (string);
794 ST_STACK_PUSH (pr, st_float_new (dblval));
797 static void
798 LargeInteger_printString (st_processor *pr)
800 st_smi radix = pop_integer (pr);
801 st_oop x = pop_large_integer (pr);
802 char *string;
803 st_oop result;
805 if (radix < 2 || radix > 36)
806 set_success (pr, false);
808 if (pr->success) {
809 string = st_large_integer_to_string (x, radix);
810 result = st_string_new (memory->moving_space, string);
813 if (pr->success)
814 ST_STACK_PUSH (pr, result);
815 else
816 ST_STACK_UNPOP (pr, 2);
819 static void
820 LargeInteger_hash (st_processor *pr)
822 st_oop receiver = ST_STACK_POP (pr);
823 mp_int *value;
824 st_smi result;
825 const char *c;
826 unsigned int hash;
827 int len;
829 value = st_large_integer_value (receiver);
830 c = (const char *) value->dp;
831 len = value->used * sizeof (mp_digit);
832 hash = 5381;
834 for(unsigned int i = 0; i < len; i++)
835 if (c[i])
836 hash = ((hash << 5) + hash) + c[i];
838 result = hash;
840 if (result < 0)
841 result = -result;
843 ST_STACK_PUSH (pr, st_smi_new (result));
847 static inline st_oop
848 pop_float (st_processor *pr)
850 st_oop object = ST_STACK_POP (pr);
852 set_success (pr, st_object_class (object) == st_float_class);
854 return object;
857 static void
858 Float_add (st_processor *pr)
860 st_oop y = pop_float (pr);
861 st_oop x = pop_float (pr);
862 st_oop result = st_nil;
864 if (pr->success)
865 result = st_float_new (st_float_value (x) + st_float_value (y));
867 if (pr->success)
868 ST_STACK_PUSH (pr, result);
869 else
870 ST_STACK_UNPOP (pr, 2);
873 static void
874 Float_sub (st_processor *pr)
876 st_oop y = pop_float (pr);
877 st_oop x = pop_float (pr);
878 st_oop result = st_nil;
880 if (pr->success)
881 result = st_float_new (st_float_value (x) - st_float_value (y));
883 if (pr->success)
884 ST_STACK_PUSH (pr, result);
885 else
886 ST_STACK_UNPOP (pr, 2);
889 static void
890 Float_lt (st_processor *pr)
892 st_oop y = pop_float (pr);
893 st_oop x = pop_float (pr);
894 st_oop result = st_nil;
896 if (pr->success)
897 result = isless (st_float_value (x), st_float_value (y)) ? st_true : st_false;
899 if (pr->success)
900 ST_STACK_PUSH (pr, result);
901 else
902 ST_STACK_UNPOP (pr, 2);
905 static void
906 Float_gt (st_processor *pr)
908 st_oop y = pop_float (pr);
909 st_oop x = pop_float (pr);
910 st_oop result = st_nil;
912 if (pr->success)
913 result = isgreater (st_float_value (x), st_float_value (y)) ? st_true : st_false;
915 if (pr->success)
916 ST_STACK_PUSH (pr, result);
917 else
918 ST_STACK_UNPOP (pr, 2);
921 static void
922 Float_le (st_processor *pr)
924 st_oop y = pop_float (pr);
925 st_oop x = pop_float (pr);
926 st_oop result = st_nil;
928 if (pr->success)
929 result = islessequal (st_float_value (x), st_float_value (y)) ? st_true : st_false;
931 if (pr->success)
932 ST_STACK_PUSH (pr, result);
933 else
934 ST_STACK_UNPOP (pr, 2);
937 static void
938 Float_ge (st_processor *pr)
940 st_oop y = pop_float (pr);
941 st_oop x = pop_float (pr);
942 st_oop result = st_nil;
944 if (pr->success)
945 result = isgreaterequal (st_float_value (x), st_float_value (y)) ? st_true : st_false;
947 if (pr->success)
948 ST_STACK_PUSH (pr, result);
949 else
950 ST_STACK_UNPOP (pr, 2);
953 static void
954 Float_eq (st_processor *pr)
956 st_oop y = pop_float (pr);
957 st_oop x = pop_float (pr);
958 st_oop result = st_nil;
960 if (pr->success)
961 result = (st_float_value (x) == st_float_value (y)) ? st_true : st_false;
963 if (pr->success)
964 ST_STACK_PUSH (pr, result);
965 else
966 ST_STACK_UNPOP (pr, 2);
969 static void
970 Float_ne (st_processor *pr)
972 st_oop y = pop_float (pr);
973 st_oop x = pop_float (pr);
974 st_oop result = st_nil;
976 if (pr->success)
977 result = (st_float_value (x) != st_float_value (y)) ? st_true : st_false;
979 if (pr->success)
980 ST_STACK_PUSH (pr, result);
981 else
982 ST_STACK_UNPOP (pr, 2);
985 static void
986 Float_mul (st_processor *pr)
988 st_oop y = pop_float (pr);
989 st_oop x = pop_float (pr);
990 st_oop result = st_nil;
992 if (pr->success)
993 result = st_float_new (st_float_value (x) * st_float_value (y));
995 if (pr->success)
996 ST_STACK_PUSH (pr, result);
997 else
998 ST_STACK_UNPOP (pr, 2);
1001 static void
1002 Float_div (st_processor *pr)
1004 st_oop y = pop_float (pr);
1005 st_oop x = pop_float (pr);
1006 st_oop result = st_nil;
1008 set_success (pr, y != 0);
1010 if (pr->success)
1011 result = st_float_new (st_float_value (x) / st_float_value (y));
1013 if (pr->success)
1014 ST_STACK_PUSH (pr, result);
1015 else
1016 ST_STACK_UNPOP (pr, 2);
1019 static void
1020 Float_sin (st_processor *pr)
1022 st_oop receiver = ST_STACK_POP (pr);
1023 st_oop result;
1024 double value;
1026 value = st_float_value (receiver);
1028 result = st_float_new (sin (value));
1030 if (pr->success)
1031 ST_STACK_PUSH (pr, result);
1032 else
1033 ST_STACK_UNPOP (pr, 1);
1036 static void
1037 Float_cos (st_processor *pr)
1039 st_oop receiver = ST_STACK_POP (pr);
1040 st_oop result;
1041 double value;
1043 value = st_float_value (receiver);
1045 result = st_float_new (cos (value));
1047 if (pr->success)
1048 ST_STACK_PUSH (pr, result);
1049 else
1050 ST_STACK_UNPOP (pr, 1);
1053 static void
1054 Float_tan (st_processor *pr)
1056 st_oop receiver = ST_STACK_POP (pr);
1057 st_oop result;
1058 double value;
1060 value = st_float_value (receiver);
1062 result = st_float_new (tan (value));
1064 if (pr->success)
1065 ST_STACK_PUSH (pr, result);
1066 else
1067 ST_STACK_UNPOP (pr, 1);
1070 static void
1071 Float_arcSin (st_processor *pr)
1073 st_oop receiver = ST_STACK_POP (pr);
1074 st_oop result;
1075 double value;
1077 value = st_float_value (receiver);
1079 result = st_float_new (asin (value));
1081 if (pr->success)
1082 ST_STACK_PUSH (pr, result);
1083 else
1084 ST_STACK_UNPOP (pr, 1);
1087 static void
1088 Float_arcCos (st_processor *pr)
1090 st_oop receiver = ST_STACK_POP (pr);
1091 st_oop result;
1092 double value;
1094 value = st_float_value (receiver);
1096 result = st_float_new (acos (value));
1098 if (pr->success)
1099 ST_STACK_PUSH (pr, result);
1100 else
1101 ST_STACK_UNPOP (pr, 1);
1104 static void
1105 Float_arcTan (st_processor *pr)
1107 st_oop receiver = ST_STACK_POP (pr);
1108 st_oop result;
1109 double value;
1111 value = st_float_value (receiver);
1113 result = st_float_new (atan (value));
1115 if (pr->success)
1116 ST_STACK_PUSH (pr, result);
1117 else
1118 ST_STACK_UNPOP (pr, 1);
1121 static void
1122 Float_sqrt (st_processor *pr)
1124 st_oop receiver = ST_STACK_POP (pr);
1125 st_oop result;
1126 double value;
1128 value = st_float_value (receiver);
1130 result = st_float_new (sqrt (value));
1132 if (pr->success)
1133 ST_STACK_PUSH (pr, result);
1134 else
1135 ST_STACK_UNPOP (pr, 1);
1138 static void
1139 Float_log (st_processor *pr)
1141 st_oop receiver = ST_STACK_POP (pr);
1142 st_oop result;
1143 double value;
1145 value = st_float_value (receiver);
1147 result = st_float_new (log10 (value));
1149 if (pr->success)
1150 ST_STACK_PUSH (pr, result);
1151 else
1152 ST_STACK_UNPOP (pr, 1);
1155 static void
1156 Float_ln (st_processor *pr)
1158 st_oop receiver = ST_STACK_POP (pr);
1159 st_oop result;
1160 double value;
1162 value = st_float_value (receiver);
1164 result = st_float_new (log (value));
1166 if (pr->success)
1167 ST_STACK_PUSH (pr, result);
1168 else
1169 ST_STACK_UNPOP (pr, 1);
1172 static void
1173 Float_exp (st_processor *pr)
1175 st_oop receiver = ST_STACK_POP (pr);
1176 st_oop result;
1177 double value;
1179 value = st_float_value (receiver);
1181 result = st_float_new (exp (value));
1183 if (pr->success)
1184 ST_STACK_PUSH (pr, result);
1185 else
1186 ST_STACK_UNPOP (pr, 1);
1189 static void
1190 Float_truncated (st_processor *pr)
1192 st_oop receiver = ST_STACK_POP (pr);
1193 st_smi result;
1195 result = (st_smi) trunc (st_float_value (receiver));
1197 ST_STACK_PUSH (pr, st_smi_new (result));
1200 static void
1201 Float_fractionPart (st_processor *pr)
1203 st_oop receiver = ST_STACK_POP (pr);
1204 double frac_part, int_part;
1205 st_oop result;
1207 frac_part = modf (st_float_value (receiver), &int_part);
1209 result = st_float_new (frac_part);
1211 ST_STACK_PUSH (pr, result);
1214 static void
1215 Float_integerPart (st_processor *pr)
1217 st_oop receiver = ST_STACK_POP (pr);
1218 double int_part;
1219 st_oop result;
1221 modf (st_float_value (receiver), &int_part);
1223 result = st_smi_new ((st_smi) int_part);
1224 ST_STACK_PUSH (pr, result);
1227 static void
1228 Float_hash (st_processor *pr)
1230 st_oop receiver = ST_STACK_POP (pr);
1231 unsigned int hash = 0;
1232 st_smi result;
1233 double value;
1234 unsigned char *c;
1236 value = st_float_value (receiver);
1238 if (value == 0)
1239 value = fabs (value);
1241 c = (unsigned char *) & value;
1242 for (int i = 0; i < sizeof (double); i++) {
1243 hash = (hash * 971) ^ c[i];
1246 result = hash;
1248 if (result < 0)
1249 result = -result;
1251 ST_STACK_PUSH (pr, st_smi_new (result));
1254 static void
1255 print_backtrace (st_processor *pr)
1257 st_oop context;
1259 context = pr->context;
1261 while (context != st_nil) {
1263 char *selector;
1264 char *class;
1265 st_oop home;
1266 st_oop receiver;
1268 if (st_object_class (context) == st_block_context_class)
1269 home = ST_BLOCK_CONTEXT (context)->home;
1270 else
1271 home = context;
1273 receiver = ST_METHOD_CONTEXT (home)->receiver;
1275 selector = (char*) st_byte_array_bytes (ST_METHOD (ST_METHOD_CONTEXT (home)->method)->selector);
1277 if (st_object_class (st_object_class (receiver)) == st_metaclass_class)
1278 class = st_strdup_printf ("%s class", (char *) st_byte_array_bytes (ST_CLASS (receiver)->name));
1279 else
1280 class = (char*) st_byte_array_bytes (ST_CLASS (st_object_class (receiver))->name);
1282 printf ("%s>>#%s", class, selector);
1283 if (st_object_class (context) == st_block_context_class)
1284 printf ("[]\n");
1285 else
1286 printf ("\n");
1288 if (st_object_class (context) == st_block_context_class)
1289 context = ST_BLOCK_CONTEXT (context)->caller;
1290 else
1291 context = ST_CONTEXT_PART (context)->sender;
1295 static void
1296 Object_error (st_processor *pr)
1298 st_oop message;
1300 message = ST_STACK_POP (pr);
1302 printf ("= An error occurred during program execution\n");
1303 printf ("= %s\n", st_byte_array_bytes (message));
1305 printf ("\nTraceback:\n");
1306 print_backtrace (pr);
1308 exit (1);
1311 static void
1312 Object_class (st_processor *pr)
1314 st_oop object;
1316 object = ST_STACK_POP (pr);
1318 ST_STACK_PUSH (pr, st_object_class (object));
1321 static void
1322 Object_identityHash (st_processor *pr)
1324 st_oop object;
1325 st_oop result;
1327 object = ST_STACK_POP (pr);
1329 if (st_object_is_heap (object))
1330 result = ST_HEADER (object)->hash;
1331 else if (st_object_is_smi (object))
1332 result = st_smi_new (st_smi_hash (object));
1333 else
1334 result = st_smi_new (st_character_hash (object));
1336 ST_STACK_PUSH (pr, result);
1339 static void
1340 Object_copy (st_processor *pr)
1342 st_oop receiver;
1343 st_oop copy;
1345 receiver = ST_STACK_POP (pr);
1347 if (st_object_is_heap (receiver))
1348 copy = st_descriptor_for_object (receiver)->copy (receiver);
1349 else
1350 copy = receiver;
1352 ST_STACK_PUSH (pr, copy);
1355 static void
1356 Object_equivalent (st_processor *pr)
1358 st_oop y = ST_STACK_POP (pr);
1359 st_oop x = ST_STACK_POP (pr);
1361 ST_STACK_PUSH (pr, ((x == y) ? st_true : st_false));
1364 static void
1365 Object_perform (st_processor *pr)
1367 st_oop receiver;
1368 st_oop selector;
1369 st_oop method;
1370 st_uint selector_index;
1372 selector = pr->message_selector;
1373 pr->message_selector = pr->stack[pr->sp - pr->message_argcount];
1374 receiver = pr->message_receiver;
1376 set_success (pr, st_object_is_symbol (pr->message_selector));
1377 method = st_processor_lookup_method (pr, st_object_class (receiver));
1378 set_success (pr, st_method_get_arg_count (method) == (pr->message_argcount - 1));
1380 if (pr->success) {
1382 selector_index = pr->sp - pr->message_argcount;
1384 st_oops_move (pr->stack + selector_index,
1385 pr->stack + selector_index + 1,
1386 pr->message_argcount - 1);
1388 pr->sp -= 1;
1389 pr->message_argcount -= 1;
1390 st_processor_execute_method (pr, method);
1392 } else {
1393 pr->message_selector = selector;
1397 static void
1398 Object_perform_withArguments (st_processor *pr)
1400 st_oop receiver;
1401 st_oop selector;
1402 st_oop method;
1403 st_oop array;
1404 st_smi array_size;
1406 array = ST_STACK_POP (pr);
1408 set_success (pr, st_object_class (array) == st_array_class);
1410 if (st_object_class (pr->context) == st_block_context_class)
1411 method = ST_METHOD_CONTEXT (ST_BLOCK_CONTEXT (pr->context)->home)->method;
1412 else
1413 method = ST_METHOD_CONTEXT (pr->context)->method;
1415 array_size = st_smi_value (st_arrayed_object_size (array));
1416 set_success (pr, (pr->sp + array_size - 1) < st_method_get_stack_depth (method));
1418 if (pr->success) {
1420 selector = pr->message_selector;
1421 pr->message_selector = ST_STACK_POP (pr);
1422 receiver = ST_STACK_PEEK (pr);
1423 pr->message_argcount = array_size;
1425 set_success (pr, st_object_is_symbol (pr->message_selector));
1427 st_oops_copy (pr->stack + pr->sp,
1428 st_array_elements (array),
1429 array_size);
1431 pr->sp += array_size;
1433 method = st_processor_lookup_method (pr, st_object_class (receiver));
1434 set_success (pr, st_method_get_arg_count (method) == array_size);
1436 if (pr->success) {
1437 st_processor_execute_method (pr, method);
1438 } else {
1439 pr->sp -= pr->message_argcount;
1440 ST_STACK_PUSH (pr, pr->message_selector);
1441 ST_STACK_PUSH (pr, array);
1442 pr->message_argcount = 2;
1443 pr->message_selector = selector;
1446 } else {
1447 ST_STACK_UNPOP (pr, 1);
1451 static void
1452 Behavior_new (st_processor *pr)
1454 st_oop class;
1455 st_oop instance;
1456 st_smi format;
1458 class = ST_STACK_POP (pr);
1459 format = st_smi_value (ST_BEHAVIOR (class)->format);
1461 set_success (pr, st_descriptors[format]->allocate != NULL);
1463 if (!pr->success) {
1464 ST_STACK_UNPOP (pr, 1);
1465 return;
1468 instance = st_descriptors[format]->allocate (memory->moving_space, class);
1469 ST_STACK_PUSH (pr, instance);
1472 static void
1473 Behavior_newSize (st_processor *pr)
1475 st_oop class;
1476 st_smi size;
1477 st_smi format;
1478 st_oop instance;
1480 size = pop_integer32 (pr);
1481 class = ST_STACK_POP (pr);
1483 format = st_smi_value (ST_BEHAVIOR (class)->format);
1485 set_success (pr, st_descriptors[format]->allocate_arrayed != NULL);
1487 if (!pr->success) {
1488 ST_STACK_UNPOP (pr, 2);
1489 return;
1492 instance = st_descriptors[format]->allocate_arrayed (memory->moving_space, class, size);
1493 ST_STACK_PUSH (pr, instance);
1496 static void
1497 SequenceableCollection_size (st_processor *pr)
1499 st_oop object;
1501 object = ST_STACK_POP (pr);
1503 ST_STACK_PUSH (pr, st_arrayed_object_size (object));
1506 static void
1507 Array_at (st_processor *pr)
1509 st_smi index = pop_integer (pr);
1510 st_oop receiver = ST_STACK_POP (pr);
1512 if (ST_UNLIKELY (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver)))) {
1513 set_success (pr, false);
1514 ST_STACK_UNPOP (pr, 2);
1515 return;
1518 ST_STACK_PUSH (pr, st_array_at (receiver, index));
1521 static void
1522 Array_at_put (st_processor *pr)
1524 st_oop object = ST_STACK_POP (pr);
1525 st_smi index = pop_integer32 (pr);
1526 st_oop receiver = ST_STACK_POP (pr);
1528 if (ST_UNLIKELY (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver)))) {
1529 set_success (pr, false);
1530 ST_STACK_UNPOP (pr, 3);
1531 return;
1534 st_array_at_put (receiver, index, object);
1535 ST_STACK_PUSH (pr, object);
1538 static void
1539 ByteArray_at (st_processor *pr)
1541 st_smi index = pop_integer32 (pr);
1542 st_oop receiver = ST_STACK_POP (pr);
1543 st_oop result;
1545 if (!pr->success) {
1546 ST_STACK_UNPOP (pr, 2);
1547 return;
1550 if (ST_UNLIKELY (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver)))) {
1551 set_success (pr, false);
1552 ST_STACK_UNPOP (pr, 2);
1553 return;
1556 result = st_smi_new (st_byte_array_at (receiver, index));
1558 ST_STACK_PUSH (pr, result);
1561 static void
1562 ByteArray_at_put (st_processor *pr)
1564 st_smi byte = pop_integer (pr);
1565 st_smi index = pop_integer32 (pr);
1566 st_oop receiver = ST_STACK_POP (pr);
1568 if (!pr->success) {
1569 ST_STACK_UNPOP (pr, 3);
1570 return;
1573 if (ST_UNLIKELY (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver)))) {
1574 set_success (pr, false);
1575 ST_STACK_UNPOP (pr, 3);
1576 return;
1579 st_byte_array_at_put (receiver, index, byte);
1581 ST_STACK_PUSH (pr, st_smi_new (byte));
1584 static void
1585 ByteArray_hash (st_processor *pr)
1587 st_oop receiver = ST_STACK_POP (pr);
1588 st_uint hash;
1590 hash = st_byte_array_hash (receiver);
1592 ST_STACK_PUSH (pr, st_smi_new (hash));
1595 static void
1596 ByteString_at (st_processor *pr)
1598 st_smi index = pop_integer32 (pr);
1599 st_oop receiver = ST_STACK_POP (pr);
1600 st_oop character;
1601 char *charptr;
1603 if (ST_UNLIKELY (!pr->success)) {
1604 ST_STACK_UNPOP (pr, 2);
1605 return;
1608 if (ST_UNLIKELY (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver)))) {
1609 set_success (pr, false);
1610 ST_STACK_UNPOP (pr, 2);
1611 return;
1614 character = st_character_new (st_byte_array_at (receiver, index));
1616 ST_STACK_PUSH (pr, character);
1619 static void
1620 ByteString_at_put (st_processor *pr)
1622 st_oop character = ST_STACK_POP (pr);
1623 st_smi index = pop_integer32 (pr);
1624 st_oop receiver = ST_STACK_POP (pr);
1626 if (!pr->success) {
1627 ST_STACK_UNPOP (pr, 3);
1628 return;
1631 set_success (pr, st_object_class (character) == st_character_class);
1633 if (ST_UNLIKELY (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver)))) {
1634 set_success (pr, false);
1635 ST_STACK_UNPOP (pr, 3);
1636 return;
1639 st_byte_array_at_put (receiver, index, (st_uchar) st_character_value (character));
1641 ST_STACK_PUSH (pr, character);
1645 static void
1646 ByteString_size (st_processor *pr)
1648 st_oop receiver;
1649 st_uint size;
1651 receiver = ST_STACK_POP (pr);
1653 size = st_arrayed_object_size (receiver);
1655 /* TODO: allow size to go into a LargeInteger on overflow */
1656 ST_STACK_PUSH (pr, size);
1659 static void
1660 ByteString_compare (st_processor *pr)
1662 st_oop argument = ST_STACK_POP (pr);
1663 st_oop receiver = ST_STACK_POP (pr);
1664 int order;
1666 if (st_object_format (argument) != ST_FORMAT_BYTE_ARRAY)
1667 set_success (pr, false);
1669 if (pr->success)
1670 order = strcmp ((const char *) st_byte_array_bytes (receiver),
1671 (const char *) st_byte_array_bytes (argument));
1673 if (pr->success)
1674 ST_STACK_PUSH (pr, st_smi_new (order));
1675 else
1676 ST_STACK_UNPOP (pr, 2);
1679 static void
1680 WideString_at (st_processor *pr)
1682 st_smi index = pop_integer32 (pr);
1683 st_oop receiver = ST_STACK_POP (pr);
1684 st_uchar *bytes;
1685 st_unichar c;
1687 if (!pr->success) {
1688 ST_STACK_UNPOP (pr, 2);
1689 return;
1692 if (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver))) {
1693 set_success (pr, false);
1694 ST_STACK_UNPOP (pr, 2);
1695 return;
1698 c = st_word_array_at (receiver, index);
1700 ST_STACK_PUSH (pr, st_character_new (c));
1703 static void
1704 WideString_at_put (st_processor *pr)
1706 st_oop character = ST_STACK_POP (pr);
1707 st_smi index = pop_integer32 (pr);
1708 st_oop receiver = ST_STACK_POP (pr);
1709 st_uchar *bytes;
1710 st_unichar c;
1712 if (!pr->success) {
1713 ST_STACK_UNPOP (pr, 3);
1714 return;
1717 set_success (pr, st_object_class (character) == st_character_class);
1719 if (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver))) {
1720 set_success (pr, false);
1721 ST_STACK_UNPOP (pr, 3);
1722 return;
1725 st_word_array_at_put (receiver, index, character);
1727 ST_STACK_PUSH (pr, character);
1730 static void
1731 WordArray_at (st_processor *pr)
1733 st_oop receiver;
1734 st_smi index;
1735 st_uint element;
1737 index = pop_integer32 (pr);
1738 receiver = ST_STACK_POP (pr);
1740 if (ST_UNLIKELY (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver)))) {
1741 set_success (pr, false);
1742 ST_STACK_UNPOP (pr, 2);
1743 return;
1746 element = st_word_array_at (receiver, index);
1748 ST_STACK_PUSH (pr, st_smi_new (element));
1751 static void
1752 WordArray_at_put (st_processor *pr)
1754 st_smi value = pop_integer (pr);
1755 st_smi index = pop_integer32 (pr);
1756 st_oop receiver = ST_STACK_POP (pr);
1758 if (!pr->success) {
1759 ST_STACK_UNPOP (pr, 3);
1760 return;
1763 if (ST_UNLIKELY (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver)))) {
1764 set_success (pr, false);
1765 ST_STACK_UNPOP (pr, 3);
1766 return;
1769 st_word_array_at_put (receiver, index, value);
1771 ST_STACK_PUSH (pr, st_smi_new (value));
1774 static void
1775 FloatArray_at (st_processor *pr)
1777 st_oop receiver;
1778 st_smi index;
1779 double element;
1781 index = pop_integer32 (pr);
1782 receiver = ST_STACK_POP (pr);
1784 if (ST_UNLIKELY (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver)))) {
1785 set_success (pr, false);
1786 ST_STACK_UNPOP (pr, 2);
1787 return;
1790 element = st_float_array_at (receiver, index);
1791 ST_STACK_PUSH (pr, st_float_new (element));
1794 static void
1795 FloatArray_at_put (st_processor *pr)
1797 st_oop flt = ST_STACK_POP (pr);
1798 st_smi index = pop_integer32 (pr);
1799 st_oop receiver = ST_STACK_POP (pr);
1801 set_success (pr, st_object_is_heap (flt) &&
1802 st_object_format (flt) == ST_FORMAT_FLOAT);
1804 if (ST_UNLIKELY (index < 1 || index > st_smi_value (st_arrayed_object_size (receiver)))) {
1805 set_success (pr, false);
1806 ST_STACK_UNPOP (pr, 3);
1807 return;
1810 if (!pr->success) {
1811 ST_STACK_UNPOP (pr, 3);
1812 return;
1815 st_float_array_at_put (receiver, index, st_float_value (flt));
1816 ST_STACK_PUSH (pr, flt);
1819 static inline void
1820 activate_block_context (st_processor *pr)
1822 st_oop block;
1823 st_smi argcount;
1825 block = pr->message_receiver;
1826 argcount = st_smi_value (ST_BLOCK_CONTEXT (block)->argcount);
1827 if (argcount != pr->message_argcount) {
1828 pr->success = false;
1829 return;
1832 st_oops_copy (ST_BLOCK_CONTEXT (block)->stack,
1833 pr->stack + pr->sp - argcount,
1834 argcount);
1836 pr->sp -= pr->message_argcount + 1;
1838 ST_CONTEXT_PART (block)->ip = ST_BLOCK_CONTEXT (block)->initial_ip;
1839 ST_CONTEXT_PART (block)->sp = st_smi_new (argcount);
1840 ST_BLOCK_CONTEXT (block)->caller = pr->context;
1842 st_processor_set_active_context (pr, block);
1845 static void
1846 BlockContext_value (st_processor *pr)
1848 activate_block_context (pr);
1851 static void
1852 BlockContext_valueWithArguments (st_processor *pr)
1854 st_oop block;
1855 st_oop values;
1856 st_smi argcount;
1858 block = pr->message_receiver;
1859 values = ST_STACK_PEEK (pr);
1861 if (st_object_class (values) != st_array_class) {
1862 set_success (pr, false);
1863 return;
1866 argcount = st_smi_value (ST_BLOCK_CONTEXT (block)->argcount);
1867 if (argcount != st_smi_value (st_arrayed_object_size (values))) {
1868 set_success (pr, false);
1869 return;
1872 st_oops_copy (ST_BLOCK_CONTEXT (block)->stack,
1873 ST_ARRAY (values)->elements,
1874 argcount);
1876 pr->sp -= pr->message_argcount + 1;
1878 ST_CONTEXT_PART (block)->ip = ST_BLOCK_CONTEXT (block)->initial_ip;
1879 ST_CONTEXT_PART (block)->sp = st_smi_new (argcount);
1880 ST_BLOCK_CONTEXT (block)->caller = pr->context;
1882 st_processor_set_active_context (pr, block);
1885 static void
1886 UndefinedObject_exitWithResult (st_processor *pr)
1888 longjmp (pr->main_loop, 0);
1891 static void
1892 Character_value (st_processor *pr)
1894 st_oop receiver = ST_STACK_POP (pr);
1896 ST_STACK_PUSH (pr, st_smi_new (st_character_value (receiver)));
1899 static void
1900 Character_characterFor (st_processor *pr)
1902 st_oop receiver;
1903 st_smi value;
1905 value = pop_integer (pr);
1906 receiver = ST_STACK_POP (pr);
1908 if (pr->success)
1909 ST_STACK_PUSH (pr, st_character_new (value));
1910 else
1911 ST_STACK_UNPOP (pr, 2);
1914 const struct st_primitive st_primitives[] = {
1915 { "SmallInteger_add", SmallInteger_add },
1916 { "SmallInteger_sub", SmallInteger_sub },
1917 { "SmallInteger_lt", SmallInteger_lt },
1918 { "SmallInteger_gt", SmallInteger_gt },
1919 { "SmallInteger_le", SmallInteger_le },
1920 { "SmallInteger_ge", SmallInteger_ge },
1921 { "SmallInteger_eq", SmallInteger_eq },
1922 { "SmallInteger_ne", SmallInteger_ne },
1923 { "SmallInteger_mul", SmallInteger_mul },
1924 { "SmallInteger_div", SmallInteger_div },
1925 { "SmallInteger_intDiv", SmallInteger_intDiv },
1926 { "SmallInteger_mod", SmallInteger_mod },
1927 { "SmallInteger_bitOr", SmallInteger_bitOr },
1928 { "SmallInteger_bitXor", SmallInteger_bitXor },
1929 { "SmallInteger_bitAnd", SmallInteger_bitAnd },
1930 { "SmallInteger_bitShift", SmallInteger_bitShift },
1931 { "SmallInteger_asFloat", SmallInteger_asFloat },
1932 { "SmallInteger_asLargeInteger", SmallInteger_asLargeInteger },
1934 { "LargeInteger_add", LargeInteger_add },
1935 { "LargeInteger_sub", LargeInteger_sub },
1936 { "LargeInteger_lt", LargeInteger_lt },
1937 { "LargeInteger_gt", LargeInteger_gt },
1938 { "LargeInteger_le", LargeInteger_le },
1939 { "LargeInteger_ge", LargeInteger_ge },
1940 { "LargeInteger_eq", LargeInteger_eq },
1941 { "LargeInteger_ne", LargeInteger_ne },
1942 { "LargeInteger_mul", LargeInteger_mul },
1943 { "LargeInteger_div", LargeInteger_div },
1944 { "LargeInteger_intDiv", LargeInteger_intDiv },
1945 { "LargeInteger_mod", LargeInteger_mod },
1946 { "LargeInteger_gcd", LargeInteger_gcd },
1947 { "LargeInteger_lcm", LargeInteger_lcm },
1948 { "LargeInteger_squared", LargeInteger_squared },
1949 { "LargeInteger_bitOr", LargeInteger_bitOr },
1950 { "LargeInteger_bitXor", LargeInteger_bitXor },
1951 { "LargeInteger_bitAnd", LargeInteger_bitAnd },
1952 { "LargeInteger_bitShift", LargeInteger_bitShift },
1953 { "LargeInteger_printString", LargeInteger_printString },
1954 { "LargeInteger_asFloat", LargeInteger_asFloat },
1955 { "LargeInteger_hash", LargeInteger_hash },
1957 { "Float_add", Float_add },
1958 { "Float_sub", Float_sub },
1959 { "Float_lt", Float_lt },
1960 { "Float_gt", Float_gt },
1961 { "Float_le", Float_le },
1962 { "Float_ge", Float_ge },
1963 { "Float_eq", Float_eq },
1964 { "Float_ne", Float_ne },
1965 { "Float_mul", Float_mul },
1966 { "Float_div", Float_div },
1967 { "Float_exp", Float_exp },
1968 { "Float_sin", Float_sin },
1969 { "Float_cos", Float_cos },
1970 { "Float_tan", Float_tan },
1971 { "Float_arcSin", Float_arcSin },
1972 { "Float_arcCos", Float_arcCos },
1973 { "Float_arcTan", Float_arcTan },
1974 { "Float_ln", Float_ln },
1975 { "Float_log", Float_log },
1976 { "Float_sqrt", Float_sqrt },
1977 { "Float_truncated", Float_truncated },
1978 { "Float_fractionPart", Float_fractionPart },
1979 { "Float_integerPart", Float_integerPart },
1980 { "Float_hash", Float_hash },
1982 { "Object_error", Object_error },
1983 { "Object_class", Object_class },
1984 { "Object_identityHash", Object_identityHash },
1985 { "Object_copy", Object_copy },
1986 { "Object_equivalent", Object_equivalent },
1987 { "Object_perform", Object_perform },
1988 { "Object_perform_withArguments", Object_perform_withArguments },
1990 { "Behavior_new", Behavior_new },
1991 { "Behavior_newSize", Behavior_newSize },
1994 { "SequenceableCollection_size", SequenceableCollection_size },
1996 { "Array_at", Array_at },
1997 { "Array_at_put", Array_at_put },
1999 { "ByteArray_at", ByteArray_at },
2000 { "ByteArray_at_put", ByteArray_at_put },
2001 { "ByteArray_hash", ByteArray_hash },
2003 { "ByteString_at", ByteString_at },
2004 { "ByteString_at_put", ByteString_at_put },
2005 { "ByteString_size", ByteString_size },
2006 { "ByteString_compare", ByteString_compare },
2008 { "WideString_at", WideString_at },
2009 { "WideString_at_put", WideString_at_put },
2011 { "WordArray_at", WordArray_at },
2012 { "WordArray_at_put", WordArray_at_put },
2014 { "FloatArray_at", FloatArray_at },
2015 { "FloatArray_at_put", FloatArray_at_put },
2017 { "UndefinedObject_exitWithResult", UndefinedObject_exitWithResult },
2019 { "Character_value", Character_value },
2020 { "Character_characterFor", Character_characterFor },
2022 { "BlockContext_value", BlockContext_value },
2023 { "BlockContext_valueWithArguments", BlockContext_valueWithArguments },
2026 /* returns 0 if there no primitive function corresponding
2027 * to the given name */
2029 st_primitive_index_for_name (const char *name)
2031 st_assert (name != NULL);
2032 for (int i = 0; i < ST_N_ELEMENTS (st_primitives); i++)
2033 if (streq (name, st_primitives[i].name))
2034 return i;
2035 return -1;