]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: fix callback heap code on 64-bit Windows
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 4 Apr 2010 21:46:36 +0000 (17:46 -0400)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 4 Apr 2010 21:46:36 +0000 (17:46 -0400)
vm/callbacks.cpp
vm/callbacks.hpp

index fbf36c7ceaf1e9beb7085e2bc756275bad11337a..38479a3cb4fe82cc6ff606acce81a572c66a7ae1 100755 (executable)
@@ -19,7 +19,25 @@ void factor_vm::init_callbacks(cell size)
        callbacks = new callback_heap(size,this);
 }
 
-void callback_heap::store_callback_operand(code_block *stub, cell index, cell value)
+bool callback_heap::setup_seh_p()
+{
+#if defined(WINDOWS) && defined(FACTOR_X86)
+       return true;
+#else
+       return false;
+#endif
+}
+
+bool callback_heap::return_takes_param_p()
+{
+#if defined(FACTOR_X86) || defined(FACTOR_AMD64)
+       return true;
+#else
+       return false;
+#endif
+}
+
+instruction_operand callback_heap::callback_operand(code_block *stub, cell index)
 {
        tagged<array> code_template(parent->special_objects[CALLBACK_STUB]);
 
@@ -33,17 +51,23 @@ void callback_heap::store_callback_operand(code_block *stub, cell index, cell va
                offset);
 
        instruction_operand op(rel,stub,0);
-       op.store_value(value);
+
+       return op;
+}
+
+void callback_heap::store_callback_operand(code_block *stub, cell index)
+{
+       parent->store_external_address(callback_operand(stub,index));
+}
+
+void callback_heap::store_callback_operand(code_block *stub, cell index, cell value)
+{
+       callback_operand(stub,index).store_value(value);
 }
 
 void callback_heap::update(code_block *stub)
 {
-#ifdef WIN32
-       cell index = 2;
-#else
-       cell index = 1;
-#endif
-       store_callback_operand(stub,index,(cell)callback_entry_point(stub));
+       store_callback_operand(stub,setup_seh_p() ? 2 : 1,(cell)callback_entry_point(stub));
        stub->flush_icache();
 }
 
@@ -70,21 +94,23 @@ code_block *callback_heap::add(cell owner, cell return_rewind)
        /* Store VM pointer */
        store_callback_operand(stub,0,(cell)parent);
 
-#ifdef WIN32
-       store_callback_operand(stub,1,(cell)&exception_handler);
-       cell index = 1;
-#else
-       cell index = 0;
-#endif
+       cell index;
+
+       if(setup_seh_p())
+       {
+               store_callback_operand(stub,1);
+               index = 1;
+       }
+       else
+               index = 0;
 
        /* Store VM pointer */
        store_callback_operand(stub,index + 2,(cell)parent);
 
        /* On x86, the RET instruction takes an argument which depends on
        the callback's calling convention */
-#if defined(FACTOR_X86) || defined(FACTOR_AMD64)
-       store_callback_operand(stub,index + 3,return_rewind);
-#endif
+       if(return_takes_param_p())
+               store_callback_operand(stub,index + 3,return_rewind);
 
        update(stub);
 
index 607984ad233c9136c927bdf2c084136c394433e2..a0ab3d6bf965b2ea77527dcdc9781105d89294d3 100644 (file)
@@ -38,6 +38,10 @@ struct callback_heap {
                return w->entry_point;
        }
 
+       bool setup_seh_p();
+       bool return_takes_param_p();
+       instruction_operand callback_operand(code_block *stub, cell index);
+       void store_callback_operand(code_block *stub, cell index);
        void store_callback_operand(code_block *stub, cell index, cell value);
 
        void update(code_block *stub);