mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
If executing from storage, work out line numbers and print filename for Errors
Bangle.js: Don't store line numbers in functions - no need when execing from flash
This commit is contained in:
parent
8ec757da9a
commit
03d147ae1f
@ -54,6 +54,8 @@
|
||||
Bangle.js: Ensure builtin E.show* (and fake LEDs) wake the LCD up
|
||||
Storage check now *only* happens on first boot
|
||||
Ensure __FILE__ is set by the time bootcode runs
|
||||
If executing from storage, work out line numbers and print filename for Errors
|
||||
Bangle.js: Don't store line numbers in functions - no need when execing from flash
|
||||
|
||||
2v10 : Bangle.js: Improved HRM calculations - swapped autocorrelation for bandpass filter
|
||||
Bangle.js: Significantly improved step counting algorithm using bandpass filter (fix #1846)
|
||||
|
||||
@ -136,6 +136,7 @@ This is a partial list of definitions that can be added in a `BOARD.py` file's `
|
||||
* `ESPR_NO_LOADING_SCREEN` - Bangle.js, don't show a 'loading' screen when loading a new app
|
||||
* `ESPR_BOOTLOADER_SPIFLASH` - Allow bootloader to flash direct from a file in SPI flash storage
|
||||
* `ESPR_BANGLE_UNISTROKE` - Build in 'unistroke' touch gesture recognition
|
||||
* `ESPR_NO_LINE_NUMBERS` - disable storing and reporting of Line Numbers. Usually these take 1 var per function, but if we're executing a function from flash we can just work it out from the file when needed
|
||||
|
||||
### chip
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ info = {
|
||||
'DEFINES+=-DDUMP_IGNORE_VARIABLES=\'"g\\0"\'',
|
||||
'DEFINES+=-DUSE_FONT_6X8 -DGRAPHICS_PALETTED_IMAGES -DGRAPHICS_ANTIALIAS',
|
||||
'DEFINES+=-DNO_DUMP_HARDWARE_INITIALISATION', # don't dump hardware init - not used and saves 1k of flash
|
||||
'DEFINES += -DESPR_NO_LINE_NUMBERS=1', # we execute mainly from flash, so line numbers can be worked out
|
||||
'DEFINES+=-DAPP_TIMER_OP_QUEUE_SIZE=6', # Bangle.js accelerometer poll handler needs something else in queue size
|
||||
'DFU_PRIVATE_KEY=targets/nrf5x_dfu/dfu_private_key.pem',
|
||||
'DFU_SETTINGS=--application-version 0xff --hw-version 52 --sd-req 0x8C,0x91',
|
||||
|
||||
@ -54,6 +54,7 @@ info = {
|
||||
'DEFINES+=-DDUMP_IGNORE_VARIABLES=\'"g\\0"\'',
|
||||
'DEFINES+=-DUSE_FONT_6X8 -DGRAPHICS_PALETTED_IMAGES',
|
||||
'DEFINES+=-DNO_DUMP_HARDWARE_INITIALISATION', # don't dump hardware init - not used and saves 1k of flash
|
||||
'DEFINES += -DESPR_NO_LINE_NUMBERS=1', # we execute mainly from flash, so line numbers can be worked out
|
||||
'INCLUDE += -I$(ROOT)/libs/banglejs -I$(ROOT)/libs/misc',
|
||||
'WRAPPERSOURCES += libs/banglejs/jswrap_bangle.c',
|
||||
'WRAPPERSOURCES += libs/graphics/jswrap_font_6x15.c',
|
||||
|
||||
@ -39,6 +39,7 @@ info = {
|
||||
'DEFINES += -DSPIFLASH_BASE=0x8000000 -DSPIFLASH_LENGTH=4194304',
|
||||
# 'DEFINES+=-DCUSTOM_GETBATTERY=jswrap_banglejs_getBattery',
|
||||
'DEFINES+=-DDUMP_IGNORE_VARIABLES=\'"g\\0"\'',
|
||||
'DEFINES += -DESPR_NO_LINE_NUMBERS=1', # we execute mainly from flash, so line numbers can be worked out
|
||||
'DEFINES+=-DUSE_FONT_6X8 -DGRAPHICS_PALETTED_IMAGES -DGRAPHICS_ANTIALIAS',
|
||||
'INCLUDE += -I$(ROOT)/libs/banglejs -I$(ROOT)/libs/misc',
|
||||
'WRAPPERSOURCES += libs/banglejs/jswrap_bangle.c',
|
||||
|
||||
@ -39,6 +39,7 @@ info = {
|
||||
'DEFINES += -DSPIFLASH_BASE=0x8000000 -DSPIFLASH_LENGTH=8388608',
|
||||
# 'DEFINES+=-DCUSTOM_GETBATTERY=jswrap_banglejs_getBattery',
|
||||
'DEFINES+=-DDUMP_IGNORE_VARIABLES=\'"g\\0"\'',
|
||||
'DEFINES += -DESPR_NO_LINE_NUMBERS=1', # we execute mainly from flash, so line numbers can be worked out
|
||||
'DEFINES+=-DUSE_FONT_6X8 -DGRAPHICS_PALETTED_IMAGES',
|
||||
'INCLUDE += -I$(ROOT)/libs/banglejs -I$(ROOT)/libs/misc',
|
||||
'WRAPPERSOURCES += libs/banglejs/jswrap_bangle.c',
|
||||
|
||||
@ -571,6 +571,38 @@ uint32_t jsfFindFile(JsfFileName name, JsfFileHeader *returnedHeader) {
|
||||
return a;
|
||||
}
|
||||
|
||||
static uint32_t jsfBankFindFileFromAddr(uint32_t bankAddress, uint32_t bankEndAddress, uint32_t containsAddr, JsfFileHeader *returnedHeader) {
|
||||
uint32_t addr = bankAddress;
|
||||
JsfFileHeader header;
|
||||
memset(&header,0,sizeof(JsfFileHeader));
|
||||
if (jsfGetFileHeader(addr, &header, false)) do {
|
||||
uint32_t endOfFile = addr + (uint32_t)sizeof(JsfFileHeader) + jsfGetFileSize(&header);
|
||||
if ((header.name.firstChars != 0) && // not been replaced
|
||||
(addr<=containsAddr && containsAddr<=endOfFile)) {
|
||||
// Now load the whole header (with name) and check properly
|
||||
jsfGetFileHeader(addr, &header, true);
|
||||
if (returnedHeader)
|
||||
*returnedHeader = header;
|
||||
return addr+(uint32_t)sizeof(JsfFileHeader);
|
||||
}
|
||||
} while (jsfGetNextFileHeader(&addr, &header, GNFH_GET_ALL|GNFH_READ_ONLY_FILENAME_START)); // still only get first 4 chars of name
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t jsfFindFileFromAddr(uint32_t containsAddr, JsfFileHeader *returnedHeader) {
|
||||
if (containsAddr>=JSF_START_ADDRESS && containsAddr<=JSF_END_ADDRESS) {
|
||||
uint32_t a = jsfBankFindFileFromAddr(JSF_START_ADDRESS, JSF_END_ADDRESS, containsAddr, returnedHeader);
|
||||
if (a) return a;
|
||||
}
|
||||
#ifdef JSF_BANK2_START_ADDRESS
|
||||
if (containsAddr>=JSF_BANK2_START_ADDRESS && containsAddr<=JSF_BANK2_END_ADDRESS) {
|
||||
uint32_t a = jsfBankFindFileFromAddr(JSF_BANK2_START_ADDRESS, JSF_BANK2_END_ADDRESS, containsAddr, returnedHeader);
|
||||
if (a) return a;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jsfBankDebugFiles(uint32_t addr) {
|
||||
uint32_t pageAddr = 0, pageLen = 0, pageEndAddr = 0;
|
||||
|
||||
@ -698,25 +730,14 @@ JsVar *jsfReadFile(JsfFileName name, int offset, int length) {
|
||||
if (length<=0) return jsvNewFromEmptyString();
|
||||
// now increment address by offset
|
||||
addr += (uint32_t)offset;
|
||||
return jsvAddressToVar(addr, (uint32_t)length);
|
||||
}
|
||||
|
||||
JsVar* jsvAddressToVar(size_t addr, uint32_t length) {
|
||||
if (length<=0) return jsvNewFromEmptyString();
|
||||
size_t mappedAddr = jshFlashGetMemMapAddress((size_t)addr);
|
||||
#ifdef SPIFLASH_BASE // if using SPI flash it can't be memory-mapped
|
||||
if (!mappedAddr) {
|
||||
/*JsVar *v = jsvNewStringOfLength(length, NULL);
|
||||
if (v) {
|
||||
JsvStringIterator it;
|
||||
jsvStringIteratorNew(&it, v, 0);
|
||||
while (length && jsvStringIteratorHasChar(&it)) {
|
||||
unsigned char *data;
|
||||
unsigned int l = 0;
|
||||
jsvStringIteratorGetPtrAndNext(&it, &data, &l);
|
||||
jshFlashRead(data, addr, l);
|
||||
addr += l;
|
||||
length -= l;
|
||||
}
|
||||
jsvStringIteratorFree(&it);
|
||||
}
|
||||
return v;*/
|
||||
return jsvNewFlashString((char*)(size_t)addr, (size_t)length);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -53,6 +53,10 @@ uint32_t jsfGetFileSize(JsfFileHeader *header);
|
||||
JsfFileFlags jsfGetFileFlags(JsfFileHeader *header);
|
||||
/// Find a 'file' in the memory store. Return the address of data start (and header if returnedHeader!=0). Returns 0 if not found
|
||||
uint32_t jsfFindFile(JsfFileName name, JsfFileHeader *returnedHeader);
|
||||
/// Find a 'file' in the memory store that contains this address. Return the address of data start (and header if returnedHeader!=0). Returns 0 if not found
|
||||
uint32_t jsfFindFileFromAddr(uint32_t containsAddr, JsfFileHeader *returnedHeader);
|
||||
/// Given an address in memory (or flash) return the correct JsVar to access it
|
||||
JsVar* jsvAddressToVar(size_t addr, uint32_t length);
|
||||
/// Return the contents of a file as a memory mapped var
|
||||
JsVar *jsfReadFile(JsfFileName name, int offset, int length);
|
||||
/// Write a file. For simple stuff just leave offset and size as 0
|
||||
|
||||
@ -2487,9 +2487,12 @@ void jsiDebuggerLoop() {
|
||||
char lineStr[9];
|
||||
// Get a string fo the form '1234 ' for the line number
|
||||
// ... but only if the line number was set, otherwise use spaces
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
if (lex->lineNumberOffset) {
|
||||
itostr((JsVarInt)jslGetLineNumber() + (JsVarInt)lex->lineNumberOffset - 1, lineStr, 10);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
lineStr[0]=0;
|
||||
}
|
||||
size_t lineLen = strlen(lineStr);
|
||||
|
||||
22
src/jslex.c
22
src/jslex.c
@ -12,6 +12,9 @@
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
#include "jslex.h"
|
||||
#ifndef SAVE_ON_FLASH
|
||||
#include "jsflash.h"
|
||||
#endif
|
||||
|
||||
JsLex *lex;
|
||||
|
||||
@ -676,7 +679,9 @@ void jslInit(JsVar *var) {
|
||||
lex->tokenLastStart = 0;
|
||||
lex->tokenl = 0;
|
||||
lex->tokenValue = 0;
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
lex->lineNumberOffset = 0;
|
||||
#endif
|
||||
// set up iterator
|
||||
jsvStringIteratorNew(&lex->it, lex->sourceVar, 0);
|
||||
jsvUnLock(lex->it.var); // see jslGetNextCh
|
||||
@ -1086,9 +1091,26 @@ void jslPrintTokenisedString(JsVar *code, vcbprintf_callback user_callback, void
|
||||
|
||||
void jslPrintPosition(vcbprintf_callback user_callback, void *user_data, size_t tokenPos) {
|
||||
size_t line,col;
|
||||
#ifndef SAVE_ON_FLASH
|
||||
if (jsvIsNativeString(lex->sourceVar) || jsvIsFlashString(lex->sourceVar)) {
|
||||
uint32_t stringAddr = (uint32_t)lex->sourceVar->varData.nativeStr.ptr;
|
||||
JsfFileHeader header;
|
||||
uint32_t fileAddr = jsfFindFileFromAddr(stringAddr, &header);
|
||||
if (fileAddr) {
|
||||
JsVar *fileStr = jsvAddressToVar(fileAddr, jsfGetFileSize(&header));
|
||||
jsvGetLineAndCol(fileStr, tokenPos + stringAddr - fileAddr, &line, &col);
|
||||
JsVar *name = jsfVarFromName(header.name);
|
||||
cbprintf(user_callback, user_data,"line %d col %d in %v\n", line, col, name);
|
||||
jsvUnLock2(fileStr,name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
jsvGetLineAndCol(lex->sourceVar, tokenPos, &line, &col);
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
if (lex->lineNumberOffset)
|
||||
line += (size_t)lex->lineNumberOffset - 1;
|
||||
#endif
|
||||
cbprintf(user_callback, user_data, "line %d col %d\n", line, col);
|
||||
}
|
||||
|
||||
|
||||
@ -125,9 +125,11 @@ typedef struct JsLex
|
||||
JsVar *tokenValue; ///< JsVar containing the current token - used only for strings/regex
|
||||
unsigned char tokenl; ///< the current length of token
|
||||
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
/** Amount we add to the line number when we're reporting to the user
|
||||
* 1-based, so 0 means NO LINE NUMBER KNOWN */
|
||||
uint16_t lineNumberOffset;
|
||||
#endif
|
||||
|
||||
/* Where we get our data from...
|
||||
*
|
||||
|
||||
@ -346,12 +346,14 @@ NO_INLINE bool jspeFunctionDefinitionInternal(JsVar *funcVar, bool expressionOnl
|
||||
JSP_ASSERT_MATCH(LEX_R_RETURN);
|
||||
}
|
||||
}
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
// Get the line number (if needed)
|
||||
JsVarInt lineNumber = 0;
|
||||
if (funcVar && lex->lineNumberOffset && !(forcePretokenise||jsfGetFlag(JSF_PRETOKENISE))) {
|
||||
// jslGetLineNumber is slow, so we only do it if we have debug info
|
||||
lineNumber = (JsVarInt)jslGetLineNumber() + (JsVarInt)lex->lineNumberOffset - 1;
|
||||
}
|
||||
#endif
|
||||
// Get the code - parse it and figure out where it stops
|
||||
JslCharPos funcBegin;
|
||||
jslSkipWhiteSpace();
|
||||
@ -402,6 +404,7 @@ NO_INLINE bool jspeFunctionDefinitionInternal(JsVar *funcVar, bool expressionOnl
|
||||
if (funcScopeVar) {
|
||||
jsvUnLock2(jsvAddNamedChild(funcVar, funcScopeVar, JSPARSE_FUNCTION_SCOPE_NAME), funcScopeVar);
|
||||
}
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
// If we've got a line number, add a var for it
|
||||
if (lineNumber) {
|
||||
JsVar *funcLineNumber = jsvNewFromInteger(lineNumber);
|
||||
@ -409,6 +412,7 @@ NO_INLINE bool jspeFunctionDefinitionInternal(JsVar *funcVar, bool expressionOnl
|
||||
jsvUnLock2(jsvAddNamedChild(funcVar, funcLineNumber, JSPARSE_FUNCTION_LINENUMBER_NAME), funcLineNumber);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
jslCharPosFree(&funcBegin);
|
||||
@ -629,7 +633,9 @@ NO_INLINE JsVar *jspeFunctionCall(JsVar *function, JsVar *functionName, JsVar *t
|
||||
JsVar *functionScope = 0;
|
||||
JsVar *functionCode = 0;
|
||||
JsVar *functionInternalName = 0;
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
uint16_t functionLineNumber = 0;
|
||||
#endif
|
||||
|
||||
/** NOTE: We expect that the function object will have:
|
||||
*
|
||||
@ -695,7 +701,10 @@ NO_INLINE JsVar *jspeFunctionCall(JsVar *function, JsVar *functionName, JsVar *t
|
||||
else if (jsvIsStringEqual(param, JSPARSE_FUNCTION_THIS_NAME)) {
|
||||
jsvUnLock(thisVar);
|
||||
thisVar = jsvSkipName(param);
|
||||
} else if (jsvIsStringEqual(param, JSPARSE_FUNCTION_LINENUMBER_NAME)) functionLineNumber = (uint16_t)jsvGetIntegerAndUnLock(jsvSkipName(param));
|
||||
}
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
else if (jsvIsStringEqual(param, JSPARSE_FUNCTION_LINENUMBER_NAME)) functionLineNumber = (uint16_t)jsvGetIntegerAndUnLock(jsvSkipName(param));
|
||||
#endif
|
||||
else if (jsvIsFunctionParameter(param)) {
|
||||
JsVar *defaultVal = jsvSkipName(param);
|
||||
jsvAddFunctionParameter(functionRoot, jsvNewFromStringVar(param,1,JSVAPPENDSTRINGVAR_MAXLENGTH), defaultVal);
|
||||
@ -759,7 +768,9 @@ NO_INLINE JsVar *jspeFunctionCall(JsVar *function, JsVar *functionName, JsVar *t
|
||||
JsLex newLex;
|
||||
JsLex *oldLex = jslSetLex(&newLex);
|
||||
jslInit(functionCode);
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
newLex.lineNumberOffset = functionLineNumber;
|
||||
#endif
|
||||
JSP_SAVE_EXECUTE();
|
||||
// force execute without any previous state
|
||||
#ifdef USE_DEBUGGER
|
||||
@ -2955,7 +2966,9 @@ JsVar *jspEvaluateExpressionVar(JsVar *str) {
|
||||
assert(jsvIsString(str));
|
||||
JsLex *oldLex = jslSetLex(&lex);
|
||||
jslInit(str);
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
lex.lineNumberOffset = oldLex->lineNumberOffset;
|
||||
#endif
|
||||
|
||||
// actually do the parsing
|
||||
JsVar *v = jspeExpression();
|
||||
@ -2973,7 +2986,9 @@ JsVar *jspEvaluateVar(JsVar *str, JsVar *scope, uint16_t lineNumberOffset) {
|
||||
assert(jsvIsString(str));
|
||||
JsLex *oldLex = jslSetLex(&lex);
|
||||
jslInit(str);
|
||||
#ifndef ESPR_NO_LINE_NUMBERS
|
||||
lex.lineNumberOffset = lineNumberOffset;
|
||||
#endif
|
||||
|
||||
|
||||
JsExecInfo oldExecInfo = execInfo;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user