mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Bug 1286009 - Distinguish failure reasons of JS_{En,De}codeScript. r=luke
This commit is contained in:
parent
97b9917978
commit
c4ddfd637a
@ -14,6 +14,5 @@ var test = (function () {
|
||||
try {
|
||||
evalWithCache(test, {});
|
||||
} catch (x) {
|
||||
assertEq(x.message.includes("AsmJS"), true);
|
||||
assertEq(x.message.includes("XDR"), true);
|
||||
assertEq(x.message.includes("Asm.js is not supported by XDR"), true);
|
||||
}
|
||||
|
@ -162,7 +162,6 @@ MSG_DEF(JSMSG_USER_DEFINED_ERROR, 0, JSEXN_ERR, "JS_ReportError was called"
|
||||
|
||||
// Internal errors
|
||||
MSG_DEF(JSMSG_ALLOC_OVERFLOW, 0, JSEXN_INTERNALERR, "allocation size overflow")
|
||||
MSG_DEF(JSMSG_BAD_BUILD_ID, 0, JSEXN_INTERNALERR, "bad build ID for XDR script")
|
||||
MSG_DEF(JSMSG_BAD_BYTECODE, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}")
|
||||
MSG_DEF(JSMSG_BUFFER_TOO_SMALL, 0, JSEXN_INTERNALERR, "buffer too small")
|
||||
MSG_DEF(JSMSG_BUILD_ID_NOT_AVAILABLE, 0, JSEXN_INTERNALERR, "build ID is not available")
|
||||
|
@ -26,13 +26,17 @@ FreezeThaw(JSContext* cx, JS::HandleScript script)
|
||||
|
||||
// freeze
|
||||
uint32_t nbytes;
|
||||
void* memory = JS_EncodeScript(cx, script, &nbytes);
|
||||
if (!memory)
|
||||
void* memory = nullptr;
|
||||
TranscodeResult rs = JS_EncodeScript(cx, script, &nbytes, &memory);
|
||||
if (rs != TranscodeResult_Ok)
|
||||
return nullptr;
|
||||
|
||||
// thaw
|
||||
JSScript* script2 = JS_DecodeScript(cx, memory, nbytes);
|
||||
JS::RootedScript script2(cx);
|
||||
rs = JS_DecodeScript(cx, memory, nbytes, &script2);
|
||||
js_free(memory);
|
||||
if (rs != TranscodeResult_Ok)
|
||||
return nullptr;
|
||||
return script2;
|
||||
}
|
||||
|
||||
|
@ -6592,44 +6592,50 @@ JS::detail::AssertArgumentsAreSane(JSContext* cx, HandleValue value)
|
||||
}
|
||||
#endif /* JS_DEBUG */
|
||||
|
||||
JS_PUBLIC_API(void*)
|
||||
JS_EncodeScript(JSContext* cx, HandleScript scriptArg, uint32_t* lengthp)
|
||||
JS_PUBLIC_API(TranscodeResult)
|
||||
JS_EncodeScript(JSContext* cx, HandleScript scriptArg,
|
||||
uint32_t* lengthp, void** buffer)
|
||||
{
|
||||
XDREncoder encoder(cx);
|
||||
RootedScript script(cx, scriptArg);
|
||||
if (!encoder.codeScript(&script))
|
||||
return nullptr;
|
||||
return encoder.forgetData(lengthp);
|
||||
*buffer = nullptr;
|
||||
if (encoder.codeScript(&script))
|
||||
*buffer = encoder.forgetData(lengthp);
|
||||
MOZ_ASSERT(bool(*buffer) == (encoder.resultCode() == TranscodeResult_Ok));
|
||||
return encoder.resultCode();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void*)
|
||||
JS_EncodeInterpretedFunction(JSContext* cx, HandleObject funobjArg, uint32_t* lengthp)
|
||||
JS_PUBLIC_API(TranscodeResult)
|
||||
JS_EncodeInterpretedFunction(JSContext* cx, HandleObject funobjArg,
|
||||
uint32_t* lengthp, void** buffer)
|
||||
{
|
||||
XDREncoder encoder(cx);
|
||||
RootedFunction funobj(cx, &funobjArg->as<JSFunction>());
|
||||
if (!encoder.codeFunction(&funobj))
|
||||
return nullptr;
|
||||
return encoder.forgetData(lengthp);
|
||||
*buffer = nullptr;
|
||||
if (encoder.codeFunction(&funobj))
|
||||
*buffer = encoder.forgetData(lengthp);
|
||||
MOZ_ASSERT(bool(*buffer) == (encoder.resultCode() == TranscodeResult_Ok));
|
||||
return encoder.resultCode();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript*)
|
||||
JS_DecodeScript(JSContext* cx, const void* data, uint32_t length)
|
||||
JS_PUBLIC_API(TranscodeResult)
|
||||
JS_DecodeScript(JSContext* cx, const void* data, uint32_t length,
|
||||
JS::MutableHandleScript scriptp)
|
||||
{
|
||||
XDRDecoder decoder(cx, data, length);
|
||||
RootedScript script(cx);
|
||||
if (!decoder.codeScript(&script))
|
||||
return nullptr;
|
||||
return script;
|
||||
decoder.codeScript(scriptp);
|
||||
MOZ_ASSERT(bool(scriptp) == (decoder.resultCode() == TranscodeResult_Ok));
|
||||
return decoder.resultCode();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject*)
|
||||
JS_DecodeInterpretedFunction(JSContext* cx, const void* data, uint32_t length)
|
||||
JS_PUBLIC_API(TranscodeResult)
|
||||
JS_DecodeInterpretedFunction(JSContext* cx, const void* data, uint32_t length,
|
||||
JS::MutableHandleFunction funp)
|
||||
{
|
||||
XDRDecoder decoder(cx, data, length);
|
||||
RootedFunction funobj(cx);
|
||||
if (!decoder.codeFunction(&funobj))
|
||||
return nullptr;
|
||||
return funobj;
|
||||
decoder.codeFunction(funp);
|
||||
MOZ_ASSERT(bool(funp) == (decoder.resultCode() == TranscodeResult_Ok));
|
||||
return decoder.resultCode();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
|
@ -5836,17 +5836,38 @@ class MOZ_RAII AutoHideScriptedCaller
|
||||
* Encode/Decode interpreted scripts and functions to/from memory.
|
||||
*/
|
||||
|
||||
extern JS_PUBLIC_API(void*)
|
||||
JS_EncodeScript(JSContext* cx, JS::HandleScript script, uint32_t* lengthp);
|
||||
enum TranscodeResult
|
||||
{
|
||||
// Successful encoding / decoding.
|
||||
TranscodeResult_Ok = 0,
|
||||
|
||||
extern JS_PUBLIC_API(void*)
|
||||
JS_EncodeInterpretedFunction(JSContext* cx, JS::HandleObject funobj, uint32_t* lengthp);
|
||||
// A warning message, is set to the message out-param.
|
||||
TranscodeResult_Failure = 0x100,
|
||||
TranscodeResult_Failure_BadBuildId = TranscodeResult_Failure | 0x1,
|
||||
TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2,
|
||||
TranscodeResult_Failure_AsmJSNotSupported = TranscodeResult_Failure | 0x3,
|
||||
TranscodeResult_Failure_UnknownClassKind = TranscodeResult_Failure | 0x4,
|
||||
|
||||
extern JS_PUBLIC_API(JSScript*)
|
||||
JS_DecodeScript(JSContext* cx, const void* data, uint32_t length);
|
||||
// A error, the JSContext has a pending exception.
|
||||
TranscodeResult_Throw = 0x200
|
||||
};
|
||||
|
||||
extern JS_PUBLIC_API(TranscodeResult)
|
||||
JS_EncodeScript(JSContext* cx, JS::HandleScript script,
|
||||
uint32_t* lengthp, void** buffer);
|
||||
|
||||
extern JS_PUBLIC_API(TranscodeResult)
|
||||
JS_EncodeInterpretedFunction(JSContext* cx, JS::HandleObject funobj,
|
||||
uint32_t* lengthp, void** buffer);
|
||||
|
||||
extern JS_PUBLIC_API(TranscodeResult)
|
||||
JS_DecodeScript(JSContext* cx, const void* data, uint32_t length,
|
||||
JS::MutableHandleScript scriptp);
|
||||
|
||||
extern JS_PUBLIC_API(TranscodeResult)
|
||||
JS_DecodeInterpretedFunction(JSContext* cx, const void* data, uint32_t length,
|
||||
JS::MutableHandleFunction funp);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject*)
|
||||
JS_DecodeInterpretedFunction(JSContext* cx, const void* data, uint32_t length);
|
||||
|
||||
namespace js {
|
||||
|
||||
|
@ -358,10 +358,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
|
||||
if (!comp->creationOptions().cloneSingletons() ||
|
||||
!comp->behaviors().getSingletonsAsTemplates())
|
||||
{
|
||||
JS_ReportErrorASCII(cx,
|
||||
"Can't serialize a run-once non-function script "
|
||||
"when we're not doing singleton cloning");
|
||||
return false;
|
||||
return xdr->fail(TranscodeResult_Failure_RunOnceNotSupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -795,8 +792,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
|
||||
funEnclosingScope = function->nonLazyScript()->enclosingScope();
|
||||
} else {
|
||||
MOZ_ASSERT(function->isAsmJSNative());
|
||||
JS_ReportErrorASCII(cx, "AsmJS modules are not yet supported in XDR serialization.");
|
||||
return false;
|
||||
return xdr->fail(TranscodeResult_Failure_AsmJSNotSupported);
|
||||
}
|
||||
|
||||
funEnclosingScopeIndex = FindScopeIndex(script, *funEnclosingScope);
|
||||
@ -831,7 +827,7 @@ js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope, HandleScrip
|
||||
|
||||
default: {
|
||||
MOZ_ASSERT(false, "Unknown class kind.");
|
||||
return false;
|
||||
return xdr->fail(TranscodeResult_Failure_UnknownClassKind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1511,6 +1511,42 @@ CacheEntry_setBytecode(JSContext* cx, HandleObject cache, uint8_t* buffer, uint3
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ConvertTranscodeResultToJSException(JSContext* cx, TranscodeResult rv)
|
||||
{
|
||||
switch (rv) {
|
||||
case TranscodeResult_Ok:
|
||||
return true;
|
||||
|
||||
default:
|
||||
MOZ_FALLTHROUGH;
|
||||
case TranscodeResult_Failure:
|
||||
MOZ_ASSERT(!cx->isExceptionPending());
|
||||
JS_ReportErrorASCII(cx, "generic warning");
|
||||
return false;
|
||||
case TranscodeResult_Failure_BadBuildId:
|
||||
MOZ_ASSERT(!cx->isExceptionPending());
|
||||
JS_ReportErrorASCII(cx, "the build-id does not match");
|
||||
return false;
|
||||
case TranscodeResult_Failure_RunOnceNotSupported:
|
||||
MOZ_ASSERT(!cx->isExceptionPending());
|
||||
JS_ReportErrorASCII(cx, "run-once script are not supported by XDR");
|
||||
return false;
|
||||
case TranscodeResult_Failure_AsmJSNotSupported:
|
||||
MOZ_ASSERT(!cx->isExceptionPending());
|
||||
JS_ReportErrorASCII(cx, "Asm.js is not supported by XDR");
|
||||
return false;
|
||||
case TranscodeResult_Failure_UnknownClassKind:
|
||||
MOZ_ASSERT(!cx->isExceptionPending());
|
||||
JS_ReportErrorASCII(cx, "Unknown class kind, go fix it.");
|
||||
return false;
|
||||
|
||||
case TranscodeResult_Throw:
|
||||
MOZ_ASSERT(cx->isExceptionPending());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
Evaluate(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
@ -1656,7 +1692,9 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
if (loadBytecode) {
|
||||
script = JS_DecodeScript(cx, loadBuffer, loadLength);
|
||||
TranscodeResult rv = JS_DecodeScript(cx, loadBuffer, loadLength, &script);
|
||||
if (!ConvertTranscodeResultToJSException(cx, rv))
|
||||
return false;
|
||||
} else {
|
||||
mozilla::Range<const char16_t> chars = codeChars.twoByteRange();
|
||||
(void) JS::Compile(cx, options, chars.start().get(), chars.length(), &script);
|
||||
@ -1705,8 +1743,9 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
if (saveBytecode) {
|
||||
saveBuffer = reinterpret_cast<uint8_t*>(JS_EncodeScript(cx, script, &saveLength));
|
||||
if (!saveBuffer)
|
||||
TranscodeResult rv = JS_EncodeScript(cx, script, &saveLength,
|
||||
reinterpret_cast<void**>(&saveBuffer.rwget()));
|
||||
if (!ConvertTranscodeResultToJSException(cx, rv))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,16 @@ XDRBuffer::grow(size_t n)
|
||||
return true;
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
void
|
||||
XDRState<mode>::postProcessContextErrors(JSContext* cx)
|
||||
{
|
||||
if (cx->isExceptionPending()) {
|
||||
MOZ_ASSERT(resultCode_ == TranscodeResult_Ok);
|
||||
resultCode_ = TranscodeResult_Throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRState<mode>::codeChars(const Latin1Char* chars, size_t nchars)
|
||||
@ -110,10 +120,8 @@ VersionCheck(XDRState<mode>* xdr)
|
||||
if (!xdr->codeUint32(&buildIdLength))
|
||||
return false;
|
||||
|
||||
if (mode == XDR_DECODE && buildIdLength != buildId.length()) {
|
||||
JS_ReportErrorNumberASCII(xdr->cx(), GetErrorMessage, nullptr, JSMSG_BAD_BUILD_ID);
|
||||
return false;
|
||||
}
|
||||
if (mode == XDR_DECODE && buildIdLength != buildId.length())
|
||||
return xdr->fail(TranscodeResult_Failure_BadBuildId);
|
||||
|
||||
if (mode == XDR_ENCODE) {
|
||||
if (!xdr->codeBytes(buildId.begin(), buildIdLength))
|
||||
@ -131,11 +139,9 @@ VersionCheck(XDRState<mode>* xdr)
|
||||
if (!xdr->codeBytes(decodedBuildId.begin(), buildIdLength))
|
||||
return false;
|
||||
|
||||
if (!PodEqual(decodedBuildId.begin(), buildId.begin(), buildIdLength)) {
|
||||
// We do not provide binary compatibility with older scripts.
|
||||
JS_ReportErrorNumberASCII(xdr->cx(), GetErrorMessage, nullptr, JSMSG_BAD_BUILD_ID);
|
||||
return false;
|
||||
}
|
||||
// We do not provide binary compatibility with older scripts.
|
||||
if (!PodEqual(decodedBuildId.begin(), buildId.begin(), buildIdLength))
|
||||
return xdr->fail(TranscodeResult_Failure_BadBuildId);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -143,18 +149,26 @@ VersionCheck(XDRState<mode>* xdr)
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRState<mode>::codeFunction(MutableHandleFunction objp)
|
||||
XDRState<mode>::codeFunction(MutableHandleFunction funp)
|
||||
{
|
||||
if (mode == XDR_DECODE)
|
||||
objp.set(nullptr);
|
||||
funp.set(nullptr);
|
||||
else
|
||||
MOZ_ASSERT(objp->nonLazyScript()->enclosingScope()->is<GlobalScope>());
|
||||
MOZ_ASSERT(funp->nonLazyScript()->enclosingScope()->is<GlobalScope>());
|
||||
|
||||
if (!VersionCheck(this))
|
||||
if (!VersionCheck(this)) {
|
||||
postProcessContextErrors(cx());
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedScope scope(cx(), &cx()->global()->emptyGlobalScope());
|
||||
return XDRInterpretedFunction(this, scope, nullptr, objp);
|
||||
if (!XDRInterpretedFunction(this, scope, nullptr, funp)) {
|
||||
postProcessContextErrors(cx());
|
||||
funp.set(nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
@ -166,10 +180,18 @@ XDRState<mode>::codeScript(MutableHandleScript scriptp)
|
||||
else
|
||||
MOZ_ASSERT(!scriptp->enclosingScope());
|
||||
|
||||
if (!VersionCheck(this))
|
||||
if (!VersionCheck(this)) {
|
||||
postProcessContextErrors(cx());
|
||||
return false;
|
||||
}
|
||||
|
||||
return XDRScript(this, nullptr, nullptr, nullptr, scriptp);
|
||||
if (!XDRScript(this, nullptr, nullptr, nullptr, scriptp)) {
|
||||
postProcessContextErrors(cx());
|
||||
scriptp.set(nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
|
@ -79,16 +79,28 @@ template <XDRMode mode>
|
||||
class XDRState {
|
||||
public:
|
||||
XDRBuffer buf;
|
||||
TranscodeResult resultCode_;
|
||||
|
||||
protected:
|
||||
explicit XDRState(JSContext* cx)
|
||||
: buf(cx) { }
|
||||
: buf(cx), resultCode_(TranscodeResult_Ok) { }
|
||||
|
||||
public:
|
||||
JSContext* cx() const {
|
||||
return buf.cx();
|
||||
}
|
||||
|
||||
// Record logical failures of XDR.
|
||||
void postProcessContextErrors(JSContext* cx);
|
||||
TranscodeResult resultCode() const {
|
||||
return resultCode_;
|
||||
}
|
||||
bool fail(TranscodeResult code) {
|
||||
MOZ_ASSERT(resultCode_ == TranscodeResult_Ok);
|
||||
resultCode_ = code;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool codeUint8(uint8_t* n) {
|
||||
if (mode == XDR_ENCODE) {
|
||||
uint8_t* ptr = buf.write(sizeof *n);
|
||||
|
@ -29,31 +29,24 @@ ReadCachedScript(StartupCache* cache, nsACString& uri, JSContext* cx,
|
||||
if (NS_FAILED(rv))
|
||||
return rv; // don't warn since NOT_AVAILABLE is an ok error
|
||||
|
||||
scriptp.set(JS_DecodeScript(cx, buf.get(), len));
|
||||
if (!scriptp)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
TranscodeResult code = JS_DecodeScript(cx, buf.get(), len, scriptp);
|
||||
if (code == TranscodeResult_Ok)
|
||||
return NS_OK;
|
||||
|
||||
if ((code & TranscodeResult_Failure) != 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
MOZ_ASSERT((code & TranscodeResult_Throw) != 0);
|
||||
JS_ClearPendingException(cx);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ReadCachedFunction(StartupCache* cache, nsACString& uri, JSContext* cx,
|
||||
nsIPrincipal* systemPrincipal, JSFunction** functionp)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
/* This doesn't actually work ...
|
||||
nsAutoArrayPtr<char> buf;
|
||||
uint32_t len;
|
||||
nsresult rv = cache->GetBuffer(PromiseFlatCString(uri).get(),
|
||||
getter_Transfers(buf), &len);
|
||||
if (NS_FAILED(rv))
|
||||
return rv; // don't warn since NOT_AVAILABLE is an ok error
|
||||
|
||||
JSObject* obj = JS_DecodeInterpretedFunction(cx, buf, len, nsJSPrincipals::get(systemPrincipal), nullptr);
|
||||
if (!obj)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
JSFunction* function = JS_ValueToFunction(cx, OBJECT_TO_JSVAL(obj));
|
||||
*functionp = function;
|
||||
return NS_OK;*/
|
||||
// This doesn't actually work ...
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -63,14 +56,17 @@ WriteCachedScript(StartupCache* cache, nsACString& uri, JSContext* cx,
|
||||
MOZ_ASSERT(JS_GetScriptPrincipals(script) == nsJSPrincipals::get(systemPrincipal));
|
||||
|
||||
uint32_t size;
|
||||
void* data = JS_EncodeScript(cx, script, &size);
|
||||
if (!data) {
|
||||
// JS_EncodeScript may have set a pending exception.
|
||||
void* data = nullptr;
|
||||
TranscodeResult code = JS_EncodeScript(cx, script, &size, &data);
|
||||
if (code != TranscodeResult_Ok) {
|
||||
if ((code & TranscodeResult_Failure) != 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
MOZ_ASSERT((code & TranscodeResult_Throw) != 0);
|
||||
JS_ClearPendingException(cx);
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(size);
|
||||
MOZ_ASSERT(size && data);
|
||||
nsresult rv = cache->PutBuffer(PromiseFlatCString(uri).get(), static_cast<char*>(data), size);
|
||||
js_free(data);
|
||||
return rv;
|
||||
@ -80,19 +76,6 @@ nsresult
|
||||
WriteCachedFunction(StartupCache* cache, nsACString& uri, JSContext* cx,
|
||||
nsIPrincipal* systemPrincipal, JSFunction* function)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
/* This doesn't actually work ...
|
||||
uint32_t size;
|
||||
void* data =
|
||||
JS_EncodeInterpretedFunction(cx, JS_GetFunctionObject(function), &size);
|
||||
if (!data) {
|
||||
// JS_EncodeInterpretedFunction may have set a pending exception.
|
||||
JS_ClearPendingException(cx);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(size);
|
||||
nsresult rv = cache->PutBuffer(PromiseFlatCString(uri).get(), static_cast<char*>(data), size);
|
||||
js_free(data);
|
||||
return rv;*/
|
||||
// This doesn't actually work ...
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -1091,17 +1091,24 @@ WriteScriptOrFunction(nsIObjectOutputStream* stream, JSContext* cx,
|
||||
|
||||
|
||||
uint32_t size;
|
||||
void* data;
|
||||
void* data = nullptr;
|
||||
TranscodeResult code;
|
||||
{
|
||||
if (functionObj)
|
||||
data = JS_EncodeInterpretedFunction(cx, functionObj, &size);
|
||||
code = JS_EncodeInterpretedFunction(cx, functionObj, &size, &data);
|
||||
else
|
||||
data = JS_EncodeScript(cx, script, &size);
|
||||
code = JS_EncodeScript(cx, script, &size, &data);
|
||||
}
|
||||
|
||||
if (!data)
|
||||
if (code != TranscodeResult_Ok) {
|
||||
if ((code & TranscodeResult_Failure) != 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
MOZ_ASSERT((code & TranscodeResult_Throw) != 0);
|
||||
JS_ClearPendingException(cx);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
MOZ_ASSERT(size);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(size && data);
|
||||
rv = stream->Write32(size);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = stream->WriteBytes(static_cast<char*>(data), size);
|
||||
@ -1139,18 +1146,25 @@ ReadScriptOrFunction(nsIObjectInputStream* stream, JSContext* cx,
|
||||
return rv;
|
||||
|
||||
{
|
||||
TranscodeResult code;
|
||||
if (scriptp) {
|
||||
JSScript* script = JS_DecodeScript(cx, data, size);
|
||||
if (!script)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
else
|
||||
*scriptp = script;
|
||||
Rooted<JSScript*> script(cx);
|
||||
code = JS_DecodeScript(cx, data, size, &script);
|
||||
if (code == TranscodeResult_Ok)
|
||||
*scriptp = script.get();
|
||||
} else {
|
||||
JSObject* funobj = JS_DecodeInterpretedFunction(cx, data, size);
|
||||
if (!funobj)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
else
|
||||
*functionObjp = funobj;
|
||||
Rooted<JSFunction*> funobj(cx);
|
||||
code = JS_DecodeInterpretedFunction(cx, data, size, &funobj);
|
||||
if (code == TranscodeResult_Ok)
|
||||
*functionObjp = JS_GetFunctionObject(funobj.get());
|
||||
}
|
||||
|
||||
if (code != TranscodeResult_Ok) {
|
||||
if ((code & TranscodeResult_Failure) != 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
MOZ_ASSERT((code & TranscodeResult_Throw) != 0);
|
||||
JS_ClearPendingException(cx);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user