@ -389,6 +389,43 @@ static void *find_field(lua_State *state, int index, const char *mode)
 
		
	
		
			
				    return  p ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				static  int  cur_iter_index ( lua_State  * state ,  int  len ,  int  fidx ,  int  first_idx  =  - 1 )  
		
	
		
			
				{  
		
	
		
			
				    int  rv ; 
 
		
	
		
			
				
 
		
	
		
			
				    if  ( lua_isnil ( state ,  fidx ) ) 
 
		
	
		
			
				        rv  =  first_idx ; 
 
		
	
		
			
				    else 
 
		
	
		
			
				    { 
 
		
	
		
			
				        if  ( lua_isnumber ( state ,  fidx ) ) 
 
		
	
		
			
				            rv  =  lua_tointeger ( state ,  fidx ) ; 
 
		
	
		
			
				        else 
 
		
	
		
			
				        { 
 
		
	
		
			
				            lua_pushvalue ( state ,  fidx ) ; 
 
		
	
		
			
				            lua_rawget ( state ,  UPVAL_FIELDTABLE ) ; 
 
		
	
		
			
				            if  ( ! lua_isnumber ( state ,  - 1 ) ) 
 
		
	
		
			
				                field_error ( state ,  fidx ,  " index not found " ,  " iterate " ) ; 
 
		
	
		
			
				            rv  =  lua_tointeger ( state ,  - 1 ) ; 
 
		
	
		
			
				            lua_pop ( state ,  1 ) ; 
 
		
	
		
			
				        } 
 
		
	
		
			
				
 
		
	
		
			
				        if  ( rv  <  0  | |  rv  > =  len ) 
 
		
	
		
			
				            field_error ( state ,  fidx ,  " index out of bounds " ,  " iterate " ) ; 
 
		
	
		
			
				    } 
 
		
	
		
			
				
 
		
	
		
			
				    return  rv ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				static  void  iter_idx_to_name ( lua_State  * state ,  int  idx )  
		
	
		
			
				{  
		
	
		
			
				    lua_pushvalue ( state ,  idx ) ; 
 
		
	
		
			
				    lua_rawget ( state ,  UPVAL_FIELDTABLE ) ; 
 
		
	
		
			
				    if  ( lua_isnil ( state ,  - 1 ) ) 
 
		
	
		
			
				        lua_pop ( state ,  1 ) ; 
 
		
	
		
			
				    else 
 
		
	
		
			
				        lua_replace ( state ,  idx ) ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				static  uint8_t  * check_method_call ( lua_State  * state ,  int  min_args ,  int  max_args )  
		
	
		
			
				{  
		
	
		
			
				    int  argc  =  lua_gettop ( state ) - 1 ; 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -592,6 +629,24 @@ static int meta_struct_newindex(lua_State *state)
 
		
	
		
			
				    return  0 ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/**
  
		
	
		
			
				 *  Metamethod :  iterator  for  structures . 
 
		
	
		
			
				 */ 
 
		
	
		
			
				static  int  meta_struct_next ( lua_State  * state )  
		
	
		
			
				{  
		
	
		
			
				    if  ( lua_gettop ( state )  <  2 )  lua_pushnil ( state ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    int  len  =  lua_objlen ( state ,  UPVAL_FIELDTABLE ) ; 
 
		
	
		
			
				    int  idx  =  cur_iter_index ( state ,  len + 1 ,  2 ,  0 ) ; 
 
		
	
		
			
				    if  ( idx  = =  len ) 
 
		
	
		
			
				        return  0 ; 
 
		
	
		
			
				
 
		
	
		
			
				    lua_rawgeti ( state ,  UPVAL_FIELDTABLE ,  idx + 1 ) ; 
 
		
	
		
			
				    lua_dup ( state ) ; 
 
		
	
		
			
				    lua_gettable ( state ,  1 ) ; 
 
		
	
		
			
				    return  2 ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/**
  
		
	
		
			
				 *  Metamethod :  __index  for  primitives ,  i . e .  simple  object  references . 
 
		
	
		
			
				 *    Fields  point  to  identity ,  or  NULL  for  metafields . 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -722,6 +777,39 @@ static int meta_container_newindex(lua_State *state)
 
		
	
		
			
				    return  0 ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/**
  
		
	
		
			
				 *  Metamethod :  integer  iterator  for  containers . 
 
		
	
		
			
				 */ 
 
		
	
		
			
				static  int  meta_container_nexti ( lua_State  * state )  
		
	
		
			
				{  
		
	
		
			
				    if  ( lua_gettop ( state )  <  2 )  lua_pushnil ( state ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    uint8_t  * ptr  =  get_object_addr ( state ,  1 ,  2 ,  " iterate " ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    auto  id  =  ( container_identity * ) lua_touserdata ( state ,  UPVAL_CONTAINER_ID ) ; 
 
		
	
		
			
				    int  len  =  id - > lua_item_count ( state ,  ptr ,  container_identity : : COUNT_LEN ) ; 
 
		
	
		
			
				    int  idx  =  cur_iter_index ( state ,  len ,  2 ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    if  ( + + idx  > =  len ) 
 
		
	
		
			
				        return  0 ; 
 
		
	
		
			
				
 
		
	
		
			
				    lua_pushinteger ( state ,  idx ) ; 
 
		
	
		
			
				    id - > lua_item_read ( state ,  2 ,  ptr ,  idx ) ; 
 
		
	
		
			
				    return  2 ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/**
  
		
	
		
			
				 *  Metamethod :  name  iterator  for  containers . 
 
		
	
		
			
				 */ 
 
		
	
		
			
				static  int  meta_container_next ( lua_State  * state )  
		
	
		
			
				{  
		
	
		
			
				    if  ( ! meta_container_nexti ( state ) ) 
 
		
	
		
			
				        return  0 ; 
 
		
	
		
			
				
 
		
	
		
			
				    iter_idx_to_name ( state ,  lua_gettop ( state ) - 1 ) ; 
 
		
	
		
			
				    return  2 ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/**
  
		
	
		
			
				 *  Method :  resize  container 
 
		
	
		
			
				 */ 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -781,6 +869,17 @@ static int meta_bitfield_len(lua_State *state)
 
		
	
		
			
				    return  1 ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				static  void  read_bitfield ( lua_State  * state ,  uint8_t  * ptr ,  bitfield_identity  * id ,  int  idx )  
		
	
		
			
				{  
		
	
		
			
				    int  size  =  id - > getBits ( ) [ idx ] . size ; 
 
		
	
		
			
				
 
		
	
		
			
				    int  value  =  getBitfieldField ( ptr ,  idx ,  size ) ; 
 
		
	
		
			
				    if  ( size  < =  1 ) 
 
		
	
		
			
				        lua_pushboolean ( state ,  value  ! =  0 ) ; 
 
		
	
		
			
				    else 
 
		
	
		
			
				        lua_pushinteger ( state ,  value ) ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/**
  
		
	
		
			
				 *  Metamethod :  __index  for  bitfields . 
 
		
	
		
			
				 */ 
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -803,13 +902,7 @@ static int meta_bitfield_index(lua_State *state)
 
		
	
		
			
				    } 
 
		
	
		
			
				
 
		
	
		
			
				    int  idx  =  check_container_index ( state ,  id - > getNumBits ( ) ,  2 ,  iidx ,  " read " ) ; 
 
		
	
		
			
				    int  size  =  id - > getBits ( ) [ idx ] . size ; 
 
		
	
		
			
				
 
		
	
		
			
				    int  value  =  getBitfieldField ( ptr ,  idx ,  size ) ; 
 
		
	
		
			
				    if  ( size  < =  1 ) 
 
		
	
		
			
				        lua_pushboolean ( state ,  value  ! =  0 ) ; 
 
		
	
		
			
				    else 
 
		
	
		
			
				        lua_pushinteger ( state ,  value ) ; 
 
		
	
		
			
				    read_bitfield ( state ,  ptr ,  id ,  idx ) ; 
 
		
	
		
			
				    return  1 ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -846,6 +939,44 @@ static int meta_bitfield_newindex(lua_State *state)
 
		
	
		
			
				    return  0 ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/**
  
		
	
		
			
				 *  Metamethod :  integer  iterator  for  bitfields . 
 
		
	
		
			
				 */ 
 
		
	
		
			
				static  int  meta_bitfield_nexti ( lua_State  * state )  
		
	
		
			
				{  
		
	
		
			
				    if  ( lua_gettop ( state )  <  2 )  lua_pushnil ( state ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    uint8_t  * ptr  =  get_object_addr ( state ,  1 ,  2 ,  " iterate " ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    auto  id  =  ( bitfield_identity * ) lua_touserdata ( state ,  UPVAL_CONTAINER_ID ) ; 
 
		
	
		
			
				    int  len  =  id - > getNumBits ( ) ; 
 
		
	
		
			
				    int  idx  =  cur_iter_index ( state ,  len ,  2 ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    if  ( idx  <  0 ) 
 
		
	
		
			
				        idx  =  0 ; 
 
		
	
		
			
				    else 
 
		
	
		
			
				        idx  + =  std : : max ( 1 ,  ( int ) id - > getBits ( ) [ idx ] . size ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    if  ( idx  > =  len ) 
 
		
	
		
			
				        return  0 ; 
 
		
	
		
			
				
 
		
	
		
			
				    lua_pushinteger ( state ,  idx ) ; 
 
		
	
		
			
				    read_bitfield ( state ,  ptr ,  id ,  idx ) ; 
 
		
	
		
			
				    return  2 ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/**
  
		
	
		
			
				 *  Metamethod :  name  iterator  for  bitfields . 
 
		
	
		
			
				 */ 
 
		
	
		
			
				static  int  meta_bitfield_next ( lua_State  * state )  
		
	
		
			
				{  
		
	
		
			
				    if  ( ! meta_bitfield_nexti ( state ) ) 
 
		
	
		
			
				        return  0 ; 
 
		
	
		
			
				
 
		
	
		
			
				    iter_idx_to_name ( state ,  lua_gettop ( state ) - 1 ) ; 
 
		
	
		
			
				    return  2 ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/**
  
		
	
		
			
				 *  Metamethod :  __index  for  df . global 
 
		
	
		
			
				 */ 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -906,24 +1037,32 @@ static void AddMethodWrapper(lua_State *state, int meta_idx, int field_idx,
 
		
	
		
			
				/**
  
		
	
		
			
				 *  Add  fields  in  the  array  to  the  UPVAL_FIELDTABLE  candidates  on  the  stack . 
 
		
	
		
			
				 */ 
 
		
	
		
			
				static  void  IndexFields ( lua_State  * state ,  struct_identity  * pstruct )  
		
	
		
			
				static  void  IndexFields ( lua_State  * state ,  int  base ,  struct_identity  * pstruct )  
		
	
		
			
				{  
		
	
		
			
				    // stack: metatable fieldtable
 
 
		
	
		
			
				    if  ( pstruct - > getParent ( ) ) 
 
		
	
		
			
				        IndexFields ( state ,  base ,  pstruct - > getParent ( ) ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    int  base  =  lua_gettop ( state )  -  2 ; 
 
		
	
		
			
				
 
		
	
		
			
				    for  ( struct_identity  * p  =  pstruct ;  p ;  p  =  p - > getParent ( ) ) 
 
		
	
		
			
				    { 
 
		
	
		
			
				        auto  fields  =  p - > getFields ( ) ; 
 
		
	
		
			
				    auto  fields  =  pstruct - > getFields ( ) ; 
 
		
	
		
			
				    if  ( ! fields ) 
 
		
	
		
			
				            continue ; 
 
		
	
		
			
				        return ; 
 
		
	
		
			
				
 
		
	
		
			
				    int  cnt  =  lua_objlen ( state ,  base + 3 ) ;  // field iter table
 
 
		
	
		
			
				
 
		
	
		
			
				    for  ( int  i  =  0 ;  fields [ i ] . mode  ! =  struct_field_info : : END ;  + + i ) 
 
		
	
		
			
				    { 
 
		
	
		
			
				        // Qualify conflicting field names with the type
 
 
		
	
		
			
				        std : : string  name  =  fields [ i ] . name ; 
 
		
	
		
			
				
 
		
	
		
			
				        lua_getfield ( state ,  base + 2 ,  name . c_str ( ) ) ; 
 
		
	
		
			
				        if  ( ! lua_isnil ( state ,  - 1 ) ) 
 
		
	
		
			
				            name  =  pstruct - > getName ( )  +  ( " . "  +  name ) ; 
 
		
	
		
			
				        lua_pop ( state ,  1 ) ; 
 
		
	
		
			
				
 
		
	
		
			
				        // Handle the field
 
 
		
	
		
			
				        switch  ( fields [ i ] . mode ) 
 
		
	
		
			
				        { 
 
		
	
		
			
				        case  struct_field_info : : OBJ_METHOD : 
 
		
	
		
			
				                AddMethodWrapper ( state ,  base + 1 ,  base + 2 ,  fields [ i ] . name , 
 
		
	
		
			
				            AddMethodWrapper ( state ,  base + 1 ,  base + 2 ,  name. c_str ( )  , 
 
		
	
		
			
				                             ( function_identity_base * ) fields [ i ] . type ) ; 
 
		
	
		
			
				            break ; 
 
		
	
		
			
				
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -931,14 +1070,13 @@ static void IndexFields(lua_State *state, struct_identity *pstruct)
 
		
	
		
			
				            break ; 
 
		
	
		
			
				
 
		
	
		
			
				        default : 
 
		
	
		
			
				                lua_pushstring ( state , fields [ i ] . name  ) ; 
 
		
	
		
			
				            AssociateId ( state ,  base + 3 ,  + + cnt ,  name . c_str ( ) ) ; 
 
		
	
		
			
				            lua_pushlightuserdata ( state ,  ( void * ) & fields [ i ] ) ; 
 
		
	
		
			
				                 lua_ raw set( state , base + 2 ) ; 
 
		
	
		
			
				            lua_ setfield ( state ,   base + 2 ,  name . c_str ( ) ) ; 
 
		
	
		
			
				            break ; 
 
		
	
		
			
				        } 
 
		
	
		
			
				    } 
 
		
	
		
			
				}  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				void  LuaWrapper : : IndexStatics ( lua_State  * state ,  int  meta_idx ,  int  ftable_idx ,  struct_identity  * pstruct )  
		
	
		
			
				{  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -976,8 +1114,20 @@ static void MakeFieldMetatable(lua_State *state, struct_identity *pstruct,
 
		
	
		
			
				
 
		
	
		
			
				    MakeMetatable ( state ,  pstruct ,  " struct " ) ;  // meta, fields
 
 
		
	
		
			
				
 
		
	
		
			
				    IndexFields ( state ,  pstruct ) ; 
 
		
	
		
			
				    // Index the fields
 
 
		
	
		
			
				    lua_newtable ( state ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    IndexFields ( state ,  base ,  pstruct ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    // Add the iteration metamethods
 
 
		
	
		
			
				    PushStructMethod ( state ,  base + 1 ,  base + 3 ,  meta_struct_next ) ; 
 
		
	
		
			
				    SetPairsMethod ( state ,  base + 1 ,  " __pairs " ) ; 
 
		
	
		
			
				    lua_pushnil ( state ) ; 
 
		
	
		
			
				    SetPairsMethod ( state ,  base + 1 ,  " __ipairs " ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    lua_setfield ( state ,  base + 1 ,  " _index_table " ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    // Add the indexing metamethods
 
 
		
	
		
			
				    SetStructMethod ( state ,  base + 1 ,  base + 2 ,  reader ,  " __index " ) ; 
 
		
	
		
			
				    SetStructMethod ( state ,  base + 1 ,  base + 2 ,  writer ,  " __newindex " ) ; 
 
		
	
		
			
				
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -995,8 +1145,21 @@ static void MakePrimitiveMetatable(lua_State *state, type_identity *type)
 
		
	
		
			
				
 
		
	
		
			
				    SetPtrMethods ( state ,  base + 1 ,  base + 2 ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    // Index the fields
 
 
		
	
		
			
				    lua_newtable ( state ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    EnableMetaField ( state ,  base + 2 ,  " value " ,  type ) ; 
 
		
	
		
			
				    AssociateId ( state ,  base + 3 ,  1 ,  " value " ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    // Add the iteration metamethods
 
 
		
	
		
			
				    PushStructMethod ( state ,  base + 1 ,  base + 3 ,  meta_struct_next ) ; 
 
		
	
		
			
				    SetPairsMethod ( state ,  base + 1 ,  " __pairs " ) ; 
 
		
	
		
			
				    lua_pushnil ( state ) ; 
 
		
	
		
			
				    SetPairsMethod ( state ,  base + 1 ,  " __ipairs " ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    lua_setfield ( state ,  base + 1 ,  " _index_table " ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    // Add the indexing metamethods
 
 
		
	
		
			
				    SetStructMethod ( state ,  base + 1 ,  base + 2 ,  meta_primitive_index ,  " __index " ) ; 
 
		
	
		
			
				    SetStructMethod ( state ,  base + 1 ,  base + 2 ,  meta_primitive_newindex ,  " __newindex " ) ; 
 
		
	
		
			
				}  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -1048,7 +1211,15 @@ static void MakeContainerMetatable(lua_State *state, container_identity *type,
 
		
	
		
			
				    AddContainerMethodFun ( state ,  base + 1 ,  base + 2 ,  method_container_erase ,  " erase " ,  type ,  item ,  count ) ; 
 
		
	
		
			
				    AddContainerMethodFun ( state ,  base + 1 ,  base + 2 ,  method_container_insert ,  " insert " ,  type ,  item ,  count ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    // push the index table
 
 
		
	
		
			
				    AttachEnumKeys ( state ,  base + 1 ,  base + 2 ,  ienum ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    PushContainerMethod ( state ,  base + 1 ,  base + 3 ,  meta_container_next ,  type ,  item ,  count ) ; 
 
		
	
		
			
				    SetPairsMethod ( state ,  base + 1 ,  " __pairs " ) ; 
 
		
	
		
			
				    PushContainerMethod ( state ,  base + 1 ,  base + 3 ,  meta_container_nexti ,  type ,  item ,  count ) ; 
 
		
	
		
			
				    SetPairsMethod ( state ,  base + 1 ,  " __ipairs " ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    lua_pop ( state ,  1 ) ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/*
  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -1078,6 +1249,13 @@ void bitfield_identity::build_metatable(lua_State *state)
 
		
	
		
			
				
 
		
	
		
			
				    AttachEnumKeys ( state ,  base + 1 ,  base + 2 ,  this ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    PushContainerMethod ( state ,  base + 1 ,  base + 3 ,  meta_bitfield_next ,  this ,  NULL ,  - 1 ) ; 
 
		
	
		
			
				    SetPairsMethod ( state ,  base + 1 ,  " __pairs " ) ; 
 
		
	
		
			
				    PushContainerMethod ( state ,  base + 1 ,  base + 3 ,  meta_bitfield_nexti ,  this ,  NULL ,  - 1 ) ; 
 
		
	
		
			
				    SetPairsMethod ( state ,  base + 1 ,  " __ipairs " ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    lua_pop ( state ,  1 ) ; 
 
		
	
		
			
				
 
		
	
		
			
				    EnableMetaField ( state ,  base + 2 ,  " whole " ,  this ) ; 
 
		
	
		
			
				}