From 270e5fe88b0666021a7a6393334db7feeb8245f8 Mon Sep 17 00:00:00 2001
From: John Hodge <tpg@mutabah.net>
Date: Sat, 12 Feb 2011 09:28:35 +0800
Subject: [PATCH] Big bugfixes from trying a Clone/fork bomb

- User heap bugfixes (why was I using sbrk?)
- Threads_Kill (handling non-active threads)
- Proc_Clone (Error handling from MM)
- MM_NewKStack (OOM handling)
---
 Kernel/Makefile.BuildNum.x86_64               |  2 +-
 Kernel/arch/x86/mm_virt.c                     | 20 ++++-
 Kernel/arch/x86/proc.c                        |  7 +-
 Kernel/binary.c                               |  2 +-
 Kernel/include/threads.h                      |  1 +
 Kernel/threads.c                              | 80 ++++++++++++-------
 Modules/Display/VESA/main.c                   | 17 +++-
 Usermode/Applications/bomb_src/main.c         | 24 +++++-
 Usermode/Libraries/crt0.o_src/crt0.asm        |  2 +-
 Usermode/Libraries/ld-acess.so_src/core.asm   | 69 +++++++++++++++-
 Usermode/Libraries/ld-acess.so_src/export.c   |  3 +-
 Usermode/Libraries/libc.so_src/heap.c         | 60 ++++++++++----
 .../Libraries/libspiderscript.so_src/lex.c    |  2 +
 .../Libraries/libspiderscript.so_src/parse.c  | 11 +--
 14 files changed, 238 insertions(+), 62 deletions(-)

diff --git a/Kernel/Makefile.BuildNum.x86_64 b/Kernel/Makefile.BuildNum.x86_64
index 89ed6d5e..205d26c1 100644
--- a/Kernel/Makefile.BuildNum.x86_64
+++ b/Kernel/Makefile.BuildNum.x86_64
@@ -1 +1 @@
-BUILD_NUM = 224
+BUILD_NUM = 225
diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c
index 8882f38e..a07f876d 100644
--- a/Kernel/arch/x86/mm_virt.c
+++ b/Kernel/arch/x86/mm_virt.c
@@ -660,14 +660,28 @@ tVAddr MM_NewKStack(void)
 	Uint	i;
 	for(base = KERNEL_STACKS; base < KERNEL_STACKS_END; base += KERNEL_STACK_SIZE)
 	{
+		// Check if space is free
 		if(MM_GetPhysAddr(base) != 0)	continue;
-		for(i = 0; i < KERNEL_STACK_SIZE; i += 0x1000) {
-			MM_Allocate(base+i);
+		// Allocate
+		//for(i = KERNEL_STACK_SIZE; i -= 0x1000 ; )
+		for(i = 0; i < KERNEL_STACK_SIZE; i += 0x1000 )
+		{
+			if( MM_Allocate(base+i) == 0 )
+			{
+				// On error, print a warning and return error
+				Warning("MM_NewKStack - Out of memory");
+				// - Clean up
+				//for( i += 0x1000 ; i < KERNEL_STACK_SIZE; i += 0x1000 )
+				//	MM_Deallocate(base+i);
+				return 0;
+			}
 		}
+		// Success
 		Log("MM_NewKStack - Allocated %p", base + KERNEL_STACK_SIZE);
 		return base+KERNEL_STACK_SIZE;
 	}
-	Warning("MM_NewKStack - No address space left\n");
+	// No stacks left
+	Warning("MM_NewKStack - No address space left");
 	return 0;
 }
 
diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c
index d3c4ab47..4812609a 100644
--- a/Kernel/arch/x86/proc.c
+++ b/Kernel/arch/x86/proc.c
@@ -566,6 +566,11 @@ int Proc_Clone(Uint *Err, Uint Flags)
 	// Initialise Memory Space (New Addr space or kernel stack)
 	if(Flags & CLONE_VM) {
 		newThread->MemState.CR3 = MM_Clone();
+		// Check for errors
+		if(newThread->MemState.CR3 == 0) {
+			Threads_Kill(newThread, -2);
+			return -1;
+		}
 		newThread->KernelStack = cur->KernelStack;
 	} else {
 		Uint	tmpEbp, oldEsp = esp;
@@ -581,7 +586,7 @@ int Proc_Clone(Uint *Err, Uint Flags)
 		newThread->KernelStack = MM_NewKStack();
 		// Check for errors
 		if(newThread->KernelStack == 0) {
-			free(newThread);
+			Threads_Kill(newThread, -2);
 			return -1;
 		}
 
diff --git a/Kernel/binary.c b/Kernel/binary.c
index aa5d9547..fa49e850 100644
--- a/Kernel/binary.c
+++ b/Kernel/binary.c
@@ -160,7 +160,7 @@ int Proc_Execve(char *File, char **ArgV, char **EnvP)
 	{
 		Log_Warning("BIN", "Proc_Execve - Unable to load '%s'", Threads_GetName(-1));
 		LEAVE('-');
-		Threads_Exit(0, 0);
+		Threads_Exit(0, -10);
 		for(;;);
 	}
 	
diff --git a/Kernel/include/threads.h b/Kernel/include/threads.h
index 6fbc11fc..fc2303c9 100644
--- a/Kernel/include/threads.h
+++ b/Kernel/include/threads.h
@@ -113,6 +113,7 @@ extern tThread	*Proc_GetCurThread(void);
 extern tThread	*Threads_GetThread(Uint TID);
 extern void	Threads_SetPriority(tThread *Thread, int Pri);
 extern int	Threads_Wake(tThread *Thread);
+extern void	Threads_Kill(tThread *Thread, int Status);
 extern void	Threads_AddActive(tThread *Thread);
 extern tThread	*Threads_GetNextToRun(int CPU, tThread *Last);
 
diff --git a/Kernel/threads.c b/Kernel/threads.c
index 87001540..5d15c929 100644
--- a/Kernel/threads.c
+++ b/Kernel/threads.c
@@ -279,6 +279,7 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
 	SHORTLOCK( &glThreadListLock );
 	new->GlobalPrev = NULL;	// Protect against bugs
 	new->GlobalNext = gAllThreads;
+	gAllThreads->GlobalPrev = new;
 	gAllThreads = new;
 	SHORTREL( &glThreadListLock );
 	
@@ -466,15 +467,15 @@ void Threads_Kill(tThread *Thread, int Status)
 	tMsg	*msg;
 	
 	// TODO: Kill all children
-	#if 0
+	#if 1
 	{
 		tThread	*child;
 		// TODO: I should keep a .Parent pointer, and a .Children list
-		for(child = gActiveThreads;
+		for(child = gAllThreads;
 			child;
-			child = child->Next)
+			child = child->GlobalNext)
 		{
-			if(child->PTID == Thread->TID)
+			if(child->Parent == Thread)
 				Threads_Kill(child, -1);
 		}
 	}
@@ -496,29 +497,52 @@ void Threads_Kill(tThread *Thread, int Status)
 	// Lock thread list
 	SHORTLOCK( &glThreadListLock );
 	
-	// Delete from active list
-	#if SCHEDULER_TYPE == SCHED_RR_PRI
-	if( !Threads_int_DelFromQueue( &gaActiveThreads[Thread->Priority], Thread ) )
-	#else
-	if( !Threads_int_DelFromQueue( &gActiveThreads, Thread ) )
-	#endif
+	switch(Thread->Status)
 	{
-		Warning("Proc_Exit - Current thread is not on the active queue");
-		SHORTREL( &glThreadListLock );
-		SHORTREL( &Thread->IsLocked );
-		return;
-	}
+	case THREAD_STAT_PREINIT:	// Only on main list
+		break;
 	
-	// Ensure that we are not rescheduled
-	Thread->Remaining = 0;	// Clear Remaining Quantum
-	Thread->Quantum = 0;	// Clear Quantum to indicate dead thread
-	
-	// Update bookkeeping
-	giNumActiveThreads --;
-	#if SCHEDULER_TYPE == SCHED_LOTTERY
-	if( Thread != Proc_GetCurThread() )
-		giFreeTickets -= caiTICKET_COUNTS[ Thread->Priority ];
-	#endif
+	// Currently active thread
+	case THREAD_STAT_ACTIVE:
+		#if SCHEDULER_TYPE == SCHED_RR_PRI
+		if( Threads_int_DelFromQueue( &gaActiveThreads[Thread->Priority], Thread ) )
+		#else
+		if( Threads_int_DelFromQueue( &gActiveThreads, Thread ) )
+		#endif
+		{
+			// Ensure that we are not rescheduled
+			Thread->Remaining = 0;	// Clear Remaining Quantum
+			Thread->Quantum = 0;	// Clear Quantum to indicate dead thread
+			
+			// Update bookkeeping
+			giNumActiveThreads --;
+			#if SCHEDULER_TYPE == SCHED_LOTTERY
+			if( Thread != Proc_GetCurThread() )
+				giFreeTickets -= caiTICKET_COUNTS[ Thread->Priority ];
+			#endif
+		}
+		else
+		{
+			Log_Warning("Threads",
+				"Threads_Kill - Thread %p(%i,%s) marked as active, but not on list",
+				Thread, Thread->TID, Thread->ThreadName
+				);
+		}
+		break;
+	case THREAD_STAT_SLEEPING:
+		if( !Threads_int_DelFromQueue( &gSleepingThreads, Thread ) )
+		{
+			Log_Warning("Threads",
+				"Threads_Kill - Thread %p(%i,%s) marked as sleeping, but not on list",
+				Thread, Thread->TID, Thread->ThreadName
+				);
+		}
+		break;
+	default:
+		Log_Warning("Threads", "Threads_Kill - BUG Un-checked status (%i)",
+			Thread->Status);
+		break;
+	}
 	
 	// Save exit status
 	Thread->RetStatus = Status;
