]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor
authorDoug Coleman <erg@jobim.local>
Thu, 21 May 2009 00:31:23 +0000 (19:31 -0500)
committerDoug Coleman <erg@jobim.local>
Thu, 21 May 2009 00:31:23 +0000 (19:31 -0500)
basis/windows/advapi32/advapi32.factor [changed mode: 0644->0755]
vm/callstack.cpp
vm/callstack.hpp
vm/layouts.hpp

old mode 100644 (file)
new mode 100755 (executable)
index 6e04087..6d80534
@@ -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
index 608a5c39e5c1b0d777408e2b4158ec39b20e3349..39988ae976406eb35033402ea5a336a684ddf3b1 100755 (executable)
@@ -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);
-
-                       return tag_fixnum(quot_code_offset_to_scan(
-                               quot,(cell)(return_addr - quot_xt)));
+                       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)));
+                       }
                }
-       }
-       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)
index d92e5f69e0edd2bb31b3f42d1d8423bf0a43618e..a3cc058e2b63476a4a9bdec4ee983fde53d6ef59 100755 (executable)
@@ -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);
+       }
 }
 
 }
index 3fe89cb5582dbf2a643d7fa6509534c72e88d5e4..7736143c50cf924c9cb921ee84e226843e99e332 100755 (executable)
@@ -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)); }
 };