Merge branch 'master' of git://factorcode.org/git/factor

db4
Doug Coleman 2009-05-20 19:31:23 -05:00
commit dc2791ec45
4 changed files with 46 additions and 30 deletions

3
basis/windows/advapi32/advapi32.factor Normal file → Executable file
View File

@ -1,4 +1,5 @@
USING: alien.syntax kernel math windows.types math.bitwise ;
USING: alien.syntax kernel math windows.types windows.kernel32
math.bitwise ;
IN: windows.advapi32
LIBRARY: advapi32

View File

@ -107,41 +107,43 @@ stack_frame *frame_successor(stack_frame *frame)
/* Allocates memory */
cell frame_scan(stack_frame *frame)
{
if(frame_type(frame) == QUOTATION_TYPE)
switch(frame_type(frame))
{
cell quot = frame_executing(frame);
if(quot == F)
return F;
else
case QUOTATION_TYPE:
{
char *return_addr = (char *)FRAME_RETURN_ADDRESS(frame);
char *quot_xt = (char *)(frame_code(frame) + 1);
cell quot = frame_executing(frame);
if(quot == F)
return F;
else
{
char *return_addr = (char *)FRAME_RETURN_ADDRESS(frame);
char *quot_xt = (char *)(frame_code(frame) + 1);
return tag_fixnum(quot_code_offset_to_scan(
quot,(cell)(return_addr - quot_xt)));
return tag_fixnum(quot_code_offset_to_scan(
quot,(cell)(return_addr - quot_xt)));
}
}
}
else
case WORD_TYPE:
return F;
default:
critical_error("Bad frame type",frame_type(frame));
return F;
}
}
namespace
{
struct stack_frame_counter {
cell count;
stack_frame_counter() : count(0) {}
void operator()(stack_frame *frame) { count += 2; }
};
struct stack_frame_accumulator {
cell index;
gc_root<array> frames;
stack_frame_accumulator(cell count) : index(0), frames(allot_array(count,F)) {}
growable_array frames;
void operator()(stack_frame *frame)
{
set_array_nth(frames.untagged(),index++,frame_executing(frame));
set_array_nth(frames.untagged(),index++,frame_scan(frame));
gc_root<object> executing(frame_executing(frame));
gc_root<object> scan(frame_scan(frame));
frames.add(executing.value());
frames.add(scan.value());
}
};
@ -151,13 +153,11 @@ PRIMITIVE(callstack_to_array)
{
gc_root<callstack> callstack(dpop());
stack_frame_counter counter;
iterate_callstack_object(callstack.untagged(),counter);
stack_frame_accumulator accum(counter.count);
stack_frame_accumulator accum;
iterate_callstack_object(callstack.untagged(),accum);
accum.frames.trim();
dpush(accum.frames.value());
dpush(accum.frames.elements.value());
}
stack_frame *innermost_stack_frame(callstack *stack)

View File

@ -33,9 +33,19 @@ template<typename T> void iterate_callstack(cell top, cell bottom, T &iterator)
}
}
template<typename T> void iterate_callstack_object(callstack *stack, T &iterator)
/* This is a little tricky. The iterator may allocate memory, so we
keep the callstack in a GC root and use relative offsets */
template<typename T> void iterate_callstack_object(callstack *stack_, T &iterator)
{
iterate_callstack((cell)stack->top(),(cell)stack->bottom(),iterator);
gc_root<callstack> stack(stack_);
fixnum frame_offset = untag_fixnum(stack->length) - sizeof(stack_frame);
while(frame_offset >= 0)
{
stack_frame *frame = stack->frame_at(frame_offset);
frame_offset -= frame->size;
iterator(frame);
}
}
}

View File

@ -309,6 +309,11 @@ struct callstack : public object {
/* tagged */
cell length;
stack_frame *frame_at(cell offset)
{
return (stack_frame *)((char *)(this + 1) + offset);
}
stack_frame *top() { return (stack_frame *)(this + 1); }
stack_frame *bottom() { return (stack_frame *)((cell)(this + 1) + untag_fixnum(length)); }
};