SourceHook.h (4305B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 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 * The context-wide source hook allows the source of scripts/functions to be 9 * discarded, if that source is constant and readily-reloadable if it's needed 10 * in the future. 11 * 12 * Ordinarily, functions and scripts store a copy of their underlying source, to 13 * support |Function.prototype.toString| and debuggers. Some scripts, however, 14 * might be constant and retrievable on demand -- perhaps burned into the binary 15 * or in a readonly file provided by the embedding. Why not just ask the 16 * embedding for a copy of the source? 17 * 18 * The context-wide |SourceHook| gives embedders a way to respond to these 19 * requests. The source of scripts/functions compiled with the compile option 20 * |JS::CompileOptions::setSourceIsLazy(true)| is eligible to be discarded. 21 * (The exact conditions under which source is discarded are unspecified.) *If* 22 * source is discarded, performing an operation that requires source uses the 23 * source hook to load the source. 24 * 25 * The source hook must return the *exact* same source for every call. (This is 26 * why the source hook is unsuitable for use with scripts loaded from the web: 27 * in general, their contents can change over time.) If the source hook doesn't 28 * return the exact same source, Very Bad Things may happen. (For example, 29 * previously-valid indexes into the source will no longer be coherent: they 30 * might index out of bounds, into the middle of multi-unit code points, &c.) 31 * 32 * These APIs are experimental because they shouldn't provide a per-*context* 33 * mechanism, rather something that's per-compilation. 34 */ 35 36 #ifndef js_experimental_SourceHook_h 37 #define js_experimental_SourceHook_h 38 39 #include "mozilla/UniquePtr.h" // mozilla::UniquePtr 40 41 #include <stddef.h> // size_t 42 43 #include "jstypes.h" // JS_PUBLIC_API 44 45 struct JS_PUBLIC_API JSContext; 46 47 namespace js { 48 49 /** 50 * A class of objects that return source code on demand. 51 * 52 * When code is compiled with setSourceIsLazy(true), SpiderMonkey doesn't 53 * retain the source code (and doesn't do lazy bytecode generation). If we ever 54 * need the source code, say, in response to a call to Function.prototype. 55 * toSource or Debugger.Source.prototype.text, then we call the 'load' member 56 * function of the instance of this class that has hopefully been registered 57 * with the runtime, passing the code's URL, and hope that it will be able to 58 * find the source. 59 */ 60 class SourceHook { 61 public: 62 virtual ~SourceHook() = default; 63 64 /** 65 * Attempt to load the source for |filename|. 66 * 67 * On success, return true and store an owning pointer to the UTF-8 or UTF-16 68 * contents of the file in whichever of |twoByteSource| or |utf8Source| is 69 * non-null. (Exactly one of these will be non-null.) If the stored pointer 70 * is non-null, source was loaded and must be |js_free|'d when it's no longer 71 * needed. If the stored pointer is null, the JS engine will simply act as if 72 * source was unavailable, and users like |Function.prototype.toString| will 73 * produce fallback results, e.g. "[native code]". 74 * 75 * On failure, return false. The contents of whichever of |twoByteSource| or 76 * |utf8Source| was initially non-null are unspecified and must not be 77 * |js_free|'d. 78 */ 79 virtual bool load(JSContext* cx, const char* filename, 80 char16_t** twoByteSource, char** utf8Source, 81 size_t* length) = 0; 82 }; 83 84 /** 85 * Have |cx| use |hook| to retrieve lazily-retrieved source code. See the 86 * comments for SourceHook. The context takes ownership of the hook, and 87 * will delete it when the context itself is deleted, or when a new hook is 88 * set. 89 */ 90 extern JS_PUBLIC_API void SetSourceHook(JSContext* cx, 91 mozilla::UniquePtr<SourceHook> hook); 92 93 /** Remove |cx|'s source hook, and return it. The caller now owns the hook. */ 94 extern JS_PUBLIC_API mozilla::UniquePtr<SourceHook> ForgetSourceHook( 95 JSContext* cx); 96 97 } // namespace js 98 99 #endif // js_experimental_SourceHook_h