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
25 #include "st-primitives.h"
28 #include "st-large-integer.h"
31 #include "st-object.h"
32 #include "st-behavior.h"
33 #include "st-context.h"
34 #include "st-method.h"
35 #include "st-symbol.h"
36 #include "st-character.h"
37 #include "st-dictionary.h"
38 #include "st-unicode.h"
39 #include "st-compiler.h"
51 #define ST_PRIMITIVE_FAIL(cpu) \
56 set_success (struct st_cpu
*cpu
, bool success
)
58 cpu
->success
= cpu
->success
&& success
;
62 pop_integer (struct st_cpu
*cpu
)
64 st_oop object
= ST_STACK_POP (cpu
);
66 if (ST_LIKELY (st_object_is_smi (object
)))
67 return st_smi_value (object
);
69 ST_PRIMITIVE_FAIL (cpu
);
74 pop_integer32 (struct st_cpu
*cpu
)
76 st_oop object
= ST_STACK_POP (cpu
);
78 if (ST_LIKELY (st_object_is_smi (object
)))
79 return st_smi_value (object
);
80 else if (st_object_class (object
) == ST_LARGE_INTEGER_CLASS
)
81 return (int) mp_get_int (st_large_integer_value (object
));
83 ST_PRIMITIVE_FAIL (cpu
);
88 SmallInteger_add (struct st_cpu
*cpu
)
90 int y
= pop_integer (cpu
);
91 int x
= pop_integer (cpu
);
94 if (ST_LIKELY (cpu
->success
)) {
96 if (((result
<< 1) ^ (result
<< 2)) >= 0) {
97 ST_STACK_PUSH (cpu
, st_smi_new (result
));
100 ST_PRIMITIVE_FAIL (cpu
);
104 ST_STACK_UNPOP (cpu
, 2);
108 SmallInteger_sub (struct st_cpu
*cpu
)
110 int y
= pop_integer (cpu
);
111 int x
= pop_integer (cpu
);
115 if (ST_LIKELY (cpu
->success
)) {
117 if (((result
<< 1) ^ (result
<< 2)) >= 0) {
118 ST_STACK_PUSH (cpu
, st_smi_new (result
));
121 ST_PRIMITIVE_FAIL (cpu
);
125 ST_STACK_UNPOP (cpu
, 2);
129 SmallInteger_lt (struct st_cpu
*cpu
)
131 int y
= pop_integer (cpu
);
132 int x
= pop_integer (cpu
);
135 if (ST_LIKELY (cpu
->success
)) {
136 result
= (x
< y
) ? ST_TRUE
: ST_FALSE
;
137 ST_STACK_PUSH (cpu
, result
);
141 ST_STACK_UNPOP (cpu
, 2);
145 SmallInteger_gt (struct st_cpu
*cpu
)
147 int y
= pop_integer (cpu
);
148 int x
= pop_integer (cpu
);
151 if (ST_LIKELY (cpu
->success
)) {
152 result
= (x
> y
) ? ST_TRUE
: ST_FALSE
;
153 ST_STACK_PUSH (cpu
, result
);
157 ST_STACK_UNPOP (cpu
, 2);
161 SmallInteger_le (struct st_cpu
*cpu
)
163 int y
= pop_integer (cpu
);
164 int x
= pop_integer (cpu
);
167 if (ST_LIKELY (cpu
->success
)) {
168 result
= (x
<= y
) ? ST_TRUE
: ST_FALSE
;
169 ST_STACK_PUSH (cpu
, result
);
173 ST_STACK_UNPOP (cpu
, 2);
177 SmallInteger_ge (struct st_cpu
*cpu
)
179 int y
= pop_integer (cpu
);
180 int x
= pop_integer (cpu
);
183 if (ST_LIKELY (cpu
->success
)) {
184 result
= (x
>= y
) ? ST_TRUE
: ST_FALSE
;
185 ST_STACK_PUSH (cpu
, result
);
189 ST_STACK_UNPOP (cpu
, 2);
193 SmallInteger_eq (struct st_cpu
*cpu
)
195 int y
= pop_integer (cpu
);
196 int x
= pop_integer (cpu
);
199 if (ST_LIKELY (cpu
->success
)) {
200 result
= (x
== y
) ? ST_TRUE
: ST_FALSE
;
201 ST_STACK_PUSH (cpu
, result
);
205 ST_STACK_UNPOP (cpu
, 2);
209 SmallInteger_ne (struct st_cpu
*cpu
)
211 int y
= pop_integer (cpu
);
212 int x
= pop_integer (cpu
);
215 if (ST_LIKELY (cpu
->success
)) {
216 result
= (x
!= y
) ? ST_TRUE
: ST_FALSE
;
217 ST_STACK_PUSH (cpu
, result
);
221 ST_STACK_UNPOP (cpu
, 2);
225 SmallInteger_mul (struct st_cpu
*cpu
)
227 int y
= pop_integer (cpu
);
228 int x
= pop_integer (cpu
);
233 if (result
>= ST_SMALL_INTEGER_MIN
&& result
<= ST_SMALL_INTEGER_MAX
) {
234 ST_STACK_PUSH (cpu
, st_smi_new ((int) result
));
237 ST_PRIMITIVE_FAIL (cpu
);
241 ST_STACK_UNPOP (cpu
, 2);
246 SmallInteger_div (struct st_cpu
*cpu
)
248 int y
= pop_integer (cpu
);
249 int x
= pop_integer (cpu
);
252 if (ST_LIKELY (cpu
->success
)) {
254 if (y
!= 0 && x
% y
== 0) {
255 result
= st_smi_new (x
/ y
);
256 ST_STACK_PUSH (cpu
, result
);
259 ST_PRIMITIVE_FAIL (cpu
);
263 ST_STACK_UNPOP (cpu
, 2);
267 SmallInteger_intDiv (struct st_cpu
*cpu
)
269 int y
= pop_integer (cpu
);
270 int x
= pop_integer (cpu
);
273 if (ST_LIKELY (cpu
->success
)) {
276 result
= st_smi_new (x
/ y
);
277 ST_STACK_PUSH (cpu
, result
);
280 ST_PRIMITIVE_FAIL (cpu
);
284 ST_STACK_UNPOP (cpu
, 2);
288 SmallInteger_mod (struct st_cpu
*cpu
)
290 int y
= pop_integer (cpu
);
291 int x
= pop_integer (cpu
);
294 if (ST_LIKELY (cpu
->success
)) {
295 result
= st_smi_new (x
% y
);
296 ST_STACK_PUSH (cpu
, result
);
300 ST_STACK_UNPOP (cpu
, 2);
304 SmallInteger_bitOr (struct st_cpu
*cpu
)
306 int y
= pop_integer (cpu
);
307 int x
= pop_integer (cpu
);
308 st_oop result
= ST_NIL
;
310 if (ST_LIKELY (cpu
->success
)) {
311 result
= st_smi_new (x
| y
);
312 ST_STACK_PUSH (cpu
, result
);
316 ST_STACK_UNPOP (cpu
, 2);
320 SmallInteger_bitXor (struct st_cpu
*cpu
)
322 int y
= pop_integer (cpu
);
323 int x
= pop_integer (cpu
);
326 if (ST_LIKELY (cpu
->success
)) {
327 result
= st_smi_new (x
^ y
);
328 ST_STACK_PUSH (cpu
, result
);
332 ST_STACK_UNPOP (cpu
, 2);
336 SmallInteger_bitAnd (struct st_cpu
*cpu
)
338 int y
= pop_integer (cpu
);
339 int x
= pop_integer (cpu
);
340 st_oop result
= ST_NIL
;
342 if (ST_LIKELY (cpu
->success
)) {
343 result
= st_smi_new (x
& y
);
344 ST_STACK_PUSH (cpu
, result
);
348 ST_STACK_UNPOP (cpu
, 2);
352 SmallInteger_bitShift (struct st_cpu
*cpu
)
354 int y
= pop_integer (cpu
);
355 int x
= pop_integer (cpu
);
356 st_oop result
= ST_NIL
;
358 if (ST_LIKELY (cpu
->success
)) {
360 result
= st_smi_new (x
<< y
);
362 result
= st_smi_new (x
>> (-y
));
364 result
= st_smi_new (x
);
366 ST_STACK_PUSH (cpu
, result
);
370 ST_STACK_UNPOP (cpu
, 2);
374 SmallInteger_asFloat (struct st_cpu
*cpu
)
376 int x
= pop_integer (cpu
);
377 st_oop result
= ST_NIL
;
379 if (ST_LIKELY (cpu
->success
)) {
380 result
= st_float_new ((double) x
);
381 ST_STACK_PUSH (cpu
, result
);
385 ST_STACK_UNPOP (cpu
, 1);
389 SmallInteger_asLargeInteger (struct st_cpu
*cpu
)
391 int receiver
= pop_integer (cpu
);
395 mp_init_set (&value
, abs (receiver
));
398 mp_neg (&value
, &value
);
400 result
= st_large_integer_new (&value
);
401 ST_STACK_PUSH (cpu
, result
);
404 #define VALUE(oop) (&(ST_LARGE_INTEGER(oop)->value))
406 /* useful macros to avoid duplication of error-handling code */
408 #define OP_PROLOGUE \
413 #define BINARY_OP(op, a, b) \
415 result = op (VALUE (a), VALUE (b), &value);
417 #define BINARY_DIV_OP(op, a, b) \
419 result = op (VALUE (a), VALUE (b), &value, NULL);
421 #define UNARY_OP(op, a) \
423 result = op (VALUE (a), &value);
427 pop_large_integer (struct st_cpu
*cpu
)
429 st_oop object
= ST_STACK_POP (cpu
);
431 set_success (cpu
, st_object_class (object
) == ST_LARGE_INTEGER_CLASS
);
437 LargeInteger_add (struct st_cpu
*cpu
)
439 st_oop b
= pop_large_integer (cpu
);
440 st_oop a
= pop_large_integer (cpu
);
444 ST_STACK_UNPOP (cpu
, 2);
448 BINARY_OP (mp_add
, a
, b
);
450 result
= st_large_integer_new (&value
);
451 ST_STACK_PUSH (cpu
, result
);
455 LargeInteger_sub (struct st_cpu
*cpu
)
457 st_oop b
= pop_large_integer (cpu
);
458 st_oop a
= pop_large_integer (cpu
);
462 ST_STACK_UNPOP (cpu
, 2);
466 BINARY_OP (mp_sub
, a
, b
);
468 result
= st_large_integer_new (&value
);
469 ST_STACK_PUSH (cpu
, result
);
473 LargeInteger_mul (struct st_cpu
*cpu
)
475 st_oop b
= pop_large_integer (cpu
);
476 st_oop a
= pop_large_integer (cpu
);
480 ST_STACK_UNPOP (cpu
, 2);
484 BINARY_OP (mp_mul
, a
, b
);
486 result
= st_large_integer_new (&value
);
487 ST_STACK_PUSH (cpu
, result
);
491 LargeInteger_div (struct st_cpu
*cpu
)
493 st_oop b
= pop_large_integer (cpu
);
494 st_oop a
= pop_large_integer (cpu
);
495 mp_int quotient
, remainder
;
499 ST_STACK_UNPOP (cpu
, 2);
503 mp_init_multi ("ient
, &remainder
, NULL
);
504 mp_div (VALUE (a
), VALUE (b
), "ient
, &remainder
);
509 mp_radix_size (&remainder
, 10, &size
);
510 str
= st_malloc (size
);
511 mp_toradix (&remainder
, str
, 10);
513 if (mp_cmp_d (&remainder
, 0) == MP_EQ
) {
514 result
= st_large_integer_new ("ient
);
515 ST_STACK_PUSH (cpu
, result
);
516 mp_clear (&remainder
);
518 set_success (cpu
, false);
519 ST_STACK_UNPOP (cpu
, 2);
520 mp_clear_multi ("ient
, &remainder
, NULL
);
525 LargeInteger_intDiv (struct st_cpu
*cpu
)
527 st_oop b
= pop_large_integer (cpu
);
528 st_oop a
= pop_large_integer (cpu
);
532 ST_STACK_UNPOP (cpu
, 2);
536 BINARY_DIV_OP (mp_div
, a
, b
);
538 result
= st_large_integer_new (&value
);
539 ST_STACK_PUSH (cpu
, result
);
543 LargeInteger_mod (struct st_cpu
*cpu
)
545 st_oop b
= pop_large_integer (cpu
);
546 st_oop a
= pop_large_integer (cpu
);
550 ST_STACK_UNPOP (cpu
, 2);
554 BINARY_OP (mp_mod
, a
, b
);
556 result
= st_large_integer_new (&value
);
557 ST_STACK_PUSH (cpu
, result
);
561 LargeInteger_gcd (struct st_cpu
*cpu
)
563 st_oop b
= pop_large_integer (cpu
);
564 st_oop a
= pop_large_integer (cpu
);
568 ST_STACK_UNPOP (cpu
, 2);
572 BINARY_OP (mp_gcd
, a
, b
);
574 result
= st_large_integer_new (&value
);
575 ST_STACK_PUSH (cpu
, result
);
579 LargeInteger_lcm (struct st_cpu
*cpu
)
581 st_oop b
= pop_large_integer (cpu
);
582 st_oop a
= pop_large_integer (cpu
);
586 ST_STACK_UNPOP (cpu
, 2);
590 BINARY_OP (mp_lcm
, a
, b
);
592 result
= st_large_integer_new (&value
);
593 ST_STACK_PUSH (cpu
, result
);
597 LargeInteger_eq (struct st_cpu
*cpu
)
599 st_oop b
= pop_large_integer (cpu
);
600 st_oop a
= pop_large_integer (cpu
);
605 ST_STACK_UNPOP (cpu
, 2);
609 relation
= mp_cmp (VALUE (a
), VALUE (b
));
610 result
= (relation
== MP_EQ
) ? ST_TRUE
: ST_FALSE
;
611 ST_STACK_PUSH (cpu
, result
);
615 LargeInteger_ne (struct st_cpu
*cpu
)
617 st_oop b
= pop_large_integer (cpu
);
618 st_oop a
= pop_large_integer (cpu
);
623 ST_STACK_UNPOP (cpu
, 2);
627 relation
= mp_cmp (VALUE (a
), VALUE (b
));
628 result
= (relation
== MP_EQ
) ? ST_FALSE
: ST_TRUE
;
629 ST_STACK_PUSH (cpu
, result
);
633 LargeInteger_lt (struct st_cpu
*cpu
)
635 st_oop b
= pop_large_integer (cpu
);
636 st_oop a
= pop_large_integer (cpu
);
641 ST_STACK_UNPOP (cpu
, 2);
645 relation
= mp_cmp (VALUE (a
), VALUE (b
));
646 result
= (relation
== MP_LT
) ? ST_TRUE
: ST_FALSE
;
647 ST_STACK_PUSH (cpu
, result
);
651 LargeInteger_gt (struct st_cpu
*cpu
)
653 st_oop b
= pop_large_integer (cpu
);
654 st_oop a
= pop_large_integer (cpu
);
660 ST_STACK_UNPOP (cpu
, 2);
664 relation
= mp_cmp (VALUE (a
), VALUE (b
));
665 result
= (relation
== MP_GT
) ? ST_TRUE
: ST_FALSE
;
666 ST_STACK_PUSH (cpu
, result
);
670 LargeInteger_le (struct st_cpu
*cpu
)
672 st_oop b
= pop_large_integer (cpu
);
673 st_oop a
= pop_large_integer (cpu
);
678 ST_STACK_UNPOP (cpu
, 2);
682 relation
= mp_cmp (VALUE (a
), VALUE (b
));
683 result
= (relation
== MP_LT
|| relation
== MP_EQ
) ? ST_TRUE
: ST_FALSE
;
684 ST_STACK_PUSH (cpu
, result
);
688 LargeInteger_ge (struct st_cpu
*cpu
)
690 st_oop b
= pop_large_integer (cpu
);
691 st_oop a
= pop_large_integer (cpu
);
696 ST_STACK_UNPOP (cpu
, 2);
700 relation
= mp_cmp (VALUE (a
), VALUE (b
));
701 result
= (relation
== MP_GT
|| relation
== MP_EQ
) ? ST_TRUE
: ST_FALSE
;
702 ST_STACK_PUSH (cpu
, result
);
706 LargeInteger_squared (struct st_cpu
*cpu
)
708 st_oop receiver
= pop_large_integer (cpu
);
712 ST_STACK_UNPOP (cpu
, 1);
716 UNARY_OP (mp_sqr
, receiver
);
718 result
= st_large_integer_new (&value
);
719 ST_STACK_PUSH (cpu
, result
);
723 LargeInteger_bitOr (struct st_cpu
*cpu
)
725 st_oop b
= pop_large_integer (cpu
);
726 st_oop a
= pop_large_integer (cpu
);
730 ST_STACK_UNPOP (cpu
, 2);
734 BINARY_OP (mp_or
, a
, b
);
736 result
= st_large_integer_new (&value
);
737 ST_STACK_PUSH (cpu
, result
);
741 LargeInteger_bitAnd (struct st_cpu
*cpu
)
743 st_oop b
= pop_large_integer (cpu
);
744 st_oop a
= pop_large_integer (cpu
);
748 ST_STACK_UNPOP (cpu
, 2);
752 BINARY_OP (mp_and
, a
, b
);
754 result
= st_large_integer_new (&value
);
755 ST_STACK_PUSH (cpu
, result
);
759 LargeInteger_bitXor (struct st_cpu
*cpu
)
761 st_oop b
= pop_large_integer (cpu
);
762 st_oop a
= pop_large_integer (cpu
);
766 ST_STACK_UNPOP (cpu
, 2);
770 BINARY_OP (mp_xor
, a
, b
);
772 result
= st_large_integer_new (&value
);
773 ST_STACK_PUSH (cpu
, result
);
777 LargeInteger_bitShift (struct st_cpu
*cpu
)
779 int displacement
= pop_integer32 (cpu
);
780 st_oop receiver
= pop_large_integer (cpu
);
785 ST_STACK_UNPOP (cpu
, 2);
791 if (displacement
>= 0)
792 mp_mul_2d (VALUE (receiver
), displacement
, &value
);
794 mp_div_2d (VALUE (receiver
), abs (displacement
), &value
, NULL
);
796 result
= st_large_integer_new (&value
);
797 ST_STACK_PUSH (cpu
, result
);
800 #define ST_DIGIT_RADIX (1L << DIGIT_BIT)
804 LargeInteger_asFloat (struct st_cpu
*cpu
)
806 st_oop receiver
= pop_large_integer (cpu
);
812 m
= st_large_integer_value (receiver
);
814 ST_STACK_PUSH (cpu
, st_float_new (0));
819 result
= DIGIT (m
, i
);
821 result
= (result
* ST_DIGIT_RADIX
) + DIGIT (m
, i
);
823 if (m
->sign
== MP_NEG
)
826 ST_STACK_PUSH (cpu
, st_float_new (result
));
830 LargeInteger_printStringBase (struct st_cpu
*cpu
)
832 int radix
= pop_integer (cpu
);
833 st_oop x
= pop_large_integer (cpu
);
837 if (radix
< 2 || radix
> 36)
838 set_success (cpu
, false);
841 string
= st_large_integer_to_string (x
, radix
);
842 result
= st_string_new (string
);
846 ST_STACK_PUSH (cpu
, result
);
848 ST_STACK_UNPOP (cpu
, 2);
852 LargeInteger_hash (struct st_cpu
*cpu
)
854 st_oop receiver
= ST_STACK_POP (cpu
);
861 value
= st_large_integer_value (receiver
);
862 c
= (const char *) value
->dp
;
863 len
= value
->used
* sizeof (mp_digit
);
866 for(unsigned int i
= 0; i
< len
; i
++)
868 hash
= ((hash
<< 5) + hash
) + c
[i
];
875 ST_STACK_PUSH (cpu
, st_smi_new (result
));
880 pop_float (struct st_cpu
*cpu
)
882 st_oop object
= ST_STACK_POP (cpu
);
884 set_success (cpu
, st_object_class (object
) == ST_FLOAT_CLASS
);
890 Float_add (struct st_cpu
*cpu
)
892 st_oop y
= pop_float (cpu
);
893 st_oop x
= pop_float (cpu
);
894 st_oop result
= ST_NIL
;
897 result
= st_float_new (st_float_value (x
) + st_float_value (y
));
900 ST_STACK_PUSH (cpu
, result
);
902 ST_STACK_UNPOP (cpu
, 2);
906 Float_sub (struct st_cpu
*cpu
)
908 st_oop y
= pop_float (cpu
);
909 st_oop x
= pop_float (cpu
);
910 st_oop result
= ST_NIL
;
913 result
= st_float_new (st_float_value (x
) - st_float_value (y
));
916 ST_STACK_PUSH (cpu
, result
);
918 ST_STACK_UNPOP (cpu
, 2);
922 Float_lt (struct st_cpu
*cpu
)
924 st_oop y
= pop_float (cpu
);
925 st_oop x
= pop_float (cpu
);
926 st_oop result
= ST_NIL
;
929 result
= isless (st_float_value (x
), st_float_value (y
)) ? ST_TRUE
: ST_FALSE
;
932 ST_STACK_PUSH (cpu
, result
);
934 ST_STACK_UNPOP (cpu
, 2);
938 Float_gt (struct st_cpu
*cpu
)
940 st_oop y
= pop_float (cpu
);
941 st_oop x
= pop_float (cpu
);
942 st_oop result
= ST_NIL
;
945 result
= isgreater (st_float_value (x
), st_float_value (y
)) ? ST_TRUE
: ST_FALSE
;
948 ST_STACK_PUSH (cpu
, result
);
950 ST_STACK_UNPOP (cpu
, 2);
954 Float_le (struct st_cpu
*cpu
)
956 st_oop y
= pop_float (cpu
);
957 st_oop x
= pop_float (cpu
);
958 st_oop result
= ST_NIL
;
961 result
= islessequal (st_float_value (x
), st_float_value (y
)) ? ST_TRUE
: ST_FALSE
;
964 ST_STACK_PUSH (cpu
, result
);
966 ST_STACK_UNPOP (cpu
, 2);
970 Float_ge (struct st_cpu
*cpu
)
972 st_oop y
= pop_float (cpu
);
973 st_oop x
= pop_float (cpu
);
974 st_oop result
= ST_NIL
;
977 result
= isgreaterequal (st_float_value (x
), st_float_value (y
)) ? ST_TRUE
: ST_FALSE
;
980 ST_STACK_PUSH (cpu
, result
);
982 ST_STACK_UNPOP (cpu
, 2);
986 Float_eq (struct st_cpu
*cpu
)
988 st_oop y
= pop_float (cpu
);
989 st_oop x
= pop_float (cpu
);
990 st_oop result
= ST_NIL
;
993 result
= (st_float_value (x
) == st_float_value (y
)) ? ST_TRUE
: ST_FALSE
;
996 ST_STACK_PUSH (cpu
, result
);
998 ST_STACK_UNPOP (cpu
, 2);
1002 Float_ne (struct st_cpu
*cpu
)
1004 st_oop y
= pop_float (cpu
);
1005 st_oop x
= pop_float (cpu
);
1006 st_oop result
= ST_NIL
;
1009 result
= (st_float_value (x
) != st_float_value (y
)) ? ST_TRUE
: ST_FALSE
;
1012 ST_STACK_PUSH (cpu
, result
);
1014 ST_STACK_UNPOP (cpu
, 2);
1018 Float_mul (struct st_cpu
*cpu
)
1020 st_oop y
= pop_float (cpu
);
1021 st_oop x
= pop_float (cpu
);
1022 st_oop result
= ST_NIL
;
1025 result
= st_float_new (st_float_value (x
) * st_float_value (y
));
1028 ST_STACK_PUSH (cpu
, result
);
1030 ST_STACK_UNPOP (cpu
, 2);
1034 Float_div (struct st_cpu
*cpu
)
1036 st_oop y
= pop_float (cpu
);
1037 st_oop x
= pop_float (cpu
);
1038 st_oop result
= ST_NIL
;
1040 set_success (cpu
, y
!= 0);
1043 result
= st_float_new (st_float_value (x
) / st_float_value (y
));
1046 ST_STACK_PUSH (cpu
, result
);
1048 ST_STACK_UNPOP (cpu
, 2);
1052 Float_sin (struct st_cpu
*cpu
)
1054 st_oop receiver
= ST_STACK_POP (cpu
);
1058 value
= st_float_value (receiver
);
1060 result
= st_float_new (sin (value
));
1063 ST_STACK_PUSH (cpu
, result
);
1065 ST_STACK_UNPOP (cpu
, 1);
1069 Float_cos (struct st_cpu
*cpu
)
1071 st_oop receiver
= ST_STACK_POP (cpu
);
1075 value
= st_float_value (receiver
);
1077 result
= st_float_new (cos (value
));
1080 ST_STACK_PUSH (cpu
, result
);
1082 ST_STACK_UNPOP (cpu
, 1);
1086 Float_tan (struct st_cpu
*cpu
)
1088 st_oop receiver
= ST_STACK_POP (cpu
);
1092 value
= st_float_value (receiver
);
1094 result
= st_float_new (tan (value
));
1097 ST_STACK_PUSH (cpu
, result
);
1099 ST_STACK_UNPOP (cpu
, 1);
1103 Float_arcSin (struct st_cpu
*cpu
)
1105 st_oop receiver
= ST_STACK_POP (cpu
);
1109 value
= st_float_value (receiver
);
1111 result
= st_float_new (asin (value
));
1114 ST_STACK_PUSH (cpu
, result
);
1116 ST_STACK_UNPOP (cpu
, 1);
1120 Float_arcCos (struct st_cpu
*cpu
)
1122 st_oop receiver
= ST_STACK_POP (cpu
);
1126 value
= st_float_value (receiver
);
1128 result
= st_float_new (acos (value
));
1131 ST_STACK_PUSH (cpu
, result
);
1133 ST_STACK_UNPOP (cpu
, 1);
1137 Float_arcTan (struct st_cpu
*cpu
)
1139 st_oop receiver
= ST_STACK_POP (cpu
);
1143 value
= st_float_value (receiver
);
1145 result
= st_float_new (atan (value
));
1148 ST_STACK_PUSH (cpu
, result
);
1150 ST_STACK_UNPOP (cpu
, 1);
1154 Float_sqrt (struct st_cpu
*cpu
)
1156 st_oop receiver
= ST_STACK_POP (cpu
);
1160 value
= st_float_value (receiver
);
1162 result
= st_float_new (sqrt (value
));
1165 ST_STACK_PUSH (cpu
, result
);
1167 ST_STACK_UNPOP (cpu
, 1);
1171 Float_log (struct st_cpu
*cpu
)
1173 st_oop receiver
= ST_STACK_POP (cpu
);
1177 value
= st_float_value (receiver
);
1179 result
= st_float_new (log10 (value
));
1182 ST_STACK_PUSH (cpu
, result
);
1184 ST_STACK_UNPOP (cpu
, 1);
1188 Float_ln (struct st_cpu
*cpu
)
1190 st_oop receiver
= ST_STACK_POP (cpu
);
1194 value
= st_float_value (receiver
);
1196 result
= st_float_new (log (value
));
1199 ST_STACK_PUSH (cpu
, result
);
1201 ST_STACK_UNPOP (cpu
, 1);
1205 Float_exp (struct st_cpu
*cpu
)
1207 st_oop receiver
= ST_STACK_POP (cpu
);
1211 value
= st_float_value (receiver
);
1213 result
= st_float_new (exp (value
));
1216 ST_STACK_PUSH (cpu
, result
);
1218 ST_STACK_UNPOP (cpu
, 1);
1222 Float_truncated (struct st_cpu
*cpu
)
1224 st_oop receiver
= ST_STACK_POP (cpu
);
1227 result
= (int) trunc (st_float_value (receiver
));
1229 ST_STACK_PUSH (cpu
, st_smi_new (result
));
1233 Float_fractionPart (struct st_cpu
*cpu
)
1235 st_oop receiver
= ST_STACK_POP (cpu
);
1236 double frac_part
, int_part
;
1239 frac_part
= modf (st_float_value (receiver
), &int_part
);
1241 result
= st_float_new (frac_part
);
1243 ST_STACK_PUSH (cpu
, result
);
1247 Float_integerPart (struct st_cpu
*cpu
)
1249 st_oop receiver
= ST_STACK_POP (cpu
);
1253 modf (st_float_value (receiver
), &int_part
);
1255 result
= st_smi_new ((int) int_part
);
1256 ST_STACK_PUSH (cpu
, result
);
1260 Float_hash (struct st_cpu
*cpu
)
1262 st_oop receiver
= ST_STACK_POP (cpu
);
1263 unsigned int hash
= 0;
1268 value
= st_float_value (receiver
);
1271 value
= fabs (value
);
1273 c
= (unsigned char *) & value
;
1274 for (int i
= 0; i
< sizeof (double); i
++) {
1275 hash
= (hash
* 971) ^ c
[i
];
1283 ST_STACK_PUSH (cpu
, st_smi_new (result
));
1287 Float_printStringBase (struct st_cpu
*cpu
)
1289 int base
= pop_integer(cpu
);
1290 st_oop receiver
= ST_STACK_POP (cpu
);
1294 if (!cpu
->success
||
1295 !st_object_is_heap (receiver
) ||
1296 st_object_format (receiver
) != ST_FORMAT_FLOAT
) {
1297 cpu
->success
= false;
1298 ST_STACK_UNPOP (cpu
, 2);
1302 /* ignore base for the time being */
1303 tmp
= st_strdup_printf ("%g", st_float_value (receiver
));
1304 string
= st_string_new (tmp
);
1307 ST_STACK_PUSH (cpu
, string
);
1311 Object_error (struct st_cpu
*cpu
)
1317 traceback
= ST_STACK_POP (cpu
);
1318 message
= ST_STACK_POP (cpu
);
1319 receiver
= ST_STACK_POP (cpu
);
1321 if (!st_object_is_heap (traceback
) ||
1322 st_object_format (traceback
) != ST_FORMAT_BYTE_ARRAY
) {
1323 /* can't resume execution in this prim */
1327 if (!st_object_is_heap (message
) ||
1328 st_object_format (message
) != ST_FORMAT_BYTE_ARRAY
) {
1329 /* can't resume execution in this prim */
1333 printf ("An error occurred during program execution\n");
1334 printf ("message: %s\n\n", st_byte_array_bytes (message
));
1336 printf ("Traceback:\n");
1337 puts (st_byte_array_bytes (traceback
));
1339 /* set success to false to signal error */
1340 cpu
->success
= false;
1341 longjmp (cpu
->main_loop
, 0);
1345 Object_class (struct st_cpu
*cpu
)
1349 object
= ST_STACK_POP (cpu
);
1351 ST_STACK_PUSH (cpu
, st_object_class (object
));
1355 Object_identityHash (struct st_cpu
*cpu
)
1360 object
= ST_STACK_POP (cpu
);
1362 if (st_object_is_smi (object
))
1363 hash
= st_smi_hash (object
);
1364 else if (st_object_is_character (object
))
1365 hash
= st_character_hash (object
);
1367 st_object_set_hashed (object
, true);
1368 hash
= st_identity_hashtable_hash (memory
->ht
, object
);
1370 ST_STACK_PUSH (cpu
, st_smi_new (hash
));
1374 Object_copy (struct st_cpu
*cpu
)
1381 (void) ST_STACK_POP (cpu
);
1383 if (!st_object_is_heap (cpu
->message_receiver
)) {
1384 ST_STACK_PUSH (cpu
, cpu
->message_receiver
);
1388 switch (st_object_format (cpu
->message_receiver
)) {
1390 case ST_FORMAT_OBJECT
:
1392 class = ST_OBJECT_CLASS (cpu
->message_receiver
);
1393 size
= st_smi_value (ST_BEHAVIOR_INSTANCE_SIZE (class));
1394 copy
= st_object_new (class);
1395 st_oops_copy (ST_OBJECT_FIELDS (copy
),
1396 ST_OBJECT_FIELDS (cpu
->message_receiver
),
1401 case ST_FORMAT_ARRAY
:
1403 size
= st_smi_value (ST_ARRAYED_OBJECT (cpu
->message_receiver
)->size
);
1404 copy
= st_object_new_arrayed (ST_OBJECT_CLASS (cpu
->message_receiver
), size
);
1405 st_oops_copy (ST_ARRAY (copy
)->elements
,
1406 ST_ARRAY (cpu
->message_receiver
)->elements
,
1410 case ST_FORMAT_BYTE_ARRAY
:
1412 size
= st_smi_value (ST_ARRAYED_OBJECT (cpu
->message_receiver
)->size
);
1413 copy
= st_object_new_arrayed (ST_OBJECT_CLASS (cpu
->message_receiver
), size
);
1414 memcpy (st_byte_array_bytes (copy
),
1415 st_byte_array_bytes (cpu
->message_receiver
),
1419 case ST_FORMAT_FLOAT_ARRAY
:
1421 size
= st_smi_value (st_arrayed_object_size (cpu
->message_receiver
));
1422 copy
= st_object_new_arrayed (ST_OBJECT_CLASS (cpu
->message_receiver
), size
);
1423 memcpy (st_float_array_elements (copy
),
1424 st_float_array_elements (cpu
->message_receiver
),
1425 sizeof (double) * size
);
1429 case ST_FORMAT_WORD_ARRAY
:
1431 size
= st_smi_value (st_arrayed_object_size (cpu
->message_receiver
));
1432 copy
= st_object_new_arrayed (ST_OBJECT_CLASS (cpu
->message_receiver
), size
);
1433 memcpy (st_word_array_elements (copy
),
1434 st_word_array_elements (cpu
->message_receiver
),
1435 sizeof (st_uint
) * size
);
1438 case ST_FORMAT_FLOAT
:
1440 copy
= st_object_new (ST_FLOAT_CLASS
);
1441 st_float_set_value (copy
, st_float_value (cpu
->message_receiver
));
1444 case ST_FORMAT_LARGE_INTEGER
:
1449 copy
= st_object_new (ST_LARGE_INTEGER_CLASS
);
1451 result
= mp_init_copy (st_large_integer_value (copy
),
1452 st_large_integer_value (cpu
->message_receiver
));
1453 if (result
!= MP_OKAY
)
1457 case ST_FORMAT_HANDLE
:
1459 copy
= st_object_new (ST_HANDLE_CLASS
);
1460 ST_HANDLE_VALUE (copy
) = ST_HANDLE_VALUE (cpu
->message_receiver
);
1462 case ST_FORMAT_CONTEXT
:
1463 case ST_FORMAT_INTEGER_ARRAY
:
1465 /* not implemented yet */
1469 ST_STACK_PUSH (cpu
, copy
);
1473 Object_equivalent (struct st_cpu
*cpu
)
1475 st_oop y
= ST_STACK_POP (cpu
);
1476 st_oop x
= ST_STACK_POP (cpu
);
1478 ST_STACK_PUSH (cpu
, ((x
== y
) ? ST_TRUE
: ST_FALSE
));
1482 lookup_method (st_oop
class, st_oop selector
)
1485 st_oop parent
= class;
1488 while (parent
!= ST_NIL
) {
1489 method
= st_dictionary_at (ST_BEHAVIOR_METHOD_DICTIONARY (parent
), selector
);
1490 if (method
!= ST_NIL
)
1492 parent
= ST_BEHAVIOR_SUPERCLASS (parent
);
1499 Object_perform (struct st_cpu
*cpu
)
1504 st_uint selector_index
;
1506 selector
= cpu
->message_selector
;
1507 cpu
->message_selector
= cpu
->stack
[cpu
->sp
- cpu
->message_argcount
];
1508 receiver
= cpu
->message_receiver
;
1510 set_success (cpu
, st_object_is_symbol (cpu
->message_selector
));
1511 method
= lookup_method (st_object_class (receiver
), cpu
->message_selector
);
1512 set_success (cpu
, st_method_get_arg_count (method
) == (cpu
->message_argcount
- 1));
1515 selector_index
= cpu
->sp
- cpu
->message_argcount
;
1517 st_oops_move (cpu
->stack
+ selector_index
,
1518 cpu
->stack
+ selector_index
+ 1,
1519 cpu
->message_argcount
- 1);
1522 cpu
->message_argcount
-= 1;
1523 cpu
->new_method
= method
;
1524 st_cpu_execute_method ();
1527 cpu
->message_selector
= selector
;
1532 Object_perform_withArguments (struct st_cpu
*cpu
)
1540 array
= ST_STACK_POP (cpu
);
1542 set_success (cpu
, st_object_format (array
) == ST_FORMAT_ARRAY
);
1544 if (ST_OBJECT_CLASS (cpu
->context
) == ST_BLOCK_CONTEXT_CLASS
)
1545 method
= ST_METHOD_CONTEXT_METHOD (ST_BLOCK_CONTEXT_HOME (cpu
->context
));
1547 method
= ST_METHOD_CONTEXT_METHOD (cpu
->context
);
1549 array_size
= st_smi_value (st_arrayed_object_size (array
));
1550 set_success (cpu
, (cpu
->sp
+ array_size
- 1) < (st_method_get_large_context (method
) ? 32 : 12));
1554 selector
= cpu
->message_selector
;
1555 cpu
->message_selector
= ST_STACK_POP (cpu
);
1556 receiver
= ST_STACK_PEEK (cpu
);
1557 cpu
->message_argcount
= array_size
;
1559 set_success (cpu
, st_object_is_symbol (cpu
->message_selector
));
1561 st_oops_copy (cpu
->stack
+ cpu
->sp
,
1562 st_array_elements (array
),
1565 cpu
->sp
+= array_size
;
1567 method
= lookup_method (st_object_class (receiver
), cpu
->message_selector
);
1568 set_success (cpu
, st_method_get_arg_count (method
) == array_size
);
1571 cpu
->new_method
= method
;
1572 st_cpu_execute_method ();
1574 cpu
->sp
-= cpu
->message_argcount
;
1575 ST_STACK_PUSH (cpu
, cpu
->message_selector
);
1576 ST_STACK_PUSH (cpu
, array
);
1577 cpu
->message_argcount
= 2;
1578 cpu
->message_selector
= selector
;
1582 ST_STACK_UNPOP (cpu
, 1);
1587 Behavior_new (struct st_cpu
*cpu
)
1593 class = ST_STACK_POP (cpu
);
1595 switch (st_smi_value (ST_BEHAVIOR_FORMAT (class))) {
1596 case ST_FORMAT_OBJECT
:
1597 instance
= st_object_allocate (class);
1599 case ST_FORMAT_CONTEXT
:
1600 /* not implemented */
1603 case ST_FORMAT_FLOAT
:
1604 instance
= st_float_allocate (class);
1606 case ST_FORMAT_LARGE_INTEGER
:
1607 instance
= st_large_integer_allocate (class, NULL
);
1609 case ST_FORMAT_HANDLE
:
1610 instance
= st_handle_allocate (class);
1613 /* should not reach */
1617 ST_STACK_PUSH (cpu
, instance
);
1621 Behavior_newSize (struct st_cpu
*cpu
)
1628 size
= pop_integer32 (cpu
);
1629 class = ST_STACK_POP (cpu
);
1631 switch (st_smi_value (ST_BEHAVIOR_FORMAT (class))) {
1632 case ST_FORMAT_ARRAY
:
1633 instance
= st_array_allocate (class, size
);
1635 case ST_FORMAT_BYTE_ARRAY
:
1636 instance
= st_byte_array_allocate (class, size
);
1638 case ST_FORMAT_WORD_ARRAY
:
1639 instance
= st_word_array_allocate (class, size
);
1641 case ST_FORMAT_FLOAT_ARRAY
:
1642 instance
= st_float_array_allocate (class, size
);
1644 case ST_FORMAT_INTEGER_ARRAY
:
1645 /* not implemented */
1649 /* should not reach */
1653 ST_STACK_PUSH (cpu
, instance
);
1657 Behavior_compile (struct st_cpu
*cpu
)
1659 st_compiler_error error
;
1663 string
= ST_STACK_POP (cpu
);
1664 receiver
= ST_STACK_POP (cpu
);
1665 if (!st_object_is_heap (string
) ||
1666 st_object_format (string
) != ST_FORMAT_BYTE_ARRAY
) {
1667 cpu
->success
= false;
1668 ST_STACK_UNPOP (cpu
, 2);
1672 if (!st_compile_string (receiver
,
1673 (char *) st_byte_array_bytes (string
),
1675 cpu
->success
= false;
1676 ST_STACK_UNPOP (cpu
, 2);
1680 ST_STACK_PUSH (cpu
, receiver
);
1684 SequenceableCollection_size (struct st_cpu
*cpu
)
1688 object
= ST_STACK_POP (cpu
);
1690 ST_STACK_PUSH (cpu
, st_arrayed_object_size (object
));
1694 Array_at (struct st_cpu
*cpu
)
1696 int index
= pop_integer32 (cpu
);
1697 st_oop receiver
= ST_STACK_POP (cpu
);
1699 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1700 set_success (cpu
, false);
1701 ST_STACK_UNPOP (cpu
, 2);
1705 ST_STACK_PUSH (cpu
, st_array_at (receiver
, index
));
1709 Array_at_put (struct st_cpu
*cpu
)
1711 st_oop object
= ST_STACK_POP (cpu
);
1712 int index
= pop_integer32 (cpu
);
1713 st_oop receiver
= ST_STACK_POP (cpu
);
1715 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1716 set_success (cpu
, false);
1717 ST_STACK_UNPOP (cpu
, 3);
1721 st_array_at_put (receiver
, index
, object
);
1722 ST_STACK_PUSH (cpu
, object
);
1726 ByteArray_at (struct st_cpu
*cpu
)
1728 int index
= pop_integer32 (cpu
);
1729 st_oop receiver
= ST_STACK_POP (cpu
);
1732 if (!cpu
->success
) {
1733 ST_STACK_UNPOP (cpu
, 2);
1737 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1738 set_success (cpu
, false);
1739 ST_STACK_UNPOP (cpu
, 2);
1743 result
= st_smi_new (st_byte_array_at (receiver
, index
));
1745 ST_STACK_PUSH (cpu
, result
);
1749 ByteArray_at_put (struct st_cpu
*cpu
)
1751 int byte
= pop_integer (cpu
);
1752 int index
= pop_integer32 (cpu
);
1753 st_oop receiver
= ST_STACK_POP (cpu
);
1755 if (!cpu
->success
) {
1756 ST_STACK_UNPOP (cpu
, 3);
1760 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1761 set_success (cpu
, false);
1762 ST_STACK_UNPOP (cpu
, 3);
1766 st_byte_array_at_put (receiver
, index
, byte
);
1768 ST_STACK_PUSH (cpu
, st_smi_new (byte
));
1772 ByteArray_hash (struct st_cpu
*cpu
)
1774 st_oop receiver
= ST_STACK_POP (cpu
);
1777 hash
= st_byte_array_hash (receiver
);
1779 ST_STACK_PUSH (cpu
, st_smi_new (hash
));
1783 ByteString_at (struct st_cpu
*cpu
)
1785 int index
= pop_integer32 (cpu
);
1786 st_oop receiver
= ST_STACK_POP (cpu
);
1790 if (ST_UNLIKELY (!cpu
->success
)) {
1791 ST_STACK_UNPOP (cpu
, 2);
1795 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1796 set_success (cpu
, false);
1797 ST_STACK_UNPOP (cpu
, 2);
1801 character
= st_character_new (st_byte_array_at (receiver
, index
));
1803 ST_STACK_PUSH (cpu
, character
);
1807 ByteString_at_put (struct st_cpu
*cpu
)
1809 st_oop character
= ST_STACK_POP (cpu
);
1810 int index
= pop_integer32 (cpu
);
1811 st_oop receiver
= ST_STACK_POP (cpu
);
1813 if (!cpu
->success
) {
1814 ST_STACK_UNPOP (cpu
, 3);
1818 set_success (cpu
, st_object_class (character
) == ST_CHARACTER_CLASS
);
1820 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1821 set_success (cpu
, false);
1822 ST_STACK_UNPOP (cpu
, 3);
1826 st_byte_array_at_put (receiver
, index
, (st_uchar
) st_character_value (character
));
1828 ST_STACK_PUSH (cpu
, character
);
1833 ByteString_size (struct st_cpu
*cpu
)
1838 receiver
= ST_STACK_POP (cpu
);
1840 size
= st_arrayed_object_size (receiver
);
1842 /* TODO: allow size to go into a LargeInteger on overflow */
1843 ST_STACK_PUSH (cpu
, size
);
1847 ByteString_compare (struct st_cpu
*cpu
)
1849 st_oop argument
= ST_STACK_POP (cpu
);
1850 st_oop receiver
= ST_STACK_POP (cpu
);
1853 if (st_object_format (argument
) != ST_FORMAT_BYTE_ARRAY
)
1854 set_success (cpu
, false);
1857 order
= strcmp ((const char *) st_byte_array_bytes (receiver
),
1858 (const char *) st_byte_array_bytes (argument
));
1861 ST_STACK_PUSH (cpu
, st_smi_new (order
));
1863 ST_STACK_UNPOP (cpu
, 2);
1867 WideString_at (struct st_cpu
*cpu
)
1869 int index
= pop_integer32 (cpu
);
1870 st_oop receiver
= ST_STACK_POP (cpu
);
1874 if (!cpu
->success
) {
1875 ST_STACK_UNPOP (cpu
, 2);
1879 if (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
))) {
1880 set_success (cpu
, false);
1881 ST_STACK_UNPOP (cpu
, 2);
1885 c
= st_word_array_at (receiver
, index
);
1887 ST_STACK_PUSH (cpu
, st_character_new (c
));
1891 WideString_at_put (struct st_cpu
*cpu
)
1893 st_oop character
= ST_STACK_POP (cpu
);
1894 int index
= pop_integer32 (cpu
);
1895 st_oop receiver
= ST_STACK_POP (cpu
);
1899 if (!cpu
->success
) {
1900 ST_STACK_UNPOP (cpu
, 3);
1904 set_success (cpu
, st_object_class (character
) == ST_CHARACTER_CLASS
);
1906 if (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
))) {
1907 set_success (cpu
, false);
1908 ST_STACK_UNPOP (cpu
, 3);
1912 st_word_array_at_put (receiver
, index
, character
);
1914 ST_STACK_PUSH (cpu
, character
);
1918 WordArray_at (struct st_cpu
*cpu
)
1924 index
= pop_integer32 (cpu
);
1925 receiver
= ST_STACK_POP (cpu
);
1927 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1928 set_success (cpu
, false);
1929 ST_STACK_UNPOP (cpu
, 2);
1933 element
= st_word_array_at (receiver
, index
);
1935 ST_STACK_PUSH (cpu
, st_smi_new (element
));
1939 WordArray_at_put (struct st_cpu
*cpu
)
1941 int value
= pop_integer (cpu
);
1942 int index
= pop_integer32 (cpu
);
1943 st_oop receiver
= ST_STACK_POP (cpu
);
1945 if (!cpu
->success
) {
1946 ST_STACK_UNPOP (cpu
, 3);
1950 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1951 set_success (cpu
, false);
1952 ST_STACK_UNPOP (cpu
, 3);
1956 st_word_array_at_put (receiver
, index
, value
);
1958 ST_STACK_PUSH (cpu
, st_smi_new (value
));
1962 FloatArray_at (struct st_cpu
*cpu
)
1968 index
= pop_integer32 (cpu
);
1969 receiver
= ST_STACK_POP (cpu
);
1971 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1972 set_success (cpu
, false);
1973 ST_STACK_UNPOP (cpu
, 2);
1977 element
= st_float_array_at (receiver
, index
);
1978 ST_STACK_PUSH (cpu
, st_float_new (element
));
1982 FloatArray_at_put (struct st_cpu
*cpu
)
1984 st_oop flt
= ST_STACK_POP (cpu
);
1985 int index
= pop_integer32 (cpu
);
1986 st_oop receiver
= ST_STACK_POP (cpu
);
1988 set_success (cpu
, st_object_is_heap (flt
) &&
1989 st_object_format (flt
) == ST_FORMAT_FLOAT
);
1991 if (ST_UNLIKELY (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
)))) {
1992 set_success (cpu
, false);
1993 ST_STACK_UNPOP (cpu
, 3);
1997 if (!cpu
->success
) {
1998 ST_STACK_UNPOP (cpu
, 3);
2002 st_float_array_at_put (receiver
, index
, st_float_value (flt
));
2003 ST_STACK_PUSH (cpu
, flt
);
2007 BlockContext_value (struct st_cpu
*cpu
)
2013 block
= cpu
->message_receiver
;
2014 argcount
= st_smi_value (ST_BLOCK_CONTEXT_ARGCOUNT (block
));
2015 if (ST_UNLIKELY (argcount
!= cpu
->message_argcount
)) {
2016 cpu
->success
= false;
2020 st_oops_copy (ST_BLOCK_CONTEXT_STACK (block
),
2021 cpu
->stack
+ cpu
->sp
- argcount
,
2023 cpu
->sp
-= cpu
->message_argcount
+ 1;
2025 ST_CONTEXT_PART_IP (block
) = ST_BLOCK_CONTEXT_INITIALIP (block
);
2026 ST_CONTEXT_PART_SP (block
) = st_smi_new (argcount
);
2027 ST_BLOCK_CONTEXT_CALLER (block
) = cpu
->context
;
2029 st_cpu_set_active_context (block
);
2033 BlockContext_valueWithArguments (struct st_cpu
*cpu
)
2039 block
= cpu
->message_receiver
;
2040 values
= ST_STACK_PEEK (cpu
);
2042 if (st_object_class (values
) != ST_ARRAY_CLASS
) {
2043 set_success (cpu
, false);
2047 argcount
= st_smi_value (ST_BLOCK_CONTEXT_ARGCOUNT (block
));
2048 if (argcount
!= st_smi_value (st_arrayed_object_size (values
))) {
2049 set_success (cpu
, false);
2053 st_oops_copy (ST_BLOCK_CONTEXT_STACK (block
),
2054 ST_ARRAY (values
)->elements
,
2057 cpu
->sp
-= cpu
->message_argcount
+ 1;
2059 ST_CONTEXT_PART_IP (block
) = ST_BLOCK_CONTEXT_INITIALIP (block
);
2060 ST_CONTEXT_PART_SP (block
) = st_smi_new (argcount
);
2061 ST_BLOCK_CONTEXT_CALLER (block
) = cpu
->context
;
2063 st_cpu_set_active_context (block
);
2067 System_exitWithResult (struct st_cpu
*cpu
)
2069 /* set success to true to signal that everything was alright */
2070 cpu
->success
= true;
2071 longjmp (cpu
->main_loop
, 0);
2075 Character_value (struct st_cpu
*cpu
)
2077 st_oop receiver
= ST_STACK_POP (cpu
);
2079 ST_STACK_PUSH (cpu
, st_smi_new (st_character_value (receiver
)));
2083 Character_characterFor (struct st_cpu
*cpu
)
2088 value
= pop_integer (cpu
);
2089 receiver
= ST_STACK_POP (cpu
);
2092 ST_STACK_PUSH (cpu
, st_character_new (value
));
2094 ST_STACK_UNPOP (cpu
, 2);
2098 FileStream_open (struct st_cpu
*cpu
)
2106 mode
= pop_integer32 (cpu
);
2107 filename
= ST_STACK_POP (cpu
);
2108 if (st_object_format (filename
) != ST_FORMAT_BYTE_ARRAY
) {
2109 cpu
->success
= false;
2110 ST_STACK_UNPOP (cpu
, 2);
2119 cpu
->success
= false;
2120 ST_STACK_UNPOP (cpu
, 2);
2124 str
= st_byte_array_bytes (filename
);
2126 fd
= open (str
, O_WRONLY
| O_CREAT
, 0644);
2128 fprintf (stderr
, strerror (errno
));
2129 cpu
->success
= false;
2130 ST_STACK_UNPOP (cpu
, 2);
2137 (void) ST_STACK_POP (cpu
);
2139 handle
= st_object_new (ST_HANDLE_CLASS
);
2140 ST_HANDLE_VALUE (handle
) = fd
;
2142 ST_STACK_PUSH (cpu
, handle
);
2146 FileStream_close (struct st_cpu
*cpu
)
2151 handle
= ST_STACK_POP (cpu
);
2152 fd
= ST_HANDLE_VALUE (handle
);
2154 if (close (fd
) < 0) {
2155 cpu
->success
= false;
2156 ST_STACK_UNPOP (cpu
, 1);
2160 /* leave receiver on stack */
2165 FileStream_write (struct st_cpu
*cpu
)
2174 array
= ST_STACK_POP (cpu
);
2175 handle
= ST_STACK_POP (cpu
);
2176 if (st_object_format (array
) != ST_FORMAT_BYTE_ARRAY
) {
2177 cpu
->success
= false;
2178 ST_STACK_UNPOP (cpu
, 1);
2181 if (st_object_format (handle
) != ST_FORMAT_HANDLE
) {
2182 cpu
->success
= false;
2183 ST_STACK_UNPOP (cpu
, 2);
2187 fd
= ST_HANDLE_VALUE (handle
);
2188 buffer
= st_byte_array_bytes (array
);
2189 size
= st_smi_value (st_arrayed_object_size (array
));
2192 while (total
< size
) {
2193 count
= write (fd
, buffer
+ total
, size
- total
);
2195 cpu
->success
= false;
2196 ST_STACK_UNPOP (cpu
, 2);
2202 /* leave receiver on stack */
2206 FileStream_seek (struct st_cpu
*cpu
)
2208 /* not implemented yet */
2213 FileStream_read (struct st_cpu
*cpu
)
2215 /* not implemented yet */
2219 const struct st_primitive st_primitives
[] = {
2220 { "SmallInteger_add", SmallInteger_add
},
2221 { "SmallInteger_sub", SmallInteger_sub
},
2222 { "SmallInteger_lt", SmallInteger_lt
},
2223 { "SmallInteger_gt", SmallInteger_gt
},
2224 { "SmallInteger_le", SmallInteger_le
},
2225 { "SmallInteger_ge", SmallInteger_ge
},
2226 { "SmallInteger_eq", SmallInteger_eq
},
2227 { "SmallInteger_ne", SmallInteger_ne
},
2228 { "SmallInteger_mul", SmallInteger_mul
},
2229 { "SmallInteger_div", SmallInteger_div
},
2230 { "SmallInteger_intDiv", SmallInteger_intDiv
},
2231 { "SmallInteger_mod", SmallInteger_mod
},
2232 { "SmallInteger_bitOr", SmallInteger_bitOr
},
2233 { "SmallInteger_bitXor", SmallInteger_bitXor
},
2234 { "SmallInteger_bitAnd", SmallInteger_bitAnd
},
2235 { "SmallInteger_bitShift", SmallInteger_bitShift
},
2236 { "SmallInteger_asFloat", SmallInteger_asFloat
},
2237 { "SmallInteger_asLargeInteger", SmallInteger_asLargeInteger
},
2239 { "LargeInteger_add", LargeInteger_add
},
2240 { "LargeInteger_sub", LargeInteger_sub
},
2241 { "LargeInteger_lt", LargeInteger_lt
},
2242 { "LargeInteger_gt", LargeInteger_gt
},
2243 { "LargeInteger_le", LargeInteger_le
},
2244 { "LargeInteger_ge", LargeInteger_ge
},
2245 { "LargeInteger_eq", LargeInteger_eq
},
2246 { "LargeInteger_ne", LargeInteger_ne
},
2247 { "LargeInteger_mul", LargeInteger_mul
},
2248 { "LargeInteger_div", LargeInteger_div
},
2249 { "LargeInteger_intDiv", LargeInteger_intDiv
},
2250 { "LargeInteger_mod", LargeInteger_mod
},
2251 { "LargeInteger_gcd", LargeInteger_gcd
},
2252 { "LargeInteger_lcm", LargeInteger_lcm
},
2253 { "LargeInteger_squared", LargeInteger_squared
},
2254 { "LargeInteger_bitOr", LargeInteger_bitOr
},
2255 { "LargeInteger_bitXor", LargeInteger_bitXor
},
2256 { "LargeInteger_bitAnd", LargeInteger_bitAnd
},
2257 { "LargeInteger_bitShift", LargeInteger_bitShift
},
2258 { "LargeInteger_printStringBase", LargeInteger_printStringBase
},
2259 { "LargeInteger_asFloat", LargeInteger_asFloat
},
2260 { "LargeInteger_hash", LargeInteger_hash
},
2262 { "Float_add", Float_add
},
2263 { "Float_sub", Float_sub
},
2264 { "Float_lt", Float_lt
},
2265 { "Float_gt", Float_gt
},
2266 { "Float_le", Float_le
},
2267 { "Float_ge", Float_ge
},
2268 { "Float_eq", Float_eq
},
2269 { "Float_ne", Float_ne
},
2270 { "Float_mul", Float_mul
},
2271 { "Float_div", Float_div
},
2272 { "Float_exp", Float_exp
},
2273 { "Float_sin", Float_sin
},
2274 { "Float_cos", Float_cos
},
2275 { "Float_tan", Float_tan
},
2276 { "Float_arcSin", Float_arcSin
},
2277 { "Float_arcCos", Float_arcCos
},
2278 { "Float_arcTan", Float_arcTan
},
2279 { "Float_ln", Float_ln
},
2280 { "Float_log", Float_log
},
2281 { "Float_sqrt", Float_sqrt
},
2282 { "Float_truncated", Float_truncated
},
2283 { "Float_fractionPart", Float_fractionPart
},
2284 { "Float_integerPart", Float_integerPart
},
2285 { "Float_hash", Float_hash
},
2286 { "Float_printStringBase", Float_printStringBase
},
2288 { "Object_error", Object_error
},
2289 { "Object_class", Object_class
},
2290 { "Object_identityHash", Object_identityHash
},
2291 { "Object_copy", Object_copy
},
2292 { "Object_equivalent", Object_equivalent
},
2293 { "Object_perform", Object_perform
},
2294 { "Object_perform_withArguments", Object_perform_withArguments
},
2296 { "Behavior_new", Behavior_new
},
2297 { "Behavior_newSize", Behavior_newSize
},
2298 { "Behavior_compile", Behavior_compile
},
2301 { "SequenceableCollection_size", SequenceableCollection_size
},
2303 { "Array_at", Array_at
},
2304 { "Array_at_put", Array_at_put
},
2306 { "ByteArray_at", ByteArray_at
},
2307 { "ByteArray_at_put", ByteArray_at_put
},
2308 { "ByteArray_hash", ByteArray_hash
},
2310 { "ByteString_at", ByteString_at
},
2311 { "ByteString_at_put", ByteString_at_put
},
2312 { "ByteString_size", ByteString_size
},
2313 { "ByteString_compare", ByteString_compare
},
2315 { "WideString_at", WideString_at
},
2316 { "WideString_at_put", WideString_at_put
},
2318 { "WordArray_at", WordArray_at
},
2319 { "WordArray_at_put", WordArray_at_put
},
2321 { "FloatArray_at", FloatArray_at
},
2322 { "FloatArray_at_put", FloatArray_at_put
},
2324 { "System_exitWithResult", System_exitWithResult
},
2326 { "Character_value", Character_value
},
2327 { "Character_characterFor", Character_characterFor
},
2329 { "BlockContext_value", BlockContext_value
},
2330 { "BlockContext_valueWithArguments", BlockContext_valueWithArguments
},
2332 { "FileStream_open", FileStream_open
},
2333 { "FileStream_close", FileStream_close
},
2334 { "FileStream_read", FileStream_read
},
2335 { "FileStream_write", FileStream_write
},
2336 { "FileStream_seek", FileStream_seek
},
2340 /* returns 0 if there no primitive function corresponding
2341 * to the given name */
2343 st_primitive_index_for_name (const char *name
)
2345 st_assert (name
!= NULL
);
2346 for (int i
= 0; i
< ST_N_ELEMENTS (st_primitives
); i
++)
2347 if (streq (name
, st_primitives
[i
].name
))