static JSBool XDRDoubleValue(JSXDRState *xdr, jsdouble *dp) { jsdpun u; u.d = (xdr->mode == JSXDR_ENCODE) ? *dp : 0.0; if (!JS_XDRUint32(xdr, &u.s.lo) || !JS_XDRUint32(xdr, &u.s.hi)) return JS_FALSE; if (xdr->mode == JSXDR_DECODE) *dp = u.d; return JS_TRUE; }
JS_XDRDouble(JSXDRState *xdr, jsdouble **dp) { jsdpun u; if (xdr->mode == JSXDR_ENCODE) u.d = **dp; if (!JS_XDRUint32(xdr, &u.s.lo) || !JS_XDRUint32(xdr, &u.s.hi)) return JS_FALSE; if (xdr->mode == JSXDR_DECODE) { *dp = JS_NewDouble(xdr->cx, u.d); if (!*dp) return JS_FALSE; } return JS_TRUE; }
JS_XDRString(JSXDRState *xdr, JSString **strp) { uint32 nchars; jschar *chars; if (xdr->mode == JSXDR_ENCODE) nchars = JSSTRING_LENGTH(*strp); if (!JS_XDRUint32(xdr, &nchars)) return JS_FALSE; if (xdr->mode == JSXDR_DECODE) { chars = (jschar *) JS_malloc(xdr->cx, (nchars + 1) * sizeof(jschar)); if (!chars) return JS_FALSE; } else { chars = JSSTRING_CHARS(*strp); } if (!XDRChars(xdr, chars, nchars)) goto bad; if (xdr->mode == JSXDR_DECODE) { chars[nchars] = 0; *strp = JS_NewUCString(xdr->cx, chars, nchars); if (!*strp) goto bad; } return JS_TRUE; bad: if (xdr->mode == JSXDR_DECODE) JS_free(xdr->cx, chars); return JS_FALSE; }
JSBool js_XDRAtom(JSXDRState *xdr, JSAtom **atomp) { jsval v; uint32 type; if (xdr->mode == JSXDR_ENCODE) { v = ATOM_KEY(*atomp); return JS_XDRValue(xdr, &v); } /* * Inline JS_XDRValue when decoding to avoid ceation of GC things when * then corresponding atom already exists. See bug 321985. */ if (!JS_XDRUint32(xdr, &type)) return JS_FALSE; if (type == JSVAL_STRING) return js_XDRStringAtom(xdr, atomp); if (type == JSVAL_DOUBLE) { jsdouble d = 0; if (!XDRDoubleValue(xdr, &d)) return JS_FALSE; *atomp = js_AtomizeDouble(xdr->cx, d); return *atomp != NULL; } return XDRValueBody(xdr, type, &v) && js_AtomizePrimitiveValue(xdr->cx, v, atomp); }
JS_XDRString(JSXDRState *xdr, JSString **strp) { uint32 nchars; jschar *chars; if (xdr->mode == JSXDR_ENCODE) nchars = (*strp)->length(); if (!JS_XDRUint32(xdr, &nchars)) return JS_FALSE; if (xdr->mode == JSXDR_DECODE) { chars = (jschar *) xdr->cx->malloc((nchars + 1) * sizeof(jschar)); if (!chars) return JS_FALSE; } else { chars = (*strp)->chars(); } if (!XDRChars(xdr, chars, nchars)) goto bad; if (xdr->mode == JSXDR_DECODE) { chars[nchars] = 0; *strp = JS_NewUCString(xdr->cx, chars, nchars); if (!*strp) goto bad; } return JS_TRUE; bad: if (xdr->mode == JSXDR_DECODE) xdr->cx->free(chars); return JS_FALSE; }
JS_XDRUint16(JSXDRState *xdr, uint16 *s) { uint32 l = *s; if (!JS_XDRUint32(xdr, &l)) return JS_FALSE; *s = (uint16) l; return JS_TRUE; }
JS_XDRUint8(JSXDRState *xdr, uint8 *b) { uint32 l = *b; if (!JS_XDRUint32(xdr, &l)) return JS_FALSE; *b = (uint8) l; return JS_TRUE; }
JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp) { uint32 null = (*strp == NULL); if (!JS_XDRUint32(xdr, &null)) return JS_FALSE; if (null) { *strp = NULL; return JS_TRUE; } return JS_XDRString(xdr, strp); }
JS_XDRValue(JSXDRState *xdr, jsval *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); } return JS_XDRUint32(xdr, &type) && XDRValueBody(xdr, type, vp); }
extern JSBool js_XDRStringAtom(JSXDRState *xdr, JSAtom **atomp) { JSString *str; uint32 nchars; JSAtom *atom; JSContext *cx; jschar *chars; jschar stackChars[256]; if (xdr->mode == JSXDR_ENCODE) { JS_ASSERT(ATOM_IS_STRING(*atomp)); str = ATOM_TO_STRING(*atomp); return JS_XDRString(xdr, &str); } /* * Inline JS_XDRString when decoding to avoid JSString allocation * for already existing atoms. See bug 321985. */ if (!JS_XDRUint32(xdr, &nchars)) return JS_FALSE; atom = NULL; cx = xdr->cx; if (nchars <= JS_ARRAY_LENGTH(stackChars)) { chars = stackChars; } else { /* * This is very uncommon. Don't use the tempPool arena for this as * most allocations here will be bigger than tempPool's arenasize. */ chars = (jschar *) cx->malloc(nchars * sizeof(jschar)); if (!chars) return JS_FALSE; } if (XDRChars(xdr, chars, nchars)) atom = js_AtomizeChars(cx, chars, nchars, 0); if (chars != stackChars) cx->free(chars); if (!atom) return JS_FALSE; *atomp = atom; return JS_TRUE; }
JS_XDRString(JSXDRState *xdr, JSString **strp) { uint32 i, len, padlen, nbytes; jschar *chars = NULL, *raw; if (xdr->mode == JSXDR_ENCODE) len = JSSTRING_LENGTH(*strp); if (!JS_XDRUint32(xdr, &len)) return JS_FALSE; nbytes = len * sizeof(jschar); if (xdr->mode == JSXDR_DECODE) { if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar)))) return JS_FALSE; } else { chars = JSSTRING_CHARS(*strp); } padlen = nbytes % JSXDR_ALIGN; if (padlen) { padlen = JSXDR_ALIGN - padlen; nbytes += padlen; } if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes))) goto bad; if (xdr->mode == JSXDR_ENCODE) { for (i = 0; i < len; i++) raw[i] = JSXDR_SWAB16(chars[i]); if (padlen) memset((char *)raw + nbytes - padlen, 0, padlen); } else if (xdr->mode == JSXDR_DECODE) { for (i = 0; i < len; i++) chars[i] = JSXDR_SWAB16(raw[i]); chars[len] = 0; if (!(*strp = JS_NewUCString(xdr->cx, chars, len))) goto bad; } return JS_TRUE; bad: if (xdr->mode == JSXDR_DECODE) JS_free(xdr->cx, chars); return JS_FALSE; }
extern JSBool js_XDRStringAtom(JSXDRState *xdr, JSAtom **atomp) { JSString *str; uint32 nchars; JSAtom *atom; JSContext *cx; void *mark; jschar *chars; if (xdr->mode == JSXDR_ENCODE) { JS_ASSERT(ATOM_IS_STRING(*atomp)); str = ATOM_TO_STRING(*atomp); return JS_XDRString(xdr, &str); } /* * Inline JS_XDRString when decoding to avoid JSString allocation * for already existing atoms. See bug 321985. */ if (!JS_XDRUint32(xdr, &nchars)) return JS_FALSE; atom = NULL; cx = xdr->cx; mark = JS_ARENA_MARK(&cx->tempPool); JS_ARENA_ALLOCATE_CAST(chars, jschar *, &cx->tempPool, nchars * sizeof(jschar)); if (!chars) JS_ReportOutOfMemory(cx); else if (XDRChars(xdr, chars, nchars)) atom = js_AtomizeChars(cx, chars, nchars, 0); JS_ARENA_RELEASE(&cx->tempPool, mark); if (!atom) return JS_FALSE; *atomp = atom; return JS_TRUE; }
JSBool js_XDRAtom(JSXDRState *xdr, JSAtom **atomp) { jsval v; uint32 type; jsdouble d; JSAtom *atom; if (xdr->mode == JSXDR_ENCODE) { v = ATOM_KEY(*atomp); return JS_XDRValue(xdr, &v); } /* * Inline JS_XDRValue when decoding to avoid ceation of GC things when * then corresponding atom already exists. See bug 321985. */ if (!JS_XDRUint32(xdr, &type)) return JS_FALSE; if (type == JSVAL_STRING) return js_XDRStringAtom(xdr, atomp); if (type == JSVAL_DOUBLE) { if (!XDRDoubleValue(xdr, &d)) return JS_FALSE; atom = js_AtomizeDouble(xdr->cx, d, 0); } else { if (!XDRValueBody(xdr, type, &v)) return JS_FALSE; atom = js_AtomizeValue(xdr->cx, v, 0); } if (!atom) return JS_FALSE; *atomp = atom; return JS_TRUE; }
/* * FIXME: This performs lossy conversion and we need to switch to * js_XDRStringAtom while allowing to read older XDR files. See bug 325202. */ JSBool js_XDRCStringAtom(JSXDRState *xdr, JSAtom **atomp) { char *bytes; uint32 nbytes; JSAtom *atom; JSContext *cx; void *mark; if (xdr->mode == JSXDR_ENCODE) { JS_ASSERT(ATOM_IS_STRING(*atomp)); bytes = JS_GetStringBytes(ATOM_TO_STRING(*atomp)); return JS_XDRCString(xdr, &bytes); } /* * Inline JS_XDRCString when decoding not to malloc temporary buffer * just to free it after atomization. See bug 321985. */ if (!JS_XDRUint32(xdr, &nbytes)) return JS_FALSE; atom = NULL; cx = xdr->cx; mark = JS_ARENA_MARK(&cx->tempPool); JS_ARENA_ALLOCATE_CAST(bytes, char *, &cx->tempPool, nbytes * sizeof *bytes); if (!bytes) JS_ReportOutOfMemory(cx); else if (JS_XDRBytes(xdr, bytes, nbytes)) atom = js_Atomize(cx, bytes, nbytes, 0); JS_ARENA_RELEASE(&cx->tempPool, mark); if (!atom) return JS_FALSE; *atomp = atom; return JS_TRUE; }
JS_XDRCString(JSXDRState *xdr, char **sp) { uint32 len; if (xdr->mode == JSXDR_ENCODE) len = strlen(*sp); JS_XDRUint32(xdr, &len); if (xdr->mode == JSXDR_DECODE) { if (!(*sp = (char *) JS_malloc(xdr->cx, len + 1))) return JS_FALSE; } if (!JS_XDRBytes(xdr, *sp, len)) { if (xdr->mode == JSXDR_DECODE) JS_free(xdr->cx, *sp); return JS_FALSE; } if (xdr->mode == JSXDR_DECODE) { (*sp)[len] = '\0'; } else if (xdr->mode == JSXDR_FREE) { JS_free(xdr->cx, *sp); *sp = NULL; } return JS_TRUE; }
static JSBool XDRValueBody(JSXDRState *xdr, uint32 type, jsval *vp) { switch (type) { case JSVAL_XDRNULL: *vp = JSVAL_NULL; break; case JSVAL_XDRVOID: *vp = JSVAL_VOID; break; case JSVAL_STRING: { JSString *str; if (xdr->mode == JSXDR_ENCODE) str = JSVAL_TO_STRING(*vp); if (!JS_XDRString(xdr, &str)) return JS_FALSE; if (xdr->mode == JSXDR_DECODE) *vp = STRING_TO_JSVAL(str); break; } case JSVAL_DOUBLE: { jsdouble *dp; if (xdr->mode == JSXDR_ENCODE) dp = JSVAL_TO_DOUBLE(*vp); if (!JS_XDRDouble(xdr, &dp)) return JS_FALSE; if (xdr->mode == JSXDR_DECODE) *vp = DOUBLE_TO_JSVAL(dp); break; } case JSVAL_OBJECT: { JSObject *obj; if (xdr->mode == JSXDR_ENCODE) obj = JSVAL_TO_OBJECT(*vp); if (!js_XDRObject(xdr, &obj)) return JS_FALSE; if (xdr->mode == JSXDR_DECODE) *vp = OBJECT_TO_JSVAL(obj); break; } case JSVAL_BOOLEAN: { uint32 b; if (xdr->mode == JSXDR_ENCODE) b = (uint32) JSVAL_TO_BOOLEAN(*vp); if (!JS_XDRUint32(xdr, &b)) return JS_FALSE; if (xdr->mode == JSXDR_DECODE) *vp = BOOLEAN_TO_JSVAL((JSBool) b); break; } default: { uint32 i; JS_ASSERT(type & JSVAL_INT); if (xdr->mode == JSXDR_ENCODE) i = (uint32) JSVAL_TO_INT(*vp); if (!JS_XDRUint32(xdr, &i)) return JS_FALSE; if (xdr->mode == JSXDR_DECODE) *vp = INT_TO_JSVAL((int32) i); break; } } return JS_TRUE; }