bugs 31003 and (mostly) 68045, r=rogerl, sr=shaver&hyatt

- Fix bug where script jssrcnote vector terminator was not XDRed.
- Ensure that memory is cleared by serializing zero padding bytes as needed
  under JS_XDRBytes and JS_XDRString.
- Fix JS_XDRValue to handle undefined and null JS types properly (bug 31003).
  Also make it cast from jsint to uint32 and back carefully, so as to work
  with negative numbers even on targets where jsval is a signed 64 bit type.
- Add JS_XDRScript public API.
- Optimize the per-JSXDRState class registry so it uses a JSDHashTable upon
  searching for a class-id by name in an overpopulated (for linear search)
  registry table.
- Clean up API nits such as JS_XDRNewBase => JS_XDRInitBase, with parameter
  list rotation to put cx last (JS_XDRInitBase is an infallible init helper,
  not an error-reporting, cx-comes-first, API entry point).
- Fix some XXX comments, unneeded masks, other nits.
- Make sure all JS XDR API functions start with JS_XDR.
This commit is contained in:
brendan%mozilla.org 2001-03-06 01:56:30 +00:00
Родитель 5496fd604a
Коммит 69ab37f337
4 изменённых файлов: 520 добавлений и 430 удалений

Просмотреть файл

@ -3096,9 +3096,9 @@ js_XDRObject(JSXDRState *xdr, JSObject **objp)
if (xdr->mode == JSXDR_ENCODE) { if (xdr->mode == JSXDR_ENCODE) {
clasp = OBJ_GET_CLASS(cx, *objp); clasp = OBJ_GET_CLASS(cx, *objp);
className = clasp->name; className = clasp->name;
classId = JS_FindClassIdByName(xdr, className); classId = JS_XDRFindClassIdByName(xdr, className);
classDef = !classId; classDef = !classId;
if (classDef && !JS_RegisterClass(xdr, clasp, &classId)) if (classDef && !JS_XDRRegisterClass(xdr, clasp, &classId))
return JS_FALSE; return JS_FALSE;
} else { } else {
classDef = 0; classDef = 0;
@ -3123,11 +3123,11 @@ js_XDRObject(JSXDRState *xdr, JSObject **objp)
if (!ok) if (!ok)
goto out; goto out;
clasp = OBJ_GET_CLASS(cx, proto); clasp = OBJ_GET_CLASS(cx, proto);
ok = JS_RegisterClass(xdr, clasp, &classId); ok = JS_XDRRegisterClass(xdr, clasp, &classId);
if (!ok) if (!ok)
goto out; goto out;
} else { } else {
clasp = JS_FindClassById(xdr, classId); clasp = JS_XDRFindClassById(xdr, classId);
if (!clasp) { if (!clasp) {
char numBuf[12]; char numBuf[12];
JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)classId); JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)classId);
@ -3312,4 +3312,3 @@ void printAtom(JSAtom *atom) {
} }
#endif #endif

Просмотреть файл

