buffers to use 0x4000000 as base offset instead of using negative
values, to reduce possibility of && and || operators (which do float
compares to 0 in the vm) breaking on string variables
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10066
d7cf8633-e32d-0410-b094-
e92efae38249
}
sizebuf_t vm_tempstringsbuf;
}
sizebuf_t vm_tempstringsbuf;
+#define PRVM_KNOWNSTRINGBASE 0x40000000
const char *PRVM_GetString(int num)
{
const char *PRVM_GetString(int num)
{
- if (num < prog->stringssize)
- return prog->strings + num;
- else
-#if 1
- if (num <= prog->stringssize + vm_tempstringsbuf.maxsize)
- {
- num -= prog->stringssize;
- if (num < vm_tempstringsbuf.cursize)
- return (char *)vm_tempstringsbuf.data + num;
- else
- {
- VM_Warning("PRVM_GetString: Invalid temp-string offset (%i >= %i vm_tempstringsbuf.cursize)\n", num, vm_tempstringsbuf.cursize);
- return "";
- }
- }
+ // invalid
+ VM_Warning("PRVM_GetString: Invalid string offset (%i < 0)\n", num);
+ return "";
+ }
+ else if (num < prog->stringssize)
+ {
+ // constant string from progs.dat
+ return prog->strings + num;
+ }
+ else if (num <= prog->stringssize + vm_tempstringsbuf.maxsize)
+ {
+ // tempstring returned by engine to QC (becomes invalid after returning to engine)
+ num -= prog->stringssize;
+ if (num < vm_tempstringsbuf.cursize)
+ return (char *)vm_tempstringsbuf.data + num;
- VM_Warning("PRVM_GetString: Invalid constant-string offset (%i >= %i prog->stringssize)\n", num, prog->stringssize);
+ VM_Warning("PRVM_GetString: Invalid temp-string offset (%i >= %i vm_tempstringsbuf.cursize)\n", num, vm_tempstringsbuf.cursize);
+ else if (num & PRVM_KNOWNSTRINGBASE)
- num = -1 - num;
-#if 0
- if (num >= (1<<30))
- {
- // special range reserved for tempstrings
- num -= (1<<30);
- if (num < vm_tempstringsbuf.cursize)
- return (char *)vm_tempstringsbuf.data + num;
- else
- {
- VM_Warning("PRVM_GetString: Invalid temp-string offset (%i >= %i vm_tempstringsbuf.cursize)\n", num, vm_tempstringsbuf.cursize);
- return "";
- }
- }
- else
-#endif
- if (num < prog->numknownstrings)
+ // allocated string
+ num = num - PRVM_KNOWNSTRINGBASE;
+ if (num >= 0 && num < prog->numknownstrings)
{
if (!prog->knownstrings[num])
{
{
if (!prog->knownstrings[num])
{
+ else
+ {
+ // invalid string offset
+ VM_Warning("PRVM_GetString: Invalid constant-string offset (%i >= %i prog->stringssize)\n", num, prog->stringssize);
+ return "";
+ }
}
const char *PRVM_ChangeEngineString(int i, const char *s)
{
const char *old;
}
const char *PRVM_ChangeEngineString(int i, const char *s)
{
const char *old;
+ i = i - PRVM_KNOWNSTRINGBASE;
if(i < 0 || i >= prog->numknownstrings)
PRVM_ERROR("PRVM_ChangeEngineString: s is not an engine string");
old = prog->knownstrings[i];
if(i < 0 || i >= prog->numknownstrings)
PRVM_ERROR("PRVM_ChangeEngineString: s is not an engine string");
old = prog->knownstrings[i];
if (s >= (char *)vm_tempstringsbuf.data && s < (char *)vm_tempstringsbuf.data + vm_tempstringsbuf.maxsize)
#if 1
return prog->stringssize + (s - (char *)vm_tempstringsbuf.data);
if (s >= (char *)vm_tempstringsbuf.data && s < (char *)vm_tempstringsbuf.data + vm_tempstringsbuf.maxsize)
#if 1
return prog->stringssize + (s - (char *)vm_tempstringsbuf.data);
-#else
- return -1 - ((1<<30) + (s - (char *)vm_tempstringsbuf.data));
#endif
// see if it's a known string address
for (i = 0;i < prog->numknownstrings;i++)
if (prog->knownstrings[i] == s)
#endif
// see if it's a known string address
for (i = 0;i < prog->numknownstrings;i++)
if (prog->knownstrings[i] == s)
+ return PRVM_KNOWNSTRINGBASE + i;
// new unknown engine string
if (developer_insane.integer)
Con_DPrintf("new engine string %p = \"%s\"\n", s, s);
// new unknown engine string
if (developer_insane.integer)
Con_DPrintf("new engine string %p = \"%s\"\n", s, s);
prog->knownstrings_freeable[i] = false;
if(prog->leaktest_active)
prog->knownstrings_origin[i] = NULL;
prog->knownstrings_freeable[i] = false;
if(prog->leaktest_active)
prog->knownstrings_origin[i] = NULL;
+ return PRVM_KNOWNSTRINGBASE + i;
}
// temp string handling
}
// temp string handling
if(prog->leaktest_active)
memcpy((char **)prog->knownstrings_origin, oldstrings_origin, prog->numknownstrings * sizeof(char *));
}
if(prog->leaktest_active)
memcpy((char **)prog->knownstrings_origin, oldstrings_origin, prog->numknownstrings * sizeof(char *));
}
- // TODO why not Mem_Free the old ones?
+ if (oldstrings)
+ Mem_Free(oldstrings);
+ if (oldstrings_freeable)
+ Mem_Free((unsigned char *)oldstrings_freeable);
+ if (oldstrings_origin)
+ Mem_Free(oldstrings_origin);
}
prog->numknownstrings++;
}
}
prog->numknownstrings++;
}
prog->knownstrings_origin[i] = PRVM_AllocationOrigin();
if (pointer)
*pointer = (char *)(prog->knownstrings[i]);
prog->knownstrings_origin[i] = PRVM_AllocationOrigin();
if (pointer)
*pointer = (char *)(prog->knownstrings[i]);
+ return PRVM_KNOWNSTRINGBASE + i;
}
void PRVM_FreeString(int num)
}
void PRVM_FreeString(int num)
PRVM_ERROR("PRVM_FreeString: attempt to free a NULL string");
else if (num >= 0 && num < prog->stringssize)
PRVM_ERROR("PRVM_FreeString: attempt to free a constant string");
PRVM_ERROR("PRVM_FreeString: attempt to free a NULL string");
else if (num >= 0 && num < prog->stringssize)
PRVM_ERROR("PRVM_FreeString: attempt to free a constant string");
- else if (num < 0 && num >= -prog->numknownstrings)
+ else if (num >= PRVM_KNOWNSTRINGBASE && num < PRVM_KNOWNSTRINGBASE + prog->numknownstrings)
+ num = num - PRVM_KNOWNSTRINGBASE;
if (!prog->knownstrings[num])
PRVM_ERROR("PRVM_FreeString: attempt to free a non-existent or already freed string");
if (!prog->knownstrings_freeable[num])
if (!prog->knownstrings[num])
PRVM_ERROR("PRVM_FreeString: attempt to free a non-existent or already freed string");
if (!prog->knownstrings_freeable[num])