Some optimization attempts in progress.

Toying with a more efficient native-function-use implementation.
Replace getErrorCode with a macro.
Store initial slice array on the stack, mallocing at the end.
This commit is contained in:
Sage Vaillancourt 2022-04-12 22:40:50 -04:00 committed by Sage Vaillancourt
parent 0fd58832bf
commit d9d2bca8c8
6 changed files with 44 additions and 36 deletions

View File

@ -1,5 +1,4 @@
#include "object.h" #include "object.h"
#include "pebblisp.h"
#include "env.h" #include "env.h"
#include <stdio.h> #include <stdio.h>
@ -622,10 +621,6 @@ inline int isValidType(const Object test)
return 0; return 0;
} }
/**
* Clones the given lambda with new allocations
* Will behave unexpectedly if given something other than a lambda object!
*/
inline Object cloneLambda(const Object old) inline Object cloneLambda(const Object old)
{ {
old.lambda->refs += 1; old.lambda->refs += 1;
@ -638,7 +633,6 @@ Object cloneString(Object obj)
return obj; return obj;
} }
// Returns an Object with a deep copy of the given Object
Object cloneOther(const Object src) Object cloneOther(const Object src)
{ {
return src.other->clone ? src.other->clone(src.other) : src; return src.other->clone ? src.other->clone(src.other) : src;
@ -815,15 +809,6 @@ inline Object errorObject(enum errorCode err)
return o; return o;
} }
inline enum errorCode getErrorCode(const Object obj)
{
#ifdef SIMPLE_ERRORS
return obj.error;
#else
return obj.error->code;
#endif
}
#ifndef SIMPLE_ERRORS #ifndef SIMPLE_ERRORS
inline void errorAddContext(Object* o, const char* context, int lineNo, const char* fileName) inline void errorAddContext(Object* o, const char* context, int lineNo, const char* fileName)

View File

@ -19,7 +19,6 @@
#endif #endif
#define MAX_TOK_CNT 1024 #define MAX_TOK_CNT 1024
#define MAX_ENV_ELM 100
#define RESULT_LENGTH 128 #define RESULT_LENGTH 128
#define FOR_POINTER_IN_LIST(_list) \ #define FOR_POINTER_IN_LIST(_list) \
@ -239,7 +238,11 @@ Object otherObject();
Object errorObject(enum errorCode err); Object errorObject(enum errorCode err);
enum errorCode getErrorCode(Object obj); #ifdef SIMPLE_ERRORS
#define getErrorCode(OBJ) ((OBJ).error)
#else
#define getErrorCode(OBJ) ((OBJ).error->code)
#endif
Object errorWithContextLineNo(enum errorCode code, const char* context, int lineNo, const char* fileName); Object errorWithContextLineNo(enum errorCode code, const char* context, int lineNo, const char* fileName);

View File

@ -419,6 +419,13 @@ Object parseBin(struct Slice* s)
return numberObject(num); return numberObject(num);
} }
struct InlinedFunction {
Object (* func)(Object*, int, struct Environment*);
Object* arguments;
int argCount;
//struct Environment* env;
};
Result parseAtom(struct Slice* s) Result parseAtom(struct Slice* s)
{ {
const char c = s->text[0]; const char c = s->text[0];
@ -441,15 +448,27 @@ Result parseAtom(struct Slice* s)
} else if (c == '"'/* || c == '\''*/) { } else if (c == '"'/* || c == '\''*/) {
return (Result) { objFromSlice(s->text, s->length), s }; return (Result) { objFromSlice(s->text, s->length), s };
} else if (s->text[s->length] == '.') { } else if (s->text[s->length] == '.') {
struct InlinedFunction f ={
.func = structAccess,
.arguments = malloc(sizeof(Object) * 2),
.argCount = 2,
};
f.arguments[0] = symFromSlice(s->text, s->length);
struct Slice* next = s + 2;
f.arguments[1] = stringFromSlice(next->text, next->length);
return (Result) { list, next };
/*
Object structAccessFunc = newObject(TYPE_FUNC); Object structAccessFunc = newObject(TYPE_FUNC);
structAccessFunc.func = &structAccess; structAccessFunc.func = &structAccess;
Object list = startList(structAccessFunc); Object list = startList(structAccessFunc);
Object theStruct = symFromSlice(s->text, s->length); Object theStruct = symFromSlice(s->text, s->length);
nf_addToList(&list, theStruct); nf_addToList(&list, theStruct);
struct Slice* next = s + 2; struct Slice* next = s + 2;
Object structField = objFromSlice(&next->text[-1], next->length + 1); Object structField = stringFromSlice(next->text, next->length);
nf_addToList(&list, structField); nf_addToList(&list, structField);
return (Result) { list, next }; return (Result) { list, next };
*/
} }
return (Result) { symFromSlice(s->text, s->length), s }; return (Result) { symFromSlice(s->text, s->length), s };
} }

