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);
212 CELL code_format = to_cell(get(ds)); \
213 F_VECTOR *code = untag_vector(get(ds - CELLS)); \
214 F_VECTOR *words = untag_vector(get(ds - CELLS * 2)); \
215 F_VECTOR *literals = untag_vector(get(ds - CELLS * 3)); \
216 F_VECTOR *rel = untag_vector(get(ds - CELLS * 4)); \
217 CELL code_length = align8(untag_fixnum_fast(code->top) * code_format); \
218 CELL rel_length = untag_fixnum_fast(rel->top) * CELLS; \
219 CELL literal_length = untag_fixnum_fast(literals->top) * CELLS; \
220 CELL words_length = untag_fixnum_fast(words->top) * CELLS;
222 void primitive_add_compiled_block(void)
227 /* read parameters from stack, leaving them on the stack */
230 /* try allocating a new code block */
231 CELL total_length = sizeof(F_COMPILED) + code_length
232 + rel_length + literal_length + words_length;
234 start = heap_allot(&compiling,total_length);
236 /* if allocation failed, do a code GC */
239 garbage_collection(TENURED,true);
240 start = heap_allot(&compiling,total_length);
242 /* insufficient room even after code GC, give up */
244 critical_error("code heap exhausted",0);
248 /* we have to read the parameters again, since we may have called
249 code GC in which case the data heap semi-spaces will have switched */
252 /* now we can pop the parameters from the stack */
255 /* begin depositing the code block's contents */
258 /* compiled header */
260 header.code_length = code_length;
261 header.reloc_length = rel_length;
262 header.literal_length = literal_length;
263 header.words_length = words_length;
264 header.finalized = false;
266 memcpy((void*)here,&header,sizeof(F_COMPILED));
267 here += sizeof(F_COMPILED);
270 deposit_integers(here,code,code_format);
274 deposit_integers(here,rel,CELLS);
278 deposit_objects(here,literals,literal_length);
279 here += literal_length;
282 deposit_objects(here,words,words_length);
283 here += words_length;
285 /* push the XT of the new word on the stack */
286 box_unsigned_cell(start + sizeof(F_COMPILED));
291 void primitive_finalize_compile(void)
293 F_ARRAY *array = untag_array(dpop());
296 CELL count = untag_fixnum_fast(array->capacity);
298 for(i = 0; i < count; i++)
300 F_ARRAY *pair = untag_array(get(AREF(array,i)));
301 F_WORD *word = untag_word(get(AREF(pair,0)));
302 word->xt = to_cell(get(AREF(pair,1)));
306 /* perform relocation */
307 for(i = 0; i < count; i++)
309 F_ARRAY *pair = untag_array(get(AREF(array,i)));
310 CELL xt = to_cell(get(AREF(pair,1)));
311 iterate_code_heap_step(xt_to_compiled(xt),finalize_code_block);