This commit is contained in:
2026-02-19 03:12:58 -06:00
parent ab43ab0d2c
commit 65fa37cc03
7 changed files with 886 additions and 54 deletions

View File

@@ -790,6 +790,50 @@ ${sw("w", "%fp", "%dest", "%r")}
@entry
${sr("a", "%obj_slot")}
${sr("b", "%key_slot")}
%ptag =l and %a, 7
%is_ptr =w ceql %ptag, 1
jnz %is_ptr, @arr_ptr, @fallback
@arr_ptr
%arr_ptr =l and %a, -8
%arr_hdr =l loadl %arr_ptr
@arr_chase
%arr_ty =l and %arr_hdr, 7
%arr_is_fwd =w ceql %arr_ty, 7
jnz %arr_is_fwd, @arr_follow, @arr_chk
@arr_follow
%arr_ptr =l shr %arr_hdr, 3
%arr_hdr =l loadl %arr_ptr
jmp @arr_chase
@arr_chk
%arr_is_array =w ceql %arr_ty, 0
jnz %arr_is_array, @arr_index, @fallback
@arr_index
%idx_tag =l and %b, 1
%idx_is_int =w ceql %idx_tag, 0
jnz %idx_is_int, @idx_ok, @ret_null
@idx_ok
%idx_l =l sar %b, 1
%idx_w =w copy %idx_l
%idx_neg =w csltw %idx_w, 0
jnz %idx_neg, @ret_null, @arr_len
@arr_len
%len_p =l add %arr_ptr, 8
%len_l =l loadl %len_p
%len_w =w copy %len_l
%in =w csltw %idx_w, %len_w
jnz %in, @load, @ret_null
@load
%idx_off_l =l extsw %idx_w
%idx_off_l =l shl %idx_off_l, 3
%vals_p =l add %arr_ptr, 16
%elem_p =l add %vals_p, %idx_off_l
%r =l loadl %elem_p
${sw("w", "%fp", "%dest", "%r")}
ret %fp
@ret_null
${sw("w", "%fp", "%dest", text(qbe.js_null))}
ret %fp
@fallback
%r =l call $cell_rt_load_dynamic(l %ctx, l %a, l %b)
%is_exc =w ceql %r, 15
jnz %is_exc, @exc, @ok
@@ -805,14 +849,49 @@ ${sw("w", "%fp", "%dest", "%r")}
@entry
${sr("a", "%arr_slot")}
${sr("b", "%idx_slot")}
%r =l call $cell_rt_load_index(l %ctx, l %a, l %b)
%is_exc =w ceql %r, 15
jnz %is_exc, @exc, @ok
@ok
%idx_tag =l and %b, 1
%idx_is_int =w ceql %idx_tag, 0
jnz %idx_is_int, @idx_ok, @ret_null
@idx_ok
%idx_l =l sar %b, 1
%idx_w =w copy %idx_l
%idx_neg =w csltw %idx_w, 0
jnz %idx_neg, @ret_null, @arr_init
@arr_init
%ptag =l and %a, 7
%is_ptr =w ceql %ptag, 1
jnz %is_ptr, @arr_ptr_ok, @ret_null
@arr_ptr_ok
%arr_ptr =l and %a, -8
%arr_hdr =l loadl %arr_ptr
@arr_chase
%arr_ty =l and %arr_hdr, 7
%arr_is_fwd =w ceql %arr_ty, 7
jnz %arr_is_fwd, @arr_follow, @arr_chk
@arr_follow
%arr_ptr =l shr %arr_hdr, 3
%arr_hdr =l loadl %arr_ptr
jmp @arr_chase
@arr_chk
%arr_is_array =w ceql %arr_ty, 0
jnz %arr_is_array, @arr_len, @ret_null
@arr_len
%len_p =l add %arr_ptr, 8
%len_l =l loadl %len_p
%len_w =w copy %len_l
%in =w csltw %idx_w, %len_w
jnz %in, @load, @ret_null
@load
%idx_off_l =l extsw %idx_w
%idx_off_l =l shl %idx_off_l, 3
%vals_p =l add %arr_ptr, 16
%elem_p =l add %vals_p, %idx_off_l
%r =l loadl %elem_p
${sw("w", "%fp", "%dest", "%r")}
ret %fp
@exc
ret 0
@ret_null
${sw("w", "%fp", "%dest", text(qbe.js_null))}
ret %fp
}`
// store_field(ctx, fp, obj_slot, val_slot, lit_idx) — no dest write
@@ -834,10 +913,37 @@ ${sr("b", "%val_slot")}
${sr("a", "%obj_slot")}
${sr("b", "%val_slot")}
${sr("c", "%key_slot")}
%ptag =l and %a, 7
%is_ptr =w ceql %ptag, 1
jnz %is_ptr, @arr_ptr, @fallback
@arr_ptr
%arr_ptr =l and %a, -8
%arr_hdr =l loadl %arr_ptr
@arr_chase
%arr_ty =l and %arr_hdr, 7
%arr_is_fwd =w ceql %arr_ty, 7
jnz %arr_is_fwd, @arr_follow, @arr_chk
@arr_follow
%arr_ptr =l shr %arr_hdr, 3
%arr_hdr =l loadl %arr_ptr
jmp @arr_chase
@arr_chk
%arr_is_array =w ceql %arr_ty, 0
jnz %arr_is_array, @arr_key_chk, @fallback
@arr_key_chk
%idx_tag =l and %c, 1
%idx_is_int =w ceql %idx_tag, 0
jnz %idx_is_int, @arr_store, @bad
@arr_store
%fp2 =l call $__store_index_ss(l %ctx, l %fp, l %obj_slot, l %val_slot, l %key_slot)
ret %fp2
@fallback
%ok =w call $cell_rt_store_dynamic(l %ctx, l %b, l %a, l %c)
jnz %ok, @ok, @exc
@ok
ret %fp
@bad
call $cell_rt_disrupt(l %ctx)
@exc
ret 0
}`
@@ -848,10 +954,151 @@ ${sr("c", "%key_slot")}
${sr("a", "%obj_slot")}
${sr("b", "%val_slot")}
${sr("c", "%idx_slot")}
%ok =w call $cell_rt_store_index(l %ctx, l %b, l %a, l %c)
jnz %ok, @ok, @exc
@ok
%idx_tag =l and %c, 1
%idx_is_int =w ceql %idx_tag, 0
jnz %idx_is_int, @idx_ok, @bad
@idx_ok
%idx_l =l sar %c, 1
%idx_w =w copy %idx_l
%idx_neg =w csltw %idx_w, 0
jnz %idx_neg, @bad, @arr_init
@arr_init
%ptag =l and %a, 7
%is_ptr =w ceql %ptag, 1
jnz %is_ptr, @arr_ptr_ok, @bad
@arr_ptr_ok
%arr_val =l copy %a
%arr_ptr =l and %arr_val, -8
%arr_hdr =l loadl %arr_ptr
@arr_chase
%arr_ty =l and %arr_hdr, 7
%arr_is_fwd =w ceql %arr_ty, 7
jnz %arr_is_fwd, @arr_follow, @arr_chk
@arr_follow
%arr_ptr =l shr %arr_hdr, 3
%arr_hdr =l loadl %arr_ptr
jmp @arr_chase
@arr_chk
%arr_is_array =w ceql %arr_ty, 0
jnz %arr_is_array, @stone_chk, @bad
@stone_chk
%arr_stone =l and %arr_hdr, 8
%arr_is_stone =w cnel %arr_stone, 0
jnz %arr_is_stone, @bad, @lens
@lens
%len_p =l add %arr_ptr, 8
%len_l =l loadl %len_p
%len_w =w copy %len_l
%cap_l =l shr %arr_hdr, 8
%cap_w =w copy %cap_l
%need_grow =w csgew %idx_w, %cap_w
jnz %need_grow, @grow_init, @set_item
@grow_init
%new_cap_w =w copy %cap_w
%cap_zero =w ceqw %new_cap_w, 0
jnz %cap_zero, @grow_cap0, @grow_check
@grow_cap0
%new_cap_w =w copy 2
jmp @grow_check
@grow_loop
%new_cap_w =w shl %new_cap_w, 1
%new_cap_neg =w csltw %new_cap_w, 0
jnz %new_cap_neg, @bad, @grow_check
@grow_check
%need_more =w cslew %new_cap_w, %idx_w
jnz %need_more, @grow_loop, @grow_alloc
@grow_alloc
%new_arr =l call $JS_NewArrayCap(l %ctx, w %new_cap_w)
%new_exc =w ceql %new_arr, 15
jnz %new_exc, @exc, @grow_refresh
@grow_refresh
%fp2 =l call $cell_rt_refresh_fp_checked(l %ctx)
jnz %fp2, @grow_reload, @exc
@grow_reload
%fp =l copy %fp2
${sr("ga", "%obj_slot")}
${sr("gb", "%val_slot")}
${sr("gc", "%idx_slot")}
%a =l copy %ga
%b =l copy %gb
%c =l copy %gc
%arr_val =l copy %a
%arr_ptr =l and %arr_val, -8
%arr_hdr =l loadl %arr_ptr
@grow_arr_chase
%arr_ty =l and %arr_hdr, 7
%arr_is_fwd =w ceql %arr_ty, 7
jnz %arr_is_fwd, @grow_arr_follow, @grow_arr_ok
@grow_arr_follow
%arr_ptr =l shr %arr_hdr, 3
%arr_hdr =l loadl %arr_ptr
jmp @grow_arr_chase
@grow_arr_ok
%grow_arr_is_array =w ceql %arr_ty, 0
jnz %grow_arr_is_array, @grow_arr_type_ok, @bad
@grow_arr_type_ok
%old_cap_l =l shr %arr_hdr, 8
%old_len_p =l add %arr_ptr, 8
%old_len_l =l loadl %old_len_p
%old_len_w =w copy %old_len_l
%new_ptr =l and %new_arr, -8
%old_vals =l add %arr_ptr, 16
%new_vals =l add %new_ptr, 16
%i_w =w copy 0
@copy_cond
%copy_more =w csltw %i_w, %old_len_w
jnz %copy_more, @copy_body, @copy_done
@copy_body
%i_l =l extsw %i_w
%i_off =l shl %i_l, 3
%old_ep =l add %old_vals, %i_off
%new_ep =l add %new_vals, %i_off
%ev =l loadl %old_ep
%ev_is_self =w ceql %ev, %arr_val
jnz %ev_is_self, @copy_self, @copy_store
@copy_self
storel %new_arr, %new_ep
jmp @copy_next
@copy_store
storel %ev, %new_ep
@copy_next
%i_w =w add %i_w, 1
jmp @copy_cond
@copy_done
storel %old_len_l, %old_len_p
%old_size =l shl %old_cap_l, 3
%old_size =l add %old_size, 16
%fwd =l shl %new_ptr, 3
%fwd =l or %fwd, 7
storel %fwd, %arr_ptr
%arr_size_p =l add %arr_ptr, 8
storel %old_size, %arr_size_p
%obj_slot_o =l shl %obj_slot, 3
%obj_slot_p =l add %fp2, %obj_slot_o
storel %new_arr, %obj_slot_p
%arr_val =l copy %new_arr
%arr_ptr =l copy %new_ptr
%arr_hdr =l loadl %arr_ptr
%len_p =l add %arr_ptr, 8
storel %old_len_l, %len_p
%len_l =l copy %old_len_l
%len_w =w copy %old_len_w
@set_item
%need_len =w csgew %idx_w, %len_w
jnz %need_len, @bump_len, @store_item
@bump_len
%next_len_w =w add %idx_w, 1
%next_len_l =l extsw %next_len_w
storel %next_len_l, %len_p
@store_item
%idx2_l =l extsw %idx_w
%idx2_off =l shl %idx2_l, 3
%vals_p =l add %arr_ptr, 16
%item_p =l add %vals_p, %idx2_off
storel %b, %item_p
ret %fp
@bad
call $cell_rt_disrupt(l %ctx)
@exc
ret 0
}`
@@ -937,12 +1184,133 @@ ${alloc_tail("%r")}
@entry
${sr("a", "%arr_slot")}
${sr("b", "%val_slot")}
%r =l call $cell_rt_push(l %ctx, l %a, l %b)
%ptag =l and %a, 7
%is_ptr =w ceql %ptag, 1
jnz %is_ptr, @arr_init, @bad
@arr_init
%arr_val =l copy %a
%arr_ptr =l and %arr_val, -8
%arr_hdr =l loadl %arr_ptr
@arr_chase
%arr_ty =l and %arr_hdr, 7
%arr_is_fwd =w ceql %arr_ty, 7
jnz %arr_is_fwd, @arr_follow, @arr_ok
@arr_follow
%arr_ptr =l shr %arr_hdr, 3
%arr_hdr =l loadl %arr_ptr
jmp @arr_chase
@arr_ok
%arr_is_array =w ceql %arr_ty, 0
jnz %arr_is_array, @arr_type_ok, @bad
@arr_type_ok
%arr_stone =l and %arr_hdr, 8
%arr_is_stone =w cnel %arr_stone, 0
jnz %arr_is_stone, @bad, @lens
@lens
%len_p =l add %arr_ptr, 8
%len_l =l loadl %len_p
%len_w =w copy %len_l
%cap_l =l shr %arr_hdr, 8
%cap_w =w copy %cap_l
%need_grow =w csgew %len_w, %cap_w
jnz %need_grow, @grow, @store_push
@grow
%new_cap_w =w copy %cap_w
%cap_zero =w ceqw %new_cap_w, 0
jnz %cap_zero, @grow_cap0, @grow_dbl
@grow_cap0
%new_cap_w =w copy 2
jmp @grow_alloc
@grow_dbl
%new_cap_w =w shl %new_cap_w, 1
%new_cap_neg =w csltw %new_cap_w, 0
jnz %new_cap_neg, @bad, @grow_alloc
@grow_alloc
%new_arr =l call $JS_NewArrayCap(l %ctx, w %new_cap_w)
%new_exc =w ceql %new_arr, 15
jnz %new_exc, @exc, @grow_refresh
@grow_refresh
%fp2 =l call $cell_rt_refresh_fp_checked(l %ctx)
jnz %fp2, @ok, @exc
@ok
${sw("w", "%fp2", "%arr_slot", "%r")}
ret %fp2
jnz %fp2, @grow_reload, @exc
@grow_reload
%fp =l copy %fp2
${sr("ga", "%arr_slot")}
${sr("gb", "%val_slot")}
%a =l copy %ga
%b =l copy %gb
%arr_val =l copy %a
%arr_ptr =l and %arr_val, -8
%arr_hdr =l loadl %arr_ptr
@grow_arr_chase
%arr_ty =l and %arr_hdr, 7
%arr_is_fwd =w ceql %arr_ty, 7
jnz %arr_is_fwd, @grow_arr_follow, @grow_arr_ok
@grow_arr_follow
%arr_ptr =l shr %arr_hdr, 3
%arr_hdr =l loadl %arr_ptr
jmp @grow_arr_chase
@grow_arr_ok
%grow_arr_is_array =w ceql %arr_ty, 0
jnz %grow_arr_is_array, @grow_arr_type_ok, @bad
@grow_arr_type_ok
%old_cap_l =l shr %arr_hdr, 8
%old_len_p =l add %arr_ptr, 8
%old_len_l =l loadl %old_len_p
%old_len_w =w copy %old_len_l
%new_ptr =l and %new_arr, -8
%old_vals =l add %arr_ptr, 16
%new_vals =l add %new_ptr, 16
%i_w =w copy 0
@copy_cond
%copy_more =w csltw %i_w, %old_len_w
jnz %copy_more, @copy_body, @copy_done
@copy_body
%i_l =l extsw %i_w
%i_off =l shl %i_l, 3
%old_ep =l add %old_vals, %i_off
%new_ep =l add %new_vals, %i_off
%ev =l loadl %old_ep
%ev_is_self =w ceql %ev, %arr_val
jnz %ev_is_self, @copy_self, @copy_store
@copy_self
storel %new_arr, %new_ep
jmp @copy_next
@copy_store
storel %ev, %new_ep
@copy_next
%i_w =w add %i_w, 1
jmp @copy_cond
@copy_done
storel %old_len_l, %old_len_p
%old_size =l shl %old_cap_l, 3
%old_size =l add %old_size, 16
%fwd =l shl %new_ptr, 3
%fwd =l or %fwd, 7
storel %fwd, %arr_ptr
%arr_size_p =l add %arr_ptr, 8
storel %old_size, %arr_size_p
%arr_slot_o =l shl %arr_slot, 3
%arr_slot_p =l add %fp2, %arr_slot_o
storel %new_arr, %arr_slot_p
%arr_val =l copy %new_arr
%arr_ptr =l copy %new_ptr
%arr_hdr =l loadl %arr_ptr
%len_p =l add %arr_ptr, 8
storel %old_len_l, %len_p
%len_l =l copy %old_len_l
%len_w =w copy %old_len_w
@store_push
%idx_l =l extsw %len_w
%idx_off =l shl %idx_l, 3
%vals_p =l add %arr_ptr, 16
%item_p =l add %vals_p, %idx_off
storel %b, %item_p
%next_len_w =w add %len_w, 1
%next_len_l =l extsw %next_len_w
storel %next_len_l, %len_p
ret %fp
@bad
call $cell_rt_disrupt(l %ctx)
@exc
ret 0
}`
@@ -951,8 +1319,51 @@ ${sw("w", "%fp2", "%arr_slot", "%r")}
h[] = `export function l $__pop_ss(l %ctx, l %fp, l %dest, l %arr_slot) {
@entry
${sr("a", "%arr_slot")}
%r =l call $cell_rt_pop(l %ctx, l %a)
${alloc_tail("%r")}
%ptag =l and %a, 7
%is_ptr =w ceql %ptag, 1
jnz %is_ptr, @arr_init, @bad
@arr_init
%arr_ptr =l and %a, -8
%arr_hdr =l loadl %arr_ptr
@arr_chase
%arr_ty =l and %arr_hdr, 7
%arr_is_fwd =w ceql %arr_ty, 7
jnz %arr_is_fwd, @arr_follow, @arr_ok
@arr_follow
%arr_ptr =l shr %arr_hdr, 3
%arr_hdr =l loadl %arr_ptr
jmp @arr_chase
@arr_ok
%arr_is_array =w ceql %arr_ty, 0
jnz %arr_is_array, @arr_type_ok, @bad
@arr_type_ok
%arr_stone =l and %arr_hdr, 8
%arr_is_stone =w cnel %arr_stone, 0
jnz %arr_is_stone, @bad, @len_chk
@len_chk
%len_p =l add %arr_ptr, 8
%len_l =l loadl %len_p
%len_w =w copy %len_l
%empty =w ceqw %len_w, 0
jnz %empty, @ret_null, @do_pop
@do_pop
%last_w =w sub %len_w, 1
%last_l =l extsw %last_w
%last_off =l shl %last_l, 3
%vals_p =l add %arr_ptr, 16
%item_p =l add %vals_p, %last_off
%r =l loadl %item_p
storel ${text(qbe.js_null)}, %item_p
%new_len_l =l extsw %last_w
storel %new_len_l, %len_p
${sw("w", "%fp", "%dest", "%r")}
ret %fp
@ret_null
${sw("w", "%fp", "%dest", text(qbe.js_null))}
ret %fp
@bad
call $cell_rt_disrupt(l %ctx)
ret 0
}`
// length(ctx, fp, dest, src)