diff --git a/ChangeLog b/ChangeLog index 89378d25a8..203d0f8d3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ Fix irregular timing on Espruino boards with clock crystal (inc rev 1v4) Sort out 'Number()' constructor not being picky enough - parseFloat now parses 'Infinity' (Fix #325, mostly fix #322) Stop iterator in FOR loop being called once more after a break + Fix bug allObjects found with iterating over undefined 1v70 : Make pipe remove its drain/close listeners. Stops out of memory for repeated piping. Fix parseInt for values too large to go in an int (#406) diff --git a/README.md b/README.md index aa00dddb9d..13f30d6af3 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ If you are a board manufacturer interested in getting your board officially supp * [Espruino Board](http://www.espruino.com/EspruinoBoard) - great support. * Linux - WORKING * STM32VLDISCOVERY - WORKING - limited memory so some features removed -* STM32F3DISCOVERY - WORKING +* STM32F3DISCOVERY - setWatch is broken (issue #183) * STM32F4DISCOVERY - WORKING * STM32F401CDISCOVERY - appears WORKING, but very little testing done * STM32F429IDISCOVERY - WORKING over serial (A9/A10). No USB and no LCD support @@ -78,7 +78,7 @@ If you are a board manufacturer interested in getting your board officially supp * Raspberry Pi - WORKING - GPIO via filesystem (no SPI or I2C) * Sony SmartWatch - NOT WORKING - USB VCP support for F2 still needed * MBed platforms - have not worked for a while - full hardware wrapper still required -* ARDUINOMEGA2560 - has never worked +* ARDUINOMEGA2560 - compiles, but has never worked. Almost certainly due to ints being 16 bits. * LC-TECH STM32F103RBT6 - WORKING, but with some issues (LED inverted logic, BTN needs pullup to work) diff --git a/src/jsparse.c b/src/jsparse.c index 9be3be3190..089de9aef6 100644 --- a/src/jsparse.c +++ b/src/jsparse.c @@ -1805,60 +1805,62 @@ NO_INLINE JsVar *jspeStatementFor() { execInfo.execute &= (JsExecFlags)~EXEC_IN_LOOP; JSP_RESTORE_EXECUTE(); - if (jsvIsIterable(array)) { - JsvIsInternalChecker checkerFunction = jsvGetInternalFunctionCheckerFor(array); - JsVar *foundPrototype = 0; - - JsvIterator it; - jsvIteratorNew(&it, array); - bool hasHadBreak = false; - while (JSP_SHOULD_EXECUTE && jsvIteratorHasElement(&it) && !hasHadBreak) { - JsVar *loopIndexVar = jsvIteratorGetKey(&it); - bool ignore = false; - if (checkerFunction && checkerFunction(loopIndexVar)) { - ignore = true; - if (jsvIsString(loopIndexVar) && - jsvIsStringEqual(loopIndexVar, JSPARSE_INHERITS_VAR)) - foundPrototype = jsvSkipName(loopIndexVar); - } - if (!ignore) { - JsVar *indexValue = jsvIsName(loopIndexVar) ? - jsvCopyNameOnly(loopIndexVar, false/*no copy children*/, false/*not a name*/) : - loopIndexVar; - if (indexValue) { // could be out of memory - assert(!jsvIsName(indexValue) && jsvGetRefs(indexValue)==0); - jsvSetValueOfName(forStatement, indexValue); - if (indexValue!=loopIndexVar) jsvUnLock(indexValue); + if (JSP_SHOULD_EXECUTE) { + if (jsvIsIterable(array)) { + JsvIsInternalChecker checkerFunction = jsvGetInternalFunctionCheckerFor(array); + JsVar *foundPrototype = 0; + + JsvIterator it; + jsvIteratorNew(&it, array); + bool hasHadBreak = false; + while (JSP_SHOULD_EXECUTE && jsvIteratorHasElement(&it) && !hasHadBreak) { + JsVar *loopIndexVar = jsvIteratorGetKey(&it); + bool ignore = false; + if (checkerFunction && checkerFunction(loopIndexVar)) { + ignore = true; + if (jsvIsString(loopIndexVar) && + jsvIsStringEqual(loopIndexVar, JSPARSE_INHERITS_VAR)) + foundPrototype = jsvSkipName(loopIndexVar); + } + if (!ignore) { + JsVar *indexValue = jsvIsName(loopIndexVar) ? + jsvCopyNameOnly(loopIndexVar, false/*no copy children*/, false/*not a name*/) : + loopIndexVar; + if (indexValue) { // could be out of memory + assert(!jsvIsName(indexValue) && jsvGetRefs(indexValue)==0); + jsvSetValueOfName(forStatement, indexValue); + if (indexValue!=loopIndexVar) jsvUnLock(indexValue); + + jsvIteratorNext(&it); + + jslSeekToP(execInfo.lex, &forBodyStart); + execInfo.execute |= EXEC_IN_LOOP; + jsvUnLock(jspeBlockOrStatement()); + execInfo.execute &= (JsExecFlags)~EXEC_IN_LOOP; - jsvIteratorNext(&it); - - jslSeekToP(execInfo.lex, &forBodyStart); - execInfo.execute |= EXEC_IN_LOOP; - jsvUnLock(jspeBlockOrStatement()); - execInfo.execute &= (JsExecFlags)~EXEC_IN_LOOP; - - if (execInfo.execute == EXEC_CONTINUE) - execInfo.execute = EXEC_YES; - if (execInfo.execute == EXEC_BREAK) { - execInfo.execute = EXEC_YES; - hasHadBreak = true; + if (execInfo.execute == EXEC_CONTINUE) + execInfo.execute = EXEC_YES; + if (execInfo.execute == EXEC_BREAK) { + execInfo.execute = EXEC_YES; + hasHadBreak = true; + } } + } else + jsvIteratorNext(&it); + jsvUnLock(loopIndexVar); + + if (!jsvIteratorHasElement(&it) && foundPrototype) { + jsvIteratorFree(&it); + jsvIteratorNew(&it, foundPrototype); + jsvUnLock(foundPrototype); + foundPrototype = 0; } - } else - jsvIteratorNext(&it); - jsvUnLock(loopIndexVar); - - if (!jsvIteratorHasElement(&it) && foundPrototype) { - jsvIteratorFree(&it); - jsvIteratorNew(&it, foundPrototype); - jsvUnLock(foundPrototype); - foundPrototype = 0; - } + } + assert(!foundPrototype); + jsvIteratorFree(&it); + } else { + jsExceptionHere(JSET_ERROR, "FOR loop can only iterate over Arrays, Strings or Objects, not %t", array); } - assert(!foundPrototype); - jsvIteratorFree(&it); - } else { - jsExceptionHere(JSET_ERROR, "FOR loop can only iterate over Arrays, Strings or Objects, not %t", array); } jslSeekToP(execInfo.lex, &forBodyEnd); jslCharPosFree(&forBodyStart); diff --git a/tests/test_for_noexec.js b/tests/test_for_noexec.js new file mode 100644 index 0000000000..99740f98ed --- /dev/null +++ b/tests/test_for_noexec.js @@ -0,0 +1,5 @@ +//http://forum.espruino.com/conversations/256957/#comment11907195 +var c = undefined; +if (c) for (var i in c) ; +for (var i in c) ; +result = 1;