scope storage and access performance optimizations
This commit is contained in:
parent
88c2d47e13
commit
e500678dae
161
interpreter.c
161
interpreter.c
|
@ -476,6 +476,7 @@ ValueObject *createScopeValue(ScopeObject *src,
|
||||||
void *mem1 = NULL;
|
void *mem1 = NULL;
|
||||||
void *mem2 = NULL;
|
void *mem2 = NULL;
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
|
unsigned int pos = 0;
|
||||||
|
|
||||||
/* Traverse the target to the terminal child and parent */
|
/* Traverse the target to the terminal child and parent */
|
||||||
status = resolveTerminalSlot(src, dest, target, &parent, &child);
|
status = resolveTerminalSlot(src, dest, target, &parent, &child);
|
||||||
|
@ -488,26 +489,52 @@ ValueObject *createScopeValue(ScopeObject *src,
|
||||||
name = resolveIdentifierName(target, src);
|
name = resolveIdentifierName(target, src);
|
||||||
if (!name) goto createScopeValueAbort;
|
if (!name) goto createScopeValueAbort;
|
||||||
|
|
||||||
/* Add value to local scope */
|
/* realloc if power of two */
|
||||||
mem1 = realloc(dest->names, sizeof(IdentifierNode *) * newnumvals);
|
if (newnumvals && !(newnumvals & (newnumvals - 1))) {
|
||||||
if (!mem1) {
|
int allocnumvals = (newnumvals << 1);
|
||||||
perror("realloc");
|
/* Add value to local scope */
|
||||||
goto createScopeValueAbort;
|
mem1 = realloc(dest->names, sizeof(IdentifierNode *) * allocnumvals);
|
||||||
}
|
if (!mem1) {
|
||||||
mem2 = realloc(dest->values, sizeof(ValueObject *) * newnumvals);
|
perror("realloc");
|
||||||
if (!mem2) {
|
goto createScopeValueAbort;
|
||||||
perror("realloc");
|
}
|
||||||
goto createScopeValueAbort;
|
mem2 = realloc(dest->values, sizeof(ValueObject *) * allocnumvals);
|
||||||
|
if (!mem2) {
|
||||||
|
perror("realloc");
|
||||||
|
goto createScopeValueAbort;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mem1 = dest->names;
|
||||||
|
mem2 = dest->values;
|
||||||
}
|
}
|
||||||
|
|
||||||
dest->names = mem1;
|
dest->names = mem1;
|
||||||
dest->values = mem2;
|
dest->values = mem2;
|
||||||
dest->names[dest->numvals] = name;
|
|
||||||
dest->values[dest->numvals] = createNilValueObject();
|
/* Insert in lexical order */
|
||||||
if (!dest->values[dest->numvals]) goto createScopeValueAbort;
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (dest->numvals > 0) {
|
||||||
|
/* Find insertion position */
|
||||||
|
pos = binarySearchIndex((const char **)dest->names, 0, dest->numvals - 1, (const char *)name);
|
||||||
|
|
||||||
|
/* Shift values down */
|
||||||
|
for (n = dest->numvals; n > pos; n--) {
|
||||||
|
dest->names[n] = dest->names[n - 1];
|
||||||
|
dest->values[n] = dest->values[n - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert the value */
|
||||||
|
dest->names[pos] = name;
|
||||||
|
dest->values[pos] = createNilValueObject();
|
||||||
|
if (!dest->values[pos]) goto createScopeValueAbort;
|
||||||
|
}
|
||||||
|
|
||||||
dest->numvals = newnumvals;
|
dest->numvals = newnumvals;
|
||||||
|
|
||||||
return dest->values[dest->numvals - 1];
|
return dest->values[pos];
|
||||||
|
|
||||||
createScopeValueAbort: /* In case something goes wrong... */
|
createScopeValueAbort: /* In case something goes wrong... */
|
||||||
|
|
||||||
|
@ -555,22 +582,24 @@ ValueObject *updateScopeValue(ScopeObject *src,
|
||||||
|
|
||||||
/* Traverse upwards through scopes */
|
/* Traverse upwards through scopes */
|
||||||
do {
|
do {
|
||||||
unsigned int n;
|
if (parent->numvals == 0) continue;
|
||||||
/* Check for existing value in current scope */
|
|
||||||
for (n = 0; n < parent->numvals; n++) {
|
unsigned int n = binarySearchIndex((const char **)parent->names, 0, parent->numvals - 1, (const char *)name);
|
||||||
if (!strcmp(parent->names[n], name)) {
|
|
||||||
free(name);
|
if (n >= parent->numvals) continue;
|
||||||
/* Wipe out the old value */
|
|
||||||
deleteValueObject(parent->values[n]);
|
if (!strcmp(parent->names[n], name)) {
|
||||||
/* Assign the new value */
|
free(name);
|
||||||
if (value) {
|
/* Delete the old value */
|
||||||
parent->values[n] = value;
|
deleteValueObject(parent->values[n]);
|
||||||
}
|
/* Assign the new value */
|
||||||
else {
|
if (value) {
|
||||||
parent->values[n] = createNilValueObject();
|
parent->values[n] = value;
|
||||||
}
|
|
||||||
return parent->values[n];
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
parent->values[n] = createNilValueObject();
|
||||||
|
}
|
||||||
|
return parent->values[n];
|
||||||
}
|
}
|
||||||
} while ((parent = parent->parent));
|
} while ((parent = parent->parent));
|
||||||
|
|
||||||
|
@ -822,12 +851,24 @@ ValueObject *getScopeValueLocal(ScopeObject *src,
|
||||||
if (!name) goto getScopeValueLocalAbort;
|
if (!name) goto getScopeValueLocalAbort;
|
||||||
|
|
||||||
/* Check for value in current scope */
|
/* Check for value in current scope */
|
||||||
|
if (dest->numvals > 0) {
|
||||||
|
n = binarySearchIndex((const char **)dest->names, 0, dest->numvals - 1, (const char *)name);
|
||||||
|
|
||||||
|
if (n < dest->numvals) {
|
||||||
|
if (!strcmp(dest->names[n], name)) {
|
||||||
|
free(name);
|
||||||
|
return dest->values[n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
for (n = 0; n < dest->numvals; n++) {
|
for (n = 0; n < dest->numvals; n++) {
|
||||||
if (!strcmp(dest->names[n], name)) {
|
if (!strcmp(dest->names[n], name)) {
|
||||||
free(name);
|
free(name);
|
||||||
return dest->values[n];
|
return dest->values[n];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
getScopeValueLocalAbort: /* In case something goes wrong... */
|
getScopeValueLocalAbort: /* In case something goes wrong... */
|
||||||
|
|
||||||
|
@ -954,37 +995,39 @@ void deleteScopeValue(ScopeObject *src,
|
||||||
|
|
||||||
/* Traverse upwards through scopes */
|
/* Traverse upwards through scopes */
|
||||||
do {
|
do {
|
||||||
unsigned int n;
|
if (current->numvals == 0) continue;
|
||||||
/* Check for existing value in current scope */
|
|
||||||
for (n = 0; n < current->numvals; n++) {
|
unsigned int n = binarySearchIndex((const char **)current->names, 0, current->numvals - 1, (const char *)name);
|
||||||
if (!strcmp(current->names[n], name)) {
|
|
||||||
unsigned int i;
|
if (n >= current->numvals) continue;
|
||||||
unsigned int newnumvals = dest->numvals - 1;
|
|
||||||
free(name);
|
if (!strcmp(current->names[n], name)) {
|
||||||
/* Wipe out the name and value */
|
unsigned int i;
|
||||||
free(current->names[n]);
|
unsigned int newnumvals = dest->numvals - 1;
|
||||||
deleteValueObject(current->values[n]);
|
free(name);
|
||||||
/* Reorder the tables */
|
/* Wipe out the name and value */
|
||||||
for (i = n; i < current->numvals - 1; i++) {
|
free(current->names[n]);
|
||||||
current->names[i] = current->names[i + 1];
|
deleteValueObject(current->values[n]);
|
||||||
current->values[i] = current->values[i + 1];
|
/* Reorder the tables */
|
||||||
}
|
for (i = n; i < current->numvals - 1; i++) {
|
||||||
/* Resize the tables */
|
current->names[i] = current->names[i + 1];
|
||||||
mem1 = realloc(dest->names, sizeof(IdentifierNode *) * newnumvals);
|
current->values[i] = current->values[i + 1];
|
||||||
if (!mem1) {
|
|
||||||
perror("realloc");
|
|
||||||
goto deleteScopeValueAbort;
|
|
||||||
}
|
|
||||||
mem2 = realloc(dest->values, sizeof(ValueObject *) * newnumvals);
|
|
||||||
if (!mem2) {
|
|
||||||
perror("realloc");
|
|
||||||
goto deleteScopeValueAbort;
|
|
||||||
}
|
|
||||||
dest->names = mem1;
|
|
||||||
dest->values = mem2;
|
|
||||||
dest->numvals = newnumvals;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
/* Resize the tables */
|
||||||
|
mem1 = realloc(dest->names, sizeof(IdentifierNode *) * newnumvals);
|
||||||
|
if (!mem1) {
|
||||||
|
perror("realloc");
|
||||||
|
goto deleteScopeValueAbort;
|
||||||
|
}
|
||||||
|
mem2 = realloc(dest->values, sizeof(ValueObject *) * newnumvals);
|
||||||
|
if (!mem2) {
|
||||||
|
perror("realloc");
|
||||||
|
goto deleteScopeValueAbort;
|
||||||
|
}
|
||||||
|
dest->names = mem1;
|
||||||
|
dest->values = mem2;
|
||||||
|
dest->numvals = newnumvals;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} while ((current = current->parent));
|
} while ((current = current->parent));
|
||||||
|
|
||||||
|
|
29
unicode.c
29
unicode.c
|
@ -43533,6 +43533,35 @@ int binarySearch(const char **strings,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a binary search on an array of strings.
|
||||||
|
*
|
||||||
|
* \param [in] strings The array of string to search.
|
||||||
|
* \param [in] start The index to start searching at.
|
||||||
|
* \param [in] end The index to end searching at.
|
||||||
|
* \param [in] find The string to search for.
|
||||||
|
*
|
||||||
|
* \return The index where the string would appear.
|
||||||
|
*/
|
||||||
|
unsigned int binarySearchIndex(const char **strings,
|
||||||
|
int start,
|
||||||
|
int end,
|
||||||
|
const char *find)
|
||||||
|
{
|
||||||
|
int midpoint;
|
||||||
|
int cmp;
|
||||||
|
if (end < start) return start;
|
||||||
|
midpoint = ((end - start) / 2) + start;
|
||||||
|
cmp = strcmp(strings[midpoint], find);
|
||||||
|
if (cmp == 0)
|
||||||
|
return midpoint;
|
||||||
|
else if (cmp > 0)
|
||||||
|
return binarySearchIndex(strings, start, midpoint - 1, find);
|
||||||
|
else if (cmp < 0)
|
||||||
|
return binarySearchIndex(strings, midpoint + 1, end, find);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a Unicode normative name to a Unicode code point.
|
* Converts a Unicode normative name to a Unicode code point.
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int binarySearch(const char **, int, int, const char *);
|
int binarySearch(const char **, int, int, const char *);
|
||||||
|
unsigned int binarySearchIndex(const char **, int, int, const char *);
|
||||||
long convertNormativeNameToCodePoint(const char *);
|
long convertNormativeNameToCodePoint(const char *);
|
||||||
size_t convertCodePointToUTF8(unsigned long, char *);
|
size_t convertCodePointToUTF8(unsigned long, char *);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue