From 91321dab830328d4e5854aa9da7dd54c5e8cc520 Mon Sep 17 00:00:00 2001 From: Abhijith Date: Sun, 8 Jan 2017 18:43:14 -0800 Subject: [PATCH 1/2] Support for default values in array. --- libs/core/pxt.cpp | 66 ++++++++++++++--------------------------------- libs/core/pxt.h | 7 +---- 2 files changed, 21 insertions(+), 52 deletions(-) diff --git a/libs/core/pxt.cpp b/libs/core/pxt.cpp index 2f8c67cb..639b8da0 100644 --- a/libs/core/pxt.cpp +++ b/libs/core/pxt.cpp @@ -150,15 +150,10 @@ namespace pxt { if (i < length) { - if (data[i] != Segment::MissingValue) - { return data[i]; - } - error(ERR_MISSING_VALUE); - return 0; } error(ERR_OUT_OF_BOUNDS); - return 0; + return Segment::DefaultValue; } void Segment::set(uint32_t i, uint32_t value) @@ -223,12 +218,8 @@ namespace pxt { { memcpy(tmp, data, size * sizeof(uint32_t)); } - - //fill the rest with missing values; - for(uint16_t i = size; i < newSize; i++) - { - tmp[i] = Segment::MissingValue; - } + //fill the rest with default value + memset(tmp + size, Segment::DefaultValue, (newSize - size) * sizeof(uint32_t)); //free older segment; ::operator delete(data); @@ -280,12 +271,12 @@ namespace pxt { if (length > 0) { uint32_t value = data[length]; - data[length] = Segment::MissingValue; + data[length] = Segment::DefaultValue; --length; return value; } error(ERR_OUT_OF_BOUNDS); - return 0; + return Segment::DefaultValue; } //this function removes an element at index i and shifts the rest of the elements to @@ -306,7 +297,7 @@ namespace pxt { memmove(data + i, data + i + 1, (length - i - 1) * sizeof(uint32_t)); } length--; - data[length] = Segment::MissingValue; + data[length] = Segment::DefaultValue; #ifdef DEBUG_BUILD printf("After Segment::remove index:%u\n", i); this->print(); @@ -314,7 +305,7 @@ namespace pxt { return ret; } error(ERR_OUT_OF_BOUNDS); - return 0; + return Segment::DefaultValue; } //this function inserts element value at index i by shifting the rest of the elements right. @@ -360,32 +351,13 @@ namespace pxt { bool Segment::isValidIndex(uint32_t i) { - if (i > length || data[i] == Segment::MissingValue) + if (i > length) { return false; } return true; } - bool Segment::getNextValidIndex(uint32_t i, uint32_t *result) - { - while (i < length) - { - if (data[i] != Segment::MissingValue) - { - *result = i; - -#ifdef DEBUG_BUILD - printf("In Segment::getNextValidIndex result=%u\n",i); - this->print(); -#endif - return true; - } - i++; - } - return false; - } - void Segment::destroy() { #ifdef DEBUG_BUILD @@ -447,7 +419,7 @@ namespace pxt { void RefCollection::insertAt(int i, uint32_t value) { - if (i < length()) + if (((uint32_t)i) < length()) { head.insert(i, value); if (isRef()) @@ -480,26 +452,31 @@ namespace pxt { { StringData *xx = (StringData*)x; uint32_t i = start; - while(head.getNextValidIndex(start, &i)) + while(head.isValidIndex(i)) { StringData *ee = (StringData*)head.get(i); - if (xx->len == ee->len && memcmp(xx->data, ee->data, xx->len) == 0) + if (ee == xx) + { + //handles ee being null + return (int) i; + } + if (ee && xx->len == ee->len && memcmp(xx->data, ee->data, xx->len) == 0) { return (int)i; } - start = i; + i++; } } else { uint32_t i = start; - while(head.getNextValidIndex(start, &i)) + while(head.isValidIndex(i)) { if (head.get(i) == x) { return (int)i; } - start = i; + i++; } } @@ -550,12 +527,9 @@ namespace pxt { { if (this->isRef()) { - uint32_t start = 0; - uint32_t i = 0; - while(head.getNextValidIndex(start, &i)) + for(uint32_t i = 0; i < this->head.getLength(); i++) { decr(this->head.get(i)); - start = i; } } this->head.destroy(); diff --git a/libs/core/pxt.h b/libs/core/pxt.h index 6da5ec7c..95224382 100644 --- a/libs/core/pxt.h +++ b/libs/core/pxt.h @@ -38,7 +38,6 @@ namespace pxt { ERR_OUT_OF_BOUNDS = 8, ERR_REF_DELETED = 7, ERR_SIZE = 9, - ERR_MISSING_VALUE = 10, } ERROR; extern const uint32_t functionsAndBytecode[]; @@ -175,7 +174,7 @@ namespace pxt { uint16_t size; static const uint16_t MaxSize = 0xFFFF; - static const uint32_t MissingValue = 0x80000000; + static const uint32_t DefaultValue = 0x0; static uint16_t growthFactor(uint16_t size); void growByMin(uint16_t minSize); @@ -197,10 +196,6 @@ namespace pxt { uint32_t remove(uint32_t i); void insert(uint32_t i, uint32_t value); - //Returns true if there is a valid index greater than or equal to 'i', returns false otherwise - //If 'i' is valid returns it in 'result', if not tries to find the next valid - //index < length which is valid. - bool getNextValidIndex(uint32_t i, uint32_t *result); bool isValidIndex(uint32_t i); void destroy(); From c938618d29b1a15a8cbafa7034ab0b930aa5eaff Mon Sep 17 00:00:00 2001 From: Brahma Giri Abhijith Chatra Date: Sun, 8 Jan 2017 19:08:09 -0800 Subject: [PATCH 2/2] adding default values for beyond the array.length access --- libs/core/pxt.cpp | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/libs/core/pxt.cpp b/libs/core/pxt.cpp index 639b8da0..99e4f0f7 100644 --- a/libs/core/pxt.cpp +++ b/libs/core/pxt.cpp @@ -152,7 +152,6 @@ namespace pxt { { return data[i]; } - error(ERR_OUT_OF_BOUNDS); return Segment::DefaultValue; } @@ -275,7 +274,6 @@ namespace pxt { --length; return value; } - error(ERR_OUT_OF_BOUNDS); return Segment::DefaultValue; } @@ -304,7 +302,6 @@ namespace pxt { #endif return ret; } - error(ERR_OUT_OF_BOUNDS); return Segment::DefaultValue; } @@ -387,29 +384,16 @@ namespace pxt { uint32_t RefCollection::getAt(int i) { - if (head.isValidIndex(i)) + uint32_t tmp = head.get(i); + if (isRef()) { - uint32_t tmp = head.get(i); - if (isRef()) - { - incr(tmp); - } - return tmp; - } - else - { - error(ERR_OUT_OF_BOUNDS); - return 0; + incr(tmp); } + return tmp; } uint32_t RefCollection::removeAt(int i) { - if (!head.isValidIndex((uint32_t)i)) - { - error(ERR_OUT_OF_BOUNDS); - return 0; - } if (isRef()) { decr(head.get(i)); @@ -419,18 +403,11 @@ namespace pxt { void RefCollection::insertAt(int i, uint32_t value) { - if (((uint32_t)i) < length()) + head.insert(i, value); + if (isRef()) { - head.insert(i, value); - if (isRef()) - { - incr(value); - } - } - else - { - error(ERR_OUT_OF_BOUNDS); - } + incr(value); + } } void RefCollection::setAt(int i, uint32_t value)