bool WordcodeEmitter::replace(uint32_t old_instr, uint32_t new_words, bool jump_has_been_translated) { // Undo any relative offsets in the last instruction, if that wasn't done by // the commit code. if (isJumpInstruction(O[nextI - 1]) && !jump_has_been_translated) undoRelativeOffsetInJump(); // Catenate unconsumed instructions onto R (it's easier than struggling with // moving instructions across buffer boundaries) uint32_t k = new_words; for ( uint32_t n=old_instr ; n < nextI ; n++ ) { uint32_t len = calculateInstructionWidth(O[n]); S[k] = O[n]; for ( uint32_t j=0 ; j < len ; j++ ) R[k++] = I[n][j]; } // Unlink the last buffer segment if we took everything from it, push it onto // a reserve (there can only ever be one free). We know I[nextI-1] points into the // current buffer, so check if I[0] is between the start of the buffer and // the last instruction. if (!(buffers->data <= I[0] && I[0] <= I[nextI-1])) { spare_buffer = buffers; buffers = buffers->next; spare_buffer->next = NULL; dest_limit = buffers->data + sizeof(buffers->data)/sizeof(buffers->data[0]); buffer_offset -= buffers->entries_used; } dest = I[0]; // Emit the various instructions from new_data, handling branches specially. // // At this point the instance variables state, I, O, nextI, backtrack_stack, // and backtrack_idx are dead, and all the data we need for emitting the // instructions are in S and R. In addition, dest has been rolled back and // points to the address of the first instruction in the peephole window, and // nothing is live in the code buffer beyond that point. It's as if we are // in a context where we're just emitting instructions. // // Consequently, we set state to 0 and start emitting instructions from S/R // normally, calling peep() after each instruction that was not replaced by // the current action. This works without having local copies of S and R // because peephole optimization cannot insert a replacement sequence that is // longer than the matched sequence; so the segments of S and R used by any // recursive match will not affect what we're doing here. Furthermore, 'dest' // is shared between this match and recursive matches, so if a recursive match // shortens the instruction sequence the correct value of dest will be used // when we get back to the present invocation of replace(). // Reset the machine. state = 0; uint32_t i=0; while (i < k) { uintptr_t op = S[i]; uintptr_t width = calculateInstructionWidth(op); CHECK(width); if (isJumpInstruction(op)) { *dest++ = R[i++]; int32_t offset = int32_t(R[i++]); if (offset >= 0) { // Forward jump // Install a new backpatch structure makeAndInsertBackpatch(code_start + offset, uint32_t(buffer_offset + (dest + (width - 1) - buffers->data))); } else { // Backward jump // Compute new jump offset *dest = -int32_t(buffer_offset + (dest + (width - 1) - buffers->data) + offset); dest++; } if (width >= 3) *dest++ = R[i++]; if (width >= 4) *dest++ = R[i++]; AvmAssert(width <= 4); } else { switch (width) { default: AvmAssert(!"Can't happen"); case 1: *dest++ = R[i++]; break; case 2: *dest++ = R[i++]; *dest++ = R[i++]; break; case 3: *dest++ = R[i++]; *dest++ = R[i++]; *dest++ = R[i++]; break; case 5: // OP_debug *dest++ = R[i++]; *dest++ = R[i++]; *dest++ = R[i++]; *dest++ = R[i++]; *dest++ = R[i++]; break; } } if (i-width >= new_words) peep((uint32_t)op, dest-width); } return true; // always }
bool WordcodeEmitter::commit(uint32_t action) { switch (action) { case 1: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] < 4) { S[0] = WOP_getlocal0 + I[0][1]; R[0] = NEW_OPCODE(WOP_getlocal0 + I[0][1]); return replace(1,1); } return false; case 2: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_get2locals; R[0] = NEW_OPCODE(WOP_get2locals); R[1] = (I[1][1] << 16) | I[0][1]; return replace(2,2); } return false; case 3: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] < 1024 && I[1][1] < 1024 && I[2][1] < 1024) { S[0] = WOP_get3locals; R[0] = NEW_OPCODE(WOP_get3locals); R[1] = (I[2][1] << 20) | (I[1][1] << 10) | I[0][1]; return replace(3,2); } return false; case 4: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_getlocal) && I[3][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] < 256 && I[1][1] < 256 && I[2][1] < 256 && I[3][1] < 256) { S[0] = WOP_get4locals; R[0] = NEW_OPCODE(WOP_get4locals); R[1] = (I[3][1] << 24) | (I[2][1] << 16) | (I[1][1] << 8) | I[0][1]; return replace(4,2); } return false; case 5: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_getlocal) && I[3][0] == NEW_OPCODE(WOP_getlocal) && I[4][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] < 64 && I[1][1] < 64 && I[2][1] < 64 && I[3][1] < 64 && I[4][1] < 64) { S[0] = WOP_get5locals; R[0] = NEW_OPCODE(WOP_get5locals); R[1] = (I[4][1] << 24) | (I[3][1] << 18) | (I[2][1] << 12) | (I[1][1] << 6) | I[0][1]; return replace(5,2); } return false; case 6: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_add)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_add_ll; R[0] = NEW_OPCODE(WOP_add_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 7: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_add) && I[3][0] == NEW_OPCODE(WOP_setlocal)); if (I[0][1] < 1024 && I[1][1] < 1024 && I[3][1] < 1024) { S[0] = WOP_add_set_lll; R[0] = NEW_OPCODE(WOP_add_set_lll); R[1] = (I[3][1] << 20) | (I[1][1] << 10) | I[0][1]; return replace(4,2); } return false; case 8: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_subtract)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_subtract_ll; R[0] = NEW_OPCODE(WOP_subtract_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 9: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_multiply)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_multiply_ll; R[0] = NEW_OPCODE(WOP_multiply_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 10: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_divide)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_divide_ll; R[0] = NEW_OPCODE(WOP_divide_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 11: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_modulo)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_modulo_ll; R[0] = NEW_OPCODE(WOP_modulo_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 12: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_bitand)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_bitand_ll; R[0] = NEW_OPCODE(WOP_bitand_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 13: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_bitor)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_bitor_ll; R[0] = NEW_OPCODE(WOP_bitor_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 14: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_bitxor)); if (I[0][1] < 65536 && I[1][1] < 65536) { S[0] = WOP_bitxor_ll; R[0] = NEW_OPCODE(WOP_bitxor_ll); R[1] = (I[1][1] << 16) | I[0][1]; return replace(3,2); } return false; case 15: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_iflt)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_iflt_ll; R[0] = NEW_OPCODE(WOP_iflt_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 16: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifnlt)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifnlt_ll; R[0] = NEW_OPCODE(WOP_ifnlt_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 17: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifle)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifle_ll; R[0] = NEW_OPCODE(WOP_ifle_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 18: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifnle)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifnle_ll; R[0] = NEW_OPCODE(WOP_ifnle_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 19: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifgt)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifgt_ll; R[0] = NEW_OPCODE(WOP_ifgt_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 20: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifngt)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifngt_ll; R[0] = NEW_OPCODE(WOP_ifngt_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 21: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifge)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifge_ll; R[0] = NEW_OPCODE(WOP_ifge_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 22: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifnge)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifnge_ll; R[0] = NEW_OPCODE(WOP_ifnge_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 23: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifeq)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifeq_ll; R[0] = NEW_OPCODE(WOP_ifeq_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 24: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifne)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifne_ll; R[0] = NEW_OPCODE(WOP_ifne_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 25: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifstricteq)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifstricteq_ll; R[0] = NEW_OPCODE(WOP_ifstricteq_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 26: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal) && I[2][0] == NEW_OPCODE(WOP_ifstrictne)); if (I[0][1] < 65536 && I[1][1] < 65536) { undoRelativeOffsetInJump(); S[0] = WOP_ifstrictne_ll; R[0] = NEW_OPCODE(WOP_ifstrictne_ll); R[1] = I[2][1]; R[2] = (I[1][1] << 16) | I[0][1]; return replace(3,3,true); } return false; case 27: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_add)); if (true) { S[0] = WOP_add_lb; R[0] = NEW_OPCODE(WOP_add_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 28: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_subtract)); if (true) { S[0] = WOP_subtract_lb; R[0] = NEW_OPCODE(WOP_subtract_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 29: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_multiply)); if (true) { S[0] = WOP_multiply_lb; R[0] = NEW_OPCODE(WOP_multiply_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 30: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_divide)); if (true) { S[0] = WOP_divide_lb; R[0] = NEW_OPCODE(WOP_divide_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 31: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_bitand)); if (true) { S[0] = WOP_bitand_lb; R[0] = NEW_OPCODE(WOP_bitand_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 32: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_bitor)); if (true) { S[0] = WOP_bitor_lb; R[0] = NEW_OPCODE(WOP_bitor_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 33: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_bitxor)); if (true) { S[0] = WOP_bitxor_lb; R[0] = NEW_OPCODE(WOP_bitxor_lb); R[1] = I[0][1]; R[2] = I[1][1]; return replace(3,3); } return false; case 34: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_iflt)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_iflt_lb; R[0] = NEW_OPCODE(WOP_iflt_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 35: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifnlt)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifnlt_lb; R[0] = NEW_OPCODE(WOP_ifnlt_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 36: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifle)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifle_lb; R[0] = NEW_OPCODE(WOP_ifle_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 37: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifnle)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifnle_lb; R[0] = NEW_OPCODE(WOP_ifnle_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 38: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifgt)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifgt_lb; R[0] = NEW_OPCODE(WOP_ifgt_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 39: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifngt)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifngt_lb; R[0] = NEW_OPCODE(WOP_ifngt_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 40: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifge)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifge_lb; R[0] = NEW_OPCODE(WOP_ifge_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 41: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifnge)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifnge_lb; R[0] = NEW_OPCODE(WOP_ifnge_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 42: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifeq)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifeq_lb; R[0] = NEW_OPCODE(WOP_ifeq_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 43: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifne)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifne_lb; R[0] = NEW_OPCODE(WOP_ifne_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 44: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifstricteq)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifstricteq_lb; R[0] = NEW_OPCODE(WOP_ifstricteq_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 45: AvmAssert(I[0][0] == NEW_OPCODE(WOP_getlocal) && I[1][0] == NEW_OPCODE(WOP_pushbits) && I[2][0] == NEW_OPCODE(WOP_ifstrictne)); if (true) { undoRelativeOffsetInJump(); S[0] = WOP_ifstrictne_lb; R[0] = NEW_OPCODE(WOP_ifstrictne_lb); R[1] = I[2][1]; R[2] = I[0][1]; R[3] = I[1][1]; return replace(3,4,true); } return false; case 46: AvmAssert(I[0][0] == NEW_OPCODE(WOP_setlocal)); if (I[0][1] < 4) { S[0] = WOP_setlocal0 + I[0][1]; R[0] = NEW_OPCODE(WOP_setlocal0 + I[0][1]); return replace(1,1); } return false; case 47: AvmAssert(I[0][0] == NEW_OPCODE(WOP_setlocal) && I[1][0] == NEW_OPCODE(WOP_getlocal)); if (I[0][1] == I[1][1]) { S[0] = WOP_storelocal; R[0] = NEW_OPCODE(WOP_storelocal); R[1] = I[0][1]; return replace(2,2); } return false; case 48: AvmAssert(I[0][0] == NEW_OPCODE(WOP_swap) && I[1][0] == NEW_OPCODE(WOP_pop)); if (true) { S[0] = WOP_swap_pop; R[0] = NEW_OPCODE(WOP_swap_pop); return replace(2,1); } return false; default: AvmAssert(!"Should not happen"); return false; } }