OLD | NEW |
(Empty) | |
| 1 |
| 2 #if !defined(ADBLOCK_PLUS_JS_ENGINE_INTERNAL_H) |
| 3 #define ADBLOCK_PLUS_JS_ENGINE_INTERNAL_H |
| 4 |
| 5 #include <AdblockPlus/JsEngine.h> |
| 6 #include <v8.h> |
| 7 #include <array> |
| 8 #include "AllocatedArray.h" |
| 9 #include "V8Upgrade.h" |
| 10 |
| 11 class PersistentValueArray |
| 12 : public AllocatedArray<V8PersistentNG<v8::Value>> |
| 13 { |
| 14 typedef AllocatedArray<V8PersistentNG<v8::Value>> Base; |
| 15 /** |
| 16 * Copy constructor deleted. Allocation is unique to single object. |
| 17 */ |
| 18 PersistentValueArray(const PersistentValueArray&); // = delete; |
| 19 /** |
| 20 * Copy assignment deleted. Allocation is unique to single object. |
| 21 */ |
| 22 PersistentValueArray operator=(const PersistentValueArray&); // = delete; |
| 23 |
| 24 public: |
| 25 PersistentValueArray() |
| 26 : Base() |
| 27 {} |
| 28 |
| 29 PersistentValueArray(size_t n) |
| 30 : Base(n) |
| 31 {} |
| 32 |
| 33 /** |
| 34 * As-if-default move constructor |
| 35 */ |
| 36 PersistentValueArray(PersistentValueArray&& x) // = default; |
| 37 : Base(std::move(x)) |
| 38 {} |
| 39 /** |
| 40 * As-if-default move assignment |
| 41 */ |
| 42 PersistentValueArray& operator=(PersistentValueArray&& x) // = default; |
| 43 { |
| 44 Base::operator=(std::move(x)); |
| 45 return *this; |
| 46 } |
| 47 |
| 48 /** |
| 49 * Convert our array from `Persistent` to `Local`. |
| 50 */ |
| 51 AllocatedArray<v8::Local<v8::Value>> GetAsLocal(v8::Isolate* isolate) |
| 52 { |
| 53 const auto length = Base::Size(); |
| 54 AllocatedArray<v8::Local<v8::Value>> locals(length); |
| 55 for (size_t i = 0; i < length; ++i) |
| 56 { |
| 57 locals[i] = (*this)[i].Get(isolate); |
| 58 } |
| 59 return std::move(locals); |
| 60 } |
| 61 }; |
| 62 |
| 63 /** |
| 64 * \par Implementation Notes |
| 65 */ |
| 66 class JsEngineInternal |
| 67 : public AdblockPlus::JsEngine |
| 68 { |
| 69 /** |
| 70 * Unique context associated with this isolate. |
| 71 */ |
| 72 v8::Persistent<v8::Context> context; |
| 73 |
| 74 public: |
| 75 JsEngineInternal(const AdblockPlus::ScopedV8IsolatePtr& isolate); |
| 76 |
| 77 /** |
| 78 * Retrieve our persistent v8 context as a local handle. |
| 79 */ |
| 80 v8::Local<v8::Context> GetContextAsLocal() const; |
| 81 |
| 82 /** |
| 83 * Retrieve the global object of our context. |
| 84 */ |
| 85 v8::Local<v8::Object> GetGlobalObject(); |
| 86 |
| 87 /** |
| 88 * Create a JavaScript function that binds to a C++ callback. |
| 89 * |
| 90 * We save a copy of a pointer to the present instance when we |
| 91 * create the JS function inside the v8 isolate. |
| 92 * This pointer is accessible through the `v8::Arguments` class, |
| 93 * which is the argument of the callback function. |
| 94 * The isolate pointer is already available; |
| 95 * the engine pointer is available if its services are needed. |
| 96 * |
| 97 * @param callback C++ callback to invoke. |
| 98 * @return handle function instance within our isolate |
| 99 * |
| 100 * \par Precondition |
| 101 * - Single-threading has been ensured |
| 102 * - A v8::Context has been entered. |
| 103 * - A handle context already exists |
| 104 */ |
| 105 v8::Local<v8::Function> MakeCallback(v8::InvocationCallback callback); |
| 106 |
| 107 /** |
| 108 * Extract the engine from the arguments to a function created by `MakeCallbac
k` |
| 109 * |
| 110 * @param [v8::Arguments] |
| 111 * Arguments object pass as the argument to a callback function |
| 112 * @return |
| 113 * Pointer to engine instance within the arguments. |
| 114 * |
| 115 * \par Precondition |
| 116 */ |
| 117 static JsEngineInternal* ExtractEngine(const v8::Arguments& arguments); |
| 118 |
| 119 /** |
| 120 * Call a function with the global object as "this" |
| 121 */ |
| 122 v8::Local<v8::Value> ApplyFunction( |
| 123 v8::Local<v8::Function> func, |
| 124 AllocatedArray<v8::Local<v8::Value>> args); |
| 125 |
| 126 /** |
| 127 * Call a function with an arbitrary object as "this" |
| 128 * |
| 129 * Defined as a member of the engine class as part of v8 upgrade path. |
| 130 * Newer versions of v8 require a context argument for `v8::Function::Call()`. |
| 131 */ |
| 132 v8::Local<v8::Value> ApplyFunction( |
| 133 v8::Local<v8::Object> thisObject, |
| 134 v8::Local<v8::Function> func, |
| 135 AllocatedArray<v8::Local<v8::Value>> args); |
| 136 }; |
| 137 |
| 138 /** |
| 139 * Sentry class setting up a multi-threaded v8 usage environment. |
| 140 * |
| 141 * The engine has the responsibility for maintaining an isolate and a context. |
| 142 * This class maintains the following: |
| 143 * - v8 lock to ensure single-threaded JS evaluation. |
| 144 * - v8 scopes for isolate, handle, and scope. |
| 145 * - shared_ptr to engine |
| 146 */ |
| 147 class V8ExecutionScope |
| 148 { |
| 149 /** |
| 150 * Multithread lock for v8. |
| 151 * Declared first to ensure acquiring a lock before anything else happens. |
| 152 */ |
| 153 const v8::Locker lock; |
| 154 /** |
| 155 * Isolate scope required for Isolate::GetCurrent() to work. |
| 156 * Probably not needed as we upgrade our v8 version. |
| 157 */ |
| 158 const v8::Isolate::Scope isolateScope; |
| 159 /** |
| 160 * Handle scope must be declared before any member that uses handles. |
| 161 * Required to obtain the local context handle to initialize context scope. |
| 162 */ |
| 163 const v8::HandleScope handleScope; |
| 164 const v8::Context::Scope contextScope; |
| 165 public: |
| 166 V8ExecutionScope(JsEngineInternal* engine); |
| 167 }; |
| 168 |
| 169 |
| 170 |
| 171 #endif |
OLD | NEW |