Respect object boundaries in search_for_symbol().
[sbcl.git] / src / runtime / search.c
blobf2ed105224ff575121e37edc82d81745aa03d162
1 /*
2 * This software is part of the SBCL system. See the README file for
3 * more information.
5 * This software is derived from the CMU CL system, which was
6 * written at Carnegie Mellon University and released into the
7 * public domain. The software is in the public domain and is
8 * provided with absolutely no warranty. See the COPYING and CREDITS
9 * files for more information.
12 #include <string.h>
14 #include "sbcl.h"
15 #include "runtime.h"
16 #include "os.h"
17 #include "search.h"
18 #include "thread.h"
19 #include "gc-internal.h"
20 #include "genesis/primitive-objects.h"
22 boolean search_for_type(int type, lispobj **start, int *count)
24 lispobj obj;
26 while ((*count == -1 || (*count > 0)) &&
27 is_valid_lisp_addr((os_vm_address_t)*start)) {
28 obj = **start;
29 if (*count != -1)
30 *count -= 2;
32 if (widetag_of(obj) == type)
33 return 1;
35 (*start) += 2;
37 return 0;
40 static int __attribute__((unused)) strcmp_ucs4_ascii(uint32_t* a, char* b)
42 int i = 0;
44 // Lisp terminates UCS4 strings with NULL bytes - probably to no avail
45 // since null-terminated UCS4 isn't a common convention for any foreign ABI -
46 // but length has been pre-checked, so hitting an ASCII null is a win.
47 while (a[i] == ((unsigned char*)b)[i])
48 if (b[i] == 0)
49 return 0;
50 else
51 ++i;
52 return a[i] - b[i]; // same return convention as strcmp()
55 lispobj* search_for_symbol(char *name, lispobj start, lispobj end)
57 lispobj* where = (lispobj*)start;
58 lispobj* limit = (lispobj*)end;
59 struct symbol *symbol;
60 int namelen = strlen(name);
62 while (where < limit) {
63 lispobj word = *where;
64 if (widetag_of(word) == SYMBOL_WIDETAG &&
65 lowtag_of((symbol = (struct symbol *)where)->name)
66 == OTHER_POINTER_LOWTAG) {
67 struct vector *symbol_name = VECTOR(symbol->name);
68 if (is_valid_lisp_addr((os_vm_address_t)symbol_name) &&
69 /* FIXME: Broken with more than one type of string
70 (i.e. even broken given (VECTOR NIL) */
71 ((widetag_of(symbol_name->header) == SIMPLE_BASE_STRING_WIDETAG
72 && fixnum_value(symbol_name->length) == namelen
73 && !strcmp((char *)symbol_name->data, name))
74 #ifdef LISP_FEATURE_SB_UNICODE
75 || (widetag_of(symbol_name->header) == SIMPLE_CHARACTER_STRING_WIDETAG
76 && fixnum_value(symbol_name->length) == namelen
77 && !strcmp_ucs4_ascii((uint32_t*)symbol_name->data, name))
78 #endif
80 return where;
82 where += is_cons_half(word) ? 2 : sizetab[widetag_of(word)](where);
84 return 0;