@@ -50,24 +50,28 @@ void luaS_resize (lua_State *L, int newsize) {
unset_resizing_strings_gc(L);
}


static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h) {
unsigned int h, int readonly) {
TString *ts;
stringtable *tb;
if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L);
tb = &G(L)->strt;
if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
luaS_resize(L, tb->size*2); /* too crowded */
ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
ts = cast(TString *, luaM_malloc(L, readonly ? sizeof(char**)+sizeof(TString) : (l+1)*sizeof(char)+sizeof(TString)));
ts->tsv.len = l;
ts->tsv.hash = h;
ts->tsv.marked = luaC_white(G(L));
ts->tsv.tt = LUA_TSTRING;
ts->tsv.reserved = 0;
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
if (!readonly) {
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
} else {
*(char **)(ts+1) = (char *)str;
luaS_readonly(ts);
}
h = lmod(h, tb->size);
ts->tsv.next = tb->hash[h]; /* chain new entry */
tb->hash[h] = obj2gco(ts);
@@ -76,7 +80,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
}


TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, int readonly) {
GCObject *o;
unsigned int h = cast(unsigned int, l); /* seed */
size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
@@ -93,7 +97,35 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
return ts;
}
}
return newlstr(L, str, l, h); /* not found */
return newlstr(L, str, l, h, readonly); /* not found */
}

extern char stext;
extern char etext;

static int lua_is_ptr_in_ro_area(const char *p) {
#ifdef LUA_CROSS_COMPILER
return 0;
#else
return p >= &stext && p <= &etext;
#endif
}

TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
// If the pointer is in a read-only memory and the string is at least 4 chars in length,
// create it as a read-only string instead
if(lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**))
return luaS_newlstr_helper(L, str, l, 1);
else
return luaS_newlstr_helper(L, str, l, 0);
}


LUAI_FUNC TString *luaS_newrolstr (lua_State *L, const char *str, size_t l) {
if(l+1 < sizeof(char**)) // no point in creating a RO string, as it would actually be larger
return luaS_newlstr_helper(L, str, l, 0);
else
return luaS_newlstr_helper(L, str, l, 1);
}


@@ -13,19 +13,22 @@
#include "lstate.h"


#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
#define sizestring(s) (sizeof(union TString)+(luaS_isreadonly(s) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))

#define sizeudata(u) (sizeof(union Udata)+(u)->len)

#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))
#define luaS_newro(L, s) (luaS_newrolstr(L, s, strlen(s)))
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))

#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
#define luaS_readonly(s) l_setbit((s)->tsv.marked, READONLYBIT)
#define luaS_isreadonly(s) testbit((s)->marked, READONLYBIT)

LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);

LUAI_FUNC TString *luaS_newrolstr (lua_State *L, const char *str, size_t l);

#endif
@@ -161,6 +161,7 @@ LUA_API void (lua_pushnil) (lua_State *L);
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
LUA_API void (lua_pushrolstring) (lua_State *L, const char *s, size_t l);
LUA_API void (lua_pushstring) (lua_State *L, const char *s);
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
va_list argp);
@@ -28,6 +28,7 @@ typedef struct {
int swap;
int numsize;
int toflt;
size_t total;
} LoadState;

#ifdef LUAC_TRUST_BINARIES
@@ -51,12 +52,13 @@ static void LoadBlock(LoadState* S, void* b, size_t size)
{
size_t r=luaZ_read(S->Z,b,size);
IF (r!=0, "unexpected end");
S->total+=size;
}

