mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-12 14:48:40 +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.
|
||||
#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
|
||||
{
|
||||
TOKEN_LEFT_PAREN,
|
||||
@ -885,7 +882,8 @@ static int declareVariable(Compiler* compiler)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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.");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -1307,7 +1306,8 @@ static void namedCall(Compiler* compiler, bool allowAssignment,
|
||||
// Compile the assigned value.
|
||||
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);
|
||||
}
|
||||
else
|
||||
@ -1363,7 +1363,8 @@ static void unaryOp(Compiler* compiler, bool allowAssignment)
|
||||
parsePrecedence(compiler, false, PREC_UNARY + 1);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@ -1405,7 +1406,7 @@ static void field(Compiler* compiler, bool allowAssignment)
|
||||
if (compiler->fields != NULL)
|
||||
{
|
||||
// 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.length);
|
||||
}
|
||||
@ -1641,7 +1642,8 @@ static void subscript(Compiler* compiler, bool allowAssignment)
|
||||
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.
|
||||
emit1(compiler, CODE_CALL_0 + numArgs, symbol);
|
||||
@ -1684,7 +1686,8 @@ void infixOp(Compiler* compiler, bool allowAssignment)
|
||||
parsePrecedence(compiler, false, rule->precedence + 1);
|
||||
|
||||
// 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));
|
||||
emit1(compiler, CODE_CALL_1, symbol);
|
||||
}
|
||||
@ -1860,7 +1863,8 @@ void method(Compiler* compiler, Code instruction, bool isConstructor,
|
||||
// Compile the method signature.
|
||||
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.");
|
||||
|
||||
@ -2038,7 +2042,8 @@ static void forStatement(Compiler* compiler)
|
||||
emit1(compiler, CODE_LOAD_LOCAL, seqSlot);
|
||||
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);
|
||||
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, iterSlot);
|
||||
|
||||
int iteratorValueSymbol = ensureSymbol(&compiler->parser->vm->methods,
|
||||
int iteratorValueSymbol = ensureSymbol(compiler->parser->vm,
|
||||
&compiler->parser->vm->methods,
|
||||
"iteratorValue ", 14);
|
||||
emit1(compiler, CODE_CALL_1, iteratorValueSymbol);
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
// [fn] to `ObjClass` [cls].
|
||||
#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].primitive = native_##fn; \
|
||||
}
|
||||
@ -22,7 +22,7 @@
|
||||
// pushing callframes.
|
||||
#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].fiberPrimitive = native_##fn; \
|
||||
}
|
||||
@ -477,7 +477,7 @@ DEF_NATIVE(os_clock)
|
||||
static ObjClass* defineClass(WrenVM* vm, const char* name)
|
||||
{
|
||||
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);
|
||||
return classObj;
|
||||
}
|
||||
@ -487,7 +487,8 @@ void wrenInitializeCore(WrenVM* vm)
|
||||
// Define the root Object class. This has to be done a little specially
|
||||
// because it has no superclass and an unusual metaclass (Class).
|
||||
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);
|
||||
|
||||
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
|
||||
// metaclass.
|
||||
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);
|
||||
|
||||
// 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)
|
||||
{
|
||||
clearSymbolTable(&vm->methods);
|
||||
clearSymbolTable(&vm->globalSymbols);
|
||||
// TODO: Use VM's allocate fn.
|
||||
free(vm);
|
||||
clearSymbolTable(vm, &vm->methods);
|
||||
clearSymbolTable(vm, &vm->globalSymbols);
|
||||
wrenReallocate(vm, vm, 0, 0);
|
||||
}
|
||||
|
||||
static void collectGarbage(WrenVM* vm);
|
||||
@ -416,52 +415,42 @@ void initSymbolTable(SymbolTable* symbols)
|
||||
symbols->count = 0;
|
||||
}
|
||||
|
||||
void clearSymbolTable(SymbolTable* symbols)
|
||||
void clearSymbolTable(WrenVM* vm, SymbolTable* symbols)
|
||||
{
|
||||
for (int i = 0; i < symbols->count; i++)
|
||||
{
|
||||
// TODO: Use VM's allocate fn.
|
||||
free(symbols->names[i]);
|
||||
wrenReallocate(vm, symbols->names[i], 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
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.");
|
||||
for (int i = count; i < symbols->count; i++)
|
||||
{
|
||||
// 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);
|
||||
symbols->names[symbols->count] = wrenReallocate(vm, NULL, 0,
|
||||
sizeof(char) * (length + 1));
|
||||
strncpy(symbols->names[symbols->count], name, length);
|
||||
symbols->names[symbols->count][length] = '\0';
|
||||
|
||||
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 (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.
|
||||
int existing = findSymbol(symbols, name, length);
|
||||
if (existing != -1) return existing;
|
||||
|
||||
// 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)
|
||||
|
||||
@ -284,20 +284,19 @@ void unpinObj(WrenVM* vm);
|
||||
// Initializes the symbol table.
|
||||
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
|
||||
// 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
|
||||
// -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
|
||||
// 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.
|
||||
int findSymbol(SymbolTable* symbols, const char* name, size_t length);
|
||||
|
||||
Reference in New Issue
Block a user