Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions backend-v2/runtime/ArrayChunk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "ArrayChunk.h"
#include "Object.h"
#include "PersistentVectorNode.h"
#include "Exceptions.h"

ArrayChunk *ArrayChunk_create(PersistentVectorNode *node, uword_t offset) {
ArrayChunk *self = (ArrayChunk *)allocate(sizeof(ArrayChunk));
Object_create((Object *)self, arrayChunkType);
self->node = node;
self->offset = offset;
Ptr_retain(node);
return self;
}

void ArrayChunk_destroy(ArrayChunk *self, bool deallocateChildren) {
Ptr_release(self->node);
}

RTValue ArrayChunk_nth(ArrayChunk *self, int32_t i) {
uword_t idx = self->offset + i;
if (idx >= self->node->count) {
uword_t cnt = self->node->count - self->offset;
Ptr_release(self);
throwIndexOutOfBoundsException_C(i, cnt);
}
RTValue val = self->node->array[idx];
retain(val);
Ptr_release(self);
return val;
}

RTValue ArrayChunk_nth_default(ArrayChunk *self, int32_t i, RTValue notFound) {
uword_t idx = self->offset + i;
if (idx >= self->node->count) {
Ptr_release(self);
return notFound;
}
RTValue val = self->node->array[idx];
retain(val);
release(notFound);
Ptr_release(self);
return val;
}

int32_t ArrayChunk_count(ArrayChunk *self) {
int32_t res = (int32_t)(self->node->count - self->offset);
Ptr_release(self);
return res;
}
31 changes: 31 additions & 0 deletions backend-v2/runtime/ArrayChunk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef RT_ARRAY_CHUNK_H
#define RT_ARRAY_CHUNK_H

#include "ObjectProto.h"
#include "RTValue.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct PersistentVectorNode PersistentVectorNode;

struct ArrayChunk {
Object super;
PersistentVectorNode *node;
uword_t offset;
};

typedef struct ArrayChunk ArrayChunk;

ArrayChunk *ArrayChunk_create(PersistentVectorNode *node, uword_t offset);
void ArrayChunk_destroy(ArrayChunk *self, bool deallocateChildren);
RTValue ArrayChunk_nth(ArrayChunk *self, int32_t i);
RTValue ArrayChunk_nth_default(ArrayChunk *self, int32_t i, RTValue notFound);
int32_t ArrayChunk_count(ArrayChunk *self);

#ifdef __cplusplus
}
#endif

#endif
6 changes: 5 additions & 1 deletion backend-v2/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ set(SOURCES
Exception.c
BridgedObject.c
Ebr.c
StringBuilder.c)
StringBuilder.c
PersistentVectorChunkedSeq.c
PersistentVectorReverseSeq.c
ArrayChunk.c)

add_library(runtime STATIC ${SOURCES})
target_compile_options(runtime PRIVATE $<$<PLATFORM_ID:Linux>:-femulated-tls>)
Expand Down Expand Up @@ -190,6 +193,7 @@ set(TEST_MODULES
Numbers_test
Exception_test
StringBuilder_test
PersistentVectorChunkedSeq_test
)

foreach(TEST_MODULE ${TEST_MODULES})
Expand Down
57 changes: 52 additions & 5 deletions backend-v2/runtime/Function.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,59 @@ void Function_destroy(ClojureFunction *self) {
deallocate(method->closedOvers);
}
}

RTValue RT_invokeDynamic(RTValue funObj, RTValue *args, int32_t argCount) {
(void)funObj;
(void)args;
(void)argCount;
fprintf(stderr, "RT_invokeDynamic: Not yet implemented\n");
abort();
FunctionMethod *method = Function_extractMethod(funObj, argCount);
return RT_invokeMethod(funObj, method, args, argCount);
}

RTValue RT_invokeMethod(RTValue funObj, FunctionMethod *method, RTValue *args,
int32_t argCount) {
// Allocate a frame on the stack.
size_t frameSize = sizeof(Frame) + argCount * sizeof(RTValue);
Frame *frame = (Frame *)alloca(frameSize);
frame->leafFrame = NULL;
frame->bailoutEntryIndex = -1;

return RT_invokeMethodWithFrame(frame, funObj, method, args, argCount);
}