@ -247,7 +247,7 @@ script_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
#if JS_HAS_XDR #if JS_HAS_XDR
static JSBool static JSBool
XDRAtom1(JSXDRState *xdr, JSAtomListElement *ale) XDRAtomListElement(JSXDRState *xdr, JSAtomListElement *ale)
{ {
jsval value; jsval value;
jsatomid index; jsatomid index;
@ -295,7 +295,7 @@ XDRAtomMap(JSXDRState *xdr, JSAtomMap *map)
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool); JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool);
if (!ale || if (!ale ||
!XDRAtom1(xdr, ale)) { !XDRAtomListElement(xdr, ale)) {
if (!ale) if (!ale)
JS_ReportOutOfMemory(cx); JS_ReportOutOfMemory(cx);
JS_ARENA_RELEASE(&cx->tempPool, mark); JS_ARENA_RELEASE(&cx->tempPool, mark);
@ -316,7 +316,7 @@ XDRAtomMap(JSXDRState *xdr, JSAtomMap *map)
for (i = 0; i < map->length; i++) { for (i = 0; i < map->length; i++) {
ALE_SET_ATOM(&ale, map->vector[i]); ALE_SET_ATOM(&ale, map->vector[i]);
ALE_SET_INDEX(&ale, i); ALE_SET_INDEX(&ale, i);
if (!XDRAtom1(xdr, &ale)) if (!XDRAtomListElement(xdr, &ale))
return JS_FALSE; return JS_FALSE;
} }
} }
@ -348,7 +348,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic)
*hasMagic = JS_TRUE; *hasMagic = JS_TRUE;
if (xdr->mode == JSXDR_ENCODE) { if (xdr->mode == JSXDR_ENCODE) {
jssrcnote *end = script->notes; jssrcnote *sn = script->notes;
length = script->length; length = script->length;
prologLength = script->main - script->code; prologLength = script->main - script->code;
version = (int32) script->version; version = (int32) script->version;
@ -363,9 +363,10 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic)
} }
/* Count the src notes. */ /* Count the src notes. */
while (!SN_IS_TERMINATOR(end)) while (!SN_IS_TERMINATOR(sn))
end = SN_NEXT(end); sn = SN_NEXT(sn);
notelen = end - script->notes; notelen = sn - script->notes;
notelen++; /* room for the terminator */
} }
if (!JS_XDRUint32(xdr, &length)) if (!JS_XDRUint32(xdr, &length))

Просмотреть файл

