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"
26 #include "st-processor.h"
28 #include "st-word-array.h"
29 #include "st-byte-array.h"
30 #include "st-large-integer.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"
46 #define ST_PRIMITIVE_FAIL(pr) \
51 set_success (st_processor
*pr
, bool success
)
53 pr
->success
= pr
->success
&& success
;
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
);
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
);
83 SmallInteger_add (st_processor
*pr
)
85 st_smi y
= pop_integer (pr
);
86 st_smi x
= pop_integer (pr
);
89 if (ST_LIKELY (pr
->success
)) {
90 result
= st_smi_new (x
+ y
);
91 ST_STACK_PUSH (pr
, result
);
95 ST_STACK_UNPOP (pr
, 2);
99 SmallInteger_sub (st_processor
*pr
)
101 st_smi y
= pop_integer (pr
);
102 st_smi x
= pop_integer (pr
);
105 if (ST_LIKELY (pr
->success
)) {
106 result
= st_smi_new (x
- y
);
107 ST_STACK_PUSH (pr
, result
);
111 ST_STACK_UNPOP (pr
, 2);
115 SmallInteger_lt (st_processor
*pr
)
117 st_smi y
= pop_integer (pr
);
118 st_smi x
= pop_integer (pr
);
121 if (ST_LIKELY (pr
->success
)) {
122 result
= (x
< y
) ? st_true
: st_false
;
123 ST_STACK_PUSH (pr
, result
);
127 ST_STACK_UNPOP (pr
, 2);
131 SmallInteger_gt (st_processor
*pr
)
133 st_smi y
= pop_integer (pr
);
134 st_smi x
= pop_integer (pr
);
137 if (ST_LIKELY (pr
->success
)) {
138 result
= (x
> y
) ? st_true
: st_false
;
139 ST_STACK_PUSH (pr
, result
);
143 ST_STACK_UNPOP (pr
, 2);
147 SmallInteger_le (st_processor
*pr
)
149 st_smi y
= pop_integer (pr
);
150 st_smi x
= pop_integer (pr
);
153 if (ST_LIKELY (pr
->success
)) {
154 result
= (x
<= y
) ? st_true
: st_false
;
155 ST_STACK_PUSH (pr
, result
);
159 ST_STACK_UNPOP (pr
, 2);
163 SmallInteger_ge (st_processor
*pr
)
165 st_smi y
= pop_integer (pr
);
166 st_smi x
= pop_integer (pr
);
169 if (ST_LIKELY (pr
->success
)) {
170 result
= (x
>= y
) ? st_true
: st_false
;
171 ST_STACK_PUSH (pr
, result
);
175 ST_STACK_UNPOP (pr
, 2);
179 SmallInteger_eq (st_processor
*pr
)
181 st_smi y
= pop_integer (pr
);
182 st_smi x
= pop_integer (pr
);
185 if (ST_LIKELY (pr
->success
)) {
186 result
= (x
== y
) ? st_true
: st_false
;
187 ST_STACK_PUSH (pr
, result
);
191 ST_STACK_UNPOP (pr
, 2);
195 SmallInteger_ne (st_processor
*pr
)
197 st_smi y
= pop_integer (pr
);
198 st_smi x
= pop_integer (pr
);
201 if (ST_LIKELY (pr
->success
)) {
202 result
= (x
!= y
) ? st_true
: st_false
;
203 ST_STACK_PUSH (pr
, result
);
207 ST_STACK_UNPOP (pr
, 2);
211 SmallInteger_mul (st_processor
*pr
)
213 st_smi y
= pop_integer (pr
);
214 st_smi x
= pop_integer (pr
);
217 if (ST_LIKELY (pr
->success
)) {
218 result
= st_smi_new (x
* y
);
219 ST_STACK_PUSH (pr
, result
);
223 ST_STACK_UNPOP (pr
, 2);
228 SmallInteger_div (st_processor
*pr
)
230 st_smi y
= pop_integer (pr
);
231 st_smi x
= pop_integer (pr
);
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
);
241 ST_PRIMITIVE_FAIL (pr
);
245 ST_STACK_UNPOP (pr
, 2);
249 SmallInteger_intDiv (st_processor
*pr
)
251 st_smi y
= pop_integer (pr
);
252 st_smi x
= pop_integer (pr
);
255 if (ST_LIKELY (pr
->success
)) {
258 result
= st_smi_new (x
/ y
);
259 ST_STACK_PUSH (pr
, result
);
262 ST_PRIMITIVE_FAIL (pr
);
266 ST_STACK_UNPOP (pr
, 2);
270 SmallInteger_mod (st_processor
*pr
)
272 st_smi y
= pop_integer (pr
);
273 st_smi x
= pop_integer (pr
);
276 if (ST_LIKELY (pr
->success
)) {
277 result
= st_smi_new (x
% y
);
278 ST_STACK_PUSH (pr
, result
);
282 ST_STACK_UNPOP (pr
, 2);
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
);
298 ST_STACK_UNPOP (pr
, 2);
302 SmallInteger_bitXor (st_processor
*pr
)
304 st_smi y
= pop_integer (pr
);
305 st_smi x
= pop_integer (pr
);
308 if (ST_LIKELY (pr
->success
)) {
309 result
= st_smi_new (x
^ y
);
310 ST_STACK_PUSH (pr
, result
);
314 ST_STACK_UNPOP (pr
, 2);
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
);
330 ST_STACK_UNPOP (pr
, 2);
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
)) {
342 result
= st_smi_new (x
<< y
);
344 result
= st_smi_new (x
>> (-y
));
346 result
= st_smi_new (x
);
348 ST_STACK_PUSH (pr
, result
);
352 ST_STACK_UNPOP (pr
, 2);
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
);
367 ST_STACK_UNPOP (pr
, 1);
371 SmallInteger_asLargeInteger (st_processor
*pr
)
373 st_smi receiver
= pop_integer (pr
);
377 mp_init_set (&value
, abs (receiver
));
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 \
395 #define BINARY_OP(op, a, b) \
397 result = op (VALUE (a), VALUE (b), &value);
399 #define BINARY_DIV_OP(op, a, b) \
401 result = op (VALUE (a), VALUE (b), &value, NULL);
403 #define UNARY_OP(op, a) \
405 result = op (VALUE (a), &value);
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
);
419 LargeInteger_add (st_processor
*pr
)
421 st_oop b
= pop_large_integer (pr
);
422 st_oop a
= pop_large_integer (pr
);
426 ST_STACK_UNPOP (pr
, 2);
430 BINARY_OP (mp_add
, a
, b
);
432 result
= st_large_integer_new (&value
);
433 ST_STACK_PUSH (pr
, result
);
437 LargeInteger_sub (st_processor
*pr
)
439 st_oop b
= pop_large_integer (pr
);
440 st_oop a
= pop_large_integer (pr
);
444 ST_STACK_UNPOP (pr
, 2);
448 BINARY_OP (mp_sub
, a
, b
);
450 result
= st_large_integer_new (&value
);
451 ST_STACK_PUSH (pr
, result
);
455 LargeInteger_mul (st_processor
*pr
)
457 st_oop b
= pop_large_integer (pr
);
458 st_oop a
= pop_large_integer (pr
);
462 ST_STACK_UNPOP (pr
, 2);
466 BINARY_OP (mp_mul
, a
, b
);
468 result
= st_large_integer_new (&value
);
469 ST_STACK_PUSH (pr
, result
);
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
;
481 ST_STACK_UNPOP (pr
, 2);
485 mp_init_multi ("ient
, &remainder
, NULL
);
486 mp_div (VALUE (a
), VALUE (b
), "ient
, &remainder
);
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 ("ient
);
497 ST_STACK_PUSH (pr
, result
);
498 mp_clear (&remainder
);
500 set_success (pr
, false);
501 ST_STACK_UNPOP (pr
, 2);
502 mp_clear_multi ("ient
, &remainder
, NULL
);
507 LargeInteger_intDiv (st_processor
*pr
)
509 st_oop b
= pop_large_integer (pr
);
510 st_oop a
= pop_large_integer (pr
);
514 ST_STACK_UNPOP (pr
, 2);
518 BINARY_DIV_OP (mp_div
, a
, b
);
520 result
= st_large_integer_new (&value
);
521 ST_STACK_PUSH (pr
, result
);
525 LargeInteger_mod (st_processor
*pr
)
527 st_oop b
= pop_large_integer (pr
);
528 st_oop a
= pop_large_integer (pr
);
532 ST_STACK_UNPOP (pr
, 2);
536 BINARY_OP (mp_mod
, a
, b
);
538 result
= st_large_integer_new (&value
);
539 ST_STACK_PUSH (pr
, result
);
543 LargeInteger_gcd (st_processor
*pr
)
545 st_oop b
= pop_large_integer (pr
);
546 st_oop a
= pop_large_integer (pr
);
550 ST_STACK_UNPOP (pr
, 2);
554 BINARY_OP (mp_gcd
, a
, b
);
556 result
= st_large_integer_new (&value
);
557 ST_STACK_PUSH (pr
, result
);
561 LargeInteger_lcm (st_processor
*pr
)
563 st_oop b
= pop_large_integer (pr
);
564 st_oop a
= pop_large_integer (pr
);
568 ST_STACK_UNPOP (pr
, 2);
572 BINARY_OP (mp_lcm
, a
, b
);
574 result
= st_large_integer_new (&value
);
575 ST_STACK_PUSH (pr
, result
);
579 LargeInteger_eq (st_processor
*pr
)
581 st_oop b
= pop_large_integer (pr
);
582 st_oop a
= pop_large_integer (pr
);
587 ST_STACK_UNPOP (pr
, 2);
591 relation
= mp_cmp (VALUE (a
), VALUE (b
));
592 result
= (relation
== MP_EQ
) ? st_true
: st_false
;
593 ST_STACK_PUSH (pr
, result
);
597 LargeInteger_ne (st_processor
*pr
)
599 st_oop b
= pop_large_integer (pr
);
600 st_oop a
= pop_large_integer (pr
);
605 ST_STACK_UNPOP (pr
, 2);
609 relation
= mp_cmp (VALUE (a
), VALUE (b
));
610 result
= (relation
== MP_EQ
) ? st_false
: st_true
;
611 ST_STACK_PUSH (pr
, result
);
615 LargeInteger_lt (st_processor
*pr
)
617 st_oop b
= pop_large_integer (pr
);
618 st_oop a
= pop_large_integer (pr
);
623 ST_STACK_UNPOP (pr
, 2);
627 relation
= mp_cmp (VALUE (a
), VALUE (b
));
628 result
= (relation
== MP_LT
) ? st_true
: st_false
;
629 ST_STACK_PUSH (pr
, result
);
633 LargeInteger_gt (st_processor
*pr
)
635 st_oop b
= pop_large_integer (pr
);
636 st_oop a
= pop_large_integer (pr
);
642 ST_STACK_UNPOP (pr
, 2);
646 relation
= mp_cmp (VALUE (a
), VALUE (b
));
647 result
= (relation
== MP_GT
) ? st_true
: st_false
;
648 ST_STACK_PUSH (pr
, result
);
652 LargeInteger_le (st_processor
*pr
)
654 st_oop b
= pop_large_integer (pr
);
655 st_oop a
= pop_large_integer (pr
);
660 ST_STACK_UNPOP (pr
, 2);
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
);
670 LargeInteger_ge (st_processor
*pr
)
672 st_oop b
= pop_large_integer (pr
);
673 st_oop a
= pop_large_integer (pr
);
678 ST_STACK_UNPOP (pr
, 2);
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
);
688 LargeInteger_squared (st_processor
*pr
)
690 st_oop receiver
= pop_large_integer (pr
);
694 ST_STACK_UNPOP (pr
, 1);
698 UNARY_OP (mp_sqr
, receiver
);
700 result
= st_large_integer_new (&value
);
701 ST_STACK_PUSH (pr
, result
);
705 LargeInteger_bitOr (st_processor
*pr
)
707 st_oop b
= pop_large_integer (pr
);
708 st_oop a
= pop_large_integer (pr
);
712 ST_STACK_UNPOP (pr
, 2);
716 BINARY_OP (mp_or
, a
, b
);
718 result
= st_large_integer_new (&value
);
719 ST_STACK_PUSH (pr
, result
);
723 LargeInteger_bitAnd (st_processor
*pr
)
725 st_oop b
= pop_large_integer (pr
);
726 st_oop a
= pop_large_integer (pr
);
730 ST_STACK_UNPOP (pr
, 2);
734 BINARY_OP (mp_and
, a
, b
);
736 result
= st_large_integer_new (&value
);
737 ST_STACK_PUSH (pr
, result
);
741 LargeInteger_bitXor (st_processor
*pr
)
743 st_oop b
= pop_large_integer (pr
);
744 st_oop a
= pop_large_integer (pr
);
748 ST_STACK_UNPOP (pr
, 2);
752 BINARY_OP (mp_xor
, a
, b
);
754 result
= st_large_integer_new (&value
);
755 ST_STACK_PUSH (pr
, result
);
759 LargeInteger_bitShift (st_processor
*pr
)
761 st_smi displacement
= pop_integer32 (pr
);
762 st_oop receiver
= pop_large_integer (pr
);
767 ST_STACK_UNPOP (pr
, 2);
773 if (displacement
>= 0)
774 mp_mul_2d (VALUE (receiver
), displacement
, &value
);
776 mp_div_2d (VALUE (receiver
), abs (displacement
), &value
, NULL
);
778 result
= st_large_integer_new (&value
);
779 ST_STACK_PUSH (pr
, result
);
783 LargeInteger_asFloat (st_processor
*pr
)
785 st_oop receiver
= pop_large_integer (pr
);
789 string
= st_large_integer_to_string (receiver
, 10);
791 dblval
= strtod (string
, NULL
);
794 ST_STACK_PUSH (pr
, st_float_new (dblval
));
798 LargeInteger_printString (st_processor
*pr
)
800 st_smi radix
= pop_integer (pr
);
801 st_oop x
= pop_large_integer (pr
);
805 if (radix
< 2 || radix
> 36)
806 set_success (pr
, false);
809 string
= st_large_integer_to_string (x
, radix
);
810 result
= st_string_new (memory
->moving_space
, string
);
814 ST_STACK_PUSH (pr
, result
);
816 ST_STACK_UNPOP (pr
, 2);
820 LargeInteger_hash (st_processor
*pr
)
822 st_oop receiver
= ST_STACK_POP (pr
);
829 value
= st_large_integer_value (receiver
);
830 c
= (const char *) value
->dp
;
831 len
= value
->used
* sizeof (mp_digit
);
834 for(unsigned int i
= 0; i
< len
; i
++)
836 hash
= ((hash
<< 5) + hash
) + c
[i
];
843 ST_STACK_PUSH (pr
, st_smi_new (result
));
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
);
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
;
865 result
= st_float_new (st_float_value (x
) + st_float_value (y
));
868 ST_STACK_PUSH (pr
, result
);
870 ST_STACK_UNPOP (pr
, 2);
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
;
881 result
= st_float_new (st_float_value (x
) - st_float_value (y
));
884 ST_STACK_PUSH (pr
, result
);
886 ST_STACK_UNPOP (pr
, 2);
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
;
897 result
= isless (st_float_value (x
), st_float_value (y
)) ? st_true
: st_false
;
900 ST_STACK_PUSH (pr
, result
);
902 ST_STACK_UNPOP (pr
, 2);
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
;
913 result
= isgreater (st_float_value (x
), st_float_value (y
)) ? st_true
: st_false
;
916 ST_STACK_PUSH (pr
, result
);
918 ST_STACK_UNPOP (pr
, 2);
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
;
929 result
= islessequal (st_float_value (x
), st_float_value (y
)) ? st_true
: st_false
;
932 ST_STACK_PUSH (pr
, result
);
934 ST_STACK_UNPOP (pr
, 2);
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
;
945 result
= isgreaterequal (st_float_value (x
), st_float_value (y
)) ? st_true
: st_false
;
948 ST_STACK_PUSH (pr
, result
);
950 ST_STACK_UNPOP (pr
, 2);
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
;
961 result
= (st_float_value (x
) == st_float_value (y
)) ? st_true
: st_false
;
964 ST_STACK_PUSH (pr
, result
);
966 ST_STACK_UNPOP (pr
, 2);
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
;
977 result
= (st_float_value (x
) != st_float_value (y
)) ? st_true
: st_false
;
980 ST_STACK_PUSH (pr
, result
);
982 ST_STACK_UNPOP (pr
, 2);
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
;
993 result
= st_float_new (st_float_value (x
) * st_float_value (y
));
996 ST_STACK_PUSH (pr
, result
);
998 ST_STACK_UNPOP (pr
, 2);
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);
1011 result
= st_float_new (st_float_value (x
) / st_float_value (y
));
1014 ST_STACK_PUSH (pr
, result
);
1016 ST_STACK_UNPOP (pr
, 2);
1020 Float_sin (st_processor
*pr
)
1022 st_oop receiver
= ST_STACK_POP (pr
);
1026 value
= st_float_value (receiver
);
1028 result
= st_float_new (sin (value
));
1031 ST_STACK_PUSH (pr
, result
);
1033 ST_STACK_UNPOP (pr
, 1);
1037 Float_cos (st_processor
*pr
)
1039 st_oop receiver
= ST_STACK_POP (pr
);
1043 value
= st_float_value (receiver
);
1045 result
= st_float_new (cos (value
));
1048 ST_STACK_PUSH (pr
, result
);
1050 ST_STACK_UNPOP (pr
, 1);
1054 Float_tan (st_processor
*pr
)
1056 st_oop receiver
= ST_STACK_POP (pr
);
1060 value
= st_float_value (receiver
);
1062 result
= st_float_new (tan (value
));
1065 ST_STACK_PUSH (pr
, result
);
1067 ST_STACK_UNPOP (pr
, 1);
1071 Float_arcSin (st_processor
*pr
)
1073 st_oop receiver
= ST_STACK_POP (pr
);
1077 value
= st_float_value (receiver
);
1079 result
= st_float_new (asin (value
));
1082 ST_STACK_PUSH (pr
, result
);
1084 ST_STACK_UNPOP (pr
, 1);
1088 Float_arcCos (st_processor
*pr
)
1090 st_oop receiver
= ST_STACK_POP (pr
);
1094 value
= st_float_value (receiver
);
1096 result
= st_float_new (acos (value
));
1099 ST_STACK_PUSH (pr
, result
);
1101 ST_STACK_UNPOP (pr
, 1);
1105 Float_arcTan (st_processor
*pr
)
1107 st_oop receiver
= ST_STACK_POP (pr
);
1111 value
= st_float_value (receiver
);
1113 result
= st_float_new (atan (value
));
1116 ST_STACK_PUSH (pr
, result
);
1118 ST_STACK_UNPOP (pr
, 1);
1122 Float_sqrt (st_processor
*pr
)
1124 st_oop receiver
= ST_STACK_POP (pr
);
1128 value
= st_float_value (receiver
);
1130 result
= st_float_new (sqrt (value
));
1133 ST_STACK_PUSH (pr
, result
);
1135 ST_STACK_UNPOP (pr
, 1);
1139 Float_log (st_processor
*pr
)
1141 st_oop receiver
= ST_STACK_POP (pr
);
1145 value
= st_float_value (receiver
);
1147 result
= st_float_new (log10 (value
));
1150 ST_STACK_PUSH (pr
, result
);
1152 ST_STACK_UNPOP (pr
, 1);
1156 Float_ln (st_processor
*pr
)
1158 st_oop receiver
= ST_STACK_POP (pr
);
1162 value
= st_float_value (receiver
);
1164 result
= st_float_new (log (value
));
1167 ST_STACK_PUSH (pr
, result
);
1169 ST_STACK_UNPOP (pr
, 1);
1173 Float_exp (st_processor
*pr
)
1175 st_oop receiver
= ST_STACK_POP (pr
);
1179 value
= st_float_value (receiver
);
1181 result
= st_float_new (exp (value
));
1184 ST_STACK_PUSH (pr
, result
);
1186 ST_STACK_UNPOP (pr
, 1);
1190 Float_truncated (st_processor
*pr
)
1192 st_oop receiver
= ST_STACK_POP (pr
);
1195 result
= (st_smi
) trunc (st_float_value (receiver
));
1197 ST_STACK_PUSH (pr
, st_smi_new (result
));
1201 Float_fractionPart (st_processor
*pr
)
1203 st_oop receiver
= ST_STACK_POP (pr
);
1204 double frac_part
, int_part
;
1207 frac_part
= modf (st_float_value (receiver
), &int_part
);
1209 result
= st_float_new (frac_part
);
1211 ST_STACK_PUSH (pr
, result
);
1215 Float_integerPart (st_processor
*pr
)
1217 st_oop receiver
= ST_STACK_POP (pr
);
1221 modf (st_float_value (receiver
), &int_part
);
1223 result
= st_smi_new ((st_smi
) int_part
);
1224 ST_STACK_PUSH (pr
, result
);
1228 Float_hash (st_processor
*pr
)
1230 st_oop receiver
= ST_STACK_POP (pr
);
1231 unsigned int hash
= 0;
1236 value
= st_float_value (receiver
);
1239 value
= fabs (value
);
1241 c
= (unsigned char *) & value
;
1242 for (int i
= 0; i
< sizeof (double); i
++) {
1243 hash
= (hash
* 971) ^ c
[i
];
1251 ST_STACK_PUSH (pr
, st_smi_new (result
));
1255 print_backtrace (st_processor
*pr
)
1259 context
= pr
->context
;
1261 while (context
!= st_nil
) {
1268 if (st_object_class (context
) == st_block_context_class
)
1269 home
= ST_BLOCK_CONTEXT (context
)->home
;
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
));
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
)
1288 if (st_object_class (context
) == st_block_context_class
)
1289 context
= ST_BLOCK_CONTEXT (context
)->caller
;
1291 context
= ST_CONTEXT_PART (context
)->sender
;
1296 Object_error (st_processor
*pr
)
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
);
1312 Object_class (st_processor
*pr
)
1316 object
= ST_STACK_POP (pr
);
1318 ST_STACK_PUSH (pr
, st_object_class (object
));
1322 Object_identityHash (st_processor
*pr
)
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
));
1334 result
= st_smi_new (st_character_hash (object
));
1336 ST_STACK_PUSH (pr
, result
);
1340 Object_copy (st_processor
*pr
)
1345 receiver
= ST_STACK_POP (pr
);
1347 if (st_object_is_heap (receiver
))
1348 copy
= st_descriptor_for_object (receiver
)->copy (receiver
);
1352 ST_STACK_PUSH (pr
, copy
);
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
));
1365 Object_perform (st_processor
*pr
)
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));
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);
1389 pr
->message_argcount
-= 1;
1390 st_processor_execute_method (pr
, method
);
1393 pr
->message_selector
= selector
;
1398 Object_perform_withArguments (st_processor
*pr
)
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
;
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
));
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
),
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
);
1437 st_processor_execute_method (pr
, method
);
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
;
1447 ST_STACK_UNPOP (pr
, 1);
1452 Behavior_new (st_processor
*pr
)
1458 class = ST_STACK_POP (pr
);
1459 format
= st_smi_value (ST_BEHAVIOR (class)->format
);
1461 set_success (pr
, st_descriptors
[format
]->allocate
!= NULL
);
1464 ST_STACK_UNPOP (pr
, 1);
1468 instance
= st_descriptors
[format
]->allocate (memory
->moving_space
, class);
1469 ST_STACK_PUSH (pr
, instance
);
1473 Behavior_newSize (st_processor
*pr
)
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
);
1488 ST_STACK_UNPOP (pr
, 2);
1492 instance
= st_descriptors
[format
]->allocate_arrayed (memory
->moving_space
, class, size
);
1493 ST_STACK_PUSH (pr
, instance
);
1497 SequenceableCollection_size (st_processor
*pr
)
1501 object
= ST_STACK_POP (pr
);
1503 ST_STACK_PUSH (pr
, st_arrayed_object_size (object
));
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);
1518 ST_STACK_PUSH (pr
, st_array_at (receiver
, index
));
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);
1534 st_array_at_put (receiver
, index
, object
);
1535 ST_STACK_PUSH (pr
, object
);
1539 ByteArray_at (st_processor
*pr
)
1541 st_smi index
= pop_integer32 (pr
);
1542 st_oop receiver
= ST_STACK_POP (pr
);
1546 ST_STACK_UNPOP (pr
, 2);
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);
1556 result
= st_smi_new (st_byte_array_at (receiver
, index
));
1558 ST_STACK_PUSH (pr
, result
);
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
);
1569 ST_STACK_UNPOP (pr
, 3);
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);
1579 st_byte_array_at_put (receiver
, index
, byte
);
1581 ST_STACK_PUSH (pr
, st_smi_new (byte
));
1585 ByteArray_hash (st_processor
*pr
)
1587 st_oop receiver
= ST_STACK_POP (pr
);
1590 hash
= st_byte_array_hash (receiver
);
1592 ST_STACK_PUSH (pr
, st_smi_new (hash
));
1596 ByteString_at (st_processor
*pr
)
1598 st_smi index
= pop_integer32 (pr
);
1599 st_oop receiver
= ST_STACK_POP (pr
);
1603 if (ST_UNLIKELY (!pr
->success
)) {
1604 ST_STACK_UNPOP (pr
, 2);
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);
1614 character
= st_character_new (st_byte_array_at (receiver
, index
));
1616 ST_STACK_PUSH (pr
, character
);
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
);
1627 ST_STACK_UNPOP (pr
, 3);
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);
1639 st_byte_array_at_put (receiver
, index
, (st_uchar
) st_character_value (character
));
1641 ST_STACK_PUSH (pr
, character
);
1646 ByteString_size (st_processor
*pr
)
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
);
1660 ByteString_compare (st_processor
*pr
)
1662 st_oop argument
= ST_STACK_POP (pr
);
1663 st_oop receiver
= ST_STACK_POP (pr
);
1666 if (st_object_format (argument
) != ST_FORMAT_BYTE_ARRAY
)
1667 set_success (pr
, false);
1670 order
= strcmp ((const char *) st_byte_array_bytes (receiver
),
1671 (const char *) st_byte_array_bytes (argument
));
1674 ST_STACK_PUSH (pr
, st_smi_new (order
));
1676 ST_STACK_UNPOP (pr
, 2);
1680 WideString_at (st_processor
*pr
)
1682 st_smi index
= pop_integer32 (pr
);
1683 st_oop receiver
= ST_STACK_POP (pr
);
1688 ST_STACK_UNPOP (pr
, 2);
1692 if (index
< 1 || index
> st_smi_value (st_arrayed_object_size (receiver
))) {
1693 set_success (pr
, false);
1694 ST_STACK_UNPOP (pr
, 2);
1698 c
= st_word_array_at (receiver
, index
);
1700 ST_STACK_PUSH (pr
, st_character_new (c
));
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
);
1713 ST_STACK_UNPOP (pr
, 3);
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);
1725 st_word_array_at_put (receiver
, index
, character
);
1727 ST_STACK_PUSH (pr
, character
);
1731 WordArray_at (st_processor
*pr
)
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);
1746 element
= st_word_array_at (receiver
, index
);
1748 ST_STACK_PUSH (pr
, st_smi_new (element
));
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
);
1759 ST_STACK_UNPOP (pr
, 3);
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);
1769 st_word_array_at_put (receiver
, index
, value
);
1771 ST_STACK_PUSH (pr
, st_smi_new (value
));
1775 FloatArray_at (st_processor
*pr
)
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);
1790 element
= st_float_array_at (receiver
, index
);
1791 ST_STACK_PUSH (pr
, st_float_new (element
));
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);
1811 ST_STACK_UNPOP (pr
, 3);
1815 st_float_array_at_put (receiver
, index
, st_float_value (flt
));
1816 ST_STACK_PUSH (pr
, flt
);
1820 activate_block_context (st_processor
*pr
)
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;
1832 st_oops_copy (ST_BLOCK_CONTEXT (block
)->stack
,
1833 pr
->stack
+ pr
->sp
- 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
);
1846 BlockContext_value (st_processor
*pr
)
1848 activate_block_context (pr
);
1852 BlockContext_valueWithArguments (st_processor
*pr
)
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);
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);
1872 st_oops_copy (ST_BLOCK_CONTEXT (block
)->stack
,
1873 ST_ARRAY (values
)->elements
,
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
);
1886 UndefinedObject_exitWithResult (st_processor
*pr
)
1888 longjmp (pr
->main_loop
, 0);
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
)));
1900 Character_characterFor (st_processor
*pr
)
1905 value
= pop_integer (pr
);
1906 receiver
= ST_STACK_POP (pr
);
1909 ST_STACK_PUSH (pr
, st_character_new (value
));
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
))