@@ -2757,36 +2757,36 @@ fn compile_table_expr_to(
27572757 }
27582758 }
27592759
2760- // Helper function to encode table size (Lua's int2fb encoding)
2761- fn int2fb ( x : usize ) -> u32 {
2762- if x < 8 {
2763- x as u32
2760+ // Helper function to compute ceil(log2(x)) + 1 for hash size encoding
2761+ // This matches Lua's encoding: rb = (hsize != 0) ? luaO_ceillog2(hsize) + 1 : 0
2762+ fn ceillog2_plus1 ( x : usize ) -> u32 {
2763+ if x == 0 {
2764+ 0
2765+ } else if x == 1 {
2766+ 1
27642767 } else {
2765- let mut e = 0 ;
2766- let mut x = x - 1 ;
2767- while x >= 16 {
2768- x = ( x + 1 ) >> 1 ;
2769- e += 1 ;
2770- }
2771- if x < 8 {
2772- ( ( e + 1 ) << 3 | x) as u32
2773- } else {
2774- ( ( e + 2 ) << 3 | ( x - 8 ) ) as u32
2775- }
2768+ // ceil(log2(x)) = number of bits needed to represent x-1, which is floor(log2(x-1)) + 1
2769+ // For x > 1: ceil(log2(x)) = 32 - (x-1).leading_zeros() for u32
2770+ let bits = usize:: BITS - ( x - 1 ) . leading_zeros ( ) ;
2771+ bits + 1 // +1 as per Lua encoding
27762772 }
27772773 }
27782774
27792775 // Create table with size hints
2780- // NEWTABLE A B C: B = hash size (encoded), C = array size (encoded)
2781- let b_param = int2fb ( hash_count) ;
2782- let c_param = int2fb ( array_count) ;
2776+ // NEWTABLE A B C k: B = log2(hash_size)+1, C = array_size % 256
2777+ // EXTRAARG contains array_size / 256 when k=1
2778+ const MAXARG_C : usize = 255 ;
2779+ let b_param = ceillog2_plus1 ( hash_count) ;
2780+ let extra = array_count / ( MAXARG_C + 1 ) ; // higher bits of array size
2781+ let c_param = ( array_count % ( MAXARG_C + 1 ) ) as u32 ; // lower bits of array size
2782+ let k = if extra > 0 { 1 } else { 0 } ;
27832783 emit (
27842784 c,
2785- Instruction :: encode_abc ( OpCode :: NewTable , reg, b_param, c_param) ,
2785+ Instruction :: encode_abck ( OpCode :: NewTable , reg, b_param, c_param, k ) ,
27862786 ) ;
27872787
2788- // EXTRAARG instruction (always 0 for now, used for extended parameters)
2789- emit ( c, Instruction :: create_ax ( OpCode :: ExtraArg , 0 ) ) ;
2788+ // EXTRAARG instruction for extended array size
2789+ emit ( c, Instruction :: create_ax ( OpCode :: ExtraArg , extra as u32 ) ) ;
27902790
27912791 if fields. is_empty ( ) {
27922792 return Ok ( reg) ;
@@ -2913,8 +2913,8 @@ fn compile_table_expr_to(
29132913 // key is a numeric literal - try SETI optimization
29142914 if !number_token. is_float ( ) {
29152915 let int_value = number_token. get_int_value ( ) ;
2916- // SETI: B field is sB (signed byte) , range -128 to 127
2917- if int_value >= - 128 && int_value <= 127 {
2916+ // SETI: B field is unsigned byte, range 0-255
2917+ if int_value >= 0 && int_value <= 255 {
29182918 // Try to compile value as constant first (for RK optimization)
29192919 let ( value_operand, use_constant) =
29202920 if let Some ( value_expr) = field. get_value_expr ( ) {
@@ -2929,9 +2929,8 @@ fn compile_table_expr_to(
29292929 ( r, false )
29302930 } ;
29312931
2932- // Use SETI: R(A)[sB] := RK(C) where sB is signed byte
2933- // Encode sB: add OFFSET_SB (128)
2934- let encoded_b = ( int_value + 128 ) as u32 ;
2932+ // Use SETI: R(A)[B] := RK(C) where B is unsigned byte
2933+ let encoded_b = int_value as u32 ;
29352934 emit (
29362935 c,
29372936 Instruction :: create_abck (
@@ -2964,8 +2963,8 @@ fn compile_table_expr_to(
29642963 LuaIndexKey :: Expr ( key_expr) => {
29652964 // key is an expression - try to evaluate as constant integer for SETI
29662965 if let Some ( int_val) = try_eval_const_int ( & key_expr) {
2967- // SETI: B field is sB (signed byte) , range -128 to 127
2968- if int_val >= - 128 && int_val <= 127 {
2966+ // SETI: B field is unsigned byte, range 0-255
2967+ if int_val >= 0 && int_val <= 255 {
29692968 // Use SETI for small integer keys
29702969 let ( value_operand, use_constant) =
29712970 if let Some ( value_expr) = field. get_value_expr ( ) {
@@ -2980,8 +2979,8 @@ fn compile_table_expr_to(
29802979 ( r, false )
29812980 } ;
29822981
2983- // Encode sB: add OFFSET_SB (128)
2984- let encoded_b = ( int_val + 128 ) as u32 ;
2982+ // B is unsigned byte
2983+ let encoded_b = int_val as u32 ;
29852984 emit (
29862985 c,
29872986 Instruction :: create_abck (
@@ -3128,13 +3127,12 @@ pub fn compile_var_expr(c: &mut Compiler, var: &LuaVarExpr, value_reg: u32) -> R
31283127
31293128 match index_key {
31303129 LuaIndexKey :: Integer ( number_token) => {
3131- // Optimized: table[integer] = value -> SETI A sB C k
3132- // B field is sB (signed byte) , range -128 to 127
3130+ // Optimized: table[integer] = value -> SETI A B C k
3131+ // B field is unsigned byte, range 0-255
31333132 let int_value = number_token. get_int_value ( ) ;
3134- if int_value >= -128 && int_value <= 127 {
3135- // Use SETI: R(A)[sB] := RK(C)
3136- // Encode sB: add OFFSET_SB (128) to get 0-255 range
3137- let encoded_b = ( int_value + 128 ) as u32 ;
3133+ if int_value >= 0 && int_value <= 255 {
3134+ // Use SETI: R(A)[B] := RK(C)
3135+ let encoded_b = int_value as u32 ;
31383136 emit (
31393137 c,
31403138 Instruction :: encode_abc ( OpCode :: SetI , table_reg, encoded_b, value_reg) ,
0 commit comments