RTValue RT_invokeMethodWithFrame(Frame *frame, RTValue funObj,
FunctionMethod *method, RTValue *args,
int32_t argCount) {
frame->method = method;
frame->self = funObj;
frame->localsCount = argCount;

if (method->isVariadic) {
frame->variadicSeq = RT_packVariadic(argCount, args, method->fixedArity);
} else {
frame->variadicSeq = RT_boxNil();
}

// Copy arguments to locals
for (int32_t i = 0; i < argCount; i++) {
frame->locals[i] = args[i];
}

typedef RTValue (*BaselineFunc)(Frame *, RTValue, RTValue, RTValue, RTValue,
RTValue);
BaselineFunc impl = (BaselineFunc)method->baselineImplementation;

RTValue a0 = argCount > 0 ? args[0] : RT_boxNil();
RTValue a1 = argCount > 1 ? args[1] : RT_boxNil();
RTValue a2 = argCount > 2 ? args[2] : RT_boxNil();
RTValue a3 = argCount > 3 ? args[3] : RT_boxNil();
RTValue a4 = argCount > 4 ? args[4] : RT_boxNil();

RTValue result = impl(frame, a0, a1, a2, a3, a4);

// RT_invokeMethod convention: consumes args, NOT funObj.
for (int32_t i = 0; i < argCount; i++) {
release(args[i]);
}

return result;
}

