From 6264fa0ee43017eca68b07d6ddcfcb830f7594d2 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 13 Jun 2018 09:52:04 +0100 Subject: [PATCH] Fix TypedArray.indexOf (fix #1468) --- ChangeLog | 1 + src/jsvar.c | 19 ++++++++++--------- src/jswrap_array.c | 4 +--- tests/test_arraybuffer_indexOf.js | 10 ++++++++++ 4 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 tests/test_arraybuffer_indexOf.js diff --git a/ChangeLog b/ChangeLog index bc983d7c7..ada43928c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ Fix issue that caused 'dump()' not to report variables/functions on Pixl.js Add E.lookupNoCase to allow searching case-insensitively for Object keys Fix HTTP Chunked transfers when the server uses lowercase headers (fix #1458) + Fix TypedArray.indexOf (fix #1468) 1v99 : Increase jslMatch error buffer size to handle "UNFINISHED TEMPLATE LITERAL" string (#1426) nRF5x: Make FlashWrite cope with flash writes > 4k diff --git a/src/jsvar.c b/src/jsvar.c index 15fc2cb7b..6064b0c17 100644 --- a/src/jsvar.c +++ b/src/jsvar.c @@ -3025,27 +3025,28 @@ void jsvGetArrayItems(JsVar *arr, unsigned int itemCount, JsVar **itemPtr) { itemPtr[i++] = 0; // just ensure we don't end up with bad data } -/// Get the index of the value in the array (matchExact==use pointer not equality check, matchIntegerIndices = don't check non-integers) +/// Get the index of the value in the iterable var (matchExact==use pointer not equality check, matchIntegerIndices = don't check non-integers) JsVar *jsvGetIndexOfFull(JsVar *arr, JsVar *value, bool matchExact, bool matchIntegerIndices, int startIdx) { - JsVarRef indexref; - assert(jsvIsArray(arr) || jsvIsObject(arr)); - indexref = jsvGetFirstChild(arr); - while (indexref) { - JsVar *childIndex = jsvLock(indexref); + if (!jsvIsIterable(arr)) return 0; + JsvIterator it; + jsvIteratorNew(&it, arr, JSIF_DEFINED_ARRAY_ElEMENTS); + while (jsvIteratorHasElement(&it)) { + JsVar *childIndex = jsvIteratorGetKey(&it); if (!matchIntegerIndices || (jsvIsInt(childIndex) && jsvGetInteger(childIndex)>=startIdx)) { - assert(jsvIsName(childIndex)); - JsVar *childValue = jsvSkipName(childIndex); + JsVar *childValue = jsvIteratorGetValue(&it); if (childValue==value || (!matchExact && jsvMathsOpTypeEqual(childValue, value))) { jsvUnLock(childValue); + jsvIteratorFree(&it); return childIndex; } jsvUnLock(childValue); } - indexref = jsvGetNextSibling(childIndex); jsvUnLock(childIndex); + jsvIteratorNext(&it); } + jsvIteratorFree(&it); return 0; // undefined } diff --git a/src/jswrap_array.c b/src/jswrap_array.c index 19c5f1679..5de314870 100644 --- a/src/jswrap_array.c +++ b/src/jswrap_array.c @@ -107,9 +107,7 @@ JsVar *jswrap_array_indexOf(JsVar *parent, JsVar *value, JsVarInt startIdx) { JsVar *idxName = jsvGetIndexOfFull(parent, value, false/*not exact*/, true/*integer indices only*/, startIdx); // but this is the name - we must turn it into a var if (idxName == 0) return jsvNewFromInteger(-1); // not found! - JsVar *idx = jsvCopyNameOnly(idxName, false/* no children */, false/* Make sure this is not a name*/); - jsvUnLock(idxName); - return idx; + return jsvNewFromInteger(jsvGetIntegerAndUnLock(idxName)); } /*JSON{ diff --git a/tests/test_arraybuffer_indexOf.js b/tests/test_arraybuffer_indexOf.js new file mode 100644 index 000000000..22e03dde2 --- /dev/null +++ b/tests/test_arraybuffer_indexOf.js @@ -0,0 +1,10 @@ +// https://github.com/espruino/Espruino/issues/1468 + +var b = new ArrayBuffer(8); +var arr=new Array(8); +var u8 = new Uint8Array(b); +arr.fill(128,3,6); +u8.fill(128,3,6); +console.log(arr.indexOf(128));//return 3 +console.log(u8,r=u8.indexOf(128));//return -1 +result = r == 3;