@ -36,6 +36,7 @@
#include <string.h> #include <string.h>
#include "jstypes.h" #include "jstypes.h"
#include "jsutil.h" /* Added by JSIFY */ #include "jsutil.h" /* Added by JSIFY */
#include "jsdhash.h"
#include "jsprf.h" #include "jsprf.h"
#include "jsapi.h" #include "jsapi.h"
#include "jscntxt.h" #include "jscntxt.h"
@ -72,27 +73,20 @@ typedef struct JSXDRMemState {
} \ } \
JS_END_MACRO JS_END_MACRO
/* XXXbe why does NEED even allow or cope with non-ENCODE mode? */
#define MEM_NEED(xdr, bytes) \ #define MEM_NEED(xdr, bytes) \
JS_BEGIN_MACRO \ JS_BEGIN_MACRO \
if ((xdr)->mode == JSXDR_ENCODE) { \ if ((xdr)->mode == JSXDR_ENCODE) { \
uint32 _new_limit = JS_ROUNDUP(MEM_COUNT(xdr) + bytes, MEM_BLOCK);\ uint32 new_limit_ = JS_ROUNDUP(MEM_COUNT(xdr) + bytes, MEM_BLOCK);\
if (MEM_LIMIT(xdr) && \ if (MEM_LIMIT(xdr) && \
MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \ MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \
void *_data = JS_realloc((xdr)->cx, \ void *data_ = JS_realloc((xdr)->cx, (xdr)->data, new_limit_); \
(xdr)->data, \ if (!data_) \
_new_limit); \
if (!_data) \
return 0; \ return 0; \
(xdr)->data = _data; \ (xdr)->data = data_; \
MEM_LIMIT(xdr) = _new_limit; \ MEM_LIMIT(xdr) = new_limit_; \
} \ } \
} else { \ } else { \
if (MEM_LIMIT(xdr) < MEM_COUNT(xdr) + bytes) { \ MEM_LEFT(xdr, bytes); \
JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \
JSMSG_END_OF_DATA); \
return 0; \
} \
} \ } \
JS_END_MACRO JS_END_MACRO
@ -211,8 +205,7 @@ mem_tell(JSXDRState *xdr)
static void static void
mem_finalize(JSXDRState *xdr) mem_finalize(JSXDRState *xdr)
{ {
JSContext *cx = xdr->cx; JS_free(xdr->cx, xdr->data);
JS_free(cx, xdr->data);
} }
static JSXDROps xdrmem_ops = { static JSXDROps xdrmem_ops = {
@ -221,12 +214,13 @@ static JSXDROps xdrmem_ops = {
}; };
JS_PUBLIC_API(void) JS_PUBLIC_API(void)
JS_XDRNewBase(JSContext *cx, JSXDRState *xdr, JSXDRMode mode) JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx)
{ {
xdr->cx = cx;
xdr->mode = mode; xdr->mode = mode;
xdr->cx = cx;
xdr->registry = NULL; xdr->registry = NULL;
xdr->nclasses = 0; xdr->numclasses = xdr->maxclasses = 0;
xdr->reghash = NULL;
} }
JS_PUBLIC_API(JSXDRState *) JS_PUBLIC_API(JSXDRState *)
@ -235,7 +229,7 @@ JS_XDRNewMem(JSContext *cx, JSXDRMode mode)
JSXDRState *xdr = (JSXDRState *) JS_malloc(cx, sizeof(JSXDRMemState)); JSXDRState *xdr = (JSXDRState *) JS_malloc(cx, sizeof(JSXDRMemState));
if (!xdr) if (!xdr)
return NULL; return NULL;
JS_XDRNewBase(cx, xdr, mode); JS_XDRInitBase(xdr, mode, cx);
if (mode == JSXDR_ENCODE) { if (mode == JSXDR_ENCODE) {
if (!(xdr->data = JS_malloc(cx, MEM_BLOCK))) { if (!(xdr->data = JS_malloc(cx, MEM_BLOCK))) {
JS_free(cx, xdr); JS_free(cx, xdr);
@ -270,13 +264,26 @@ JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len)
MEM_PRIV(xdr)->count = 0; MEM_PRIV(xdr)->count = 0;
} }
JS_PUBLIC_API(void)
JS_XDRDestroy(JSXDRState *xdr)
{
JSContext *cx = xdr->cx;
xdr->ops->finalize(xdr);
if (xdr->registry) {
JS_free(cx, xdr->registry);
if (xdr->reghash)
JS_DHashTableDestroy(xdr->reghash);
}
JS_free(cx, xdr);
}
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_XDRUint8(JSXDRState *xdr, uint8 *b) JS_XDRUint8(JSXDRState *xdr, uint8 *b)
{ {
uint32 l = *b; uint32 l = *b;
if (!JS_XDRUint32(xdr, &l)) if (!JS_XDRUint32(xdr, &l))
return JS_FALSE; return JS_FALSE;
*b = (uint8) l & 0xff; *b = (uint8) l;
return JS_TRUE; return JS_TRUE;
} }
@ -286,14 +293,14 @@ JS_XDRUint16(JSXDRState *xdr, uint16 *s)
uint32 l = *s; uint32 l = *s;
if (!JS_XDRUint32(xdr, &l)) if (!JS_XDRUint32(xdr, &l))
return JS_FALSE; return JS_FALSE;
*s = (uint16) l & 0xffff; *s = (uint16) l;
return JS_TRUE; return JS_TRUE;
} }
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_XDRUint32(JSXDRState *xdr, uint32 *lp) JS_XDRUint32(JSXDRState *xdr, uint32 *lp)
{ {
JSBool ok = JS_FALSE; JSBool ok = JS_TRUE;
if (xdr->mode == JSXDR_ENCODE) { if (xdr->mode == JSXDR_ENCODE) {
uint32 xl = JSXDR_SWAB32(*lp); uint32 xl = JSXDR_SWAB32(*lp);
ok = xdr->ops->set32(xdr, &xl); ok = xdr->ops->set32(xdr, &xl);
@ -307,6 +314,10 @@ JS_XDRUint32(JSXDRState *xdr, uint32 *lp)
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_XDRBytes(JSXDRState *xdr, char **bytesp, uint32 len) JS_XDRBytes(JSXDRState *xdr, char **bytesp, uint32 len)
{ {
uint32 padlen;
char *padbp;
static char padbuf[JSXDR_ALIGN-1];
if (xdr->mode == JSXDR_ENCODE) { if (xdr->mode == JSXDR_ENCODE) {
if (!xdr->ops->setbytes(xdr, bytesp, len)) if (!xdr->ops->setbytes(xdr, bytesp, len))
return JS_FALSE; return JS_FALSE;
@ -316,8 +327,13 @@ JS_XDRBytes(JSXDRState *xdr, char **bytesp, uint32 len)
} }
len = xdr->ops->tell(xdr); len = xdr->ops->tell(xdr);
if (len % JSXDR_ALIGN) { if (len % JSXDR_ALIGN) {
if (!xdr->ops->seek(xdr, JSXDR_ALIGN - (len % JSXDR_ALIGN), padlen = JSXDR_ALIGN - (len % JSXDR_ALIGN);
JSXDR_SEEK_CUR)) { if (xdr->mode == JSXDR_ENCODE) {
padbp = padbuf;
if (!xdr->ops->setbytes(xdr, &padbp, padlen))
return JS_FALSE;
} else {
if (!xdr->ops->seek(xdr, padlen, JSXDR_SEEK_CUR))
return JS_FALSE; return JS_FALSE;
} }
} }
@ -374,7 +390,7 @@ JS_XDRCStringOrNull(JSXDRState *xdr, char **sp)
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_XDRString(JSXDRState *xdr, JSString **strp) JS_XDRString(JSXDRState *xdr, JSString **strp)
{ {
uint32 i, len, nbytes; uint32 i, len, padlen, nbytes;
jschar *chars = NULL, *raw; jschar *chars = NULL, *raw;
if (xdr->mode == JSXDR_ENCODE) if (xdr->mode == JSXDR_ENCODE)
@ -383,20 +399,25 @@ JS_XDRString(JSXDRState *xdr, JSString **strp)
return JS_FALSE; return JS_FALSE;
nbytes = len * sizeof(jschar); nbytes = len * sizeof(jschar);
if (xdr->mode == JSXDR_ENCODE) { if (xdr->mode == JSXDR_DECODE) {
chars = (*strp)->chars;
} else if (xdr->mode == JSXDR_DECODE) {
if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar)))) if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar))))
return JS_FALSE; return JS_FALSE;
} else {
chars = (*strp)->chars;
} }
if (nbytes % JSXDR_ALIGN) padlen = nbytes % JSXDR_ALIGN;
nbytes += JSXDR_ALIGN - (nbytes % JSXDR_ALIGN); if (padlen) {
padlen = JSXDR_ALIGN - padlen;
nbytes += padlen;
}
if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes))) if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes)))
goto bad; goto bad;
if (xdr->mode == JSXDR_ENCODE) { if (xdr->mode == JSXDR_ENCODE) {
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
raw[i] = JSXDR_SWAB16(chars[i]); raw[i] = JSXDR_SWAB16(chars[i]);
if (padlen)
memset((char *)raw + nbytes - padlen, 0, padlen);
} else if (xdr->mode == JSXDR_DECODE) { } else if (xdr->mode == JSXDR_DECODE) {
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
chars[i] = JSXDR_SWAB16(raw[i]); chars[i] = JSXDR_SWAB16(raw[i]);
@ -435,10 +456,10 @@ JS_XDRDouble(JSXDRState *xdr, jsdouble **dp)
#if IS_BIG_ENDIAN #if IS_BIG_ENDIAN
if (!JS_XDRUint32(xdr, (uint32 *)&d + 1) || if (!JS_XDRUint32(xdr, (uint32 *)&d + 1) ||
!JS_XDRUint32(xdr, (uint32 *)&d)) !JS_XDRUint32(xdr, (uint32 *)&d))
#else /* !IS_BIG_ENDIAN */ #else
if (!JS_XDRUint32(xdr, (uint32 *)&d) || if (!JS_XDRUint32(xdr, (uint32 *)&d) ||
!JS_XDRUint32(xdr, (uint32 *)&d + 1)) !JS_XDRUint32(xdr, (uint32 *)&d + 1))
#endif /* IS_BIG_ENDIAN */ #endif
return JS_FALSE; return JS_FALSE;
if (xdr->mode == JSXDR_DECODE) { if (xdr->mode == JSXDR_DECODE) {
*dp = JS_NewDouble(xdr->cx, d); *dp = JS_NewDouble(xdr->cx, d);
@ -448,14 +469,33 @@ JS_XDRDouble(JSXDRState *xdr, jsdouble **dp)
return JS_TRUE; return JS_TRUE;
} }
/* These are magic: see jsapi.h, near the top, for the real jsval tags. */
#define JSVAL_XDRNULL 0x8
#define JSVAL_XDRVOID 0xA
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_XDRValue(JSXDRState *xdr, jsval *vp) JS_XDRValue(JSXDRState *xdr, jsval *vp)
{ {
uint32 type = JSVAL_TAG(*vp); uint32 type;
if (xdr->mode == JSXDR_ENCODE) {
if (JSVAL_IS_NULL(*vp))
type = JSVAL_XDRNULL;
else if (JSVAL_IS_VOID(*vp))
type = JSVAL_XDRVOID;
else
type = JSVAL_TAG(*vp);
}
if (!JS_XDRUint32(xdr, &type)) if (!JS_XDRUint32(xdr, &type))
return JS_FALSE; return JS_FALSE;
switch (type) { switch (type) {
case JSVAL_XDRNULL:
*vp = JSVAL_NULL;
break;
case JSVAL_XDRVOID:
*vp = JSVAL_VOID;
break;
case JSVAL_STRING: { case JSVAL_STRING: {
JSString *str = JSVAL_TO_STRING(*vp); JSString *str = JSVAL_TO_STRING(*vp);
if (!JS_XDRString(xdr, &str)) if (!JS_XDRString(xdr, &str))
@ -494,20 +534,16 @@ JS_XDRValue(JSXDRState *xdr, jsval *vp)
*vp = BOOLEAN_TO_JSVAL((JSBool)b); *vp = BOOLEAN_TO_JSVAL((JSBool)b);
break; break;
} }
case JSVAL_VOID:
if (!JS_XDRUint32(xdr, (uint32 *)vp))
return JS_FALSE;
break;
default: { default: {
char numBuf[12]; char numBuf[12];
if (type & JSVAL_INT) { if (type & JSVAL_INT) {
uint32 i; uint32 i;
if (xdr->mode == JSXDR_ENCODE) if (xdr->mode == JSXDR_ENCODE)
i = JSVAL_TO_INT(*vp); i = (uint32) JSVAL_TO_INT(*vp);
if (!JS_XDRUint32(xdr, &i)) if (!JS_XDRUint32(xdr, &i))
return JS_FALSE; return JS_FALSE;
if (xdr->mode == JSXDR_DECODE) if (xdr->mode == JSXDR_DECODE)
*vp = INT_TO_JSVAL(i); *vp = INT_TO_JSVAL((int32) i);
break; break;
} }
JS_snprintf(numBuf, sizeof numBuf, "%#lx", type); JS_snprintf(numBuf, sizeof numBuf, "%#lx", type);
@ -519,62 +555,110 @@ JS_XDRValue(JSXDRState *xdr, jsval *vp)
return JS_TRUE; return JS_TRUE;
} }
JS_PUBLIC_API(JSBool)
JS_PUBLIC_API(void) JS_XDRScript(JSXDRState *xdr, JSScript **scriptp)
JS_XDRDestroy(JSXDRState *xdr)
{ {
JSContext *cx = xdr->cx; JSBool hasMagic;
xdr->ops->finalize(xdr);
if (xdr->registry) return js_XDRScript(xdr, scriptp, &hasMagic);
JS_free(cx, xdr->registry);
JS_free(cx, xdr);
} }
#define REGISTRY_CHUNK 4 #define CLASS_REGISTRY_MIN 8
#define CLASS_INDEX_TO_ID(i) ((i)+1)
#define CLASS_ID_TO_INDEX(id) ((id)-1)
typedef struct JSRegHashEntry {
JSDHashEntryHdr hdr;
const char *name;
uint32 index;
} JSRegHashEntry;
JS_PUBLIC_API(JSBool) JS_PUBLIC_API(JSBool)
JS_RegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp) JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp)
{ {
uintN nclasses; uintN numclasses, maxclasses;
JSClass **registry; JSClass **registry;
nclasses = xdr->nclasses; numclasses = xdr->numclasses;
if (nclasses == 0) { maxclasses = xdr->maxclasses;
if (numclasses == maxclasses) {
maxclasses = (maxclasses == 0) ? CLASS_REGISTRY_MIN : maxclasses << 1;
registry = (JSClass **) registry = (JSClass **)
JS_malloc(xdr->cx, REGISTRY_CHUNK * sizeof(JSClass *)); JS_realloc(xdr->cx, xdr->registry, maxclasses * sizeof(JSClass *));
} else if (nclasses % REGISTRY_CHUNK == 0) {
registry = (JSClass **)
JS_realloc(xdr->cx,
xdr->registry,
(nclasses + REGISTRY_CHUNK) * sizeof(JSClass *));
} else {
registry = xdr->registry;
}
if (!registry) if (!registry)
return JS_FALSE; return JS_FALSE;
registry[nclasses++] = clasp;
xdr->registry = registry; xdr->registry = registry;
xdr->nclasses = nclasses; xdr->maxclasses = maxclasses;
*idp = nclasses; } else {
JS_ASSERT(numclasses && numclasses < maxclasses);
registry = xdr->registry;
}
registry[numclasses] = clasp;
if (xdr->reghash) {
JSRegHashEntry *entry = (JSRegHashEntry *)
JS_DHashTableOperate(xdr->reghash, clasp->name, JS_DHASH_ADD);
if (!entry) {
JS_ReportOutOfMemory(xdr->cx);
return JS_FALSE;
}
entry->name = clasp->name;
entry->index = numclasses;
}
*idp = CLASS_INDEX_TO_ID(numclasses);
xdr->numclasses = ++numclasses;
return JS_TRUE; return JS_TRUE;
} }
JS_PUBLIC_API(uint32) JS_PUBLIC_API(uint32)
JS_FindClassIdByName(JSXDRState *xdr, const char *name) JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name)
{ {
uintN i; uintN i, numclasses;
for (i = 0; i < xdr->nclasses; i++) { numclasses = xdr->numclasses;
if (numclasses >= 10) {
JSRegHashEntry *entry;
/* Bootstrap reghash from registry on first overpopulated Find. */
if (!xdr->reghash) {
xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL,
sizeof(JSRegHashEntry),
numclasses);
if (xdr->reghash) {
for (i = 0; i < numclasses; i++) {
JSClass *clasp = xdr->registry[i];
entry = (JSRegHashEntry *)
JS_DHashTableOperate(xdr->reghash, clasp->name,
JS_DHASH_ADD);
entry->name = clasp->name;
entry->index = i;
}
}
}
/* If we managed to create reghash, use it for O(1) Find. */
if (xdr->reghash) {
entry = (JSRegHashEntry *)
JS_DHashTableOperate(xdr->reghash, name, JS_DHASH_LOOKUP);
if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr))
return CLASS_INDEX_TO_ID(entry->index);
}
}
/* Only a few classes, or we couldn't malloc reghash: use linear search. */
for (i = 0; i < numclasses; i++) {
if (!strcmp(name, xdr->registry[i]->name)) if (!strcmp(name, xdr->registry[i]->name))
return i+1; return CLASS_INDEX_TO_ID(i);
} }
return 0; return 0;
} }
JS_PUBLIC_API(JSClass *) JS_PUBLIC_API(JSClass *)
JS_FindClassById(JSXDRState *xdr, uint32 id) JS_XDRFindClassById(JSXDRState *xdr, uint32 id)
{ {
if (id > xdr->nclasses) uintN i = CLASS_ID_TO_INDEX(id);
if (i >= xdr->numclasses)
return NULL; return NULL;
return xdr->registry[id-1]; return xdr->registry[i];
} }