@@ -534,7 +558,7 @@ void Threads_Kill(tThread *Thread, int Status)
 		Threads_Wake( Thread->Parent );
 	}
 	
-	Log("Thread %i went *hurk* (%i)", Thread->TID, Thread->Status);
+	Log("Thread %i went *hurk* (%i)", Thread->TID, Status);
 	
 	// Release spinlocks
 	SHORTREL( &glThreadListLock );
@@ -915,7 +939,9 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
 	while(gDeleteThreads)
 	{
 		thread = gDeleteThreads->Next;
-		if( IS_LOCKED(&gDeleteThreads->IsLocked) ) {	// Only free if structure is unused
+		// Only free if structure is unused
+		if( !IS_LOCKED(&gDeleteThreads->IsLocked) )
+		{
 			// Set to dead
 			gDeleteThreads->Status = THREAD_STAT_BURIED;
 			// Free name
diff --git a/Modules/Display/VESA/main.c b/Modules/Display/VESA/main.c
index 479be302..1cd6a91f 100644
--- a/Modules/Display/VESA/main.c
+++ b/Modules/Display/VESA/main.c
@@ -2,7 +2,7 @@
  * AcessOS 1
  * Video BIOS Extensions (Vesa) Driver
  */
-#define DEBUG	1
+#define DEBUG	0
 #define VERSION	0x100
 
 #include <acess.h>
@@ -474,10 +474,19 @@ int Vesa_Int_FindMode(tVideo_IOCtl_Mode *data)
 			break;
 		}
 		
-		tmp = gVesa_Modes[i].width * gVesa_Modes[i].height * gVesa_Modes[i].bpp;
-		tmp -= data->width * data->height * data->bpp;
+		tmp = gVesa_Modes[i].width * gVesa_Modes[i].height;
+		tmp -= data->width * data->height;
 		tmp = tmp < 0 ? -tmp : tmp;
-		factor = tmp * 100 / (data->width * data->height * data->bpp);
+		factor = tmp * 100 / (data->width * data->height);
+		
+		if( (data->bpp == 32 || data->bpp == 24)
+		 && (gVesa_Modes[i].bpp == 32 || gVesa_Modes[i].bpp == 24) )
+		{
+			
+		}
+		else {
+			factor *= 10;
+		}
 		
 		LOG("factor = %i", factor);
 		
diff --git a/Usermode/Applications/bomb_src/main.c b/Usermode/Applications/bomb_src/main.c
index d7923224..944d6c32 100644
--- a/Usermode/Applications/bomb_src/main.c
+++ b/Usermode/Applications/bomb_src/main.c
@@ -46,8 +46,30 @@ int main(int argc, char *argv[])
 		for(;;)	clone(CLONE_VM, 0);
 	}
 	else {
-		for(;;)	clone(0, malloc(512-16)+512-16);
+		for(;;)
+		{
+			const int stackSize = 512-16; 
+			const int stackOffset = 65; 
+			char *stack = calloc(1, stackSize);
+			 int	tid;
+			if( !stack ) {
+				printf("Outta heap space!\n");
+				return 0;
+			}
+			tid = clone(0, stack+stackSize-stackOffset);
+			if( tid == 0 )
+			{
+				// Sleep forever (TODO: Fix up the stack so it can nuke)
+				for(;;) sleep();
+			}
+			if( tid < 0 ) {
+				printf("Clone failed\n");
+				return 0;
+			}
+			printf("stack = %p, tid = %i\n", stack, tid);
+		}
 	}
 
+	printf("RETURN!?\n");
 	return 0;
 }
