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-compiler.h"
28 #include "st-object.h"
29 #include "st-symbol.h"
30 #include "st-dictionary.h"
31 #include "st-method.h"
34 #include "st-universe.h"
35 #include "st-behavior.h"
36 #include "st-character.h"
37 #include "st-unicode.h"
43 #define DEFAULT_CODE_SIZE 20
45 #define CSTRING(string) ((char *) st_byte_array_bytes (string))
53 st_compiler_error
*error
;
55 /* names of temporaries, in order of appearance */
57 /* names of instvars, in order they were defined */
59 /* literal frame for the compiled code */
69 st_uint max_stack_depth
;
72 static st_uint sizes
[255] = { 0, };
75 // setup global data for compiler
79 static bool initialized
= false;
85 /* The size (in bytes) of each bytecode instruction
88 sizes
[PUSH_INSTVAR
] = 2;
89 sizes
[PUSH_LITERAL_CONST
] = 2;
90 sizes
[PUSH_LITERAL_VAR
] = 2;
94 sizes
[PUSH_FALSE
] = 1;
95 sizes
[PUSH_INTEGER
] = 2;
96 sizes
[STORE_LITERAL_VAR
] = 2;
97 sizes
[STORE_TEMP
] = 2;
98 sizes
[STORE_INSTVAR
] = 2;
99 sizes
[STORE_POP_LITERAL_VAR
] = 2;
100 sizes
[STORE_POP_TEMP
] = 2;
101 sizes
[STORE_POP_INSTVAR
] = 2;
102 sizes
[RETURN_STACK_TOP
] = 1;
103 sizes
[BLOCK_RETURN
] = 1;
104 sizes
[POP_STACK_TOP
] = 1;
105 sizes
[DUPLICATE_STACK_TOP
] = 1;
106 sizes
[PUSH_ACTIVE_CONTEXT
] = 1;
107 sizes
[BLOCK_COPY
] = 2;
108 sizes
[JUMP_TRUE
] = 3;
109 sizes
[JUMP_FALSE
] = 3;
112 sizes
[SEND_SUPER
] = 3;
113 sizes
[SEND_PLUS
] = 1;
114 sizes
[SEND_MINUS
] = 1;
124 sizes
[SEND_BITSHIFT
] = 1;
125 sizes
[SEND_BITAND
] = 1;
126 sizes
[SEND_BITOR
] = 1;
127 sizes
[SEND_BITXOR
] = 1;
129 sizes
[SEND_AT_PUT
] = 1;
130 sizes
[SEND_SIZE
] = 1;
131 sizes
[SEND_VALUE
] = 1;
132 sizes
[SEND_VALUE_ARG
] = 1;
133 sizes
[SEND_IDENTITY_EQ
] = 1;
134 sizes
[SEND_CLASS
] = 1;
136 sizes
[SEND_NEW_ARG
] = 1;
139 static int size_message (Generator
*gt
, st_node
*node
);
140 static int size_expression (Generator
*gt
, st_node
*node
);
141 static int size_statements (Generator
*gt
, st_node
*node
);
144 static void generate_expression (Generator
*gt
, st_bytecode
*code
, st_node
*node
);
145 static void generate_statements (Generator
*gt
, st_bytecode
*code
, st_node
*statements
);
148 generation_error (Generator
*gt
, const char *message
, st_node
*node
)
151 strncpy (gt
->error
->message
, message
, 255);
152 gt
->error
->line
= node
->line
;
153 gt
->error
->column
= 0;
156 longjmp (gt
->jmploc
, 0);
160 bytecode_init (st_bytecode
*code
)
162 code
->buffer
= st_malloc (DEFAULT_CODE_SIZE
);
163 code
->alloc
= DEFAULT_CODE_SIZE
;
165 code
->max_stack_depth
= 0;
169 bytecode_destroy (st_bytecode
*code
)
171 st_free (code
->buffer
);
176 get_temporaries (Generator
*gt
,
179 st_node
*temporaries
)
181 st_list
*temps
= NULL
;
183 for (st_node
*n
= arguments
; n
; n
= n
->next
) {
184 for (st_list
*l
= instvars
; l
; l
= l
->next
) {
185 if (streq (n
->variable
.name
, (char *) l
->data
))
186 generation_error (gt
, "name is already defined", arguments
);
188 temps
= st_list_prepend (temps
, (st_pointer
) n
->variable
.name
);
191 for (st_node
*n
= temporaries
; n
; n
= n
->next
) {
192 for (st_list
*l
= instvars
; l
; l
= l
->next
) {
193 if (streq (n
->variable
.name
, (char *) l
->data
))
194 generation_error (gt
, "name is already defined", temporaries
);
196 temps
= st_list_prepend (temps
, (st_pointer
) n
->variable
.name
);
199 return st_list_reverse (temps
);
207 gt
= st_new0 (Generator
);
212 gt
->temporaries
= NULL
;
218 generator_destroy (Generator
*gt
)
220 st_list_foreach (gt
->instvars
, st_free
);
221 st_list_destroy (gt
->instvars
);
222 st_list_destroy (gt
->temporaries
);
223 st_list_destroy (gt
->literals
);
229 create_literals_array (Generator
*gt
)
234 gt
->literals
= st_list_append (gt
->literals
, (st_pointer
) gt
->class);
235 literals
= st_object_new_arrayed (ST_ARRAY_CLASS
, st_list_length (gt
->literals
));
238 for (st_list
*l
= gt
->literals
; l
; l
= l
->next
) {
239 st_array_at_put (literals
, i
, (st_oop
) l
->data
);
247 create_bytecode_array (st_bytecode
*code
)
254 array
= st_object_new_arrayed (ST_BYTE_ARRAY_CLASS
, code
->size
);
255 memcpy (st_byte_array_bytes (array
), code
->buffer
, code
->size
);
261 emit (st_bytecode
*code
, st_uchar value
)
263 if (++code
->size
> code
->alloc
) {
264 code
->alloc
+= code
->alloc
;
265 code
->buffer
= st_realloc (code
->buffer
, code
->alloc
);
268 code
->buffer
[code
->size
- 1] = value
;
272 find_instvar (Generator
*gt
, char *name
)
275 for (st_list
*l
= gt
->instvars
; l
; l
= l
->next
) {
277 if (streq (name
, (char *) l
->data
))
285 find_temporary (Generator
*gt
, char *name
)
289 for (st_list
*l
= gt
->temporaries
; l
; l
= l
->next
) {
291 if (streq (name
, (char *) l
->data
))
299 find_literal_const (Generator
*gt
, st_oop literal
)
302 for (st_list
*l
= gt
->literals
; l
; l
= l
->next
) {
304 if (st_object_equal (literal
, (st_oop
) l
->data
))
308 gt
->literals
= st_list_append (gt
->literals
, (void *) literal
);
313 find_literal_var (Generator
*gt
, char *name
)
317 assoc
= st_dictionary_association_at (ST_GLOBALS
, st_symbol_new (name
));
322 for (st_list
*l
= gt
->literals
; l
; l
= l
->next
) {
323 if (st_object_equal (assoc
, (st_oop
) l
->data
))
327 gt
->literals
= st_list_append (gt
->literals
, (st_pointer
) assoc
);
332 jump_offset (Generator
*gt
, st_bytecode
*code
, int offset
)
334 st_assert (offset
<= INT16_MAX
);
339 emit (code
, offset
& 0xFF);
341 emit (code
, (offset
>> 8) & 0xFF);
346 assign_temp (Generator
*gt
, st_bytecode
*code
, int index
, bool pop
)
348 st_assert (index
<= 255);
351 emit (code
, STORE_POP_TEMP
);
353 emit (code
, STORE_TEMP
);
354 emit (code
, (st_uchar
) index
);
358 assign_instvar (Generator
*gt
, st_bytecode
*code
, int index
, bool pop
)
360 st_assert (index
<= 255);
363 emit (code
, STORE_POP_INSTVAR
);
365 emit (code
, STORE_INSTVAR
);
366 emit (code
, (st_uchar
) index
);
370 assign_literal_var (Generator
*gt
, st_bytecode
*code
, int index
, bool pop
)
372 st_assert (index
<= 255);
375 emit (code
, STORE_POP_LITERAL_VAR
);
377 emit (code
, STORE_LITERAL_VAR
);
378 emit (code
, (st_uchar
) index
);
382 push (Generator
*gt
, st_bytecode
*code
, st_uchar value
, st_uchar index
)
387 code
->max_stack_depth
++;
392 push_special (Generator
*gt
, st_bytecode
*code
, st_uchar value
)
395 code
->max_stack_depth
++;
399 generate_assign (Generator
*gt
, st_bytecode
*code
, st_node
*node
, bool pop
)
403 generate_expression (gt
, code
, node
->assign
.expression
);
405 index
= find_temporary (gt
, node
->assign
.assignee
->variable
.name
);
407 assign_temp (gt
, code
, index
, pop
);
411 index
= find_instvar (gt
, node
->assign
.assignee
->variable
.name
);
413 assign_instvar (gt
, code
, index
, pop
);
417 index
= find_literal_var (gt
, node
->assign
.assignee
->variable
.name
);
419 assign_literal_var (gt
, code
, index
, pop
);
423 generation_error (gt
, "unknown variable", node
);
428 size_assign (Generator
*gt
, st_node
*node
)
432 bytecode_init (&code
);
433 generate_assign (gt
, &code
, node
, true);
434 bytecode_destroy (&code
);
440 generate_return (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
442 generate_expression (gt
, code
, node
->retrn
.expression
);
444 emit (code
, RETURN_STACK_TOP
);
448 size_return (Generator
*gt
, st_node
*node
)
452 bytecode_init (&code
);
453 generate_return (gt
, &code
, node
);
454 bytecode_destroy (&code
);
460 get_block_temporaries (Generator
*gt
, st_node
*temporaries
)
462 st_list
*temps
= NULL
;
464 for (st_node
*node
= temporaries
; node
; node
= node
->next
) {
466 for (st_list
*l
= gt
->instvars
; l
; l
= l
->next
) {
467 if (streq (node
->variable
.name
, (char *) l
->data
))
468 generation_error (gt
, "name is already defined", node
);
471 for (st_list
*l
= gt
->temporaries
; l
; l
= l
->next
) {
472 if (streq (node
->variable
.name
, (char *) l
->data
))
473 generation_error (gt
, "name already used in method", node
);
476 temps
= st_list_prepend (temps
, (st_pointer
) node
->variable
.name
);
480 return st_list_reverse (temps
);
484 generate_block (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
490 argcount
= st_node_list_length (node
->block
.arguments
);
492 emit (code
, BLOCK_COPY
);
493 emit (code
, argcount
);
495 // get size of block code and then jump around that code
496 size
= 2 * argcount
+ size_statements (gt
, node
->block
.statements
) + sizes
[BLOCK_RETURN
];
497 jump_offset (gt
, code
, size
);
499 /* Store all block arguments into the temporary frame.
500 Note that upon a block activation, the stack pointer sits
501 above the last argument to to the block */
502 i
= st_node_list_length (node
->block
.arguments
);
504 l
= st_node_list_at (node
->block
.arguments
, i
- 1);
505 index
= find_temporary (gt
, l
->variable
.name
);
506 st_assert (index
>= 0);
507 assign_temp (gt
, code
, index
, true);
510 generate_statements (gt
, code
, node
->block
.statements
);
511 emit (code
, BLOCK_RETURN
);
515 size_block (Generator
*gt
, st_node
*node
)
519 bytecode_init (&code
);
520 generate_block (gt
, &code
, node
);
521 bytecode_destroy (&code
);
529 match_ifTrue (Generator
*gt
, st_node
*node
)
533 if (strcmp (CSTRING (node
->message
.selector
), "ifTrue:") != 0)
536 block
= node
->message
.arguments
;
537 if (block
->type
!= ST_BLOCK_NODE
|| block
->block
.arguments
!= NULL
)
544 generate_ifTrue (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
549 block
= node
->message
.arguments
;
551 generate_expression (gt
, code
, node
->message
.receiver
);
552 size
= size_statements (gt
, block
->block
.statements
);
553 size
+= node
->message
.is_statement
? sizes
[POP_STACK_TOP
] : sizes
[JUMP
];
554 emit (code
, JUMP_FALSE
);
555 emit (code
, size
& 0xFF);
556 emit (code
, (size
>> 8) & 0xFF);
557 generate_statements (gt
, code
, block
->block
.statements
);
559 if (node
->message
.is_statement
) {
560 emit (code
, POP_STACK_TOP
);
565 emit (code
, PUSH_NIL
);
572 match_ifFalse (Generator
*gt
, st_node
*node
)
576 if (strcmp (CSTRING (node
->message
.selector
), "ifFalse:") != 0)
579 block
= node
->message
.arguments
;
580 if (block
->type
!= ST_BLOCK_NODE
|| block
->block
.arguments
!= NULL
)
587 generate_ifFalse (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
592 block
= node
->message
.arguments
;
594 generate_expression (gt
, code
, node
->message
.receiver
);
595 size
= size_statements (gt
, block
->block
.statements
);
596 size
+= node
->message
.is_statement
? sizes
[POP_STACK_TOP
] : sizes
[JUMP
];
597 emit (code
, JUMP_TRUE
);
598 emit (code
, size
& 0xFF);
599 emit (code
, (size
>> 8) & 0xFF);
600 generate_statements (gt
, code
, block
->block
.statements
);
602 if (node
->message
.is_statement
) {
603 emit (code
, POP_STACK_TOP
);
608 emit (code
, PUSH_NIL
);
615 match_ifTrueifFalse (Generator
*gt
, st_node
*node
)
617 st_node
*true_block
, *false_block
;
619 if (strcmp (CSTRING (node
->message
.selector
), "ifTrue:ifFalse:") != 0)
622 true_block
= node
->message
.arguments
;
623 if (true_block
->type
!= ST_BLOCK_NODE
|| true_block
->block
.arguments
!= NULL
)
626 false_block
= node
->message
.arguments
->next
;
627 if (false_block
->type
!= ST_BLOCK_NODE
|| false_block
->block
.arguments
!= NULL
)
634 generate_ifTrueifFalse (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
638 st_node
*true_block
, *false_block
;
640 true_block
= node
->message
.arguments
;
641 false_block
= node
->message
.arguments
->next
;
643 generate_expression (gt
, code
, node
->message
.receiver
);
644 size
= size_statements (gt
, true_block
->block
.statements
) + sizes
[JUMP
];
645 emit (code
, JUMP_FALSE
);
646 emit (code
, size
& 0xFF);
647 emit (code
, (size
>> 8) & 0xFF);
648 generate_statements (gt
, code
, true_block
->block
.statements
);
649 size
= size_statements (gt
, false_block
->block
.statements
);
651 emit (code
, size
& 0xFF);
652 emit (code
, (size
>> 8) & 0xFF);
653 generate_statements (gt
, code
, false_block
->block
.statements
);
655 if (node
->message
.is_statement
)
656 emit (code
, POP_STACK_TOP
);
662 match_ifFalseifTrue (Generator
*gt
, st_node
*node
)
664 st_node
*true_block
, *false_block
;
666 if (strcmp (CSTRING (node
->message
.selector
), "ifFalse:ifTrue:") != 0)
669 true_block
= node
->message
.arguments
;
670 if (true_block
->type
!= ST_BLOCK_NODE
|| true_block
->block
.arguments
!= NULL
)
673 false_block
= node
->message
.arguments
->next
;
674 if (false_block
->type
!= ST_BLOCK_NODE
|| false_block
->block
.arguments
!= NULL
)
681 generate_ifFalseifTrue (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
683 st_node
*true_block
, *false_block
;
686 true_block
= node
->message
.arguments
;
687 false_block
= node
->message
.arguments
->next
;
689 generate_expression (gt
, code
, node
->message
.receiver
);
690 size
= size_statements (gt
, true_block
->block
.statements
) + sizes
[JUMP
];
691 emit (code
, JUMP_TRUE
);
692 emit (code
, size
& 0xFF);
693 emit (code
, (size
>> 8) & 0xFF);
694 generate_statements (gt
, code
, true_block
->block
.statements
);
695 size
= size_statements (gt
, false_block
->block
.statements
);
697 emit (code
, size
& 0xFF);
698 emit (code
, (size
>> 8) & 0xFF);
699 generate_statements (gt
, code
, false_block
->block
.statements
);
701 if (node
->message
.is_statement
)
702 emit (code
, POP_STACK_TOP
);
708 match_whileTrue (Generator
*gt
, st_node
*node
)
712 if (strcmp (CSTRING (node
->message
.selector
), "whileTrue") != 0)
715 block
= node
->message
.receiver
;
716 if (block
->type
!= ST_BLOCK_NODE
|| block
->block
.arguments
!= NULL
)
723 generate_whileTrue (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
728 block
= node
->message
.receiver
;
730 generate_statements (gt
, code
, block
->block
.statements
);
732 emit (code
, JUMP_FALSE
);
735 size
= size_statements (gt
, block
->block
.statements
);
736 size
+= sizes
[JUMP_FALSE
];
739 emit (code
, size
& 0xFF);
740 emit (code
, (size
>> 8) & 0xFF);
742 if (!node
->message
.is_statement
)
743 emit (code
, PUSH_NIL
);
749 match_whileFalse (Generator
*gt
, st_node
*node
)
753 if (strcmp (CSTRING (node
->message
.selector
), "whileFalse") != 0)
756 block
= node
->message
.receiver
;
757 if (block
->type
!= ST_BLOCK_NODE
|| block
->block
.arguments
!= NULL
)
764 generate_whileFalse (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
769 block
= node
->message
.receiver
;
770 generate_statements (gt
, code
, block
->block
.statements
);
772 emit (code
, JUMP_TRUE
);
775 size
= size_statements (gt
, block
->block
.statements
);
776 size
+= sizes
[JUMP_FALSE
];
779 emit (code
, size
& 0xFF);
780 emit (code
, (size
>> 8) & 0xFF);
782 if (!node
->message
.is_statement
)
783 emit (code
, PUSH_NIL
);
789 match_whileTrueArg (Generator
*gt
, st_node
*node
)
793 if (strcmp (CSTRING (node
->message
.selector
), "whileTrue:") != 0)
796 block
= node
->message
.receiver
;
797 if (block
->type
!= ST_BLOCK_NODE
|| block
->block
.arguments
!= NULL
)
800 block
= node
->message
.arguments
;
801 if (block
->type
!= ST_BLOCK_NODE
|| block
->block
.arguments
!= NULL
)
808 generate_whileTrueArg (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
813 generate_statements (gt
, code
, node
->message
.receiver
->block
.statements
);
814 emit (code
, JUMP_FALSE
);
815 size
= size_statements (gt
, node
->message
.arguments
->block
.statements
);
816 size
+= sizes
[POP_STACK_TOP
] + sizes
[JUMP
];
818 emit (code
, size
& 0xFF);
819 emit (code
, (size
>> 8) & 0xFF);
821 generate_statements (gt
, code
, node
->message
.arguments
->block
.statements
);
823 size
+= size_statements (gt
, node
->message
.receiver
->block
.statements
);
825 emit (code
, POP_STACK_TOP
);
827 emit (code
, size
& 0xFF);
828 emit (code
, (size
>> 8) & 0xFF);
830 if (!node
->message
.is_statement
)
831 emit (code
, PUSH_NIL
);
837 match_whileFalseArg (Generator
*gt
, st_node
*node
)
841 if (strcmp (CSTRING (node
->message
.selector
), "whileFalse:") != 0)
844 block
= node
->message
.receiver
;
845 if (block
->type
!= ST_BLOCK_NODE
|| block
->block
.arguments
!= NULL
)
848 block
= node
->message
.arguments
;
849 if (block
->type
!= ST_BLOCK_NODE
|| block
->block
.arguments
!= NULL
)
856 generate_whileFalseArg (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
861 generate_statements (gt
, code
, node
->message
.receiver
->block
.statements
);
862 emit (code
, JUMP_TRUE
);
863 size
= size_statements (gt
, node
->message
.arguments
->block
.statements
);
864 size
+= sizes
[POP_STACK_TOP
] + sizes
[JUMP
];
866 emit (code
, size
& 0xFF);
867 emit (code
, (size
>> 8) & 0xFF);
869 generate_statements (gt
, code
, node
->message
.arguments
->block
.statements
);
871 size
+= size_statements (gt
, node
->message
.receiver
->block
.statements
);
874 emit (code
, POP_STACK_TOP
);
876 emit (code
, size
& 0xFF);
877 emit (code
, (size
>> 8) & 0xFF);
879 if (!node
->message
.is_statement
)
880 emit (code
, PUSH_NIL
);
886 match_and (Generator
*gt
, st_node
*node
)
890 if (strcmp (CSTRING (node
->message
.selector
), "and:") != 0)
893 block
= node
->message
.arguments
;
894 if (block
->type
!= ST_BLOCK_NODE
|| block
->block
.arguments
!= NULL
)
901 generate_and (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
906 block
= node
->message
.arguments
;
907 generate_expression (gt
, code
, node
->message
.receiver
);
908 size
= size_statements (gt
, block
->block
.statements
) + sizes
[JUMP
];
910 emit (code
, JUMP_FALSE
);
911 emit (code
, size
& 0xFF);
912 emit (code
, (size
>> 8) & 0xFF);
914 generate_statements (gt
, code
, block
->block
.statements
);
919 emit (code
, PUSH_FALSE
);
921 if (node
->message
.is_statement
)
922 emit (code
, POP_STACK_TOP
);
928 match_or (Generator
*gt
, st_node
*node
)
932 if (strcmp (CSTRING (node
->message
.selector
), "or:") != 0)
935 block
= node
->message
.arguments
;
936 if (block
->type
!= ST_BLOCK_NODE
|| block
->block
.arguments
!= NULL
)
943 generate_or (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
948 block
= node
->message
.arguments
;
949 generate_expression (gt
, code
, node
->message
.receiver
);
950 size
= size_statements (gt
, block
->block
.statements
) + sizes
[JUMP
];
952 emit (code
, JUMP_TRUE
);
953 emit (code
, size
& 0xFF);
954 emit (code
, (size
>> 8) & 0xFF);
956 generate_statements (gt
, code
, block
->block
.statements
);
961 emit (code
, PUSH_TRUE
);
962 if (node
->message
.is_statement
)
963 emit (code
, POP_STACK_TOP
);
966 typedef void (* CodeGenerationFunc
) (Generator
*gt
, st_bytecode
*code
, st_node
*node
);
967 typedef bool (* OptimisationMatchFunc
) (Generator
*gt
, st_node
*node
);
969 static const struct optimisers
{
971 CodeGenerationFunc generation_func
;
972 OptimisationMatchFunc match_func
;
976 { generate_ifTrue
, match_ifTrue
},
977 { generate_ifFalse
, match_ifFalse
},
978 { generate_ifTrueifFalse
, match_ifTrueifFalse
},
979 { generate_ifFalseifTrue
, match_ifFalseifTrue
},
980 { generate_whileTrue
, match_whileTrue
},
981 { generate_whileFalse
, match_whileFalse
},
982 { generate_whileTrueArg
, match_whileTrueArg
},
983 { generate_whileFalseArg
, match_whileFalseArg
},
984 { generate_and
, match_and
},
985 { generate_or
, match_or
}
989 generate_message_send (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
992 st_uint argcount
= 0;
995 /* generate arguments */
996 args
= node
->message
.arguments
;
997 for (; args
; args
= args
->next
) {
998 generate_expression (gt
, code
, args
);
1002 /* check if message is a special */
1003 for (int i
= 0; i
< ST_N_ELEMENTS (__machine
.selectors
); i
++) {
1004 if (!node
->message
.super_send
&& node
->message
.selector
== __machine
.selectors
[i
]) {
1005 emit (code
, SEND_PLUS
+ i
);
1010 if (node
->message
.super_send
)
1011 emit (code
, SEND_SUPER
);
1015 index
= find_literal_const (gt
, node
->message
.selector
);
1017 emit (code
, (st_uchar
) argcount
);
1018 emit (code
, (st_uchar
) index
);
1021 if (node
->message
.is_statement
)
1022 emit (code
, POP_STACK_TOP
);
1026 size_message_send (Generator
*gt
, st_node
*node
)
1030 bytecode_init (&code
);
1031 generate_message_send (gt
, &code
, node
);
1032 bytecode_destroy (&code
);
1038 generate_cascade (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
1042 generate_expression (gt
, code
, node
->cascade
.receiver
);
1043 emit (code
, DUPLICATE_STACK_TOP
);
1045 for (st_list
*l
= node
->cascade
.messages
; l
; l
= l
->next
) {
1047 generate_message_send (gt
, code
, (st_node
*) l
->data
);
1049 if (l
->next
|| node
->cascade
.is_statement
)
1050 emit (code
, POP_STACK_TOP
);
1052 if (l
->next
&& l
->next
->next
)
1053 emit (code
, DUPLICATE_STACK_TOP
);
1058 size_cascade (Generator
*gt
, st_node
*node
)
1062 bytecode_init (&code
);
1063 generate_cascade (gt
, &code
, node
);
1064 bytecode_destroy (&code
);
1070 generate_message (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
1074 for (i
= 0; i
< ST_N_ELEMENTS (optimisers
); i
++) {
1075 if (optimisers
[i
].match_func (gt
, node
)) {
1076 optimisers
[i
].generation_func (gt
, code
, node
);
1081 generate_expression (gt
, code
, node
->message
.receiver
);
1082 generate_message_send (gt
, code
, node
);
1086 size_message (Generator
*gt
, st_node
*node
)
1090 bytecode_init (&code
);
1091 generate_message (gt
, &code
, node
);
1092 bytecode_destroy (&code
);
1098 generate_expression (Generator
*gt
, st_bytecode
*code
, st_node
*node
)
1102 switch (node
->type
) {
1103 case ST_VARIABLE_NODE
:
1105 const char *name
= node
->variable
.name
;
1107 if (streq (name
, "self")) {
1108 push_special (gt
, code
, PUSH_SELF
);
1110 } else if (streq (name
, "super")) {
1111 push_special (gt
, code
, PUSH_SELF
);
1113 } else if (streq (name
, "true")) {
1114 push_special (gt
, code
, PUSH_TRUE
);
1116 } else if (streq (name
, "false")) {
1117 push_special (gt
, code
, PUSH_FALSE
);
1119 } else if (streq (name
, "nil")) {
1120 push_special (gt
, code
, PUSH_NIL
);
1122 } else if (streq (name
, "thisContext")) {
1123 push_special (gt
, code
, PUSH_ACTIVE_CONTEXT
);
1127 index
= find_temporary (gt
, node
->variable
.name
);
1129 push (gt
, code
, PUSH_TEMP
, index
);
1132 index
= find_instvar (gt
, node
->variable
.name
);
1134 push (gt
, code
, PUSH_INSTVAR
, index
);
1137 index
= find_literal_var (gt
, node
->variable
.name
);
1139 push (gt
, code
, PUSH_LITERAL_VAR
, index
);
1142 generation_error (gt
, "unknown variable", node
);
1145 case ST_LITERAL_NODE
:
1147 /* use optimized PUSH_INTEGER for smis in the range of -127..127 */
1148 if (st_object_is_smi (node
->literal
.value
) &&
1149 ((st_smi_value (node
->literal
.value
) >= -127) &&
1150 (st_smi_value (node
->literal
.value
) <= 127))) {
1151 emit (code
, PUSH_INTEGER
);
1152 emit (code
, st_smi_value (node
->literal
.value
));
1154 index
= find_literal_const (gt
, node
->literal
.value
);
1155 push (gt
, code
, PUSH_LITERAL_CONST
, index
);
1159 case ST_ASSIGN_NODE
:
1160 generate_assign (gt
, code
, node
, false);
1164 generate_block (gt
, code
, node
);
1167 case ST_MESSAGE_NODE
:
1168 generate_message (gt
, code
, node
);
1171 case ST_CASCADE_NODE
:
1172 generate_cascade (gt
, code
, node
);
1176 st_assert_not_reached ();
1181 size_expression (Generator
*gt
, st_node
*node
)
1185 bytecode_init (&code
);
1186 generate_expression (gt
, &code
, node
);
1187 bytecode_destroy (&code
);
1193 generate_statements (Generator
*gt
, st_bytecode
*code
, st_node
*statements
)
1195 if (statements
== NULL
) {
1196 emit (code
, PUSH_NIL
);
1199 for (st_node
*node
= statements
; node
; node
= node
->next
) {
1201 switch (node
->type
) {
1203 case ST_VARIABLE_NODE
:
1204 case ST_LITERAL_NODE
:
1207 * don't generate anything in this case since we would end up with a constant
1208 * expression with no side-effects.
1210 * However, in a block with no explicit return, the value of the last statement is the implicit
1211 * value of the block.
1213 if (node
->next
== NULL
)
1214 generate_expression (gt
, code
, node
);
1217 case ST_ASSIGN_NODE
:
1219 /* don't use STORE_POP if this is the last statement */
1220 if (node
->next
== NULL
)
1221 generate_assign (gt
, code
, node
, false);
1223 generate_assign (gt
, code
, node
, true);
1226 case ST_RETURN_NODE
:
1228 st_assert (node
->next
== NULL
);
1229 generate_return (gt
, code
, node
);
1232 case ST_MESSAGE_NODE
:
1234 generate_message (gt
, code
, node
);
1237 case ST_CASCADE_NODE
:
1239 generate_cascade (gt
, code
, node
);
1243 st_assert_not_reached ();
1249 size_statements (Generator
*gt
, st_node
*statements
)
1253 bytecode_init (&code
);
1254 generate_statements (gt
, &code
, statements
);
1255 bytecode_destroy (&code
);
1261 generate_method_statements (Generator
*gt
, st_bytecode
*code
, st_node
*statements
)
1263 for (st_node
*node
= statements
; node
; node
= node
->next
) {
1265 switch (node
->type
) {
1267 case ST_VARIABLE_NODE
:
1268 case ST_LITERAL_NODE
:
1272 case ST_ASSIGN_NODE
:
1274 generate_assign (gt
, code
, node
, true);
1277 case ST_RETURN_NODE
:
1279 st_assert (node
->next
== NULL
);
1280 generate_return (gt
, code
, node
);
1283 case ST_MESSAGE_NODE
:
1285 generate_message (gt
, code
, node
);
1288 case ST_CASCADE_NODE
:
1290 generate_cascade (gt
, code
, node
);
1294 st_assert_not_reached ();
1298 emit (code
, PUSH_SELF
);
1299 emit (code
, RETURN_STACK_TOP
);
1303 collect_temporaries (Generator
*gt
, st_node
*node
)
1305 st_list
*temps
= NULL
;
1310 if (node
->type
== ST_BLOCK_NODE
) {
1311 temps
= st_list_concat (get_block_temporaries (gt
, node
->block
.arguments
),
1312 get_block_temporaries (gt
, node
->block
.temporaries
));
1315 switch (node
->type
) {
1317 temps
= st_list_concat (temps
, collect_temporaries (gt
, node
->block
.statements
));
1319 case ST_ASSIGN_NODE
:
1320 temps
= st_list_concat (temps
, collect_temporaries (gt
, node
->assign
.expression
));
1322 case ST_RETURN_NODE
:
1323 temps
= st_list_concat (temps
, collect_temporaries (gt
, node
->retrn
.expression
));
1325 case ST_MESSAGE_NODE
:
1326 temps
= st_list_concat (temps
, collect_temporaries (gt
, node
->message
.receiver
));
1327 temps
= st_list_concat (temps
, collect_temporaries (gt
, node
->message
.arguments
));
1330 case ST_CASCADE_NODE
:
1331 temps
= st_list_concat (temps
, collect_temporaries (gt
, node
->cascade
.receiver
));
1332 for (st_list
*l
= node
->cascade
.messages
; l
; l
= l
->next
)
1333 temps
= st_list_concat (temps
, collect_temporaries (gt
, (st_node
*) l
->data
));
1337 case ST_METHOD_NODE
:
1338 case ST_VARIABLE_NODE
:
1339 case ST_LITERAL_NODE
:
1343 temps
= st_list_concat (temps
, collect_temporaries (gt
, node
->next
));
1349 st_generate_method (st_oop
class, st_node
*node
, st_compiler_error
*error
)
1357 st_assert (class != ST_NIL
);
1358 st_assert (node
!= NULL
&& node
->type
== ST_METHOD_NODE
);
1362 gt
= generator_new ();
1365 if (setjmp (gt
->jmploc
)) {
1366 generator_destroy (gt
);
1371 gt
->instvars
= st_behavior_all_instance_variables (class);
1372 gt
->temporaries
= get_temporaries (gt
, gt
->instvars
, node
->method
.arguments
, node
->method
.temporaries
);
1374 /* collect all block-level temporaries */
1375 gt
->temporaries
= st_list_concat (gt
->temporaries
, collect_temporaries (gt
, node
->method
.statements
));
1377 bytecode_init (&code
);
1378 generate_method_statements (gt
, &code
, node
->method
.statements
);
1379 method
= st_object_new (ST_COMPILED_METHOD_CLASS
);
1381 argcount
= st_node_list_length (node
->method
.arguments
);
1382 tempcount
= st_list_length (gt
->temporaries
) - st_node_list_length (node
->method
.arguments
);
1384 ST_METHOD_HEADER (method
) = st_smi_new (0);
1385 st_method_set_arg_count (method
, argcount
);
1386 st_method_set_temp_count (method
, tempcount
);
1387 st_method_set_primitive_index (method
, node
->method
.primitive
);
1389 if (node
->method
.primitive
>= 0) {
1390 st_method_set_flags (method
, ST_METHOD_PRIMITIVE
);
1392 st_method_set_flags (method
, ST_METHOD_NORMAL
);
1395 ST_METHOD_LITERALS (method
) = create_literals_array (gt
);
1396 ST_METHOD_BYTECODE (method
) = create_bytecode_array (&code
);
1397 ST_METHOD_SELECTOR (method
) = node
->method
.selector
;
1399 generator_destroy (gt
);
1400 bytecode_destroy (&code
);
1409 #define FORMAT(ip) (formats[sizes[*ip]-1])
1412 print_bytecodes (st_oop literals
, st_uchar
*codes
, int len
)
1416 static const char * const formats
[] = {
1419 "<%02x %02x %02x> ",
1423 while ((ip
- codes
) < len
) {
1425 printf ("%3li ", ip
- codes
);
1427 switch ((Code
) *ip
) {
1430 printf (FORMAT (ip
), ip
[0], ip
[1]);
1431 printf ("pushTemp: %i", ip
[1]);
1436 printf (FORMAT (ip
), ip
[0], ip
[1]);
1437 printf ("pushInstvar: %i", ip
[1]);
1441 case PUSH_LITERAL_CONST
:
1442 printf (FORMAT (ip
), ip
[0], ip
[1]);
1443 printf ("pushConst: %i", ip
[1]);
1447 case PUSH_LITERAL_VAR
:
1448 printf (FORMAT (ip
), ip
[0], ip
[1]);
1449 printf ("pushLit: %i", ip
[1]);
1454 printf (FORMAT (ip
), ip
[0]);
1455 printf ("push: self");
1460 printf (FORMAT (ip
), ip
[0]);
1461 printf ("pushConst: true");
1466 printf (FORMAT (ip
), ip
[0]);
1467 printf ("pushConst: false");
1472 printf (FORMAT (ip
), ip
[0]);
1473 printf ("pushConst: nil");
1478 printf (FORMAT (ip
), ip
[0], ip
[1]);
1479 printf ("pushConst: %i", (signed char) ip
[1]);
1483 case PUSH_ACTIVE_CONTEXT
:
1484 printf (FORMAT (ip
), ip
[0]);
1485 printf ("push: thisContext");
1490 printf (FORMAT (ip
), ip
[0], ip
[1]);
1491 printf ("storeTemp: %i", ip
[1]);
1496 printf (FORMAT (ip
), ip
[0], ip
[1]);
1497 printf ("storeInstvar: %i", ip
[1]);
1501 case STORE_LITERAL_VAR
:
1502 printf (FORMAT (ip
), ip
[0], ip
[1]);
1503 printf ("storeLiteral: %i", ip
[1]);
1507 case STORE_POP_TEMP
:
1508 printf (FORMAT (ip
), ip
[0], ip
[1]);
1509 printf ("popIntoTemp: %i", ip
[1]);
1513 case STORE_POP_INSTVAR
:
1514 printf (FORMAT (ip
), ip
[0], ip
[1]);
1515 printf ("popIntoInstvar: %i", ip
[1]);
1519 case STORE_POP_LITERAL_VAR
:
1520 printf (FORMAT (ip
), ip
[0], ip
[1]);
1521 printf ("popIntoLiteral: %i", ip
[1]);
1526 printf (FORMAT (ip
), ip
[0], ip
[1]);
1527 printf ("blockCopy: %i", ip
[1]);
1532 printf (FORMAT (ip
), ip
[0], ip
[1], ip
[2]);
1534 short offset
= *((short *) (ip
+ 1));
1535 printf ("jump: %li", 3 + (ip
- codes
) + offset
);
1540 printf (FORMAT (ip
), ip
[0], ip
[1], ip
[2]);
1541 printf ("jumpTrue: %li", 3 + (ip
- codes
) + *((short *) (ip
+ 1)));
1546 printf (FORMAT (ip
), ip
[0], ip
[1], ip
[2]);
1547 printf ("jumpFalse: %li", 3 + (ip
- codes
) + *((short *) (ip
+ 1)));
1552 printf (FORMAT (ip
), ip
[0]);
1557 case DUPLICATE_STACK_TOP
:
1558 printf (FORMAT (ip
), ip
[0]);
1563 case RETURN_STACK_TOP
:
1564 printf (FORMAT (ip
), ip
[0]);
1565 printf ("returnTop");
1573 printf (FORMAT (ip
), ip
[0]);
1574 printf ("blockReturn");
1582 selector
= st_array_at (literals
, ip
[2] + 1);
1584 printf (FORMAT (ip
), ip
[0], ip
[1], ip
[2]);
1586 printf ("send: #%s", (char *) st_byte_array_bytes (selector
));
1594 selector
= st_array_at (literals
, ip
[2] + 1);
1596 printf (FORMAT (ip
), ip
[0], ip
[1], ip
[2]);
1598 printf ("sendSuper: #%s", (char *) st_byte_array_bytes (selector
));
1622 case SEND_VALUE_ARG
:
1623 case SEND_IDENTITY_EQ
:
1628 printf (FORMAT (ip
), ip
[0]);
1629 printf ("sendSpecial: #%s", st_byte_array_bytes (__machine
.selectors
[ip
[0] - SEND_PLUS
]));
1640 print_literal (st_oop lit
)
1642 if (st_object_is_smi (lit
)) {
1644 printf ("%li", st_smi_value (lit
));
1646 } else if (st_object_is_symbol (lit
)) {
1648 printf ("#%s", (char *) st_byte_array_bytes (lit
));
1650 } else if (st_object_class (lit
) == ST_STRING_CLASS
) {
1652 printf ("'%s'", (char *) st_byte_array_bytes (lit
));
1654 } else if (st_object_class (lit
) == ST_CHARACTER_CLASS
) {
1656 char outbuf
[6] = { 0 };
1657 st_unichar_to_utf8 (st_character_value (lit
), outbuf
);
1658 printf ("$%s", outbuf
);
1664 print_literals (st_oop literals
)
1666 if (literals
== ST_NIL
)
1669 printf ("literals: ");
1671 for (int i
= 1; i
<= st_smi_value (ST_ARRAYED_OBJECT (literals
)->size
); i
++) {
1673 st_oop lit
= st_array_at (literals
, i
);
1675 print_literal (lit
);
1684 st_print_method (st_oop method
)
1687 st_uchar
*bytecodes
;
1690 printf ("flags: %i; ", st_method_get_flags (method
));
1691 printf ("arg-count: %i; ", st_method_get_arg_count (method
));
1692 printf ("temp-count: %i; ", st_method_get_temp_count (method
));
1693 printf ("primitive: %i;\n", st_method_get_primitive_index (method
));
1697 literals
= ST_METHOD_LITERALS (method
);
1698 bytecodes
= st_method_bytecode_bytes (method
);
1699 size
= st_smi_value (st_arrayed_object_size (ST_METHOD_BYTECODE (method
)));
1701 print_bytecodes (literals
, bytecodes
, size
);
1703 print_literals (literals
);