cell factor_vm::compute_relocation(relocation_entry rel, cell index, code_block *compiled) { array *literals = (to_boolean(compiled->literals) ? untag<array>(compiled->literals) : NULL); cell offset = relocation_offset_of(rel) + (cell)compiled->xt(); #define ARG array_nth(literals,index) switch(relocation_type_of(rel)) { case RT_PRIMITIVE: return (cell)primitives[untag_fixnum(ARG)]; case RT_DLSYM: return (cell)get_rel_symbol(literals,index); case RT_IMMEDIATE: return ARG; case RT_XT: return (cell)object_xt(ARG); case RT_XT_PIC: return (cell)word_xt_pic(untag<word>(ARG)); case RT_XT_PIC_TAIL: return (cell)word_xt_pic_tail(untag<word>(ARG)); case RT_HERE: { fixnum arg = untag_fixnum(ARG); return (arg >= 0 ? offset + arg : (cell)(compiled + 1) - arg); } case RT_THIS: return (cell)(compiled + 1); case RT_CONTEXT: return (cell)&ctx; case RT_UNTAGGED: return untag_fixnum(ARG); case RT_MEGAMORPHIC_CACHE_HITS: return (cell)&megamorphic_cache_hits; case RT_VM: return (cell)this + untag_fixnum(ARG); case RT_CARDS_OFFSET: return cards_offset; case RT_DECKS_OFFSET: return decks_offset; default: critical_error("Bad rel type",rel); return 0; /* Can't happen */ } #undef ARG }
template<typename Iterator> void factor_vm::iterate_relocations(code_block *compiled, Iterator &iter) { if(compiled->relocation != F) { byte_array *relocation = untag<byte_array>(compiled->relocation); cell index = 0; cell length = array_capacity(relocation) / sizeof(relocation_entry); for(cell i = 0; i < length; i++) { relocation_entry rel = relocation->data<relocation_entry>()[i]; iter(rel,index,compiled); index += number_of_parameters(relocation_type_of(rel)); } } }