move wrapper symbol tables to flash on esp8266; bump to 1600 jsvars

This commit is contained in:
Thorsten von Eicken 2016-04-16 11:57:06 -07:00
parent b365baa8bf
commit 1b4c8c691e
8 changed files with 88 additions and 16 deletions

View File

@ -19,7 +19,7 @@ info = {
'espruino_page_link' : 'EspruinoESP8266',
'default_console' : "EV_SERIAL1",
'default_console_baudrate' : "115200",
'variables' : 1400,
'variables' : 1600,
'binary_name' : 'espruino_%v_esp8266',
'build' : {
'defines' : [

View File

@ -141,14 +141,14 @@ def codeOutSymbolTable(builtin):
if builtin["name"]=="global" and symName in libraries:
continue # don't include libraries on global namespace
if "generate" in sym:
listSymbols.append("{"+", ".join([str(strLen), "(void (*)(void))"+sym["generate"], getArgumentSpecifier(sym)])+"}")
listSymbols.append("{"+", ".join([str(strLen), getArgumentSpecifier(sym), "(void (*)(void))"+sym["generate"]])+"}")
listChars = listChars + symName + "\\0";
strLen = strLen + len(symName) + 1
else:
else:
print (codeName + "." + symName+" not included in Symbol Table because no 'generate'")
builtin["symbolTableChars"] = "\""+listChars+"\"";
builtin["symbolTableCount"] = str(len(listSymbols));
codeOut("static const JswSymPtr jswSymbols_"+codeName+"[] = {\n "+",\n ".join(listSymbols)+"\n};");
codeOut("static const JswSymPtr jswSymbols_"+codeName+"[] FLASH_SECT = {\n "+",\n ".join(listSymbols)+"\n};");
def codeOutBuiltins(indent, builtin):
codeOut(indent+"jswBinarySearch(&jswSymbolTables["+builtin["indexName"]+"], parent, name);");
@ -239,6 +239,7 @@ codeOut('// --------------------------------------------------------------------
codeOut('');
codeOut("""
#ifndef ESP8266
JsVar *jswBinarySearch(const JswSymList *symbolsPtr, JsVar *parent, const char *name) {
int searchMin = 0;
int searchMax = symbolsPtr->symbolCount-1;
@ -254,14 +255,51 @@ JsVar *jswBinarySearch(const JswSymList *symbolsPtr, JsVar *parent, const char *
if (cmp<0) {
// searchMin is the same
searchMax = idx-1;
} else {
} else {
searchMin = idx+1;
// searchMax is the same
// searchMax is the same
}
}
}
return 0;
}
#else
extern int os_printf_plus();
JsVar *jswBinarySearch(const JswSymList *symbolsPtr, JsVar *parent, const char *name) {
//os_printf_plus("bs%p\\n", symbolsPtr);
int searchMin = 0;
int searchMax = symbolsPtr->symbolCount -1;
while (searchMin <= searchMax) {
int idx = (searchMin+searchMax) >> 1;
const JswSymPtr *sym = &symbolsPtr->symbols[idx];
unsigned short strOffset = READ_FLASH_UINT16(&sym->strOffset);
//os_printf_plus("min=%d max=%d idx=%d sym=%p off=%d=%x\\n", searchMin, searchMax, idx, sym, strOffset, strOffset);
int cmp = flash_strcmp(name, &symbolsPtr->symbolChars[strOffset]);
//char buf[256], c, *b=buf; const char *s=&symbolsPtr->symbolChars[strOffset];
//do { c = READ_FLASH_UINT8(s++); *b++ = c; } while(c!=0);
//os_printf_plus("CMP %s %s = %d\\n", name, buf, cmp);
if (cmp==0) {
unsigned short functionSpec = READ_FLASH_UINT16(&sym->functionSpec);
os_printf_plus("%s found %p: %p %x\\n", name, sym, sym->functionPtr, functionSpec);
if ((functionSpec & JSWAT_EXECUTE_IMMEDIATELY_MASK) == JSWAT_EXECUTE_IMMEDIATELY)
return jsnCallFunction(sym->functionPtr, functionSpec, parent, 0, 0);
return jsvNewNativeFunction(sym->functionPtr, functionSpec);
} else {
if (cmp<0) {
// searchMin is the same
searchMax = idx-1;
} else {
searchMin = idx+1;
// searchMax is the same
}
}
}
os_printf_plus("%s not found\\n", name);
return 0;
}
#endif
""");
codeOut('// -----------------------------------------------------------------------------------------');
@ -301,6 +339,9 @@ for jsondata in jsondatas:
builtins[testCode] = { "name" : builtinName, "className" : className, "isProto" : isProto, "functions" : [] }
builtins[testCode]["functions"].append(jsondata);
# For the ESP8266 we want to put the structures into flash
codeOut("#ifdef ESP8266\n#define FLASH_SECT __attribute__((section(\".irom.literal2\"))) __attribute__((aligned(4)))");
codeOut("#else\n#define FLASH_SECT\n#endif\n");
print("Outputting Symbol Tables")
idx = 0
@ -313,10 +354,14 @@ for b in builtins:
codeOut('');
codeOut('');
codeOut('const JswSymList jswSymbolTables[] = {');
for b in builtins:
builtin = builtins[b]
codeOut(" {"+", ".join(["jswSymbols_"+builtin["name"], builtin["symbolTableCount"], builtin["symbolTableChars"]])+"},");
codeOut("FLASH_STR(jswSymbols_"+builtin["name"]+"_str, " + builtin["symbolTableChars"] +");");
codeOut('');
codeOut('const JswSymList jswSymbolTables[] FLASH_SECT = {');
for b in builtins:
builtin = builtins[b]
codeOut(" {"+", ".join(["jswSymbols_"+builtin["name"], "jswSymbols_"+builtin["name"]+"_str", builtin["symbolTableCount"]])+"},");
codeOut('};');
codeOut('');

View File

@ -394,6 +394,7 @@ char *flash_strncpy(char *dst, const char *src, size_t c) {
uint32_t *s = (uint32_t *)src;
size_t slen = flash_strlen(src);
size_t len = slen > c ? c : slen;
// copy full words from source string
while (len >= 4) {
uint32_t w = *s++;
@ -414,6 +415,19 @@ char *flash_strncpy(char *dst, const char *src, size_t c) {
if (slen < c) *d = 0;
return dst;
}
// Compare a string in memory with a string in flash
int flash_strcmp(const char *mem, const char *flash) {
while (1) {
char m = *mem++;
char c = READ_FLASH_UINT8(flash++);
if (m == 0) return c != 0 ? -1 : 0;
if (c == 0) return 1;
if (c > m) return -1;
if (m > c) return 1;
}
}
#endif
#ifdef FAKE_STDLIB

View File

@ -67,16 +67,23 @@ size_t flash_strlen(const char *str);
/// Copy a string from flash to RAM
char *flash_strncpy(char *dest, const char *source, size_t cap);
/// Compare a string in memory with a string in flash
int flash_strcmp(const char *mem, const char *flash);
/** Read a uint8_t from this pointer, which could be in RAM or Flash.
On ESP8266 you have to read flash in 32 bit chunks, so force a 32 bit read
and extract just the 8 bits we want */
#define READ_FLASH_UINT8(ptr) ({ uint32_t __p = (uint32_t)(char*)(ptr); volatile uint32_t __d = *(uint32_t*)(__p & (uint32_t)~3); ((uint8_t*)&__d)[__p & 3]; })
/** Read a uint16_t from this pointer, assumes that the target is 16-bit aligned. */
#define READ_FLASH_UINT16(ptr) ({ uint32_t __p = (uint32_t)(ptr); volatile uint32_t __d = *(uint32_t*)(__p & (uint32_t)~3); (uint16_t)(__p&2 ? __d>>16 : __d); })
#else
/** Read a uint8_t from this pointer, which could be in RAM or Flash.
On ARM this is just a standard read, it's different on ESP8266 */
#define READ_FLASH_UINT8(ptr) (*(uint8_t*)(ptr))
#define READ_FLASH_UINT16(ptr) (*(uint16_t*)(ptr))
#endif

View File

@ -222,8 +222,14 @@ void jswrap_object_keys_or_property_names_cb(
while (symbols) {
unsigned int i;
for (i=0;i<symbols->symbolCount;i++) {
JsVar *name = jsvNewFromString(&symbols->symbolChars[symbols->symbols[i].strOffset]);
unsigned short symbolCount = READ_FLASH_UINT16(&symbols->symbolCount);
unsigned short strOffset = READ_FLASH_UINT16(&symbols->symbols[i].strOffset);
for (i=0;i<symbolCount;i++) {
char buf[256], *b, c;
const char *s = &symbols->symbolChars[strOffset];
do { c = READ_FLASH_UINT8(s++); *b++ = c; } while(c);
JsVar *name = jsvNewFromString(buf);
//os_printf_plus("OBJ cb %s\n", buf);
callback(data, name);
jsvUnLock(name);
}

View File

@ -61,16 +61,16 @@ typedef enum {
/// Structure for each symbol in the list of built-in symbols
typedef struct {
unsigned short strOffset;
void (*functionPtr)(void);
unsigned short functionSpec; // JsnArgumentType
} PACKED_FLAGS JswSymPtr;
void (*functionPtr)(void);
} JswSymPtr;//PACKED_FLAGS
/// Information for each list of built-in symbols
typedef struct {
const JswSymPtr *symbols;
unsigned char symbolCount;
const char *symbolChars;
} PACKED_FLAGS JswSymList;
uint32_t symbolCount;
} JswSymList;//PACKED_FLAGS
/// Do a binary search of the symbol table list
JsVar *jswBinarySearch(const JswSymList *symbolsPtr, JsVar *parent, const char *name);

View File

@ -202,7 +202,7 @@ SECTIONS
.irom0.text : ALIGN(4)
{
_irom0_text_start = ABSOLUTE(.);
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
*(.irom0.literal .irom.literal .irom.literal2 .irom.text.literal .irom0.text .irom.text)
_irom0_text_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
}

View File

@ -202,7 +202,7 @@ SECTIONS
.irom0.text : ALIGN(4)
{
_irom0_text_start = ABSOLUTE(.);
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
*(.irom0.literal .irom.literal .irom.literal2 .irom.text.literal .irom0.text .irom.text)
_irom0_text_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
}