diff --git a/Usermode/Libraries/crt0.o_src/crt0.asm b/Usermode/Libraries/crt0.o_src/crt0.asm
index b923d184..b8f52703 100644
--- a/Usermode/Libraries/crt0.o_src/crt0.asm
+++ b/Usermode/Libraries/crt0.o_src/crt0.asm
@@ -15,5 +15,5 @@ _start:
 start:
 	call main
 	push eax
-	call _exit	
+	call _exit
 	jmp $	; This should never be reached
diff --git a/Usermode/Libraries/ld-acess.so_src/core.asm b/Usermode/Libraries/ld-acess.so_src/core.asm
index c44dc535..0bf80c12 100644
--- a/Usermode/Libraries/ld-acess.so_src/core.asm
+++ b/Usermode/Libraries/ld-acess.so_src/core.asm
@@ -10,9 +10,76 @@ _errno:
 	dd	0
 
 [section .text]
-; --- Process Controll ---
+; DEST
+; SRC
+_memcpy:
+	push ebp
+	mov ebp, esp
+	push edi
+	push esi	; DI and SI must be maintained, CX doesn't
+	
+	mov ecx, [ebp+16]
+	mov esi, [ebp+12]
+	mov edi, [ebp+8]
+	rep movsb
+	
+	pop esi
+	pop edi
+	pop ebp
+	ret
+
+; --- Process Control ---
 SYSCALL1	_exit, SYS_EXIT
+
+%if 0
 SYSCALL2	clone, SYS_CLONE
+%else
+[global clone:func]
+clone:
+	push ebp
+	mov ebp, esp
+	push ebx
+	
+	mov ebx, [ebp+12]	; Get new stack pointer
+	
+	; Check if the new stack is being used
+	test ebx, ebx
+	jz .doCall
+	; Modify it to include the calling function (and this)
+	%if 0
+	mov eax, [ebp]	; Get old stack frame
+	sub eax, ebp	; Get size
+	sub ebx, eax	; Alter new stack pointer
+	push eax	; < Size
+	push DWORD [ebp]	; < Source
+	push ebx	; < Dest
+	call _memcpy
+	add esp, 4*3	; Restore stack
+	; EBX should still be the new stack pointer
+	mov eax, [ebp]	; Save old stack frame pointer in new stack
+	mov [ebx-4], eax
+	mov eax, [ebp-4]	; Save EBX there too
+	mov [ebx-8], eax
+	sub ebx, 8	; Update stack pointer for system
+	%else
+	; Quick hack, just this stack frame
+	mov eax, [ebp+4]
+	mov [ebx-4], eax	; Return
+	mov [ebx-8], ebx	; EBP
+	mov DWORD [ebx-12], 0	; EBX
+	sub ebx, 12
+	%endif
+.doCall:
+	mov eax, SYS_CLONE
+	mov ecx, ebx	; Stack
+	mov ebx, [ebp+8]	; Flags
+	SYSCALL_OP
+	mov [_errno], ebx
+	pop ebx
+	pop ebp
+	ret
+%endif
+
 SYSCALL2	kill, SYS_KILL
 SYSCALL0	yield, SYS_YIELD
 SYSCALL0	sleep, SYS_SLEEP
diff --git a/Usermode/Libraries/ld-acess.so_src/export.c b/Usermode/Libraries/ld-acess.so_src/export.c
index 867e17fb..9aa47e6a 100644
--- a/Usermode/Libraries/ld-acess.so_src/export.c
+++ b/Usermode/Libraries/ld-acess.so_src/export.c
@@ -60,7 +60,8 @@ const struct {
 	EXP(_SysOpenChild),
 	
 	EXP(_SysGetPhys),
-	EXP(_SysAllocate)
+	EXP(_SysAllocate),
+	EXP(_SysDebug)
 
 };
 
