vm: fix callback heap code on 64-bit Windows

release
Slava Pestov 2010-04-04 17:46:36 -04:00
parent cd05b1007d
commit ce16c4ec2c
2 changed files with 47 additions and 17 deletions

View File

@ -19,7 +19,25 @@ void factor_vm::init_callbacks(cell size)
callbacks = new callback_heap(size,this); 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]); 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); offset);
instruction_operand op(rel,stub,0); 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) void callback_heap::update(code_block *stub)
{ {
#ifdef WIN32 store_callback_operand(stub,setup_seh_p() ? 2 : 1,(cell)callback_entry_point(stub));
cell index = 2;
#else
cell index = 1;
#endif
store_callback_operand(stub,index,(cell)callback_entry_point(stub));
stub->flush_icache(); stub->flush_icache();
} }
@ -70,21 +94,23 @@ code_block *callback_heap::add(cell owner, cell return_rewind)
/* Store VM pointer */ /* Store VM pointer */
store_callback_operand(stub,0,(cell)parent); store_callback_operand(stub,0,(cell)parent);
#ifdef WIN32 cell index;
store_callback_operand(stub,1,(cell)&exception_handler);
cell index = 1; if(setup_seh_p())
#else {
cell index = 0; store_callback_operand(stub,1);
#endif index = 1;
}
else
index = 0;
/* Store VM pointer */ /* Store VM pointer */
store_callback_operand(stub,index + 2,(cell)parent); store_callback_operand(stub,index + 2,(cell)parent);
/* On x86, the RET instruction takes an argument which depends on /* On x86, the RET instruction takes an argument which depends on
the callback's calling convention */ the callback's calling convention */
#if defined(FACTOR_X86) || defined(FACTOR_AMD64) if(return_takes_param_p())
store_callback_operand(stub,index + 3,return_rewind); store_callback_operand(stub,index + 3,return_rewind);
#endif
update(stub); update(stub);

View File

@ -38,6 +38,10 @@ struct callback_heap {
return w->entry_point; 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 store_callback_operand(code_block *stub, cell index, cell value);
void update(code_block *stub); void update(code_block *stub);