Line data Source code
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 :
8 : #include "mozilla/scache/StartupCache.h"
9 :
10 : #include "jsapi.h"
11 : #include "jsfriendapi.h"
12 :
13 : #include "nsJSPrincipals.h"
14 :
15 : using namespace JS;
16 : using namespace mozilla::scache;
17 : using mozilla::UniquePtr;
18 :
19 : // We only serialize scripts with system principals. So we don't serialize the
20 : // principals when writing a script. Instead, when reading it back, we set the
21 : // principals to the system principals.
22 : nsresult
23 91 : ReadCachedScript(StartupCache* cache, nsACString& uri, JSContext* cx,
24 : MutableHandleScript scriptp)
25 : {
26 182 : UniquePtr<char[]> buf;
27 : uint32_t len;
28 91 : nsresult rv = cache->GetBuffer(PromiseFlatCString(uri).get(), &buf, &len);
29 91 : if (NS_FAILED(rv))
30 65 : return rv; // don't warn since NOT_AVAILABLE is an ok error
31 :
32 52 : JS::TranscodeBuffer buffer;
33 26 : buffer.replaceRawBuffer(reinterpret_cast<uint8_t*>(buf.release()), len);
34 26 : JS::TranscodeResult code = JS::DecodeScript(cx, buffer, scriptp);
35 26 : if (code == JS::TranscodeResult_Ok)
36 26 : return NS_OK;
37 :
38 0 : if ((code & JS::TranscodeResult_Failure) != 0)
39 0 : return NS_ERROR_FAILURE;
40 :
41 0 : MOZ_ASSERT((code & JS::TranscodeResult_Throw) != 0);
42 0 : JS_ClearPendingException(cx);
43 0 : return NS_ERROR_OUT_OF_MEMORY;
44 : }
45 :
46 : nsresult
47 65 : WriteCachedScript(StartupCache* cache, nsACString& uri, JSContext* cx,
48 : HandleScript script)
49 : {
50 65 : MOZ_ASSERT(nsJSPrincipals::get(JS_GetScriptPrincipals(script))->GetIsSystemPrincipal());
51 :
52 130 : JS::TranscodeBuffer buffer;
53 65 : JS::TranscodeResult code = JS::EncodeScript(cx, buffer, script);
54 65 : if (code != JS::TranscodeResult_Ok) {
55 0 : if ((code & JS::TranscodeResult_Failure) != 0)
56 0 : return NS_ERROR_FAILURE;
57 0 : MOZ_ASSERT((code & JS::TranscodeResult_Throw) != 0);
58 0 : JS_ClearPendingException(cx);
59 0 : return NS_ERROR_OUT_OF_MEMORY;
60 : }
61 :
62 65 : size_t size = buffer.length();
63 65 : if (size > UINT32_MAX)
64 0 : return NS_ERROR_FAILURE;
65 195 : nsresult rv = cache->PutBuffer(PromiseFlatCString(uri).get(),
66 65 : reinterpret_cast<char*>(buffer.begin()),
67 65 : size);
68 65 : return rv;
69 : }
|