4 inline static cell callstack_object_size(cell size)
6 return sizeof(callstack) + size;
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>
12 void factor_vm::iterate_callstack_object_reversed(callstack *stack_, Iterator &iterator)
14 data_root<callstack> stack(stack_,this);
15 fixnum frame_length = factor::untag_fixnum(stack->length);
16 fixnum frame_offset = 0;
18 while(frame_offset < frame_length)
20 void *frame_top = stack->frame_top_at(frame_offset);
21 void *addr = frame_return_address(frame_top);
23 code_block *owner = code->code_block_for_address(addr);
24 cell frame_size = owner->stack_frame_size_for_address(addr);
27 // check our derived owner and frame size against the ones stored in the frame
28 // by the function prolog
29 stack_frame *frame = (stack_frame*)((char*)frame_top + frame_size) - 1;
30 FACTOR_ASSERT(owner->entry_point() == frame->entry_point);
31 FACTOR_ASSERT(frame_size == frame->size);
34 iterator(owner, addr);
35 frame_offset += frame_size;
39 template<typename Iterator> void factor_vm::iterate_callstack_object(callstack *stack_, Iterator &iterator)
41 data_root<callstack> stack(stack_,this);
42 fixnum frame_offset = factor::untag_fixnum(stack->length) - sizeof(stack_frame);
44 while(frame_offset >= 0)
46 stack_frame *frame = stack->frame_at(frame_offset);
47 frame_offset -= frame->size;
52 template<typename Iterator>
53 void factor_vm::iterate_callstack_reversed(context *ctx, Iterator &iterator)
55 if (ctx->callstack_top == ctx->callstack_bottom)
58 char *frame_top = (char*)ctx->callstack_top;
60 while (frame_top < (char*)ctx->callstack_bottom)
62 void *addr = frame_return_address((void*)frame_top);
63 FACTOR_ASSERT(addr != 0);
65 code_block *owner = code->code_block_for_address((cell)addr);
66 cell frame_size = owner->stack_frame_size_for_address((cell)addr);
69 // check our derived owner and frame size against the ones stored in the frame
70 // by the function prolog
71 stack_frame *frame = (stack_frame*)(frame_top + frame_size) - 1;
72 FACTOR_ASSERT(owner->entry_point() == frame->entry_point);
73 FACTOR_ASSERT(frame_size == frame->size);
76 frame_top += frame_size;
77 iterator(owner, addr);
81 template<typename Iterator>
82 void factor_vm::iterate_callstack(context *ctx, Iterator &iterator)
84 stack_frame *frame = ctx->callstack_bottom - 1;
86 while(frame >= ctx->callstack_top)
89 frame = frame_successor(frame);