static void LoadMem (LoadState* S, void* b, int n, size_t size)
{
LoadBlock(S,b,n*size);
if (S->swap)
if (S->swap && b)
{
char* p=(char*) b;
char c;
@@ -103,6 +105,12 @@ static int LoadChar(LoadState* S)
return x;
}

static void Align4(LoadState* S)
{
while(S->total&3)
LoadChar(S);
}

static int LoadInt(LoadState* S)
{
int x;
@@ -156,18 +164,31 @@ static TString* LoadString(LoadState* S)
return NULL;
else
{
char* s=luaZ_openspace(S->L,S->b,size);
LoadBlock(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
char* s;
if (!luaZ_direct_mode(S->Z)) {
s = luaZ_openspace(S->L,S->b,size);
LoadBlock(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing zero */
} else {
s = (char*)luaZ_get_crt_address(S->Z);
LoadBlock(S,NULL,size);
return luaS_newrolstr(S->L,s,size-1);
}
}
}

static void LoadCode(LoadState* S, Proto* f)
{
int n=LoadInt(S);
f->code=luaM_newvector(S->L,n,Instruction);
Align4(S);
if (!luaZ_direct_mode(S->Z)) {
f->code=luaM_newvector(S->L,n,Instruction);
LoadVector(S,f->code,n,sizeof(Instruction));
} else {
f->code=(Instruction*)luaZ_get_crt_address(S->Z);
LoadVector(S,NULL,n,sizeof(Instruction));
}
f->sizecode=n;
LoadVector(S,f->code,n,sizeof(Instruction));
}

static Proto* LoadFunction(LoadState* S, TString* p);
@@ -213,9 +234,15 @@ static void LoadDebug(LoadState* S, Proto* f)
{
int i,n;
n=LoadInt(S);
f->lineinfo=luaM_newvector(S->L,n,int);
Align4(S);
if (!luaZ_direct_mode(S->Z)) {
f->lineinfo=luaM_newvector(S->L,n,int);
LoadVector(S,f->lineinfo,n,sizeof(int));
} else {
f->lineinfo=(int*)luaZ_get_crt_address(S->Z);
LoadVector(S,NULL,n,sizeof(int));
}
f->sizelineinfo=n;
LoadVector(S,f->lineinfo,n,sizeof(int));
n=LoadInt(S);
f->locvars=luaM_newvector(S->L,n,LocVar);
f->sizelocvars=n;
@@ -238,6 +265,7 @@ static Proto* LoadFunction(LoadState* S, TString* p)
Proto* f;
if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
f=luaF_newproto(S->L);
if (luaZ_direct_mode(S->Z)) proto_readonly(f);
setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->linedefined=LoadInt(S);
@@ -285,6 +313,7 @@ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
S.Z=Z;
S.b=buff;
LoadHeader(&S);
S.total=0;
return LoadFunction(&S,luaS_newliteral(L,"=?"));
}

@@ -49,7 +49,7 @@ void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
z->L = L;
z->reader = reader;
z->data = data;
z->n = 0;
z->n = z->i = 0;
z->p = NULL;
}

@@ -61,10 +61,13 @@ size_t luaZ_read (ZIO *z, void *b, size_t n) {
if (luaZ_lookahead(z) == EOZ)
return n; /* return number of missing bytes */
m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
memcpy(b, z->p, m);
if (b)
memcpy(b, z->p, m);
z->n -= m;
z->i += m;
z->p += m;
b = (char *)b + m;
if (b)
b = (char *)b + m;
n -= m;
}
return 0;
@@ -42,6 +42,10 @@ typedef struct Mbuffer {

#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)

#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
#define luaZ_get_base_address(zio) ((const char *)((zio)->reader(NULL, (zio)->data, NULL)))
#define luaZ_direct_mode(zio) (luaZ_get_base_address(zio) != NULL)
#define luaZ_get_crt_address(zio) (luaZ_get_base_address(zio) + (zio)->i)

LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
@@ -55,6 +59,7 @@ LUAI_FUNC int luaZ_lookahead (ZIO *z);

struct Zio {
size_t n; /* bytes still unread */
size_t i; /* buffer offset */
const char *p; /* current position in buffer */
lua_Reader reader;
void* data; /* additional data */
@@ -236,7 +236,7 @@ static int mmcfs_closedir_r( struct _reent *r, void *d )
}

// MMC device descriptor structure
static DM_DEVICE mmcfs_device =
static const DM_DEVICE mmcfs_device =
{
"/mmc",
mmcfs_open_r, // open
@@ -246,7 +246,8 @@ static DM_DEVICE mmcfs_device =
mmcfs_lseek_r, // lseek
mmcfs_opendir_r, // opendir
mmcfs_readdir_r, // readdir
mmcfs_closedir_r // closedir
mmcfs_closedir_r, // closedir
NULL // getaddr
};

const DM_DEVICE* mmcfs_init()
@@ -184,3 +184,18 @@ int dm_closedir( DM_DIR *d )
return res;
}

const char* dm_getaddr( int fd )
{
const DM_DEVICE* pdev;

// Find device, check write function
pdev = dm_get_device_at( DM_GET_DEVID( fd ) );
if( !pdev || pdev->p_getaddr_r == NULL )
{
_REENT->_errno = ENOSYS;
return NULL;
}

return pdev->p_getaddr_r( _REENT, DM_GET_FD( fd ) );
}

@@ -142,7 +142,8 @@ static const DM_DEVICE std_device =
NULL, // lseek
NULL, // opendir
NULL, // readdir
NULL // closedir
NULL, // closedir
NULL // getaddr
};

const DM_DEVICE* std_get_desc()
@@ -93,7 +93,8 @@ static const DM_DEVICE std_device =
NULL, // lseek
NULL, // opendir
NULL, // readdir
NULL // closedir
NULL, // closedir
NULL // getaddr
};


@@ -179,7 +179,8 @@ static const DM_DEVICE rfs_device =
rfs_lseek_r, // lseek
rfs_opendir_r, // opendir
rfs_readdir_r, // readdir
rfs_closedir_r // closedir
rfs_closedir_r, // closedir
NULL // getaddr
};

const DM_DEVICE *remotefs_init()
@@ -12,6 +12,7 @@
#ifdef BUILD_ROMFS

#define ROMFS_MAX_FDS 4
#define ROMFS_ALIGN 4
#define fsmin( x , y ) ( ( x ) < ( y ) ? ( x ) : ( y ) )

