mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
move wrapper symbol tables to flash on esp8266; bump to 1600 jsvars
This commit is contained in:
parent
b365baa8bf
commit
1b4c8c691e
@ -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' : [
|
||||
|
||||
@ -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('');
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user