Hi,
JIT is currently broken on x86 Windows using optimized Visual C++ builds.
Here's the reason why. Hopefully someone more familiar with the JIT can
pick this up.
...
04e45c9a 68f06fe604 push 4E66FF0h
04e45c9f e8370a1c0b call _Parrot_set_returns_pc
04e45ca4 83c404 add esp,4
04e45ca7 68f86fe604 push 4E66FF8h
04e45cac e8e6481c0b call _Parrot_returncc
04e45cb1 83c404 add esp,4
...
Both functions(C<Parrot_set_returns_pc> and C<Parrot_returncc>) take
C<opcode_t *cur_opcode, Parrot_Interp interp> as arguments.
The stack top contains a pointer to the interpreter, C<4E66FF0h> and
C<4E66FF8h> are pointers to the opcodes.
As you can see, the code is heavily optimized. The pointer to the
interpreter is kept on the stack as it should stay the same, only the
opcode is exchanged. *should* is the key word here.
Visual C++ seems to optimize quite heavily, and it looks like it reuses
the memory on the stack where arguments are passed for local variables.
libparrot!Parrot_set_returns_pc:
push ebp
mov ebp,esp
At this point, the stack looks like so.
* stack frame pointer save (ebp+0h)
* return address (ebp+4h)
* cur_opcode (ebp+8h)
* interp (ebp+Ch)
mov eax,dword ptr [ebp+0Ch]
mov ecx,dword ptr [eax]
ecx now contains interp.
push esi
mov esi,dword ptr [ebp+8]
mov edx,dword ptr [esi+4]
push edi
mov edi,dword ptr [ecx+58h]
mov edx,dword ptr [edi+edx*4]
mov edx,dword ptr [edx+8]
mov dword ptr [eax+0E8h],esi
mov edi,dword ptr [ecx+3Ch]
mov dword ptr [ebp+0Ch],edx
I won't decode above in detail here, but it's the following code.
opcode_t * const _this = CUR_OPCODE;
parrot_context_t *ctx;
PMC *ccont;
PMC *signature = $1;
INTVAL argc;
opcode_t *src_indexes, *dest_indexes;
interp->current_returns = _this;
ctx = CONTEXT(interp->ctx);
ccont = ctx->current_cont;
Notice the last mov. This means ccont reuses the memory previously used
by interp. That's why returncc does not receive the correct interp.
Ron