FunctionMethod *Function_extractMethod(RTValue funObj, uword_t argCount) {
Expand Down
3 changes: 3 additions & 0 deletions backend-v2/runtime/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ void Function_cleanupOnce(ClojureFunction *self);
void Function_promoteToShared(ClojureFunction *self, uword_t count);

RTValue RT_invokeDynamic(RTValue funObj, RTValue *args, int32_t argCount);
RTValue RT_invokeMethod(RTValue funObj, FunctionMethod *method, RTValue *args,
int32_t argCount);
RTValue RT_invokeMethodWithFrame(Frame *frame, RTValue funObj, FunctionMethod *method, RTValue *args, int32_t argCount);
FunctionMethod *Function_extractMethod(RTValue funObj, uword_t argCount);
struct FunctionMethod *RT_updateICSlot(void *slot, RTValue currentVal,
uint64_t argCount);
Expand Down
28 changes: 28 additions & 0 deletions backend-v2/runtime/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,13 @@ inline uword_t Ptr_hash(void *ptr);
inline bool Ptr_equals(void *ptr, void *other);
inline bool Ptr_isReusable(void *ptr);

#include "ArrayChunk.h"
#include "BigInteger.h"
#include "Boolean.h"
#include "BridgedObject.h"
#include "PersistentVectorChunkedSeq.h"
#include "PersistentVectorReverseSeq.h"
#include "ArrayChunk.h"
#include "Class.h"
#include "ConcurrentHashMap.h"
#include "Double.h"
Expand Down Expand Up @@ -307,6 +311,15 @@ inline void Object_destroy(Object *restrict self, bool deallocateChildren) {
case stringBuilderType:
StringBuilder_destroy((StringBuilder *)self);
break;
case persistentVectorChunkedSeqType:
PersistentVectorChunkedSeq_destroy((PersistentVectorChunkedSeq *)self, deallocateChildren);
break;
case arrayChunkType:
ArrayChunk_destroy((ArrayChunk *)self, deallocateChildren);
break;
case persistentVectorReverseSeqType:
PersistentVectorReverseSeq_destroy((PersistentVectorReverseSeq *)self, deallocateChildren);
break;

default:
break;
Expand Down Expand Up @@ -452,6 +465,15 @@ inline void Object_promoteToShared(Object *restrict self) {
Function_promoteToShared((ClojureFunction *)self, count);
break;

case persistentVectorChunkedSeqType:
Object_promoteToShared((Object *)((PersistentVectorChunkedSeq *)self)->it.parent);
Object_promoteToSharedShallow(self, count);
break;
case arrayChunkType:
Object_promoteToShared((Object *)((ArrayChunk *)self)->node);
Object_promoteToSharedShallow(self, count);
break;

default:
Object_promoteToSharedShallow(self, count);
break;
Expand Down Expand Up @@ -494,6 +516,8 @@ inline uword_t Object_hash(Object *restrict self) {
return BridgedObject_hash((BridgedObject *)self);
case stringBuilderType:
return StringBuilder_hash((StringBuilder *)self);
case persistentVectorChunkedSeqType:
return PersistentVectorChunkedSeq_hash((PersistentVectorChunkedSeq *)self);
default:
assert(false && "Internal error: hash computation for NaN tagged types "
"should be computed earlier.");
Expand Down Expand Up @@ -579,6 +603,8 @@ inline bool Object_equals(Object *self, Object *other) {
return BridgedObject_equals((BridgedObject *)self, (BridgedObject *)other);
case stringBuilderType:
return StringBuilder_equals((StringBuilder *)self, (StringBuilder *)other);
case persistentVectorChunkedSeqType:
return PersistentVectorChunkedSeq_equals((PersistentVectorChunkedSeq *)self, (PersistentVectorChunkedSeq *)other);
default:
assert(false && "Internal error: hash computation for NaN tagged types "
"should be computed earlier.");
Expand Down Expand Up @@ -642,6 +668,8 @@ inline String *Object_toString(Object *restrict self) {
return BridgedObject_toString((BridgedObject *)self);
case stringBuilderType:
return StringBuilder_toString((StringBuilder *)self);
case persistentVectorChunkedSeqType:
return PersistentVectorChunkedSeq_toString((PersistentVectorChunkedSeq *)self);
default:
assert(false && "Internal error: Object_toString got an unsupported type");
}
Expand Down
3 changes: 3 additions & 0 deletions backend-v2/runtime/ObjectProto.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ enum objectType {
exceptionType = 21,
bridgedObjectType = 22,
stringBuilderType = 23,
persistentVectorChunkedSeqType = 24,
arrayChunkType = 25,
persistentVectorReverseSeqType = 26,
};

typedef enum objectType objectType;
Expand Down
45 changes: 45 additions & 0 deletions backend-v2/runtime/PersistentList.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,48 @@ PersistentList *PersistentList_fromArray(int32_t argCount, RTValue *args) {
RTValue RT_createListFromArray(int32_t argCount, RTValue *args) {
return RT_boxPtr(PersistentList_fromArray(argCount, args));
}

RTValue PersistentList_reduce(PersistentList *self, RTValue f, RTValue start) {
RTValue acc = start;
PersistentList *current = self;

FunctionMethod *method = Function_extractMethod(f, 2);

size_t frameSize = sizeof(Frame) + 2 * sizeof(RTValue);
Frame *frame = (Frame *)alloca(frameSize);
frame->leafFrame = NULL;
frame->bailoutEntryIndex = -1;

RTValue args[2];

while (current && !RT_isNull(current->first)) {
args[0] = acc;
args[1] = current->first;
retain(args[1]);
acc = RT_invokeMethodWithFrame(frame, f, method, args, 2);
current = current->rest;
}

Ptr_release(self);
release(f);
return acc;
}

RTValue PersistentList_reduce2(PersistentList *self, RTValue f) {
if (RT_isNull(self->first)) {
Ptr_release(self);
return RT_invokeDynamic(f, NULL, 0);
}
RTValue first = self->first;
retain(first);
PersistentList *rest = self->rest;
if (rest) Ptr_retain(rest);
Ptr_release(self);

if (!rest) {
release(f);
return first;
}

return PersistentList_reduce(rest, f, first);
}
2 changes: 2 additions & 0 deletions backend-v2/runtime/PersistentList.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ int32_t PersistentList_count(PersistentList *self);
PersistentList *PersistentList_identity(PersistentList *self);
RTValue PersistentList_next(PersistentList *self);
RTValue PersistentList_first(PersistentList *self);
RTValue PersistentList_reduce(PersistentList *self, RTValue f, RTValue start);
RTValue PersistentList_reduce2(PersistentList *self, RTValue f);

#ifdef __cplusplus
}
Expand Down
Loading
Loading