LCOV - app.info - js/src/vm/Xdr.h

LCOV - code coverage report
| Current view: | directory - js/src/vm - Xdr.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 125 | 86 | 68.8 %
| Date: | 2012-04-07 | Functions: | 40 | 30 | 75.0 %

           1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  * vim: set ts=8 sw=4 et tw=78:
           3                 :  *
           4                 :  * ***** BEGIN LICENSE BLOCK *****
           5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           6                 :  *
           7                 :  * The contents of this file are subject to the Mozilla Public License Version
           8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           9                 :  * the License. You may obtain a copy of the License at
          10                 :  * http://www.mozilla.org/MPL/
          11                 :  *
          12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          14                 :  * for the specific language governing rights and limitations under the
          15                 :  * License.
          16                 :  *
          17                 :  * The Original Code is SpiderMonkey string object code.
          18                 :  *
          19                 :  * The Initial Developer of the Original Code is
          20                 :  * the Mozilla Foundation.
          21                 :  * Portions created by the Initial Developer are Copyright (C) 2011
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *
          26                 :  * Alternatively, the contents of this file may be used under the terms of
          27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          30                 :  * of those above. If you wish to allow use of your version of this file only
          31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          32                 :  * use your version of this file under the terms of the MPL, indicate your
          33                 :  * decision by deleting the provisions above and replace them with the notice
          34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          35                 :  * the provisions above, a recipient may use your version of this file under
          36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          37                 :  *
          38                 :  * ***** END LICENSE BLOCK ***** */
          39                 :
          40                 : #ifndef Xdr_h___
          41                 : #define Xdr_h___
          42                 :
          43                 : #include "jsapi.h"
          44                 : #include "jsprvtd.h"
          45                 : #include "jsnum.h"
          46                 :
          47                 : namespace js {
          48                 :
          49                 : /*
          50                 :  * Bytecode version number. Increment the subtrahend whenever JS bytecode
          51                 :  * changes incompatibly.
          52                 :  *
          53                 :  * This version number is XDR'd near the front of xdr bytecode and
          54                 :  * aborts deserialization if there is a mismatch between the current
          55                 :  * and saved versions. If deserialization fails, the data should be
          56                 :  * invalidated if possible.
          57                 :  */
          58                 : static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 113);
          59                 :
          60                 : class XDRBuffer {
          61                 :   public:
          62            4780 :     XDRBuffer(JSContext *cx)
          63            4780 :       : context(cx), base(NULL), cursor(NULL), limit(NULL) { }
          64                 :
          65           25523 :     JSContext *cx() const {
          66           25523 :         return context;
          67                 :     }
          68                 :
          69            2390 :     void *getData(uint32_t *lengthp) const {
          70                 :         JS_ASSERT(size_t(cursor - base) <= size_t(UINT32_MAX));
          71            2390 :         *lengthp = uint32_t(cursor - base);
          72            2390 :         return base;
          73                 :     }
          74                 :
          75            2411 :     void setData(const void *data, uint32_t length) {
          76            2411 :         base = static_cast<uint8_t *>(const_cast<void *>(data));
          77            2411 :         cursor = base;
          78            2411 :         limit = base + length;
          79            2411 :     }
          80                 :
          81           71531 :     const uint8_t *read(size_t n) {
          82           71531 :         JS_ASSERT(n <= size_t(limit - cursor));
          83           71531 :         uint8_t *ptr = cursor;
          84           71531 :         cursor += n;
          85           71531 :         return ptr;
          86                 :     }
          87                 :
          88            2496 :     const char *readCString() {
          89            2496 :         char *ptr = reinterpret_cast<char *>(cursor);
          90            2496 :         cursor = reinterpret_cast<uint8_t *>(strchr(ptr, '\0')) + 1;
          91            2496 :         JS_ASSERT(base < cursor);
          92            2496 :         JS_ASSERT(cursor <= limit);
          93            2496 :         return ptr;
          94                 :     }
          95                 :
          96           74027 :     uint8_t *write(size_t n) {
          97           74027 :         if (n > size_t(limit - cursor)) {
          98            2390 :             if (!grow(n))
          99               0 :                 return NULL;
         100                 :         }
         101           74027 :         uint8_t *ptr = cursor;
         102           74027 :         cursor += n;
         103           74027 :         return ptr;
         104                 :     }
         105                 :
         106            2390 :     static bool isUint32Overflow(size_t n) {
         107            2390 :         return size_t(-1) > size_t(UINT32_MAX) && n > size_t(UINT32_MAX);
         108                 :     }
         109                 :
         110                 :     void freeBuffer();
         111                 :
         112                 :   private:
         113                 :     bool grow(size_t n);
         114                 :
         115                 :     JSContext   *const context;
         116                 :     uint8_t     *base;
         117                 :     uint8_t     *cursor;
         118                 :     uint8_t     *limit;
         119                 : };
         120                 :
         121                 : /* We use little-endian byteorder for all encoded data */
         122                 :
         123                 : #if defined IS_LITTLE_ENDIAN
         124                 :
         125                 : inline uint32_t
         126          117336 : NormalizeByteOrder32(uint32_t x)
         127                 : {
         128          117336 :     return x;
         129                 : }
         130                 :
         131                 : inline uint16_t
         132               0 : NormalizeByteOrder16(uint16_t x)
         133                 : {
         134               0 :     return x;
         135                 : }
         136                 :
         137                 : #elif defined IS_BIG_ENDIAN
         138                 :
         139                 : inline uint32_t
         140                 : NormalizeByteOrder32(uint32_t x)
         141                 : {
         142                 :     return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
         143                 : }
         144                 :
         145                 : inline uint16_t
         146                 : NormalizeByteOrder16(uint16_t x)
         147                 : {
         148                 :     return (x >> 8) | (x << 8);
         149                 : }
         150                 :
         151                 : #else
         152                 : #error "unknown byte order"
         153                 : #endif
         154                 :
         155                 : template <XDRMode mode>
         156                 : class XDRState {
         157                 :   public:
         158                 :     XDRBuffer buf;
         159                 :
         160                 :   protected:
         161                 :     JSPrincipals *principals;
         162                 :     JSPrincipals *originPrincipals;
         163                 :
         164            4780 :     XDRState(JSContext *cx)
         165            4780 :       : buf(cx), principals(NULL), originPrincipals(NULL) {
         166            4780 :     }
         167                 :
         168                 :   public:
         169           25523 :     JSContext *cx() const {
         170           25523 :         return buf.cx();
         171                 :     }
         172                 :
         173               0 :     bool codeUint8(uint8_t *n) {
         174                 :         if (mode == XDR_ENCODE) {
         175               0 :             uint8_t *ptr = buf.write(sizeof *n);
         176               0 :             if (!ptr)
         177               0 :                 return false;
         178               0 :             *ptr = *n;
         179                 :         } else {
         180               0 :             *n = *buf.read(sizeof *n);
         181                 :         }
         182               0 :         return true;
         183                 :     }
         184                 :
         185               0 :     bool codeUint16(uint16_t *n) {
         186                 :         uint16_t tmp;
         187                 :         if (mode == XDR_ENCODE) {
         188               0 :             uint8_t *ptr = buf.write(sizeof tmp);
         189               0 :             if (!ptr)
         190               0 :                 return false;
         191               0 :             tmp = NormalizeByteOrder16(*n);
         192               0 :             memcpy(ptr, &tmp, sizeof tmp);
         193                 :         } else {
         194               0 :             memcpy(&tmp, buf.read(sizeof tmp), sizeof tmp);
         195               0 :             *n = NormalizeByteOrder16(tmp);
         196                 :         }
         197               0 :         return true;
         198                 :     }
         199                 :
         200          117336 :     bool codeUint32(uint32_t *n) {
         201                 :         uint32_t tmp;
         202                 :         if (mode == XDR_ENCODE) {
         203           58668 :             uint8_t *ptr = buf.write(sizeof tmp);
         204           58668 :             if (!ptr)
         205               0 :                 return false;
         206           58668 :             tmp = NormalizeByteOrder32(*n);
         207           58668 :             memcpy(ptr, &tmp, sizeof tmp);
         208                 :         } else {
         209           58668 :             memcpy(&tmp, buf.read(sizeof tmp), sizeof tmp);
         210           58668 :             *n = NormalizeByteOrder32(tmp);
         211                 :         }
         212          117336 :         return true;
         213                 :     }
         214                 :
         215               0 :     bool codeDouble(double *dp) {
         216                 :         jsdpun tmp;
         217                 :         if (mode == XDR_ENCODE) {
         218               0 :             uint8_t *ptr = buf.write(sizeof tmp);
         219               0 :             if (!ptr)
         220               0 :                 return false;
         221               0 :             tmp.d = *dp;
         222               0 :             tmp.s.lo = NormalizeByteOrder32(tmp.s.lo);
         223               0 :             tmp.s.hi = NormalizeByteOrder32(tmp.s.hi);
         224               0 :             memcpy(ptr, &tmp.s.lo, sizeof tmp.s.lo);
         225               0 :             memcpy(ptr + sizeof tmp.s.lo, &tmp.s.hi, sizeof tmp.s.hi);
         226                 :         } else {
         227               0 :             const uint8_t *ptr = buf.read(sizeof tmp);
         228               0 :             memcpy(&tmp.s.lo, ptr, sizeof tmp.s.lo);
         229               0 :             memcpy(&tmp.s.hi, ptr + sizeof tmp.s.lo, sizeof tmp.s.hi);
         230               0 :             tmp.s.lo = NormalizeByteOrder32(tmp.s.lo);
         231               0 :             tmp.s.hi = NormalizeByteOrder32(tmp.s.hi);
         232               0 :             *dp = tmp.d;
         233                 :         }
         234               0 :         return true;
         235                 :     }
         236                 :
         237            9984 :     bool codeBytes(void *bytes, size_t len) {
         238                 :         if (mode == XDR_ENCODE) {
         239            4992 :             uint8_t *ptr = buf.write(len);
         240            4992 :             if (!ptr)
         241               0 :                 return false;
         242            4992 :             memcpy(ptr, bytes, len);
         243                 :         } else {
         244            4992 :             memcpy(bytes, buf.read(len), len);
         245                 :         }
         246            9984 :         return true;
         247                 :     }
         248                 :
         249                 :     /*
         250                 :      * During encoding the string is written into the buffer together with its
         251                 :      * terminating '\0'. During decoding the method returns a pointer into the
         252                 :      * decoding buffer and the caller must copy the string if it will outlive
         253                 :      * the decoding buffer.
         254                 :      */
         255            4992 :     bool codeCString(const char **sp) {
         256                 :         if (mode == XDR_ENCODE) {
         257            2496 :             size_t n = strlen(*sp) + 1;
         258            2496 :             uint8_t *ptr = buf.write(n);
         259            2496 :             if (!ptr)
         260               0 :                 return false;
         261            2496 :             memcpy(ptr, *sp, n);
         262                 :         } else {
         263            2496 :             *sp = buf.readCString();
         264                 :         }
         265            4992 :         return true;
         266                 :     }
         267                 :
         268            7871 :     bool codeChars(jschar *chars, size_t nchars);
         269            7871 :     bool codeString(JSString **strp);
         270                 :
         271              12 :     bool codeFunction(JSObject **objp);
         272              30 :     bool codeScript(JSScript **scriptp);
         273                 :
         274            2496 :     void initScriptPrincipals(JSScript *script) {
         275               0 :         JS_ASSERT(mode == XDR_DECODE);
         276                 :
         277                 :         /* The origin principals must be normalized at this point. */
         278            2496 :         JS_ASSERT_IF(principals, originPrincipals);
         279            2496 :         JS_ASSERT(!script->principals);
         280            2496 :         JS_ASSERT(!script->originPrincipals);
         281            2496 :         if (principals) {
         282              17 :             script->principals = principals;
         283              17 :             JS_HoldPrincipals(principals);
         284                 :         }
         285            2496 :         if (originPrincipals) {
         286              22 :             script->originPrincipals = originPrincipals;
         287              22 :             JS_HoldPrincipals(originPrincipals);
         288                 :         }
         289            2496 :     }
         290                 : };
         291                 :
         292                 : class XDREncoder : public XDRState<XDR_ENCODE> {
         293                 :   public:
         294            2390 :     XDREncoder(JSContext *cx)
         295            2390 :       : XDRState<XDR_ENCODE>(cx) {
         296            2390 :     }
         297                 :
         298            2390 :     ~XDREncoder() {
         299            2390 :         buf.freeBuffer();
         300            2390 :     }
         301                 :
         302            2369 :     const void *getData(uint32_t *lengthp) const {
         303            2369 :         return buf.getData(lengthp);
         304                 :     }
         305                 :
         306              21 :     void *forgetData(uint32_t *lengthp) {
         307              21 :         void *data = buf.getData(lengthp);
         308              21 :         buf.setData(NULL, 0);
         309              21 :         return data;
         310                 :     }
         311                 : };
         312                 :
         313                 : class XDRDecoder : public XDRState<XDR_DECODE> {
         314                 :   public:
         315                 :     XDRDecoder(JSContext *cx, const void *data, uint32_t length,
         316                 :                JSPrincipals *principals, JSPrincipals *originPrincipals);
         317                 :
         318                 : };
         319                 :
         320                 : } /* namespace js */
         321                 :
         322                 : #endif /* Xdr_h___ */

Generated by: LCOV version 1.7