]> gitweb.factorcode.org Git - factor.git/blob - vm/code_block_visitor.hpp
vm: fix crash in profiler
[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
43         void visit_object_code_block(object *obj)
44         {
45                 switch(obj->h.hi_tag())
46                 {
47                 case WORD_TYPE:
48                         {
49                                 word *w = (word *)obj;
50                                 if(w->code)
51                                         w->code = visitor(w->code);
52                                 if(w->profiling)
53                                         w->profiling = visitor(w->profiling);
54         
55                                 parent->update_word_xt(w);
56                                 break;
57                         }
58                 case QUOTATION_TYPE:
59                         {
60                                 quotation *q = (quotation *)obj;
61                                 if(q->code)
62                                         parent->set_quot_xt(q,visitor(q->code));
63                                 break;
64                         }
65                 case CALLSTACK_TYPE:
66                         {
67                                 callstack *stack = (callstack *)obj;
68                                 call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor);
69                                 parent->iterate_callstack_object(stack,call_frame_visitor);
70                                 break;
71                         }
72                 }
73         }
74
75         void visit_context_code_blocks()
76         {
77                 call_frame_code_block_visitor<Visitor> call_frame_visitor(parent,visitor);
78                 parent->iterate_active_frames(call_frame_visitor);
79         }
80
81         void visit_callback_code_blocks()
82         {
83                 callback_code_block_visitor<Visitor> callback_visitor(parent->callbacks,visitor);
84                 parent->callbacks->iterate(callback_visitor);
85         }
86
87 };
88
89 }