Remove explicit calls to free() and malloc().

This commit is contained in:
Bob Nystrom
2013-12-27 09:07:35 -08:00
parent a8c725ea3f
commit afdcafcecb
4 changed files with 45 additions and 49 deletions

View File

@ -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);

View File

@ -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.

View File

@ -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)

View File

@ -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);