Skip to content

Commit 167ed36

Browse files
author
Alex Cole
committed
Shorten the code even more.
1 parent 1618cc8 commit 167ed36

1 file changed

Lines changed: 14 additions & 31 deletions

File tree

core.inc

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -212,26 +212,19 @@ native deleteproperty(id = 0, const name[] = "", value = cellmin);
212212
*/
213213
native bool:existproperty(id = 0, const name[] = "", value = cellmin);
214214

215-
/* */ native __packpubvar(dest[], const source[], maxlength = sizeof (dest)) = strpack;
215+
/* */ native __unpackpubvar(dest[], const source[], maxlength = sizeof (dest)) = strunpack;
216216

217217
static stock __findpubvar(const __name[])
218218
{
219219
// Scans the AMX header to find a public variable and returns the address of the entry, or `0`
220220
// if there isn't one. Can't use `static` here because we rely on the string being all `\0`s.
221-
new __packed[64 char], __offset = 0;
221+
new __unpacked[64], __offset = 0;
222222
const __cellbytes = cellbits / charbits;
223223
// In 32-bit scripts this is `64`, but in 64-bit scripts it is only `96`. Part of the header
224224
// entry is always 32-bit, regardless of the cell bit width. We need it in bytes.
225225
const __defsize = __cellbytes + 4;
226-
// Convert the normal input string to a C string, via a packed string. Pack it, then reverse
227-
// every individual cell to get the correct final memory layout.
228-
__packpubvar(__packed, __name);
229-
// All cells have trailing nulls, so this can only be true when all bytes are non-zero because
230-
// the top byte is non-zero.
231-
while ((__packed[__offset] = swapchars(__packed[__offset])) > (cellmax >>> (charbits - 1)))
232-
{
233-
++__offset;
234-
}
226+
// Ensure the input is unpacked for easier (to code) comparisons.
227+
__unpackpubvar(__unpacked, __name);
235228
new __start, __end;
236229
// Now we start doing assembly magic to dig through the AMX header itself.
237230
// Get the offset from the start of the file to the start of the data segment (DAT).
@@ -258,12 +251,11 @@ static stock __findpubvar(const __name[])
258251
#emit ADD
259252
#emit ADD.C __cellbytes
260253
#emit STOR.S.pri __end
261-
// Loop through the
254+
// Loop through the list of public variables and compare their names.
262255
new __s0, __s1, __s2;
263256
// This could be made a binary search, but it would complicate the code a lot, and isn't worth
264-
// it given how rare public variables are. In fact, amx_assembly doesn't even bother with
265-
// comparing four bytes at once and just loads and compares single characters instead, which is
266-
// an option... It would simplify the code even more.
257+
// it given how rare public variables are. I actually wrote a more complex version that could
258+
// compare two packed C strings, but shorter is better here.
267259
while (__start != __end)
268260
{
269261
// Load the pointer.
@@ -278,26 +270,17 @@ static stock __findpubvar(const __name[])
278270
{
279271
#emit LREF.S.pri __s0
280272
#emit STOR.S.pri __s2
281-
if (__packed[__s1] == __s2)
282-
{
283-
__s0 += __cellbytes;
284-
++__s1;
285-
continue;
286-
}
287-
// They are different, but this could be because of junk data loaded from after the end
288-
// of the pubvar name in the AMX. We need to determine whether the `NULL` comes first.
289-
__s1 = __packed[__s1];
290-
while (__s1 && (__s1 & 0xFF) == (__s2 & 0xFF))
273+
if (__unpacked[__s1] != __s2 & 0xFF)
291274
{
292-
__s1 >>>= 8;
293-
__s2 >>>= 8;
275+
break;
294276
}
295-
if ((__s1 & 0xFF) || (__s2 & 0xFF))
277+
if (__unpacked[__s1] == '\0')
296278
{
297-
break;
279+
// The end of the string.
280+
return __start - __cellbytes;
298281
}
299-
// Enough matches.
300-
return __start - __cellbytes;
282+
++__s0;
283+
++__s1;
301284
}
302285
// This wasn't a match. Try the next one.
303286
__start += __defsize;

0 commit comments

Comments
 (0)