@@ -221,12 +221,89 @@ static void emitGCCastGeneric(sljit_compiler* compiler, Instruction* instr)
221
221
if ((srcInfo & (JumpIfCastGeneric ::IsSrcNullable | JumpIfCastGeneric ::IsSrcTagged )) == 0 ) {
222
222
sljit_emit_op1 (compiler , SLJIT_MOV_P , SLJIT_TMP_DEST_REG , 0 , SLJIT_MEM1 (srcReg ), JITFieldAccessor ::objectTypeInfo ());
223
223
if (label != nullptr ) {
224
- label -> jumpFrom (sljit_emit_cmp (compiler , isTestOrCastFail ? SLJIT_NOT_EQUAL : SLJIT_EQUAL , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )), SLJIT_IMM , kind ));
224
+ sljit_s32 type = (genericType == Value ::EqRef ) ? SLJIT_LESS_EQUAL : SLJIT_EQUAL ;
225
+ if (isTestOrCastFail ) {
226
+ type ^= 0x1 ;
227
+ }
228
+ label -> jumpFrom (sljit_emit_cmp (compiler , type , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )), SLJIT_IMM , kind ));
225
229
} else if (!isTestOrCastFail ) {
226
- context -> appendTrapJump (ExecutionContext ::CastFailureError , sljit_emit_cmp (compiler , SLJIT_NOT_EQUAL , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )), SLJIT_IMM , kind ));
230
+ sljit_s32 type = (genericType == Value ::EqRef ) ? SLJIT_GREATER : SLJIT_NOT_EQUAL ;
231
+ context -> appendTrapJump (ExecutionContext ::CastFailureError , sljit_emit_cmp (compiler , type , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )), SLJIT_IMM , kind ));
227
232
} else {
228
- sljit_emit_op2u (compiler , SLJIT_SUB | SLJIT_SET_Z , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )), SLJIT_IMM , kind );
229
- sljit_emit_op_flags (compiler , SLJIT_MOV , args [1 ].arg , args [1 ].argw , SLJIT_EQUAL );
233
+ sljit_s32 type = (genericType == Value ::EqRef ) ? SLJIT_SET_LESS_EQUAL : SLJIT_SET_Z ;
234
+ sljit_emit_op2u (compiler , SLJIT_SUB | type , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )), SLJIT_IMM , kind );
235
+ type = (genericType == Value ::EqRef ) ? SLJIT_LESS_EQUAL : SLJIT_EQUAL ;
236
+ sljit_emit_op_flags (compiler , SLJIT_MOV , args [1 ].arg , args [1 ].argw , type );
237
+ }
238
+ return ;
239
+ }
240
+
241
+ if (genericType == Value ::EqRef ) {
242
+ if ((srcInfo & JumpIfCastGeneric ::IsSrcTagged ) != 0 ) {
243
+ sljit_emit_op2 (compiler , SLJIT_ROTR , SLJIT_TMP_DEST_REG , 0 , srcReg , 0 , SLJIT_IMM , 1 );
244
+ sljit_jump * jump = sljit_emit_cmp (compiler , SLJIT_SIG_LESS_EQUAL , SLJIT_TMP_DEST_REG , 0 , SLJIT_IMM , 0 );
245
+ sljit_emit_op2 (compiler , SLJIT_SHL , SLJIT_TMP_DEST_REG , 0 , SLJIT_TMP_DEST_REG , 0 , SLJIT_IMM , 1 );
246
+
247
+ sljit_emit_op1 (compiler , SLJIT_MOV , SLJIT_TMP_DEST_REG , 0 , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), JITFieldAccessor ::objectTypeInfo ());
248
+ sljit_emit_op2 (compiler , SLJIT_SUB , SLJIT_TMP_DEST_REG , 0 , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )), SLJIT_IMM , kind + 1 );
249
+ sljit_set_label (jump , sljit_emit_label (compiler ));
250
+
251
+ if (label != nullptr ) {
252
+ sljit_s32 type = ((srcInfo & JumpIfCastGeneric ::IsNullable ) == 0 ) ? SLJIT_SIG_LESS : SLJIT_SIG_LESS_EQUAL ;
253
+ if (isTestOrCastFail ) {
254
+ type ^= 0x1 ;
255
+ }
256
+ label -> jumpFrom (sljit_emit_cmp (compiler , type , SLJIT_TMP_DEST_REG , 0 , SLJIT_IMM , 0 ));
257
+ } else if (!isTestOrCastFail ) {
258
+ sljit_s32 type = ((srcInfo & JumpIfCastGeneric ::IsNullable ) == 0 ) ? SLJIT_SIG_GREATER_EQUAL : SLJIT_SIG_GREATER ;
259
+ context -> appendTrapJump (ExecutionContext ::CastFailureError , sljit_emit_cmp (compiler , type , SLJIT_TMP_DEST_REG , 0 , SLJIT_IMM , 0 ));
260
+ } else {
261
+ sljit_s32 type = ((srcInfo & JumpIfCastGeneric ::IsNullable ) == 0 ) ? SLJIT_SET_SIG_LESS : SLJIT_SET_SIG_LESS_EQUAL ;
262
+ sljit_emit_op2u (compiler , SLJIT_SUB | type , SLJIT_TMP_DEST_REG , 0 , SLJIT_IMM , 0 );
263
+ type = ((srcInfo & JumpIfCastGeneric ::IsNullable ) == 0 ) ? SLJIT_SIG_LESS : SLJIT_SIG_LESS_EQUAL ;
264
+ sljit_emit_op_flags (compiler , SLJIT_MOV , args [1 ].arg , args [1 ].argw , type );
265
+ }
266
+ return ;
267
+ }
268
+
269
+ if (srcReg != SLJIT_TMP_DEST_REG && label == nullptr && isTestOrCastFail ) {
270
+ sljit_emit_op1 (compiler , SLJIT_MOV , SLJIT_TMP_DEST_REG , 0 , srcReg , 0 );
271
+ srcReg = SLJIT_TMP_DEST_REG ;
272
+ }
273
+
274
+ sljit_jump * jump = sljit_emit_cmp (compiler , SLJIT_EQUAL , srcReg , 0 , SLJIT_IMM , 0 );
275
+ sljit_emit_op1 (compiler , SLJIT_MOV_P , SLJIT_TMP_DEST_REG , 0 , SLJIT_MEM1 (srcReg ), JITFieldAccessor ::objectTypeInfo ());
276
+
277
+ if (label != nullptr ) {
278
+ label -> jumpFrom (sljit_emit_cmp (compiler , isTestOrCastFail ? SLJIT_GREATER : SLJIT_LESS_EQUAL , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )), SLJIT_IMM , kind ));
279
+ if ((srcInfo & JumpIfCastGeneric ::IsNullable ) != 0 ) {
280
+ isTestOrCastFail = !isTestOrCastFail ;
281
+ }
282
+
283
+ if (isTestOrCastFail ) {
284
+ label -> jumpFrom (jump );
285
+ } else {
286
+ sljit_set_label (jump , sljit_emit_label (compiler ));
287
+ }
288
+ } else if (!isTestOrCastFail ) {
289
+ context -> appendTrapJump (ExecutionContext ::CastFailureError , sljit_emit_cmp (compiler , SLJIT_GREATER , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )), SLJIT_IMM , kind ));
290
+ if ((srcInfo & JumpIfCastGeneric ::IsNullable ) != 0 ) {
291
+ sljit_set_label (jump , sljit_emit_label (compiler ));
292
+ } else {
293
+ context -> appendTrapJump (ExecutionContext ::CastFailureError , jump );
294
+ }
295
+ } else {
296
+ ASSERT (srcReg == SLJIT_TMP_DEST_REG );
297
+ kind ++ ;
298
+ if ((srcInfo & JumpIfCastGeneric ::IsNullable ) != 0 ) {
299
+ sljit_emit_op1 (compiler , SLJIT_MOV_P , SLJIT_TMP_DEST_REG , 0 , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )));
300
+ } else {
301
+ sljit_emit_op2 (compiler , SLJIT_SUB , SLJIT_TMP_DEST_REG , 0 , SLJIT_MEM1 (SLJIT_TMP_DEST_REG ), - static_cast < sljit_sw > (sizeof (sljit_up )), SLJIT_IMM , kind );
302
+ kind = 0 ;
303
+ }
304
+ sljit_set_label (jump , sljit_emit_label (compiler ));
305
+ sljit_emit_op2u (compiler , SLJIT_SUB | SLJIT_SET_SIG_LESS , SLJIT_TMP_DEST_REG , 0 , SLJIT_IMM , kind );
306
+ sljit_emit_op_flags (compiler , SLJIT_MOV , args [1 ].arg , args [1 ].argw , SLJIT_SIG_LESS );
230
307
}
231
308
return ;
232
309
}
0 commit comments