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);
}
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);

View 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);