Skip to content

Commit

Permalink
[RefC] [Test] Valgrind support & Fix invalid memory read of strSubstr (
Browse files Browse the repository at this point in the history
  • Loading branch information
seagull-kamome committed Jan 22, 2024
1 parent cf4c87c commit 5f643c0
Show file tree
Hide file tree
Showing 26 changed files with 73 additions and 95 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG_NEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ This CHANGELOG describes the merged but unreleased changes. Please see [CHANGELO

### Compiler changes

#### RefC Backend

* Fix invalid memory read onf strSubStr.

* Fix memory leaks of IORef. Now that IORef holds values by itself,
global_IORef_Storage is no longer needed.

#### NodeJS Backend

* The NodeJS executable output to `build/exec/` now has its executable bit set.
Expand Down
5 changes: 0 additions & 5 deletions src/Compiler/RefC/RefC.idr
Original file line number Diff line number Diff line change
Expand Up @@ -974,10 +974,6 @@ header = do
#include <runtime.h>
/* \{ generatedString "RefC" } */
/* a global storage for IO References */
IORef_Storage * global_IORef_Storage;
"""
let headerFiles = Libraries.Data.SortedSet.toList !(get HeaderFiles)
let headerLines = map (\h => "#include <" ++ h ++ ">\n") headerFiles
Expand All @@ -998,7 +994,6 @@ footer = do
"idris2_setArgs(argc, argv);"
""
}
global_IORef_Storage = NULL;
Value *mainExprVal = __mainExpression_0();
trampoline(mainExprVal);
return 0; // bye bye
Expand Down
8 changes: 1 addition & 7 deletions support/refc/_datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ typedef struct {

typedef struct {
Value_header header;
int32_t index;
Value *v;
} Value_IORef;

typedef struct {
Expand Down Expand Up @@ -169,9 +169,3 @@ typedef struct {
Value_header header;
pthread_cond_t *cond;
} Value_Condition;

typedef struct {
Value **refs;
int filled;
int total;
} IORef_Storage;
2 changes: 0 additions & 2 deletions support/refc/cBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,3 @@
#include "runtime.h"
#include "stringOps.h"
#include "threads.h"

extern IORef_Storage *global_IORef_Storage;
2 changes: 1 addition & 1 deletion support/refc/memoryManagement.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ void removeReference(Value *elem) {
break;
}
case IOREF_TAG:
/* nothing to delete, added for sake of completeness */
removeReference(((Value_IORef *)elem)->v);
break;

case BUFFER_TAG: {
Expand Down
50 changes: 8 additions & 42 deletions support/refc/prim.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,22 @@
#include <string.h>
#include <unistd.h>

// This is NOT THREAD SAFE in the current implementation

IORef_Storage *newIORef_Storage(int capacity) {
IORef_Storage *retVal = (IORef_Storage *)malloc(sizeof(IORef_Storage));
IDRIS2_REFC_VERIFY(retVal, "malloc failed");
retVal->filled = 0;
retVal->total = capacity;
retVal->refs = (Value **)malloc(sizeof(Value *) * retVal->total);
return retVal;
}

void doubleIORef_Storage(IORef_Storage *ior) {
Value **values = (Value **)malloc(sizeof(Value *) * ior->total * 2);
IDRIS2_REFC_VERIFY(values, "malloc failed");
ior->total *= 2;
for (int i = 0; i < ior->filled; i++) {
values[i] = ior->refs[i];
}
free(ior->refs);
ior->refs = values;
}

Value *idris2_Data_IORef_prim__newIORef(Value *erased, Value *input_value,
Value *_world) {
// if no ioRef Storag exist, start with one
if (!global_IORef_Storage) {
global_IORef_Storage = newIORef_Storage(128);
}
// expand size of needed
if (global_IORef_Storage->filled >= global_IORef_Storage->total) {
doubleIORef_Storage(global_IORef_Storage);
}

// store value
Value_IORef *ioRef = IDRIS2_NEW_VALUE(Value_IORef);
ioRef->header.tag = IOREF_TAG;
ioRef->index = global_IORef_Storage->filled;
global_IORef_Storage->refs[global_IORef_Storage->filled] =
newReference(input_value);
global_IORef_Storage->filled++;

ioRef->v = newReference(input_value);
return (Value *)ioRef;
}

Value *idris2_Data_IORef_prim__writeIORef(Value *erased, Value *_index,
Value *idris2_Data_IORef_prim__writeIORef(Value *erased, Value *_ioref,
Value *new_value, Value *_world) {
Value_IORef *index = (Value_IORef *)_index;
removeReference(global_IORef_Storage->refs[index->index]);
global_IORef_Storage->refs[index->index] = newReference(new_value);
return newReference(_index);
Value_IORef *ioref = (Value_IORef *)_ioref;
newReference(new_value);
Value *old = ioref->v;
ioref->v = new_value;
removeReference(old);
return NULL;
}

// -----------------------------------
Expand Down
4 changes: 2 additions & 2 deletions support/refc/prim.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// IORef

Value *idris2_Data_IORef_prim__newIORef(Value *, Value *, Value *);
#define idris2_Data_IORef_prim__readIORef(erased, ix, world) \
(newReference(global_IORef_Storage->refs[((Value_IORef *)ix)->index]))
#define idris2_Data_IORef_prim__readIORef(erased, ioref, world) \
(newReference(((Value_IORef *)ioref)->v))

Value *idris2_Data_IORef_prim__writeIORef(Value *, Value *, Value *, Value *);

Expand Down
4 changes: 2 additions & 2 deletions support/refc/stringOps.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ Value *strAppend(Value *a, Value *b) {

Value *strSubstr(Value *start, Value *len, Value *s) {
char *input = ((Value_String *)s)->str;
int offset = extractInt(start);
int offset = extractInt(start); /* start and len is Nat. */
int l = extractInt(len);

int tailLen = strlen(input);
int tailLen = strlen(input) - offset;
if (tailLen < l) {
l = tailLen;
}
Expand Down
4 changes: 2 additions & 2 deletions tests/refc/args/run
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
. ../../testutils.sh

idris2 --cg refc -o refc_args TestArgs.idr > /dev/null
./build/exec/refc_args a b
idris2 --cg refc -o refc_args TestArgs.idr
$VALGRIND ./build/exec/refc_args a b
./build/exec/refc_args c
4 changes: 2 additions & 2 deletions tests/refc/buffer/run
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
. ../../testutils.sh

idris2 --cg refc -o refc_buffer TestBuffer.idr > /dev/null
./build/exec/refc_buffer
idris2 --cg refc -o refc_buffer TestBuffer.idr
$VALGRIND ./build/exec/refc_buffer
base64 -i testWrite.buf

rm testWrite.buf
4 changes: 2 additions & 2 deletions tests/refc/ccompilerArgs/run
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ export LDLIBS="-lexternalc"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:./library/"
export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:./library/"

idris2 --cg refc -o cffi Main.idr > /dev/null
idris2 --cg refc -o cffi Main.idr

./build/exec/cffi
$VALGRIND ./build/exec/cffi
4 changes: 2 additions & 2 deletions tests/refc/doubles/run
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
. ../../testutils.sh

idris2 --cg refc -o refc_doubles TestDoubles.idr > /dev/null
./build/exec/refc_doubles
idris2 --cg refc -o refc_doubles TestDoubles.idr
$VALGRIND ./build/exec/refc_doubles
4 changes: 2 additions & 2 deletions tests/refc/garbageCollect/run
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
. ../../testutils.sh

idris2 --cg refc -o testGC TestGarbageCollect.idr > /dev/null
idris2 --cg refc -o testGC TestGarbageCollect.idr

./build/exec/testGC
$VALGRIND ./build/exec/testGC
4 changes: 2 additions & 2 deletions tests/refc/integers/run
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
. ../../testutils.sh

idris2 --cg refc -o refc_integers TestIntegers.idr > /dev/null
./build/exec/refc_integers
idris2 --cg refc -o refc_integers TestIntegers.idr
$VALGRIND ./build/exec/refc_integers
4 changes: 2 additions & 2 deletions tests/refc/issue1778/run
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
. ../../testutils.sh

idris2 --cg refc -o reverse Reverse.idr > /dev/null
./build/exec/reverse
idris2 --cg refc -o reverse Reverse.idr
$VALGRIND ./build/exec/reverse
5 changes: 2 additions & 3 deletions tests/refc/issue2424/run
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
. ../../testutils.sh

idris2 --cg refc -o test ControlAppMonadTest.idr > /dev/null

./build/exec/test
idris2 --cg refc -o test ControlAppMonadTest.idr
$VALGRIND ./build/exec/test
4 changes: 2 additions & 2 deletions tests/refc/issue2452/run
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
. ../../testutils.sh

idris2 --cg refc -o bits_case BitsCase.idr > /dev/null
./build/exec/bits_case
idris2 --cg refc -o bits_case BitsCase.idr
$VALGRIND ./build/exec/bits_case
4 changes: 2 additions & 2 deletions tests/refc/prims/run
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
. ../../testutils.sh

idris2 --cg refc -o test Test.idr > /dev/null
./build/exec/test
idris2 --cg refc -o test Test.idr
$VALGRIND ./build/exec/test
4 changes: 2 additions & 2 deletions tests/refc/refc001/run
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
. ../../testutils.sh

idris2 --cg refc -o refc001 Tail.idr > /dev/null
./build/exec/refc001
idris2 --cg refc -o refc001 Tail.idr
$VALGRIND ./build/exec/refc001
4 changes: 2 additions & 2 deletions tests/refc/refc002/run
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
. ../../testutils.sh

idris2 --cg refc -o refc002 RecordProjection.idr > /dev/null
./build/exec/refc002
idris2 --cg refc -o refc002 RecordProjection.idr
$VALGRIND ./build/exec/refc002
4 changes: 2 additions & 2 deletions tests/refc/refc003/run
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
. ../../testutils.sh

idris2 --cg refc -o refc003 Issue1191.idr > /dev/null
./build/exec/refc003
idris2 --cg refc -o refc003 Issue1191.idr
$VALGRIND ./build/exec/refc003
3 changes: 1 addition & 2 deletions tests/refc/reg001/run
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
. ../../testutils.sh

idris2 --cg refc Issue1843.idr -o test

./build/exec/test
$VALGRIND ./build/exec/test
13 changes: 11 additions & 2 deletions tests/refc/strings/TestStrings.idr
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,17 @@ main = do
putStrLn $ reverse helloWorld
putStrLn $ reverse ""
putStrLn $ substr 1 2 helloWorld
putStrLn $ substr 10 10 helloWorld
putStrLn $ substr 1 2 ""

let overtake0 = substr 10 10 helloWorld
putStrLn $ "\{show $ length overtake0} : \{overtake0}"
let overtake1 = substr 1 2 ""
putStrLn $ "\{show $ length overtake1} : \{overtake1}"
putStrLn $ substr (-10) (1) helloWorld
putStrLn $ substr 2 (-2) helloWorld
putStrLn $ substr (-5) (-2) helloWorld
putStrLn $ substr 1000000 1 helloWorld
putStrLn $ substr 5 100000 helloWorld

putStrLn $ show $ assert_total $ strIndex helloWorld 1

putStrLn $ strCons 'a' "bc"
Expand Down
7 changes: 6 additions & 1 deletion tests/refc/strings/expected
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ Hello, world
dlrow ,olleH

el
ld
2 : ld
0 :
H



, world
'e'
abc
a
Expand Down
4 changes: 2 additions & 2 deletions tests/refc/strings/run
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
. ../../testutils.sh

idris2 --cg refc -p contrib -o refc_strings TestStrings.idr > /dev/null
./build/exec/refc_strings
idris2 --cg refc -p contrib -o refc_strings TestStrings.idr
$VALGRIND ./build/exec/refc_strings
6 changes: 6 additions & 0 deletions tests/testutils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ idris2="$1"
rm -rf build
rm -rf prefix

if type valgrind >/dev/null 2>&1; then
export VALGRIND="valgrind --leak-check=full -s --log-file=output.valgrind.refc.log"
else
unset VALGRIND
fi

idris2() {
$idris2 --no-banner --console-width 0 --no-color "$@"
}
Expand Down

0 comments on commit 5f643c0

Please sign in to comment.