js/src/vm/Xdr.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:e4ff1f115f8d
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "vm/Xdr.h"
8
9 #include <string.h>
10
11 #include "jsapi.h"
12 #include "jsscript.h"
13
14 #include "vm/Debugger.h"
15
16 using namespace js;
17
18 void
19 XDRBuffer::freeBuffer()
20 {
21 js_free(base);
22 #ifdef DEBUG
23 memset(this, 0xe2, sizeof *this);
24 #endif
25 }
26
27 bool
28 XDRBuffer::grow(size_t n)
29 {
30 JS_ASSERT(n > size_t(limit - cursor));
31
32 const size_t MEM_BLOCK = 8192;
33 size_t offset = cursor - base;
34 size_t newCapacity = JS_ROUNDUP(offset + n, MEM_BLOCK);
35 if (isUint32Overflow(newCapacity)) {
36 JS_ReportErrorNumber(cx(), js_GetErrorMessage, nullptr, JSMSG_TOO_BIG_TO_ENCODE);
37 return false;
38 }
39
40 void *data = js_realloc(base, newCapacity);
41 if (!data) {
42 js_ReportOutOfMemory(cx());
43 return false;
44 }
45 base = static_cast<uint8_t *>(data);
46 cursor = base + offset;
47 limit = base + newCapacity;
48 return true;
49 }
50
51 template<XDRMode mode>
52 bool
53 XDRState<mode>::codeChars(jschar *chars, size_t nchars)
54 {
55 size_t nbytes = nchars * sizeof(jschar);
56 if (mode == XDR_ENCODE) {
57 uint8_t *ptr = buf.write(nbytes);
58 if (!ptr)
59 return false;
60 mozilla::NativeEndian::copyAndSwapToLittleEndian(ptr, chars, nchars);
61 } else {
62 const uint8_t *ptr = buf.read(nbytes);
63 mozilla::NativeEndian::copyAndSwapFromLittleEndian(chars, ptr, nchars);
64 }
65 return true;
66 }
67
68 template<XDRMode mode>
69 static bool
70 VersionCheck(XDRState<mode> *xdr)
71 {
72 uint32_t bytecodeVer;
73 if (mode == XDR_ENCODE)
74 bytecodeVer = XDR_BYTECODE_VERSION;
75
76 if (!xdr->codeUint32(&bytecodeVer))
77 return false;
78
79 if (mode == XDR_DECODE && bytecodeVer != XDR_BYTECODE_VERSION) {
80 /* We do not provide binary compatibility with older scripts. */
81 JS_ReportErrorNumber(xdr->cx(), js_GetErrorMessage, nullptr, JSMSG_BAD_SCRIPT_MAGIC);
82 return false;
83 }
84
85 return true;
86 }
87
88 template<XDRMode mode>
89 bool
90 XDRState<mode>::codeFunction(MutableHandleObject objp)
91 {
92 if (mode == XDR_DECODE)
93 objp.set(nullptr);
94
95 if (!VersionCheck(this))
96 return false;
97
98 return XDRInterpretedFunction(this, NullPtr(), NullPtr(), objp);
99 }
100
101 template<XDRMode mode>
102 bool
103 XDRState<mode>::codeScript(MutableHandleScript scriptp)
104 {
105 if (mode == XDR_DECODE)
106 scriptp.set(nullptr);
107
108 if (!VersionCheck(this))
109 return false;
110
111 if (!XDRScript(this, NullPtr(), NullPtr(), NullPtr(), scriptp))
112 return false;
113
114 return true;
115 }
116
117 template<XDRMode mode>
118 bool
119 XDRState<mode>::codeConstValue(MutableHandleValue vp)
120 {
121 return XDRScriptConst(this, vp);
122 }
123
124 XDRDecoder::XDRDecoder(JSContext *cx, const void *data, uint32_t length,
125 JSPrincipals *originPrincipals)
126 : XDRState<XDR_DECODE>(cx)
127 {
128 buf.setData(data, length);
129 this->originPrincipals_ = originPrincipals;
130 }
131
132 template class js::XDRState<XDR_ENCODE>;
133 template class js::XDRState<XDR_DECODE>;

mercurial