@@ -1558,7 +1558,7 @@ static void DaoOptimizer_ReduceRegister( DaoOptimizer *self, DaoRoutine *routine
1558
1558
intervals [2 * id + 1 ] = i + 1 ; /* plus one because it is alive at the exit; */
1559
1559
k += 1 ;
1560
1560
}
1561
- if ( vmc -> code == DVM_LOAD || vmc -> code == DVM_CAST ){
1561
+ if ( vmc -> code == DVM_LOAD || vmc -> code == DVM_CAST || vmc -> code == DVM_UNTAG ){
1562
1562
/* These opcodes may create a reference (alias) of ::a at the result register (::c),
1563
1563
// the liveness interval of ::a must be expanded to the point where ::c is used: */
1564
1564
for (j = i + 1 ; j < N ; ++ j ){
@@ -2708,10 +2708,9 @@ static DaoInode* DaoInferencer_InsertMove( DaoInferencer *self, DaoInode *inode,
2708
2708
* op = move -> c ;
2709
2709
return move ;
2710
2710
}
2711
- static DaoInode * DaoInferencer_InsertCast ( DaoInferencer * self , DaoInode * inode , unsigned short * op , DaoType * ct )
2711
+ static DaoInode * DaoInferencer_InsertUntag ( DaoInferencer * self , DaoInode * inode , unsigned short * op , DaoType * ct )
2712
2712
{
2713
- DaoInode * cast = DaoInferencer_InsertNode ( self , inode , DVM_CAST , 1 , ct );
2714
- cast -> b = DaoRoutine_AddConstant ( self -> routine , (DaoValue * ) ct );
2713
+ DaoInode * cast = DaoInferencer_InsertNode ( self , inode , DVM_UNTAG , 1 , ct );
2715
2714
cast -> a = * op ;
2716
2715
* op = cast -> c ;
2717
2716
return cast ;
@@ -5250,7 +5249,7 @@ int DaoInferencer_DoInference( DaoInferencer *self )
5250
5249
case DAO_CODE_MOVE :
5251
5250
if ( code == DVM_LOAD ){
5252
5251
tt = DaoType_GetAutoCastType ( at );
5253
- if ( tt != NULL ) DaoInferencer_InsertCast ( self , inode , & inode -> a , tt );
5252
+ if ( tt != NULL ) DaoInferencer_InsertUntag ( self , inode , & inode -> a , tt );
5254
5253
}
5255
5254
break ;
5256
5255
case DAO_CODE_GETF :
@@ -5260,24 +5259,24 @@ int DaoInferencer_DoInference( DaoInferencer *self )
5260
5259
case DAO_CODE_ENUM2 :
5261
5260
case DAO_CODE_CALL :
5262
5261
tt = DaoType_GetAutoCastType ( at );
5263
- if ( tt != NULL ) DaoInferencer_InsertCast ( self , inode , & inode -> a , tt );
5262
+ if ( tt != NULL ) DaoInferencer_InsertUntag ( self , inode , & inode -> a , tt );
5264
5263
break ;
5265
5264
case DAO_CODE_UNARY2 :
5266
5265
tt = DaoType_GetAutoCastType ( bt );
5267
- if ( tt != NULL ) DaoInferencer_InsertCast ( self , inode , & inode -> b , tt );
5266
+ if ( tt != NULL ) DaoInferencer_InsertUntag ( self , inode , & inode -> b , tt );
5268
5267
break ;
5269
5268
case DAO_CODE_SETF :
5270
5269
case DAO_CODE_SETI :
5271
5270
case DAO_CODE_SETM :
5272
5271
tt = DaoType_GetAutoCastType ( ct );
5273
- if ( tt != NULL ) DaoInferencer_InsertCast ( self , inode , & inode -> c , tt );
5272
+ if ( tt != NULL ) DaoInferencer_InsertUntag ( self , inode , & inode -> c , tt );
5274
5273
break ;
5275
5274
case DAO_CODE_BINARY :
5276
5275
if ( code == DVM_EQ || code == DVM_NE ) break ;
5277
5276
tt = DaoType_GetAutoCastType ( at );
5278
- if ( tt != NULL ) DaoInferencer_InsertCast ( self , inode , & inode -> a , tt );
5277
+ if ( tt != NULL ) DaoInferencer_InsertUntag ( self , inode , & inode -> a , tt );
5279
5278
tt = DaoType_GetAutoCastType ( bt );
5280
- if ( tt != NULL ) DaoInferencer_InsertCast ( self , inode , & inode -> b , tt );
5279
+ if ( tt != NULL ) DaoInferencer_InsertUntag ( self , inode , & inode -> b , tt );
5281
5280
break ;
5282
5281
}
5283
5282
if ( self -> inodes -> size != N ){
@@ -5418,9 +5417,6 @@ int DaoInferencer_DoInference( DaoInferencer *self )
5418
5417
}
5419
5418
vmc -> code = DVM_SETVH_BB + type2 [0 ]-> tid - DAO_BOOLEAN ;
5420
5419
vmc -> code += K * (code - DVM_SETVH );
5421
- }else if ( k == DAO_MT_SUB ){
5422
- /* global L = { 1.5, 2.5 }; L = { 1, 2 }; L[0] = 3.5 */
5423
- DaoInferencer_InsertCast ( self , inode , & inode -> a , * type2 );
5424
5420
}
5425
5421
break ;
5426
5422
case DVM_GETI :
@@ -5572,8 +5568,6 @@ int DaoInferencer_DoInference( DaoInferencer *self )
5572
5568
5573
5569
if ( k == DAO_MT_SUB && at != ct ){
5574
5570
/* L = { 1.5, 2.5 }; L = { 1, 2 }; L[0] = 3.5 */
5575
- vmc -> code = DVM_CAST ;
5576
- vmc -> b = DaoRoutine_AddConstant ( self -> routine , (DaoValue * ) types [opc ] );
5577
5571
if ( at -> tid && at -> tid <= DAO_COMPLEX && types [opc ]-> tid == DAO_COMPLEX ){
5578
5572
if ( at -> tid < DAO_FLOAT ){
5579
5573
DaoInferencer_InsertMove ( self , inode , & inode -> a , at , dao_type_float );
@@ -5606,6 +5600,12 @@ int DaoInferencer_DoInference( DaoInferencer *self )
5606
5600
}
5607
5601
break ;
5608
5602
}
5603
+ case DVM_UNTAG :
5604
+ tt = DaoType_GetAutoCastType ( at );
5605
+ if ( tt == NULL ) goto ErrorTyping ;
5606
+ DaoInferencer_UpdateType ( self , opc , tt );
5607
+ AssertTypeMatching ( tt , types [opc ], defs );
5608
+ break ;
5609
5609
case DVM_ADD : case DVM_SUB : case DVM_MUL :
5610
5610
case DVM_DIV : case DVM_MOD : case DVM_POW :
5611
5611
if ( DaoInferencer_HandleBinaryArith ( self , inode , defs ) == 0 ) return 0 ;
0 commit comments