static FS romfs_fd_table[ ROMFS_MAX_FDS ];
@@ -43,7 +44,7 @@ u8 romfs_open_file( const char* fname, p_read_fs_byte p_read_func, FS* pfs )
{
u32 i, j;
char fsname[ DM_MAX_FNAME_LENGTH + 1 ];
u16 fsize;
u32 fsize;

// Look for the file
i = 0;
@@ -65,17 +66,21 @@ u8 romfs_open_file( const char* fname, p_read_fs_byte p_read_func, FS* pfs )
j = i + j + 1;
// And read the size
fsize = p_read_func( j ) + ( p_read_func( j + 1 ) << 8 );
fsize += ( p_read_func( j + 2 ) << 16 ) + ( p_read_func( j + 3 ) << 24 );
j += 4;
// Round to a multiple of ROMFS_ALIGN
j = ( j + ROMFS_ALIGN - 1 ) & ~( ROMFS_ALIGN - 1 );
if( !strncasecmp( fname, fsname, DM_MAX_FNAME_LENGTH ) )
{
// Found the file
pfs->baseaddr = j + 2;
pfs->baseaddr = j;
pfs->offset = 0;
pfs->size = fsize;
pfs->p_read_func = p_read_func;
return FS_FILE_OK;
}
// Move to next file
i = j + 2 + fsize;
i = j + fsize;
}
return FS_FILE_NOT_FOUND;
}
@@ -181,8 +186,11 @@ static struct dm_dirent* romfs_readdir_r( struct _reent *r, void *d )
while( ( dm_shared_fname[ j ++ ] = romfs_read( off ++ ) ) != '\0' );
pent->fname = dm_shared_fname;
pent->fsize = romfs_read( off ) + ( romfs_read( off + 1 ) << 8 );
pent->fsize += ( romfs_read( off + 2 ) << 16 ) + ( romfs_read( off + 3 ) << 24 );
pent->ftime = 0;
*( u32* )d = off + 2 + pent->fsize;
off += 4;
off = ( off + ROMFS_ALIGN - 1 ) & ~( ROMFS_ALIGN - 1 );
*( u32* )d = off + pent->fsize;
return pent;
}

@@ -193,6 +201,14 @@ static int romfs_closedir_r( struct _reent *r, void *d )
return 0;
}

// getaddr
static const char* romfs_getaddr_r( struct _reent *r, int fd )
{
FS* pfs = romfs_fd_table + fd;

return ( const char* )romfiles_fs + pfs->baseaddr;
}

// Our ROMFS device descriptor structure
static const DM_DEVICE romfs_device =
{
@@ -204,7 +220,8 @@ static const DM_DEVICE romfs_device =
romfs_lseek_r, // lseek
romfs_opendir_r, // opendir
romfs_readdir_r, // readdir
romfs_closedir_r // closedir
romfs_closedir_r, // closedir
romfs_getaddr_r, // getaddr
};

const DM_DEVICE* romfs_init()
@@ -247,7 +247,7 @@ static int semifs_closedir_r( struct _reent *r, void *d )
}

// Semihosting device descriptor structure
static DM_DEVICE semifs_device =
static const DM_DEVICE semifs_device =
{
"/semi",
semifs_open_r, // open
@@ -257,7 +257,8 @@ static DM_DEVICE semifs_device =
semifs_lseek_r, // lseek
semifs_opendir_r, // opendir
semifs_readdir_r, // readdir
semifs_closedir_r // closedir
semifs_closedir_r, // closedir
NULL // getaddr
};

const DM_DEVICE* semifs_init()
@@ -1,4 +1,5 @@
-- A module to convert an entire directory to a C array, in the "romfs" format

module( ..., package.seeall )
require "pack"
local sf = string.format
@@ -9,12 +10,15 @@ local _crtline = ' '
local _numdata = 0
local _bytecnt = 0
local maxlen = 30
local _fcnt = 0
local alignment = 4
local outfile

-- Line output function
local function _add_data( data, outfile, moredata )
if moredata == nil then moredata = true end
_bytecnt = _bytecnt + 1
_fcnt = _fcnt + 1
if moredata then
_crtline = _crtline .. sf( "0x%02X, ", data )
else
@@ -113,19 +117,28 @@ function mkfs( dirname, outname, flist, mode, compcmd )
os.remove( newname )
end
-- Write name, size, id, numpars
_fcnt = 0
for i = 1, #fname do
_add_data( fname:byte( i ), outfile )
end
_add_data( 0, outfile ) -- ASCIIZ
local plen = string.pack( "<h", #filedata )
local plen = string.pack( "<i", #filedata )
_add_data( plen:byte( 1 ), outfile )
_add_data( plen:byte( 2 ), outfile )
_add_data( plen:byte( 3 ), outfile )
_add_data( plen:byte( 4 ), outfile )
-- Round to a multiple of 'alignment'
local actual = #filedata
while _bytecnt % alignment ~= 0 do
_add_data( 0, outfile )
actual = actual + 1
end
-- Then write the rest of the file
for i = 1, #filedata do
_add_data( filedata:byte( i ), outfile )
end
-- Report
print( sf( "Encoded file %s (%d bytes)", fname, #filedata ) )
print( sf( "Encoded file %s (%d bytes real size, %d bytes after rounding, %d bytes total)", fname, #filedata, actual, _fcnt ) )
end
end
end