3 void undefined_symbol(void)
5 general_error(ERROR_UNDEFINED_SYMBOL,F,F,true);
8 #define CREF(array,i) ((CELL)(array) + CELLS * (i))
10 INLINE CELL get_literal(CELL literal_start, CELL num)
12 return get(CREF(literal_start,num));
15 CELL get_rel_symbol(F_REL *rel, CELL literal_start)
17 CELL arg = REL_ARGUMENT(rel);
18 F_ARRAY *pair = untag_array(get_literal(literal_start,arg));
19 F_STRING *symbol = untag_string(get(AREF(pair,0)));
20 CELL library = get(AREF(pair,1));
21 DLL *dll = (library == F ? NULL : untag_dll(library));
23 if(dll != NULL && !dll->dll)
24 return (CELL)undefined_symbol;
26 CELL sym = (CELL)ffi_dlsym(dll,symbol,false);
29 return (CELL)undefined_symbol;
34 INLINE CELL compute_code_rel(F_REL *rel,
35 CELL code_start, CELL literal_start, CELL words_start)
37 CELL offset = code_start + rel->offset;
42 return primitive_to_xt(REL_ARGUMENT(rel));
44 return get_rel_symbol(rel,literal_start);
50 return CREF(literal_start,REL_ARGUMENT(rel));
52 return get(CREF(words_start,REL_ARGUMENT(rel)));
54 return code_start + REL_ARGUMENT(rel);
56 critical_error("Bad rel type",rel->type);
61 INLINE void reloc_set_2_2(CELL cell, CELL value)
63 put(cell - CELLS,((get(cell - CELLS) & ~0xffff) | ((value >> 16) & 0xffff)));
64 put(cell,((get(cell) & ~0xffff) | (value & 0xffff)));
67 INLINE void reloc_set_masked(CELL cell, CELL value, CELL mask)
69 u32 original = *(u32*)cell;
71 *(u32*)cell = (original | (value & mask));
74 void apply_relocation(F_REL *rel,
75 CELL code_start, CELL literal_start, CELL words_start)
79 CELL offset = rel->offset + code_start;
81 absolute_value = compute_code_rel(rel,
82 code_start,literal_start,words_start);
83 relative_value = absolute_value - offset;
85 switch(REL_CLASS(rel))
87 case REL_ABSOLUTE_CELL:
88 put(offset,absolute_value);
91 *(u32*)offset = absolute_value;
94 *(u32*)offset = relative_value - sizeof(u32);
96 case REL_ABSOLUTE_2_2:
97 reloc_set_2_2(offset,absolute_value);
99 case REL_RELATIVE_2_2:
100 reloc_set_2_2(offset,relative_value);
103 reloc_set_masked(offset,relative_value,REL_RELATIVE_2_MASK);
106 reloc_set_masked(offset,relative_value,REL_RELATIVE_3_MASK);
109 critical_error("Bad rel class",REL_CLASS(rel));
114 void relocate_code_block(F_COMPILED *relocating, CELL code_start,
115 CELL reloc_start, CELL literal_start, CELL words_start, CELL words_end)
117 F_REL *rel = (F_REL *)reloc_start;
118 F_REL *rel_end = (F_REL *)literal_start;
120 /* apply relocations */
122 apply_relocation(rel++,code_start,literal_start,words_start);
125 void finalize_code_block(F_COMPILED *relocating, CELL code_start,
126 CELL reloc_start, CELL literal_start, CELL words_start, CELL words_end)
130 for(scan = words_start; scan < words_end; scan += CELLS)
131 put(scan,untag_word(get(scan))->xt);
133 relocating->finalized = true;
135 relocate_code_block(relocating,code_start,reloc_start,
136 literal_start,words_start,words_end);
138 flush_icache(code_start,reloc_start - code_start);
141 void deposit_integers(CELL here, F_VECTOR *vector, CELL format)
143 CELL count = untag_fixnum_fast(vector->top);
144 F_ARRAY *array = untag_array_fast(vector->array);
149 for(i = 0; i < count; i++)
150 cput(here + i,to_fixnum(get(AREF(array,i))));
152 else if(format == CELLS)
154 for(i = 0; i < count; i++)
155 put(CREF(here,i),to_fixnum(get(AREF(array,i))));
158 critical_error("Bad format param to deposit_vector()",format);
161 void deposit_objects(CELL here, F_VECTOR *vector, CELL literal_length)
163 F_ARRAY *array = untag_array_fast(vector->array);
164 memcpy((void*)here,array + 1,literal_length);
167 CELL add_compiled_block(CELL code_format, F_VECTOR *code,
168 F_VECTOR *literals, F_VECTOR *words, F_VECTOR *rel)
170 CELL code_length = align8(untag_fixnum_fast(code->top) * code_format);
171 CELL rel_length = untag_fixnum_fast(rel->top) * CELLS;
172 CELL literal_length = untag_fixnum_fast(literals->top) * CELLS;
173 CELL words_length = untag_fixnum_fast(words->top) * CELLS;
175 CELL total_length = sizeof(F_COMPILED) + code_length + rel_length
176 + literal_length + words_length;
178 CELL start = heap_allot(&compiling,total_length);
181 /* compiled header */
183 header.code_length = code_length;
184 header.reloc_length = rel_length;
185 header.literal_length = literal_length;
186 header.words_length = words_length;
187 header.finalized = false;
189 memcpy((void*)here,&header,sizeof(F_COMPILED));
190 here += sizeof(F_COMPILED);
193 deposit_integers(here,code,code_format);
197 deposit_integers(here,rel,CELLS);
201 deposit_objects(here,literals,literal_length);
202 here += literal_length;
205 deposit_objects(here,words,words_length);
206 here += words_length;
208 return start + sizeof(F_COMPILED);
211 void primitive_add_compiled_block(void)
213 CELL code_format = to_cell(dpop());
214 F_VECTOR *code = untag_vector(dpop());
215 F_VECTOR *words = untag_vector(dpop());
216 F_VECTOR *literals = untag_vector(dpop());
217 F_VECTOR *rel = untag_vector(dpop());
219 /* push the XT of the new word on the stack */
220 box_unsigned_cell(add_compiled_block(code_format,code,literals,words,rel));
223 void primitive_finalize_compile(void)
225 F_ARRAY *array = untag_array(dpop());
228 CELL count = untag_fixnum_fast(array->capacity);
230 for(i = 0; i < count; i++)
232 F_ARRAY *pair = untag_array(get(AREF(array,i)));
233 F_WORD *word = untag_word(get(AREF(pair,0)));
234 word->xt = to_cell(get(AREF(pair,1)));
238 /* perform relocation */
239 for(i = 0; i < count; i++)
241 F_ARRAY *pair = untag_array(get(AREF(array,i)));
242 CELL xt = to_cell(get(AREF(pair,1)));
243 iterate_code_heap_step(xt_to_compiled(xt),finalize_code_block);