Просмотреть файл

@ -66,11 +66,11 @@ JS_BEGIN_EXTERN_C
#define JSXDR_SWAB32(x) x #define JSXDR_SWAB32(x) x
#define JSXDR_SWAB16(x) x #define JSXDR_SWAB16(x) x
#elif defined IS_BIG_ENDIAN #elif defined IS_BIG_ENDIAN
#define JSXDR_SWAB32(x) (((x) >> 24) | \ #define JSXDR_SWAB32(x) (((uint32)(x) >> 24) | \
(((x) >> 8) & 0xff00) | \ (((uint32)(x) >> 8) & 0xff00) | \
(((x) << 8) & 0xff0000) | \ (((uint32)(x) << 8) & 0xff0000) | \
((x) << 24)) ((uint32)(x) << 24))
#define JSXDR_SWAB16(x) (((x) >> 8) | ((x) << 8)) #define JSXDR_SWAB16(x) (((uint16)(x) >> 8) | ((uint16)(x) << 8))
#else #else
#error "unknown byte order" #error "unknown byte order"
#endif #endif
@ -105,12 +105,14 @@ struct JSXDRState {
JSXDROps *ops; JSXDROps *ops;
JSContext *cx; JSContext *cx;
JSClass **registry; JSClass **registry;
uintN nclasses; uintN numclasses;
uintN maxclasses;
void *reghash;
void *data; void *data;
}; };
extern JS_PUBLIC_API(void) extern JS_PUBLIC_API(void)
JS_XDRNewBase(JSContext *cx, JSXDRState *xdr, JSXDRMode mode); JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx);
extern JS_PUBLIC_API(JSXDRState *) extern JS_PUBLIC_API(JSXDRState *)
JS_XDRNewMem(JSContext *cx, JSXDRMode mode); JS_XDRNewMem(JSContext *cx, JSXDRMode mode);
@ -155,16 +157,20 @@ extern JS_PUBLIC_API(JSBool)
JS_XDRValue(JSXDRState *xdr, jsval *vp); JS_XDRValue(JSXDRState *xdr, jsval *vp);
extern JS_PUBLIC_API(JSBool) extern JS_PUBLIC_API(JSBool)
JS_RegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp); JS_XDRScript(JSXDRState *xdr, JSScript **scriptp);
extern JS_PUBLIC_API(JSBool)
JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp);
extern JS_PUBLIC_API(uint32) extern JS_PUBLIC_API(uint32)
JS_FindClassIdByName(JSXDRState *xdr, const char *name); JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name);
extern JS_PUBLIC_API(JSClass *) extern JS_PUBLIC_API(JSClass *)
JS_FindClassById(JSXDRState *xdr, uint32 id); JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
/* Magic values */
/*
* Magic numbers.
*/
#define JSXDR_MAGIC_SCRIPT_1 0xdead0001 #define JSXDR_MAGIC_SCRIPT_1 0xdead0001
#define JSXDR_MAGIC_SCRIPT_2 0xdead0002 #define JSXDR_MAGIC_SCRIPT_2 0xdead0002
#define JSXDR_MAGIC_SCRIPT_CURRENT JSXDR_MAGIC_SCRIPT_2 #define JSXDR_MAGIC_SCRIPT_CURRENT JSXDR_MAGIC_SCRIPT_2