]> gitweb.factorcode.org Git - factor.git/blob - vm/callstack.hpp
WIP verify_callstack function
[factor.git] / vm / callstack.hpp
1 namespace factor
2 {
3
4 inline static cell callstack_object_size(cell size)
5 {
6         return sizeof(callstack) + size;
7 }
8
9 /* This is a little tricky. The iterator may allocate memory, so we
10 keep the callstack in a GC root and use relative offsets */
11 template<typename Iterator> void factor_vm::iterate_callstack_object(callstack *stack_, Iterator &iterator)
12 {
13         data_root<callstack> stack(stack_,this);
14         fixnum frame_offset = factor::untag_fixnum(stack->length) - sizeof(stack_frame);
15
16         while(frame_offset >= 0)
17         {
18                 stack_frame *frame = stack->frame_at(frame_offset);
19                 frame_offset -= frame->size;
20                 iterator(frame);
21         }
22 }
23
24 inline void factor_vm::verify_callstack(context *ctx, cell pc)
25 {
26         if (pc == 0)
27         {
28                 std::cout << "null return address" << std::endl;
29                 return;
30         }
31
32         unsigned char *frame_top = (unsigned char*)ctx->callstack_top;
33         cell addr = pc;
34
35         while(frame_top < (unsigned char*)ctx->callstack_bottom)
36         {
37                 std::cout << std::endl;
38                 std::cout << "address " << (void*)addr << std::endl;
39                 code_block *owner = code->code_block_for_address(addr);
40                 std::cout << "owner " << (void*)owner->entry_point() << " ";
41                 print_obj(owner->owner);
42                 std::cout << std::endl;
43                 cell frame_size = owner->stack_frame_size_for_address(addr);
44                 std::cout << "frame size " << (void*)frame_size << std::endl;
45                 frame_top += frame_size;
46                 stack_frame *frame = (stack_frame*)frame_top - 1;
47                 if (owner->entry_point() != frame->entry_point)
48                 {
49                         std::cout << "unexpected frame owner " << (void*)frame->entry_point << " ";
50                         print_obj(((code_block*)frame->entry_point - 1)->owner);
51                         std::cout << std::endl;
52                 }
53                 if (frame_size != frame->size)
54                         std::cout << "unexpected frame size " << frame->size << std::endl;
55                 // XXX x86
56                 addr = *(cell*)frame_top;
57         }
58 }
59
60 inline void factor_vm::verify_callstack(context *ctx)
61 {
62         /*
63         std::cout << std::endl << std::endl
64                 << "callstack " << (void*)ctx->callstack_top
65                 << " to " << (void*)ctx->callstack_bottom << std::endl;
66
67         // XXX x86-centric
68         cell return_address = *((cell*)ctx->callstack_top);
69         verify_callstack(ctx, return_address);
70         */
71 }
72
73 template<typename Iterator> void factor_vm::iterate_callstack(context *ctx, Iterator &iterator)
74 {
75         stack_frame *frame = ctx->callstack_bottom - 1;
76
77         while(frame >= ctx->callstack_top)
78         {
79                 iterator(frame);
80                 frame = frame_successor(frame);
81         }
82 }
83
84 }