View File

@ -57,15 +57,13 @@ void* doAsync(void* args)
Object cloned = promise->object; Object cloned = promise->object;
Object first_eval = eval(&cloned, promise->env); Object first_eval = eval(&cloned, promise->env);
Object e = funcyEval(&first_eval, NULL, 0, promise->env); Object e = funcyEval(&first_eval, NULL, 0, promise->env);
cleanObject(&cloned);
promise->object = e; promise->object = e;
promise->done = 1; promise->done = 1;
cleanPromise(promise);
cleanObject(&cloned);
cleanPromise(promise);
deleteEnv(promise->env); deleteEnv(promise->env);
//cleanObject(&first_eval);
//cleanObject(&cloned);
return NULL; return NULL;
} }
@ -74,7 +72,7 @@ Object async(Object* params, int length, struct Environment* env)
Object promise = newObject(TYPE_PROMISE); Object promise = newObject(TYPE_PROMISE);
promise.promise = malloc(sizeof(struct Promise)); promise.promise = malloc(sizeof(struct Promise));
*promise.promise = (struct Promise) { *promise.promise = (struct Promise) {
.refs = 2, .refs = 2, // Held by doAsync and the returned object
.done = 0, .done = 0,
.env = env, .env = env,
.object = cloneObject(params[0]), .object = cloneObject(params[0]),

View File

@ -22,7 +22,8 @@ fn(async, "async",
tfn(await, "await", tfn(await, "await",
({ expect(isPromise), anyType }), ({ expect(isPromise), anyType }),
"Waits for a promise to resolve before proceeding.", "Waits for a promise to resolve before proceeding.\n"
"Note: Calling (await) on the same object multiple times is undefined behavior.",
"(def sleepy (fn () ((sys \"sleep 0.02\") \"Hiya\"))) (def x (async sleepy)) (await x)", "Hiya", "(def sleepy (fn () ((sys \"sleep 0.02\") \"Hiya\"))) (def x (async sleepy)) (await x)", "Hiya",
); );

View File

@ -1,6 +1,5 @@
#include "tokens.h" #include "tokens.h"
#include <stdlib.h>
#include <string.h> #include <string.h>
#define ERR_LEN 256 #define ERR_LEN 256
@ -51,12 +50,12 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
return NULL; return NULL;
} }
int token_count = MAX_TOK_CNT; struct Slice slices[MAX_TOK_CNT];
struct Slice* slices = malloc(sizeof(struct Slice) * token_count); //int token_count = MAX_TOK_CNT;
while (slices == NULL) { // do {
token_count /= 2; // slices = malloc(sizeof(struct Slice) * token_count);
slices = malloc(sizeof(struct Slice) * token_count); // token_count /= 2;
} // } while (slices == NULL);
int i = 0; int i = 0;
int slice = 0; int slice = 0;
@ -82,7 +81,7 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
err->code = MISMATCHED_PARENS; err->code = MISMATCHED_PARENS;
int start = i > ERR_LEN ? i - ERR_LEN : 0; int start = i > ERR_LEN ? i - ERR_LEN : 0;
strncpy(err->context, &input[start], ERR_LEN); strncpy(err->context, &input[start], ERR_LEN);
free(slices); //free(slices);
return NULL; return NULL;
} }
} }
@ -111,7 +110,7 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
err->code = UNEXPECTED_EOF; err->code = UNEXPECTED_EOF;
int start = i > ERR_LEN ? i - ERR_LEN : 0; int start = i > ERR_LEN ? i - ERR_LEN : 0;
strncpy(err->context, &input[start], ERR_LEN); strncpy(err->context, &input[start], ERR_LEN);
free(slices); //free(slices);
return NULL; return NULL;
} }
} }
@ -140,12 +139,15 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
err->code = MISMATCHED_PARENS; err->code = MISMATCHED_PARENS;
int start = i > ERR_LEN ? i - ERR_LEN : 0; int start = i > ERR_LEN ? i - ERR_LEN : 0;
strncpy(err->context, &input[start], ERR_LEN); strncpy(err->context, &input[start], ERR_LEN);
free(slices); //free(slices);
return NULL; return NULL;
} }
slices[slice].text = NULL; slices[slice].text = NULL;
slices[slice].length = 0; slices[slice].length = 0;
size_t size = sizeof(struct Slice) * (slice + 1);
struct Slice* allocated = malloc(size);
memcpy(allocated, slices, size);
return slices; return allocated;
} }