2009-10-24 04:54:53 -04:00
|
|
|
namespace factor
|
|
|
|
{
|
|
|
|
|
2009-11-23 19:51:08 -05:00
|
|
|
template<typename Visitor> struct code_block_visitor {
|
|
|
|
factor_vm *parent;
|
|
|
|
Visitor visitor;
|
|
|
|
|
|
|
|
explicit code_block_visitor(factor_vm *parent_, Visitor visitor_) :
|
|
|
|
parent(parent_), visitor(visitor_) {}
|
|
|
|
|
2009-11-28 20:48:26 -05:00
|
|
|
code_block *visit_code_block(code_block *compiled);
|
2009-11-23 19:51:08 -05:00
|
|
|
void visit_object_code_block(object *obj);
|
2009-11-24 20:29:59 -05:00
|
|
|
void visit_embedded_code_pointers(code_block *compiled);
|
2009-11-23 19:51:08 -05:00
|
|
|
void visit_context_code_blocks();
|
|
|
|
void visit_callback_code_blocks();
|
|
|
|
};
|
|
|
|
|
2009-11-28 20:48:26 -05:00
|
|
|
template<typename Visitor>
|
|
|
|
code_block *code_block_visitor<Visitor>::visit_code_block(code_block *compiled)
|
|
|
|
{
|
|
|
|
return visitor(compiled);
|
|
|
|
}
|
|
|
|
|
2009-11-23 19:51:08 -05:00
|
|
|
template<typename Visitor>
|
|
|
|
struct call_frame_code_block_visitor {
|
2009-10-24 05:18:33 -04:00
|
|
|
factor_vm *parent;
|
2009-10-24 04:54:53 -04:00
|
|
|
Visitor visitor;
|
|
|
|
|
2009-10-24 05:18:33 -04:00
|
|
|
explicit call_frame_code_block_visitor(factor_vm *parent_, Visitor visitor_) :
|
|
|
|
parent(parent_), visitor(visitor_) {}
|
2009-10-24 04:54:53 -04:00
|
|
|
|
|
|
|
void operator()(stack_frame *frame)
|
|
|
|
{
|
|
|
|
cell offset = (cell)FRAME_RETURN_ADDRESS(frame,parent) - (cell)frame->xt;
|
|
|
|
|
2009-10-24 05:18:33 -04:00
|
|
|
code_block *new_block = visitor(parent->frame_code(frame));
|
2009-10-24 04:54:53 -04:00
|
|
|
frame->xt = new_block->xt();
|
|
|
|
|
|
|
|
FRAME_RETURN_ADDRESS(frame,parent) = (void *)((cell)frame->xt + offset);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-11-23 19:51:08 -05:00
|
|
|
template<typename Visitor>
|
|
|
|
void code_block_visitor<Visitor>::visit_object_code_block(object *obj)
|
|
|
|
{
|
|
|
|
switch(obj->type())
|
2009-10-24 04:54:53 -04:00
|
|
|
{
|
2009-11-23 19:51:08 -05:00
|
|
|
case WORD_TYPE:
|
|
|
|
{
|
|
|
|
word *w = (word *)obj;
|
|
|
|
if(w->code)
|
|
|
|
w->code = visitor(w->code);
|
|
|
|
if(w->profiling)
|
|
|
|
w->profiling = visitor(w->profiling);
|
|
|
|
|
|
|
|
parent->update_word_xt(w);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QUOTATION_TYPE:
|
|
|
|
{
|
|
|
|
quotation *q = (quotation *)obj;
|
|
|
|
if(q->code)
|
|
|
|
parent->set_quot_xt(q,visitor(q->code));
|
2009-11-27 18:05:08 -05:00
|
|
|
else
|
|
|
|
q->xt = (void *)lazy_jit_compile;
|
2009-11-23 19:51:08 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CALLSTACK_TYPE:
|
|
|
|
{
|
|
|
|
callstack *stack = (callstack *)obj;
|
|
|
|
call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor);
|
|
|
|
parent->iterate_callstack_object(stack,call_frame_visitor);
|
|
|
|
break;
|
|
|
|
}
|
2009-10-24 04:54:53 -04:00
|
|
|
}
|
2009-11-23 19:51:08 -05:00
|
|
|
}
|
2009-10-24 04:54:53 -04:00
|
|
|
|
2009-11-23 19:51:08 -05:00
|
|
|
template<typename Visitor>
|
2009-11-24 20:29:59 -05:00
|
|
|
struct embedded_code_pointers_visitor {
|
2009-10-24 05:36:29 -04:00
|
|
|
Visitor visitor;
|
|
|
|
|
2009-11-24 20:29:59 -05:00
|
|
|
explicit embedded_code_pointers_visitor(Visitor visitor_) : visitor(visitor_) {}
|
2009-10-31 22:06:34 -04:00
|
|
|
|
2009-11-23 19:51:08 -05:00
|
|
|
void operator()(relocation_entry rel, cell index, code_block *compiled)
|
2009-10-24 05:36:29 -04:00
|
|
|
{
|
2009-11-23 19:51:08 -05:00
|
|
|
relocation_type type = rel.rel_type();
|
|
|
|
if(type == RT_XT || type == RT_XT_PIC || type == RT_XT_PIC_TAIL)
|
2009-10-24 05:36:29 -04:00
|
|
|
{
|
2009-11-24 20:29:59 -05:00
|
|
|
instruction_operand op(rel.rel_class(),rel.rel_offset() + (cell)compiled->xt());
|
2009-11-25 18:20:48 -05:00
|
|
|
op.store_code_block(visitor(op.load_code_block()));
|
2009-10-24 05:36:29 -04:00
|
|
|
}
|
|
|
|
}
|
2009-11-23 19:51:08 -05:00
|
|
|
};
|
2009-10-24 05:36:29 -04:00
|
|
|
|
2009-11-23 19:51:08 -05:00
|
|
|
template<typename Visitor>
|
2009-11-24 20:29:59 -05:00
|
|
|
void code_block_visitor<Visitor>::visit_embedded_code_pointers(code_block *compiled)
|
2009-11-23 19:51:08 -05:00
|
|
|
{
|
|
|
|
if(!parent->code->needs_fixup_p(compiled))
|
2009-10-24 05:36:29 -04:00
|
|
|
{
|
2009-11-24 20:29:59 -05:00
|
|
|
embedded_code_pointers_visitor<Visitor> visitor(this->visitor);
|
2009-11-23 19:51:08 -05:00
|
|
|
parent->iterate_relocations(compiled,visitor);
|
2009-10-24 05:36:29 -04:00
|
|
|
}
|
2009-11-23 19:51:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Visitor>
|
|
|
|
void code_block_visitor<Visitor>::visit_context_code_blocks()
|
|
|
|
{
|
|
|
|
call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor);
|
|
|
|
parent->iterate_active_frames(call_frame_visitor);
|
|
|
|
}
|
2009-10-24 05:36:29 -04:00
|
|
|
|
2009-11-23 19:51:08 -05:00
|
|
|
template<typename Visitor>
|
|
|
|
struct callback_code_block_visitor {
|
|
|
|
callback_heap *callbacks;
|
|
|
|
Visitor visitor;
|
|
|
|
|
|
|
|
explicit callback_code_block_visitor(callback_heap *callbacks_, Visitor visitor_) :
|
|
|
|
callbacks(callbacks_), visitor(visitor_) {}
|
|
|
|
|
|
|
|
void operator()(callback *stub)
|
2009-10-24 05:36:29 -04:00
|
|
|
{
|
2009-11-23 19:51:08 -05:00
|
|
|
stub->compiled = visitor(stub->compiled);
|
|
|
|
callbacks->update(stub);
|
2009-10-24 05:36:29 -04:00
|
|
|
}
|
|
|
|
};
|
2009-10-24 04:54:53 -04:00
|
|
|
|
2009-11-23 19:51:08 -05:00
|
|
|
template<typename Visitor>
|
|
|
|
void code_block_visitor<Visitor>::visit_callback_code_blocks()
|
|
|
|
{
|
|
|
|
callback_code_block_visitor<Visitor> callback_visitor(parent->callbacks,visitor);
|
|
|
|
parent->callbacks->iterate(callback_visitor);
|
|
|
|
}
|
|
|
|
|
2009-10-24 04:54:53 -04:00
|
|
|
}
|