]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: a stack underflow inside a primitive could leave a data root in an uninitialized...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sat, 18 Sep 2010 02:20:40 +0000 (19:20 -0700)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sat, 18 Sep 2010 02:46:57 +0000 (19:46 -0700)
vm/callstack.cpp
vm/errors.cpp
vm/vm.hpp

index d5155d2e6ea3c1dd50959ba87b8b84ef35abbe63..5bec7f17cfa0ffe376ba6726767e9fc33bc112dc 100755 (executable)
@@ -137,11 +137,6 @@ void factor_vm::scrub_return_address()
                frame = frame_successor(frame);
 
        set_frame_offset(frame,0);
-
-#ifdef FACTOR_DEBUG
-       /* Doing a GC here triggers all kinds of funny errors */
-       primitive_compact_gc();
-#endif
 }
 
 cell factor_vm::frame_scan(stack_frame *frame)
index 6bd34b8442dc79307a9035643d351e74c3090d03..7c4b0434239588612aa622604903486368155bfc 100755 (executable)
@@ -27,25 +27,35 @@ void out_of_memory()
        exit(1);
 }
 
-void factor_vm::throw_error(cell error)
+void factor_vm::general_error(vm_error_type error, cell arg1, cell arg2)
 {
+       /* Reset local roots before allocating anything */
+       data_roots.clear();
+       bignum_roots.clear();
+       code_roots.clear();
+
+       /* If we had an underflow or overflow, data or retain stack
+       pointers might be out of bounds, so fix them before allocating
+       anything */
+       ctx->fix_stacks();
+
+       /* If error was thrown during heap scan, we re-enable the GC */
+       gc_off = false;
+
        /* If the error handler is set, we rewind any C stack frames and
        pass the error to user-space. */
        if(!current_gc && to_boolean(special_objects[ERROR_HANDLER_QUOT]))
        {
-               /* If error was thrown during heap scan, we re-enable the GC */
-               gc_off = false;
-
-               /* Reset local roots */
-               data_roots.clear();
-               bignum_roots.clear();
-               code_roots.clear();
+#ifdef FACTOR_DEBUG
+               /* Doing a GC here triggers all kinds of funny errors */
+               primitive_compact_gc();
+#endif
 
-               /* If we had an underflow or overflow, data or retain stack
-               pointers might be out of bounds */
-               ctx->fix_stacks();
+               /* Now its safe to allocate and GC */
+               cell error_object = allot_array_4(special_objects[OBJ_ERROR],
+                       tag_fixnum(error),arg1,arg2);
 
-               ctx->push(error);
+               ctx->push(error_object);
 
                unwind_native_frames(special_objects[ERROR_HANDLER_QUOT],
                        ctx->callstack_top);
@@ -55,19 +65,13 @@ void factor_vm::throw_error(cell error)
        else
        {
                std::cout << "You have triggered a bug in Factor. Please report.\n";
-               std::cout << "early_error: ";
-               print_obj(error);
-               std::cout << std::endl;
+               std::cout << "error: " << error << std::endl;
+               std::cout << "arg 1: "; print_obj(arg1); std::cout << std::endl;
+               std::cout << "arg 2: "; print_obj(arg2); std::cout << std::endl;
                factorbug();
        }
 }
 
-void factor_vm::general_error(vm_error_type error, cell arg1, cell arg2)
-{
-       throw_error(allot_array_4(special_objects[OBJ_ERROR],
-               tag_fixnum(error),arg1,arg2));
-}
-
 void factor_vm::type_error(cell type, cell tagged)
 {
        general_error(ERROR_TYPE,tag_fixnum(type),tagged);
index 44ac81a70c554b22e29bfd39f1172fd89b765dba..2cbedbcc7b6fad894a013fc93b2d126bfc733070 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -167,7 +167,6 @@ struct factor_vm
        void primitive_profiling();
 
        // errors
-       void throw_error(cell error);
        void general_error(vm_error_type error, cell arg1, cell arg2);
        void type_error(cell type, cell tagged);
        void not_implemented_error();