diff --git a/Usermode/Libraries/libc.so_src/heap.c b/Usermode/Libraries/libc.so_src/heap.c
index d0490707..14066e9e 100644
--- a/Usermode/Libraries/libc.so_src/heap.c
+++ b/Usermode/Libraries/libc.so_src/heap.c
@@ -36,6 +36,7 @@ EXPORT void	free(void *mem);
 EXPORT void	*realloc(void *mem, Uint bytes);
 EXPORT void	*sbrk(int increment);
 LOCAL void	*extendHeap(int bytes);
+static void *FindHeapBase();
 LOCAL uint	brk(Uint newpos);
 
 //Code
@@ -68,7 +69,7 @@ EXPORT void *malloc(size_t bytes)
 	
 	while((Uint)curBlock < (Uint)_heap_end)
 	{
-		//SysDebug(" malloc: curBlock = 0x%x, curBlock->magic = 0x%x\n", curBlock, curBlock->magic);
+		//_SysDebug(" malloc: curBlock = 0x%x, curBlock->magic = 0x%x\n", curBlock, curBlock->magic);
 		if(curBlock->magic == MAGIC_FREE)
 		{
 			if(curBlock->size == bestSize)
@@ -81,14 +82,14 @@ EXPORT void *malloc(size_t bytes)
 		else if(curBlock->magic != MAGIC)
 		{
 			//Corrupt Heap
-			//SysDebug("malloc: Corrupt Heap\n");
+			_SysDebug("malloc: Corrupt Heap\n");
 			return NULL;
 		}
 		curBlock = (heap_head*)((Uint)curBlock + curBlock->size);
 	}
 	
 	if((Uint)curBlock < (Uint)_heap_start) {
-		//SysDebug("malloc: Heap underrun for some reason\n");
+		_SysDebug("malloc: Heap underrun for some reason\n");
 		return NULL;
 	}
 	
@@ -102,7 +103,7 @@ EXPORT void *malloc(size_t bytes)
 	if(!closestMatch) {
 		curBlock = extendHeap(bestSize);	//Allocate more
 		if(curBlock == NULL) {
-			//SysDebug("malloc: Out of Heap Space\n");
+			_SysDebug("malloc: Out of Heap Space\n");
 			return NULL;
 		}
 		curBlock->magic = MAGIC;
@@ -243,7 +244,6 @@ LOCAL void *extendHeap(int bytes)
 	if(foot == (void*)-1)
 		return NULL;
 	
-	
 	//Create New Block
 	// Header
 	head->magic = MAGIC_FREE;	//Unallocated
@@ -275,24 +275,52 @@ LOCAL void *extendHeap(int bytes)
 */
 EXPORT void *sbrk(int increment)
 {
-	size_t newEnd;
 	static size_t oldEnd = 0;
 	static size_t curEnd = 0;
 
-	//_SysDebug("sbrk: (increment=%i)\n", increment);
+	//_SysDebug("sbrk: (increment=%i)", increment);
 
-	if (oldEnd == 0)	curEnd = oldEnd = brk(0);
+	if (curEnd == 0) {
+		oldEnd = curEnd = (size_t)FindHeapBase();
+		//_SysAllocate(curEnd);	// Allocate the first page
+	}
 
-	//SysDebug(" sbrk: oldEnd = 0x%x\n", oldEnd);
+	//_SysDebug(" sbrk: oldEnd = 0x%x", oldEnd);
 	if (increment == 0)	return (void *) curEnd;
 
-	newEnd = curEnd + increment;
-
-	if (brk(newEnd) == curEnd)	return (void *) -1;
 	oldEnd = curEnd;
-	curEnd = newEnd;
-	//SysDebug(" sbrk: newEnd = 0x%x\n", newEnd);
 
+	// Single Page
+	if( (curEnd & 0xFFF) && (curEnd & 0xFFF) + increment < 0x1000 )
+	{
+		//if( curEnd & 0xFFF == 0 )
+		//{
+		//	if( !_SysAllocate(curEnd) )
+		//	{
+		//		_SysDebug("sbrk - Error allocating memory");
+		//		return (void*)-1;
+		//	}
+		//}
+		curEnd += increment;
+		//_SysDebug("sbrk: RETURN %p (single page, no alloc)", (void *) oldEnd);
+		return (void *)oldEnd;
+	}
+
+	increment -= curEnd & 0xFFF;
+	curEnd += 0xFFF;	curEnd &= ~0xFFF;
+	while( increment > 0 )
+	{
+		if( !_SysAllocate(curEnd) )
+		{
+			// Error?
+			_SysDebug("sbrk - Error allocating memory");
+			return (void*)-1;
+		}
+		increment -= 0x1000;
+		curEnd += 0x1000;
+	}
+
+	//_SysDebug("sbrk: RETURN %p", (void *) oldEnd);
 	return (void *) oldEnd;
 }
 
@@ -364,7 +392,7 @@ LOCAL uint brk(Uint newpos)
 	uint	ret = curpos;
 	 int	delta;
 	
-	//_SysDebug("brk: (newpos=0x%x)", newpos);
+	_SysDebug("brk: (newpos=0x%x)", newpos);
 	
 	// Find initial position
 	if(curpos == 0)	curpos = (uint)FindHeapBase();
@@ -375,7 +403,7 @@ LOCAL uint brk(Uint newpos)
 	if(newpos < curpos)	return newpos;
 	
 	delta = newpos - curpos;
-	//_SysDebug(" brk: delta = 0x%x", delta);
+	_SysDebug(" brk: delta = 0x%x", delta);
 	
 	// Do we need to add pages
 	if(curpos & 0xFFF && (curpos & 0xFFF) + delta < 0x1000)
diff --git a/Usermode/Libraries/libspiderscript.so_src/lex.c b/Usermode/Libraries/libspiderscript.so_src/lex.c
index 7121ce13..fd395e0f 100644
--- a/Usermode/Libraries/libspiderscript.so_src/lex.c
+++ b/Usermode/Libraries/libspiderscript.so_src/lex.c
@@ -7,6 +7,8 @@
 #include <stdio.h>
 #include <string.h>
 
+// Make the scope character ('.') be a symbol, otherwise it's just
+// a ident character
 #define USE_SCOPE_CHAR	0
 
 #define DEBUG	0
diff --git a/Usermode/Libraries/libspiderscript.so_src/parse.c b/Usermode/Libraries/libspiderscript.so_src/parse.c
index f32f876f..0b481980 100644
--- a/Usermode/Libraries/libspiderscript.so_src/parse.c
+++ b/Usermode/Libraries/libspiderscript.so_src/parse.c
@@ -201,7 +201,6 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser)
 	
 	// Return from a method
 	case TOK_RWD_RETURN:
-		//printf("return\n");
 		GetToken(Parser);
 		ret = AST_NewUniOp(Parser, NODETYPE_RETURN, Parse_DoExpr0(Parser));
 		break;
@@ -662,11 +661,11 @@ tAST_Node *Parse_GetVariable(tParser *Parser)
 }
 
 /**
- * \brief Get an identifier (constand or function call)
+ * \brief Get an identifier (constant or function call)
  */
 tAST_Node *Parse_GetIdent(tParser *Parser)
 {
-	tAST_Node	*ret;
+	tAST_Node	*ret = NULL;
 	char	*name;
 	SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT );
 	name = strndup( Parser->TokenStr, Parser->TokenLen );
@@ -674,7 +673,9 @@ tAST_Node *Parse_GetIdent(tParser *Parser)
 	#if 0
 	while( GetToken(Parser) == TOK_SCOPE )
 	{
-		ret = AST_New
+		ret = AST_NewScopeDereference( Parser, ret, name );
+		SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT );
+		name = strndup( Parser->TokenStr, Parser->TokenLen );
 	}
 	PutBack(Parser);
 	#endif
@@ -703,7 +704,7 @@ tAST_Node *Parse_GetIdent(tParser *Parser)
 		}
 	}
 	else {
-		// Runtime Constant
+		// Runtime Constant / Variable (When implemented)
 		#if DEBUG >= 2
 		printf("Parse_GetIdent: Referencing '%s'\n", name);
 		#endif
-- 
GitLab