String literal array values are now shared and deallocated cleanly

git-svn-id: http://picoc.googlecode.com/svn/trunk@197 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-03-11 22:28:42 +00:00
parent 815dc75dbd
commit 0523bd570d
4 changed files with 51 additions and 9 deletions

19
lex.c
View file

@ -236,6 +236,7 @@ enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value)
const char *EndPos;
char *EscBuf;
char *EscBufPos;
char *RegString;
struct Value *ArrayValue;
while (Lexer->Pos != Lexer->End && (*Lexer->Pos != '"' || Escape))
@ -256,11 +257,21 @@ enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value)
for (EscBufPos = EscBuf, Lexer->Pos = StartPos; Lexer->Pos != EndPos;)
*EscBufPos++ = LexUnEscapeCharacter(&Lexer->Pos, EndPos);
ArrayValue = VariableAllocValueAndData(NULL, sizeof(struct ArrayValue), FALSE, NULL, TRUE);
ArrayValue->Typ = CharArrayType;
ArrayValue->Val->Array.Size = EscBufPos - EscBuf + 1;
ArrayValue->Val->Array.Data = TableStrRegister2(EscBuf, EscBufPos - EscBuf);
/* try to find an existing copy of this string literal */
RegString = TableStrRegister2(EscBuf, EscBufPos - EscBuf);
HeapPopStack(EscBuf, EndPos - StartPos);
ArrayValue = VariableStringLiteralGet(RegString);
if (ArrayValue == NULL)
{
/* create and store this string literal */
ArrayValue = VariableAllocValueAndData(NULL, sizeof(struct ArrayValue), FALSE, NULL, TRUE);
ArrayValue->Typ = CharArrayType;
ArrayValue->Val->Array.Size = EscBufPos - EscBuf + 1;
ArrayValue->Val->Array.Data = RegString;
VariableStringLiteralDefine(RegString, ArrayValue);
}
/* create the the pointer for this char* */
Value->Typ = CharPtrType;
Value->Val->Pointer.Segment = ArrayValue;
Value->Val->Pointer.Data.Offset = 0;

View file

@ -311,6 +311,8 @@ void VariableGet(struct ParseState *Parser, const char *Ident, struct Value **LV
void VariableDefinePlatformVar(struct ParseState *Parser, char *Ident, struct ValueType *Typ, union AnyValue *FromValue, int IsWritable);
void VariableStackFrameAdd(struct ParseState *Parser, int NumParams);
void VariableStackFramePop(struct ParseState *Parser);
struct Value *VariableStringLiteralGet(char *Ident);
void VariableStringLiteralDefine(char *Ident, struct Value *Val);
/* library.c */
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[]);

View file

@ -13,8 +13,9 @@
#define LARGE_INT_POWER_OF_TEN 1000000000 /* the largest power of ten which fits in an int on this architecture */
#define ARCH_ALIGN_WORDSIZE sizeof(int) /* memory alignment boundary on this architecture */
#define GLOBAL_TABLE_SIZE 397 /* global variable table */
#define GLOBAL_TABLE_SIZE 97 /* global variable table */
#define STRING_TABLE_SIZE 97 /* shared string table size */
#define STRING_LITERAL_TABLE_SIZE 97 /* string literal table size */
#define PARAMETER_MAX 16 /* maximum number of parameters to a function */
#define LINEBUFFER_MAX 256 /* maximum number of characters on a line */
#define LOCAL_TABLE_SIZE 11 /* size of local variable table (can expand) */

View file

@ -4,6 +4,10 @@
struct Table GlobalTable;
struct TableEntry *GlobalHashTable[GLOBAL_TABLE_SIZE];
/* the table of string literal values */
struct Table StringLiteralTable;
struct TableEntry *StringLiteralHashTable[STRING_LITERAL_TABLE_SIZE];
/* the stack */
struct StackFrame *TopStackFrame = NULL;
@ -12,20 +16,21 @@ struct StackFrame *TopStackFrame = NULL;
void VariableInit()
{
TableInitTable(&GlobalTable, &GlobalHashTable[0], GLOBAL_TABLE_SIZE, TRUE);
TableInitTable(&StringLiteralTable, &StringLiteralHashTable[0], STRING_LITERAL_TABLE_SIZE, TRUE);
TopStackFrame = NULL;
}
/* deallocate the global table */
void VariableCleanup()
/* deallocate the global table and the string literal table */
void VariableTableCleanup(struct Table *HashTable)
{
struct TableEntry *Entry;
struct TableEntry *NextEntry;
struct Value *Val;
int Count;
for (Count = 0; Count < GlobalTable.Size; Count++)
for (Count = 0; Count < HashTable->Size; Count++)
{
for (Entry = GlobalTable.HashTable[Count]; Entry != NULL; Entry = NextEntry)
for (Entry = HashTable->HashTable[Count]; Entry != NULL; Entry = NextEntry)
{
NextEntry = Entry->Next;
Val = Entry->p.v.Val;
@ -37,6 +42,12 @@ void VariableCleanup()
}
}
void VariableCleanup()
{
VariableTableCleanup(&GlobalTable);
VariableTableCleanup(&StringLiteralTable);
}
/* allocate some memory, either on the heap or the stack and check if we've run out */
void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap)
{
@ -216,3 +227,20 @@ void VariableStackFramePop(struct ParseState *Parser)
TopStackFrame = TopStackFrame->PreviousStackFrame;
HeapPopStackFrame();
}
/* get a string literal. assumes that Ident is already registered. NULL if not found */
struct Value *VariableStringLiteralGet(char *Ident)
{
struct Value *LVal = NULL;
if (TableGet(&StringLiteralTable, Ident, &LVal))
return LVal;
else
return NULL;
}
/* define a string literal. assumes that Ident is already registered */
void VariableStringLiteralDefine(char *Ident, struct Value *Val)
{
TableSet(&StringLiteralTable, Ident, Val);
}