@@ -5280,9 +5280,8 @@ typedef struct BranchBlock {
5280
5280
BranchBlockPatch * patch_list ;
5281
5281
/* This is used to save params frame_offset of of if block */
5282
5282
int16 * param_frame_offsets ;
5283
- /* This is used to store available param num for if/else branch, so the else
5284
- * opcode can know how many parameters should be copied to the stack */
5285
- uint32 available_param_num ;
5283
+ /* This is used to recover dynamic offset for else branch */
5284
+ uint16 start_dynamic_offset ;
5286
5285
#endif
5287
5286
5288
5287
/* Indicate the operand stack is in polymorphic state.
@@ -7219,18 +7218,15 @@ check_block_stack(WASMLoaderContext *loader_ctx, BranchBlock *block,
7219
7218
* 1) POP original parameter out;
7220
7219
* 2) Push and copy original values to dynamic space.
7221
7220
* The copy instruction format:
7222
- * Part a: available param count
7221
+ * Part a: param count
7223
7222
* Part b: all param total cell num
7224
7223
* Part c: each param's cell_num, src offset and dst offset
7225
7224
* Part d: each param's src offset
7226
7225
* Part e: each param's dst offset
7227
- * Note: if the stack is in polymorphic state, the actual copied parameters may
7228
- * be fewer than the defined number in block type
7229
7226
*/
7230
7227
static bool
7231
7228
copy_params_to_dynamic_space (WASMLoaderContext * loader_ctx , bool is_if_block ,
7232
- uint32 * p_available_param_count , char * error_buf ,
7233
- uint32 error_buf_size )
7229
+ char * error_buf , uint32 error_buf_size )
7234
7230
{
7235
7231
bool ret = false;
7236
7232
int16 * frame_offset = NULL ;
@@ -7242,91 +7238,72 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
7242
7238
BlockType * block_type = & block -> block_type ;
7243
7239
WASMType * wasm_type = block_type -> u .type ;
7244
7240
uint32 param_count = block_type -> u .type -> param_count ;
7245
- uint32 available_param_count = 0 ;
7246
7241
int16 condition_offset = 0 ;
7247
7242
bool disable_emit = false;
7248
7243
int16 operand_offset = 0 ;
7249
- uint64 size ;
7250
-
7251
- if (is_if_block )
7252
- condition_offset = * loader_ctx -> frame_offset ;
7253
-
7254
- /* POP original parameter out */
7255
- for (i = 0 ; i < param_count ; i ++ ) {
7256
- int32 available_stack_cell =
7257
- (int32 )(loader_ctx -> stack_cell_num - block -> stack_cell_num );
7258
-
7259
- if (available_stack_cell <= 0 && block -> is_stack_polymorphic )
7260
- break ;
7261
-
7262
- POP_OFFSET_TYPE (wasm_type -> types [param_count - i - 1 ]);
7263
- wasm_loader_emit_backspace (loader_ctx , sizeof (int16 ));
7264
- }
7265
- available_param_count = i ;
7266
7244
7267
- size =
7268
- ( uint64 ) available_param_count * ( sizeof ( * cells ) + sizeof ( * src_offsets ) );
7245
+ uint64 size = ( uint64 ) param_count * ( sizeof ( * cells ) + sizeof ( * src_offsets ));
7246
+ bh_assert ( size > 0 );
7269
7247
7270
7248
/* For if block, we also need copy the condition operand offset. */
7271
7249
if (is_if_block )
7272
7250
size += sizeof (* cells ) + sizeof (* src_offsets );
7273
7251
7274
7252
/* Allocate memory for the emit data */
7275
- if ((size > 0 )
7276
- && !(emit_data = loader_malloc (size , error_buf , error_buf_size )))
7253
+ if (!(emit_data = loader_malloc (size , error_buf , error_buf_size )))
7277
7254
return false;
7278
7255
7279
7256
cells = emit_data ;
7280
7257
src_offsets = (int16 * )(cells + param_count );
7281
7258
7259
+ if (is_if_block )
7260
+ condition_offset = * loader_ctx -> frame_offset ;
7261
+
7262
+ /* POP original parameter out */
7263
+ for (i = 0 ; i < param_count ; i ++ ) {
7264
+ POP_OFFSET_TYPE (wasm_type -> types [param_count - i - 1 ]);
7265
+ wasm_loader_emit_backspace (loader_ctx , sizeof (int16 ));
7266
+ }
7282
7267
frame_offset = loader_ctx -> frame_offset ;
7283
7268
7284
7269
/* Get each param's cell num and src offset */
7285
- for (i = 0 ; i < available_param_count ; i ++ ) {
7270
+ for (i = 0 ; i < param_count ; i ++ ) {
7286
7271
cell = (uint8 )wasm_value_type_cell_num (wasm_type -> types [i ]);
7287
7272
cells [i ] = cell ;
7288
7273
src_offsets [i ] = * frame_offset ;
7289
7274
frame_offset += cell ;
7290
7275
}
7291
-
7292
7276
/* emit copy instruction */
7293
7277
emit_label (EXT_OP_COPY_STACK_VALUES );
7294
7278
/* Part a) */
7295
- emit_uint32 (loader_ctx , is_if_block ? available_param_count + 1
7296
- : available_param_count );
7279
+ emit_uint32 (loader_ctx , is_if_block ? param_count + 1 : param_count );
7297
7280
/* Part b) */
7298
7281
emit_uint32 (loader_ctx , is_if_block ? wasm_type -> param_cell_num + 1
7299
7282
: wasm_type -> param_cell_num );
7300
7283
/* Part c) */
7301
- for (i = 0 ; i < available_param_count ; i ++ )
7284
+ for (i = 0 ; i < param_count ; i ++ )
7302
7285
emit_byte (loader_ctx , cells [i ]);
7303
7286
if (is_if_block )
7304
7287
emit_byte (loader_ctx , 1 );
7305
7288
7306
7289
/* Part d) */
7307
- for (i = 0 ; i < available_param_count ; i ++ )
7290
+ for (i = 0 ; i < param_count ; i ++ )
7308
7291
emit_operand (loader_ctx , src_offsets [i ]);
7309
7292
if (is_if_block )
7310
7293
emit_operand (loader_ctx , condition_offset );
7311
7294
7312
7295
/* Part e) */
7313
7296
/* Push to dynamic space. The push will emit the dst offset. */
7314
- for (i = 0 ; i < available_param_count ; i ++ )
7297
+ for (i = 0 ; i < param_count ; i ++ )
7315
7298
PUSH_OFFSET_TYPE (wasm_type -> types [i ]);
7316
7299
if (is_if_block )
7317
7300
PUSH_OFFSET_TYPE (VALUE_TYPE_I32 );
7318
7301
7319
- if (p_available_param_count ) {
7320
- * p_available_param_count = available_param_count ;
7321
- }
7322
-
7323
7302
ret = true;
7324
7303
7325
7304
fail :
7326
7305
/* Free the emit data */
7327
- if (emit_data ) {
7328
- wasm_runtime_free (emit_data );
7329
- }
7306
+ wasm_runtime_free (emit_data );
7330
7307
7331
7308
return ret ;
7332
7309
}
@@ -7616,6 +7593,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
7616
7593
7617
7594
BranchBlock * cur_block = loader_ctx -> frame_csp - 1 ;
7618
7595
#if WASM_ENABLE_FAST_INTERP != 0
7596
+ uint32 cell_num ;
7619
7597
available_params = block_type .u .type -> param_count ;
7620
7598
#endif
7621
7599
for (i = 0 ; i < block_type .u .type -> param_count ; i ++ ) {
@@ -7633,6 +7611,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
7633
7611
7634
7612
POP_TYPE (
7635
7613
wasm_type -> types [wasm_type -> param_count - i - 1 ]);
7614
+ #if WASM_ENABLE_FAST_INTERP != 0
7615
+ /* decrease the frame_offset pointer accordingly to keep
7616
+ * consistent with frame_ref stack */
7617
+ cell_num = wasm_value_type_cell_num (
7618
+ wasm_type -> types [wasm_type -> param_count - i - 1 ]);
7619
+ loader_ctx -> frame_offset -= cell_num ;
7620
+ #endif
7636
7621
}
7637
7622
}
7638
7623
PUSH_CSP (LABEL_TYPE_BLOCK + (opcode - WASM_OP_BLOCK ),
@@ -7641,12 +7626,26 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
7641
7626
/* Pass parameters to block */
7642
7627
if (BLOCK_HAS_PARAM (block_type )) {
7643
7628
for (i = 0 ; i < block_type .u .type -> param_count ; i ++ ) {
7644
- PUSH_TYPE (block_type .u .type -> types [i ]);
7645
7629
#if WASM_ENABLE_FAST_INTERP != 0
7630
+ uint32 cell_num = wasm_value_type_cell_num (
7631
+ block_type .u .type -> types [i ]);
7646
7632
if (i >= available_params ) {
7647
- PUSH_OFFSET_TYPE (block_type .u .type -> types [i ]);
7633
+ /* If there isn't enough data on stack, push a dummy
7634
+ * offset to keep the stack consistent with
7635
+ * frame_ref.
7636
+ * Since the stack is already in polymorphic state,
7637
+ * the opcode will not be executed, so the dummy
7638
+ * offset won't cause any error */
7639
+ * loader_ctx -> frame_offset ++ = 0 ;
7640
+ if (cell_num > 1 ) {
7641
+ * loader_ctx -> frame_offset ++ = 0 ;
7642
+ }
7643
+ }
7644
+ else {
7645
+ loader_ctx -> frame_offset += cell_num ;
7648
7646
}
7649
7647
#endif
7648
+ PUSH_TYPE (block_type .u .type -> types [i ]);
7650
7649
}
7651
7650
}
7652
7651
@@ -7656,9 +7655,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
7656
7655
7657
7656
if (BLOCK_HAS_PARAM (block_type )) {
7658
7657
/* Make sure params are in dynamic space */
7659
- if (!copy_params_to_dynamic_space (loader_ctx , false,
7660
- NULL , error_buf ,
7661
- error_buf_size ))
7658
+ if (!copy_params_to_dynamic_space (
7659
+ loader_ctx , false, error_buf , error_buf_size ))
7662
7660
goto fail ;
7663
7661
}
7664
7662
@@ -7691,17 +7689,21 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
7691
7689
* recover them before entering else branch.
7692
7690
*
7693
7691
*/
7694
- if (if_condition_available && BLOCK_HAS_PARAM (block_type )) {
7692
+ if (BLOCK_HAS_PARAM (block_type )) {
7695
7693
uint64 size ;
7696
7694
7697
- /* skip the if condition operand offset */
7698
- wasm_loader_emit_backspace (loader_ctx , sizeof (int16 ));
7695
+ /* In polymorphic state, there may be no if condition on
7696
+ * the stack, so the offset may not emitted */
7697
+ if (if_condition_available ) {
7698
+ /* skip the if condition operand offset */
7699
+ wasm_loader_emit_backspace (loader_ctx ,
7700
+ sizeof (int16 ));
7701
+ }
7699
7702
/* skip the if label */
7700
7703
skip_label ();
7701
7704
/* Emit a copy instruction */
7702
7705
if (!copy_params_to_dynamic_space (
7703
- loader_ctx , true, & block -> available_param_num ,
7704
- error_buf , error_buf_size ))
7706
+ loader_ctx , true, error_buf , error_buf_size ))
7705
7707
goto fail ;
7706
7708
7707
7709
/* Emit the if instruction */
@@ -7722,9 +7724,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
7722
7724
- size / sizeof (int16 ),
7723
7725
(uint32 )size );
7724
7726
}
7725
- else {
7726
- block -> available_param_num = 0 ;
7727
- }
7727
+
7728
+ block -> start_dynamic_offset = loader_ctx -> dynamic_offset ;
7728
7729
7729
7730
emit_empty_label_addr_and_frame_ip (PATCH_ELSE );
7730
7731
emit_empty_label_addr_and_frame_ip (PATCH_END );
@@ -7980,30 +7981,13 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
7980
7981
7981
7982
#if WASM_ENABLE_FAST_INTERP != 0
7982
7983
/* Recover top param_count values of frame_offset stack */
7983
- if (block -> available_param_num ) {
7984
- uint32 available_param_cell_num = 0 ;
7985
-
7986
- /* total cell num of available parameters */
7987
- for (i = 0 ; i < block -> available_param_num ; i ++ ) {
7988
- uint32 cell_num = wasm_value_type_cell_num (
7989
- block -> block_type .u .type -> types [i ]);
7990
-
7991
- /* recover dynamic offset */
7992
- if (block -> param_frame_offsets [available_param_cell_num ]
7993
- >= loader_ctx -> dynamic_offset ) {
7994
- loader_ctx -> dynamic_offset =
7995
- block -> param_frame_offsets
7996
- [available_param_cell_num ]
7997
- + cell_num ;
7998
- }
7999
-
8000
- available_param_cell_num += cell_num ;
8001
- }
8002
-
8003
- bh_memcpy_s (
8004
- loader_ctx -> frame_offset , available_param_cell_num ,
8005
- block -> param_frame_offsets , available_param_cell_num );
8006
- loader_ctx -> frame_offset += available_param_cell_num ;
7984
+ if (BLOCK_HAS_PARAM ((block_type ))) {
7985
+ uint32 size ;
7986
+ size = sizeof (int16 ) * block_type .u .type -> param_cell_num ;
7987
+ bh_memcpy_s (loader_ctx -> frame_offset , size ,
7988
+ block -> param_frame_offsets , size );
7989
+ loader_ctx -> frame_offset += (size / sizeof (int16 ));
7990
+ loader_ctx -> dynamic_offset = block -> start_dynamic_offset ;
8007
7991
}
8008
7992
#endif
8009
7993
0 commit comments