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:
parent
815dc75dbd
commit
0523bd570d
19
lex.c
19
lex.c
|
@ -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;
|
||||
|
|
2
picoc.h
2
picoc.h
|
@ -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)[]);
|
||||
|
|
|
@ -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) */
|
||||
|
|
36
variable.c
36
variable.c
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue