mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-18 13:49:59 +01:00
Remove explicit calls to free() and malloc().
This commit is contained in:
@ -44,9 +44,6 @@
|
|||||||
// extra spaces added to handle arity, and another byte to terminate the string.
|
// extra spaces added to handle arity, and another byte to terminate the string.
|
||||||
#define MAX_METHOD_SIGNATURE (MAX_METHOD_NAME + MAX_PARAMETERS + 1)
|
#define MAX_METHOD_SIGNATURE (MAX_METHOD_NAME + MAX_PARAMETERS + 1)
|
||||||
|
|
||||||
// TODO: Get rid of this and use a growable buffer.
|
|
||||||
#define MAX_STRING (1024)
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TOKEN_LEFT_PAREN,
|
TOKEN_LEFT_PAREN,
|
||||||
@ -885,7 +882,8 @@ static int declareVariable(Compiler* compiler)
|
|||||||
{
|
{
|
||||||
SymbolTable* symbols = &compiler->parser->vm->globalSymbols;
|
SymbolTable* symbols = &compiler->parser->vm->globalSymbols;
|
||||||
|
|
||||||
int symbol = addSymbol(symbols, token->start, token->length);
|
int symbol = addSymbol(compiler->parser->vm, symbols,
|
||||||
|
token->start, token->length);
|
||||||
if (symbol == -1)
|
if (symbol == -1)
|
||||||
{
|
{
|
||||||
error(compiler, "Global variable is already defined.");
|
error(compiler, "Global variable is already defined.");
|
||||||
@ -1282,7 +1280,8 @@ static void methodCall(Compiler* compiler, Code instruction,
|
|||||||
consume(compiler, TOKEN_RIGHT_PAREN, "Expect ')' after arguments.");
|
consume(compiler, TOKEN_RIGHT_PAREN, "Expect ')' after arguments.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int symbol = ensureSymbol(&compiler->parser->vm->methods, name, length);
|
int symbol = ensureSymbol(compiler->parser->vm,
|
||||||
|
&compiler->parser->vm->methods, name, length);
|
||||||
|
|
||||||
emit1(compiler, instruction + numArgs, symbol);
|
emit1(compiler, instruction + numArgs, symbol);
|
||||||
}
|
}
|
||||||
@ -1307,7 +1306,8 @@ static void namedCall(Compiler* compiler, bool allowAssignment,
|
|||||||
// Compile the assigned value.
|
// Compile the assigned value.
|
||||||
expression(compiler);
|
expression(compiler);
|
||||||
|
|
||||||
int symbol = ensureSymbol(&compiler->parser->vm->methods, name, length);
|
int symbol = ensureSymbol(compiler->parser->vm,
|
||||||
|
&compiler->parser->vm->methods, name, length);
|
||||||
emit1(compiler, instruction + 1, symbol);
|
emit1(compiler, instruction + 1, symbol);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1363,7 +1363,8 @@ static void unaryOp(Compiler* compiler, bool allowAssignment)
|
|||||||
parsePrecedence(compiler, false, PREC_UNARY + 1);
|
parsePrecedence(compiler, false, PREC_UNARY + 1);
|
||||||
|
|
||||||
// Call the operator method on the left-hand side.
|
// Call the operator method on the left-hand side.
|
||||||
int symbol = ensureSymbol(&compiler->parser->vm->methods, rule->name, 1);
|
int symbol = ensureSymbol(compiler->parser->vm,
|
||||||
|
&compiler->parser->vm->methods, rule->name, 1);
|
||||||
emit1(compiler, CODE_CALL_0, symbol);
|
emit1(compiler, CODE_CALL_0, symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1405,7 +1406,7 @@ static void field(Compiler* compiler, bool allowAssignment)
|
|||||||
if (compiler->fields != NULL)
|
if (compiler->fields != NULL)
|
||||||
{
|
{
|
||||||
// Look up the field, or implicitly define it.
|
// Look up the field, or implicitly define it.
|
||||||
field = ensureSymbol(compiler->fields,
|
field = ensureSymbol(compiler->parser->vm, compiler->fields,
|
||||||
compiler->parser->previous.start,
|
compiler->parser->previous.start,
|
||||||
compiler->parser->previous.length);
|
compiler->parser->previous.length);
|
||||||
}
|
}
|
||||||
@ -1641,7 +1642,8 @@ static void subscript(Compiler* compiler, bool allowAssignment)
|
|||||||
expression(compiler);
|
expression(compiler);
|
||||||
}
|
}
|
||||||
|
|
||||||
int symbol = ensureSymbol(&compiler->parser->vm->methods, name, length);
|
int symbol = ensureSymbol(compiler->parser->vm,
|
||||||
|
&compiler->parser->vm->methods, name, length);
|
||||||
|
|
||||||
// Compile the method call.
|
// Compile the method call.
|
||||||
emit1(compiler, CODE_CALL_0 + numArgs, symbol);
|
emit1(compiler, CODE_CALL_0 + numArgs, symbol);
|
||||||
@ -1684,7 +1686,8 @@ void infixOp(Compiler* compiler, bool allowAssignment)
|
|||||||
parsePrecedence(compiler, false, rule->precedence + 1);
|
parsePrecedence(compiler, false, rule->precedence + 1);
|
||||||
|
|
||||||
// Call the operator method on the left-hand side.
|
// Call the operator method on the left-hand side.
|
||||||
int symbol = ensureSymbol(&compiler->parser->vm->methods,
|
int symbol = ensureSymbol(compiler->parser->vm,
|
||||||
|
&compiler->parser->vm->methods,
|
||||||
rule->name, strlen(rule->name));
|
rule->name, strlen(rule->name));
|
||||||
emit1(compiler, CODE_CALL_1, symbol);
|
emit1(compiler, CODE_CALL_1, symbol);
|
||||||
}
|
}
|
||||||
@ -1860,7 +1863,8 @@ void method(Compiler* compiler, Code instruction, bool isConstructor,
|
|||||||
// Compile the method signature.
|
// Compile the method signature.
|
||||||
signature(&methodCompiler, name, &length);
|
signature(&methodCompiler, name, &length);
|
||||||
|
|
||||||
int symbol = ensureSymbol(&compiler->parser->vm->methods, name, length);
|
int symbol = ensureSymbol(compiler->parser->vm,
|
||||||
|
&compiler->parser->vm->methods, name, length);
|
||||||
|
|
||||||
consume(compiler, TOKEN_LEFT_BRACE, "Expect '{' to begin method body.");
|
consume(compiler, TOKEN_LEFT_BRACE, "Expect '{' to begin method body.");
|
||||||
|
|
||||||
@ -2038,7 +2042,8 @@ static void forStatement(Compiler* compiler)
|
|||||||
emit1(compiler, CODE_LOAD_LOCAL, seqSlot);
|
emit1(compiler, CODE_LOAD_LOCAL, seqSlot);
|
||||||
emit1(compiler, CODE_LOAD_LOCAL, iterSlot);
|
emit1(compiler, CODE_LOAD_LOCAL, iterSlot);
|
||||||
|
|
||||||
int iterateSymbol = ensureSymbol(&compiler->parser->vm->methods,
|
int iterateSymbol = ensureSymbol(compiler->parser->vm,
|
||||||
|
&compiler->parser->vm->methods,
|
||||||
"iterate ", 8);
|
"iterate ", 8);
|
||||||
emit1(compiler, CODE_CALL_1, iterateSymbol);
|
emit1(compiler, CODE_CALL_1, iterateSymbol);
|
||||||
|
|
||||||
@ -2056,7 +2061,8 @@ static void forStatement(Compiler* compiler)
|
|||||||
emit1(compiler, CODE_LOAD_LOCAL, seqSlot);
|
emit1(compiler, CODE_LOAD_LOCAL, seqSlot);
|
||||||
emit1(compiler, CODE_LOAD_LOCAL, iterSlot);
|
emit1(compiler, CODE_LOAD_LOCAL, iterSlot);
|
||||||
|
|
||||||
int iteratorValueSymbol = ensureSymbol(&compiler->parser->vm->methods,
|
int iteratorValueSymbol = ensureSymbol(compiler->parser->vm,
|
||||||
|
&compiler->parser->vm->methods,
|
||||||
"iteratorValue ", 14);
|
"iteratorValue ", 14);
|
||||||
emit1(compiler, CODE_CALL_1, iteratorValueSymbol);
|
emit1(compiler, CODE_CALL_1, iteratorValueSymbol);
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
// [fn] to `ObjClass` [cls].
|
// [fn] to `ObjClass` [cls].
|
||||||
#define NATIVE(cls, name, fn) \
|
#define NATIVE(cls, name, fn) \
|
||||||
{ \
|
{ \
|
||||||
int symbol = ensureSymbol(&vm->methods, name, strlen(name)); \
|
int symbol = ensureSymbol(vm, &vm->methods, name, strlen(name)); \
|
||||||
cls->methods[symbol].type = METHOD_PRIMITIVE; \
|
cls->methods[symbol].type = METHOD_PRIMITIVE; \
|
||||||
cls->methods[symbol].primitive = native_##fn; \
|
cls->methods[symbol].primitive = native_##fn; \
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@
|
|||||||
// pushing callframes.
|
// pushing callframes.
|
||||||
#define FIBER_NATIVE(cls, name, fn) \
|
#define FIBER_NATIVE(cls, name, fn) \
|
||||||
{ \
|
{ \
|
||||||
int symbol = ensureSymbol(&vm->methods, name, strlen(name)); \
|
int symbol = ensureSymbol(vm, &vm->methods, name, strlen(name)); \
|
||||||
cls->methods[symbol].type = METHOD_FIBER; \
|
cls->methods[symbol].type = METHOD_FIBER; \
|
||||||
cls->methods[symbol].fiberPrimitive = native_##fn; \
|
cls->methods[symbol].fiberPrimitive = native_##fn; \
|
||||||
}
|
}
|
||||||
@ -477,7 +477,7 @@ DEF_NATIVE(os_clock)
|
|||||||
static ObjClass* defineClass(WrenVM* vm, const char* name)
|
static ObjClass* defineClass(WrenVM* vm, const char* name)
|
||||||
{
|
{
|
||||||
ObjClass* classObj = wrenNewClass(vm, vm->objectClass, 0);
|
ObjClass* classObj = wrenNewClass(vm, vm->objectClass, 0);
|
||||||
int symbol = addSymbol(&vm->globalSymbols, name, strlen(name));
|
int symbol = addSymbol(vm, &vm->globalSymbols, name, strlen(name));
|
||||||
vm->globals[symbol] = OBJ_VAL(classObj);
|
vm->globals[symbol] = OBJ_VAL(classObj);
|
||||||
return classObj;
|
return classObj;
|
||||||
}
|
}
|
||||||
@ -487,7 +487,8 @@ void wrenInitializeCore(WrenVM* vm)
|
|||||||
// Define the root Object class. This has to be done a little specially
|
// Define the root Object class. This has to be done a little specially
|
||||||
// because it has no superclass and an unusual metaclass (Class).
|
// because it has no superclass and an unusual metaclass (Class).
|
||||||
vm->objectClass = wrenNewSingleClass(vm, 0);
|
vm->objectClass = wrenNewSingleClass(vm, 0);
|
||||||
int objectSymbol = addSymbol(&vm->globalSymbols, "Object", strlen("Object"));
|
int objectSymbol = addSymbol(vm, &vm->globalSymbols,
|
||||||
|
"Object", strlen("Object"));
|
||||||
vm->globals[objectSymbol] = OBJ_VAL(vm->objectClass);
|
vm->globals[objectSymbol] = OBJ_VAL(vm->objectClass);
|
||||||
|
|
||||||
NATIVE(vm->objectClass, "== ", object_eqeq);
|
NATIVE(vm->objectClass, "== ", object_eqeq);
|
||||||
@ -499,7 +500,8 @@ void wrenInitializeCore(WrenVM* vm)
|
|||||||
// Now we can define Class, which is a subclass of Object, but Object's
|
// Now we can define Class, which is a subclass of Object, but Object's
|
||||||
// metaclass.
|
// metaclass.
|
||||||
vm->classClass = wrenNewSingleClass(vm, 0);
|
vm->classClass = wrenNewSingleClass(vm, 0);
|
||||||
int classSymbol = addSymbol(&vm->globalSymbols, "Class", strlen("Class"));
|
int classSymbol = addSymbol(vm, &vm->globalSymbols,
|
||||||
|
"Class", strlen("Class"));
|
||||||
vm->globals[classSymbol] = OBJ_VAL(vm->classClass);
|
vm->globals[classSymbol] = OBJ_VAL(vm->classClass);
|
||||||
|
|
||||||
// Now that Object and Class are defined, we can wire them up to each other.
|
// Now that Object and Class are defined, we can wire them up to each other.
|
||||||
|
|||||||
@ -70,10 +70,9 @@ WrenVM* wrenNewVM(WrenConfiguration* configuration)
|
|||||||
|
|
||||||
void wrenFreeVM(WrenVM* vm)
|
void wrenFreeVM(WrenVM* vm)
|
||||||
{
|
{
|
||||||
clearSymbolTable(&vm->methods);
|
clearSymbolTable(vm, &vm->methods);
|
||||||
clearSymbolTable(&vm->globalSymbols);
|
clearSymbolTable(vm, &vm->globalSymbols);
|
||||||
// TODO: Use VM's allocate fn.
|
wrenReallocate(vm, vm, 0, 0);
|
||||||
free(vm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void collectGarbage(WrenVM* vm);
|
static void collectGarbage(WrenVM* vm);
|
||||||
@ -416,52 +415,42 @@ void initSymbolTable(SymbolTable* symbols)
|
|||||||
symbols->count = 0;
|
symbols->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearSymbolTable(SymbolTable* symbols)
|
void clearSymbolTable(WrenVM* vm, SymbolTable* symbols)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < symbols->count; i++)
|
for (int i = 0; i < symbols->count; i++)
|
||||||
{
|
{
|
||||||
// TODO: Use VM's allocate fn.
|
wrenReallocate(vm, symbols->names[i], 0, 0);
|
||||||
free(symbols->names[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void truncateSymbolTable(SymbolTable* symbols, int count)
|
static int addSymbolUnchecked(WrenVM* vm, SymbolTable* symbols,
|
||||||
|
const char* name, size_t length)
|
||||||
{
|
{
|
||||||
ASSERT(count <= symbols->count, "Cannot truncate to larger size.");
|
symbols->names[symbols->count] = wrenReallocate(vm, NULL, 0,
|
||||||
for (int i = count; i < symbols->count; i++)
|
sizeof(char) * (length + 1));
|
||||||
{
|
|
||||||
// TODO: Use VM's allocate fn.
|
|
||||||
free(symbols->names[i]);
|
|
||||||
}
|
|
||||||
symbols->count = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int addSymbolUnchecked(SymbolTable* symbols, const char* name, size_t length)
|
|
||||||
{
|
|
||||||
// TODO: Get rid of explicit malloc here.
|
|
||||||
symbols->names[symbols->count] = malloc(length + 1);
|
|
||||||
strncpy(symbols->names[symbols->count], name, length);
|
strncpy(symbols->names[symbols->count], name, length);
|
||||||
symbols->names[symbols->count][length] = '\0';
|
symbols->names[symbols->count][length] = '\0';
|
||||||
|
|
||||||
return symbols->count++;
|
return symbols->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int addSymbol(SymbolTable* symbols, const char* name, size_t length)
|
int addSymbol(WrenVM* vm, SymbolTable* symbols, const char* name, size_t length)
|
||||||
{
|
{
|
||||||
// If already present, return an error.
|
// If already present, return an error.
|
||||||
if (findSymbol(symbols, name, length) != -1) return -1;
|
if (findSymbol(symbols, name, length) != -1) return -1;
|
||||||
|
|
||||||
return addSymbolUnchecked(symbols, name, length);
|
return addSymbolUnchecked(vm, symbols, name, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ensureSymbol(SymbolTable* symbols, const char* name, size_t length)
|
int ensureSymbol(WrenVM* vm, SymbolTable* symbols,
|
||||||
|
const char* name, size_t length)
|
||||||
{
|
{
|
||||||
// See if the symbol is already defined.
|
// See if the symbol is already defined.
|
||||||
int existing = findSymbol(symbols, name, length);
|
int existing = findSymbol(symbols, name, length);
|
||||||
if (existing != -1) return existing;
|
if (existing != -1) return existing;
|
||||||
|
|
||||||
// New symbol, so add it.
|
// New symbol, so add it.
|
||||||
return addSymbolUnchecked(symbols, name, length);
|
return addSymbolUnchecked(vm, symbols, name, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int findSymbol(SymbolTable* symbols, const char* name, size_t length)
|
int findSymbol(SymbolTable* symbols, const char* name, size_t length)
|
||||||
|
|||||||
@ -284,20 +284,19 @@ void unpinObj(WrenVM* vm);
|
|||||||
// Initializes the symbol table.
|
// Initializes the symbol table.
|
||||||
void initSymbolTable(SymbolTable* symbols);
|
void initSymbolTable(SymbolTable* symbols);
|
||||||
|
|
||||||
// Removes any symbols added after [count] symbols were defined.
|
|
||||||
void truncateSymbolTable(SymbolTable* symbols, int count);
|
|
||||||
|
|
||||||
// Frees all dynamically allocated memory used by the symbol table, but not the
|
// Frees all dynamically allocated memory used by the symbol table, but not the
|
||||||
// SymbolTable itself.
|
// SymbolTable itself.
|
||||||
void clearSymbolTable(SymbolTable* symbols);
|
void clearSymbolTable(WrenVM* vm, SymbolTable* symbols);
|
||||||
|
|
||||||
// Adds name to the symbol table. Returns the index of it in the table. Returns
|
// Adds name to the symbol table. Returns the index of it in the table. Returns
|
||||||
// -1 if the symbol is already present.
|
// -1 if the symbol is already present.
|
||||||
int addSymbol(SymbolTable* symbols, const char* name, size_t length);
|
int addSymbol(WrenVM* vm, SymbolTable* symbols,
|
||||||
|
const char* name, size_t length);
|
||||||
|
|
||||||
// Adds name to the symbol table. Returns the index of it in the table. Will
|
// Adds name to the symbol table. Returns the index of it in the table. Will
|
||||||
// use an existing symbol if already present.
|
// use an existing symbol if already present.
|
||||||
int ensureSymbol(SymbolTable* symbols, const char* name, size_t length);
|
int ensureSymbol(WrenVM* vm, SymbolTable* symbols,
|
||||||
|
const char* name, size_t length);
|
||||||
|
|
||||||
// Looks up name in the symbol table. Returns its index if found or -1 if not.
|
// Looks up name in the symbol table. Returns its index if found or -1 if not.
|
||||||
int findSymbol(SymbolTable* symbols, const char* name, size_t length);
|
int findSymbol(SymbolTable* symbols, const char* name, size_t length);
|
||||||
|
|||||||
Reference in New Issue
Block a user