]> gitweb.factorcode.org Git - factor.git/blob - vm/code_block_visitor.hpp
Merge optimizations from master branch
[factor.git] / vm / code_block_visitor.hpp
1 namespace factor
2 {
3
4 template<typename Visitor> struct call_frame_code_block_visitor {
5         factor_vm *parent;
6         Visitor visitor;
7
8         explicit call_frame_code_block_visitor(factor_vm *parent_, Visitor visitor_) :
9                 parent(parent_), visitor(visitor_) {}
10
11         void operator()(stack_frame *frame)
12         {
13                 cell offset = (cell)FRAME_RETURN_ADDRESS(frame,parent) - (cell)frame->xt;
14
15                 code_block *new_block = visitor(parent->frame_code(frame));
16                 frame->xt = new_block->xt();
17
18                 FRAME_RETURN_ADDRESS(frame,parent) = (void *)((cell)frame->xt + offset);
19         }
20 };
21
22 template<typename Visitor> struct callback_code_block_visitor {
23         callback_heap *callbacks;
24         Visitor visitor;
25
26         explicit callback_code_block_visitor(callback_heap *callbacks_, Visitor visitor_) :
27                 callbacks(callbacks_), visitor(visitor_) {}
28
29         void operator()(callback *stub)
30         {
31                 stub->compiled = visitor(stub->compiled);
32                 callbacks->update(stub);
33         }
34 };
35
36 template<typename Visitor> struct code_block_visitor {
37         factor_vm *parent;
38         Visitor visitor;
39
40         explicit code_block_visitor(factor_vm *parent_, Visitor visitor_) :
41                 parent(parent_), visitor(visitor_) {}
42         void visit_object_code_block(object *obj)
43         {
44                 switch(obj->h.hi_tag())
45                 {
46                 case WORD_TYPE:
47                         {
48                                 word *w = (word *)obj;
49                                 if(w->code)
50                                         w->code = visitor(w->code);
51                                 if(w->profiling)
52                                         w->code = visitor(w->profiling);
53         
54                                 parent->update_word_xt(w);
55                                 break;
56                         }
57                 case QUOTATION_TYPE:
58                         {
59                                 quotation *q = (quotation *)obj;
60                                 if(q->code)
61                                         parent->set_quot_xt(q,visitor(q->code));
62                                 break;
63                         }
64                 case CALLSTACK_TYPE:
65                         {
66                                 callstack *stack = (callstack *)obj;
67                                 call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor);
68                                 parent->iterate_callstack_object(stack,call_frame_visitor);
69                                 break;
70                         }
71                 }
72         }
73
74         void visit_context_code_blocks()
75         {
76                 call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor);
77                 parent->iterate_active_frames(call_frame_visitor);
78         }
79
80         void visit_callback_code_blocks()
81         {
82                 callback_code_block_visitor<Visitor> callback_visitor(parent->callbacks,visitor);
83                 parent->callbacks->iterate(callback_visitor);
84         }
85
86 };
87
88 }