Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/JsEngineInternal.h

Issue 29369365: Issue #4692 - Rewrite `SetTimeout` facility to avoid `JsValuePtr` and `JsValueList`
Patch Set: Created Dec. 19, 2016, 10:24 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/JsEngineInternal.h
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/JsEngineInternal.h
@@ -0,0 +1,171 @@
+
+#if !defined(ADBLOCK_PLUS_JS_ENGINE_INTERNAL_H)
+#define ADBLOCK_PLUS_JS_ENGINE_INTERNAL_H
+
+#include <AdblockPlus/JsEngine.h>
+#include <v8.h>
+#include <array>
+#include "AllocatedArray.h"
+#include "V8Upgrade.h"
+
+class PersistentValueArray
+ : public AllocatedArray<V8PersistentNG<v8::Value>>
+{
+ typedef AllocatedArray<V8PersistentNG<v8::Value>> Base;
+ /**
+ * Copy constructor deleted. Allocation is unique to single object.
+ */
+ PersistentValueArray(const PersistentValueArray&); // = delete;
+ /**
+ * Copy assignment deleted. Allocation is unique to single object.
+ */
+ PersistentValueArray operator=(const PersistentValueArray&); // = delete;
+
+public:
+ PersistentValueArray()
+ : Base()
+ {}
+
+ PersistentValueArray(size_t n)
+ : Base(n)
+ {}
+
+ /**
+ * As-if-default move constructor
+ */
+ PersistentValueArray(PersistentValueArray&& x) // = default;
+ : Base(std::move(x))
+ {}
+ /**
+ * As-if-default move assignment
+ */
+ PersistentValueArray& operator=(PersistentValueArray&& x) // = default;
+ {
+ Base::operator=(std::move(x));
+ return *this;
+ }
+
+ /**
+ * Convert our array from `Persistent` to `Local`.
+ */
+ AllocatedArray<v8::Local<v8::Value>> GetAsLocal(v8::Isolate* isolate)
+ {
+ const auto length = Base::Size();
+ AllocatedArray<v8::Local<v8::Value>> locals(length);
+ for (size_t i = 0; i < length; ++i)
+ {
+ locals[i] = (*this)[i].Get(isolate);
+ }
+ return std::move(locals);
+ }
+};
+
+/**
+ * \par Implementation Notes
+ */
+class JsEngineInternal
+ : public AdblockPlus::JsEngine
+{
+ /**
+ * Unique context associated with this isolate.
+ */
+ v8::Persistent<v8::Context> context;
+
+public:
+ JsEngineInternal(const AdblockPlus::ScopedV8IsolatePtr& isolate);
+
+ /**
+ * Retrieve our persistent v8 context as a local handle.
+ */
+ v8::Local<v8::Context> GetContextAsLocal() const;
+
+ /**
+ * Retrieve the global object of our context.
+ */
+ v8::Local<v8::Object> GetGlobalObject();
+
+ /**
+ * Create a JavaScript function that binds to a C++ callback.
+ *
+ * We save a copy of a pointer to the present instance when we
+ * create the JS function inside the v8 isolate.
+ * This pointer is accessible through the `v8::Arguments` class,
+ * which is the argument of the callback function.
+ * The isolate pointer is already available;
+ * the engine pointer is available if its services are needed.
+ *
+ * @param callback C++ callback to invoke.
+ * @return handle function instance within our isolate
+ *
+ * \par Precondition
+ * - Single-threading has been ensured
+ * - A v8::Context has been entered.
+ * - A handle context already exists
+ */
+ v8::Local<v8::Function> MakeCallback(v8::InvocationCallback callback);
+
+ /**
+ * Extract the engine from the arguments to a function created by `MakeCallback`
+ *
+ * @param [v8::Arguments]
+ * Arguments object pass as the argument to a callback function
+ * @return
+ * Pointer to engine instance within the arguments.
+ *
+ * \par Precondition
+ */
+ static JsEngineInternal* ExtractEngine(const v8::Arguments& arguments);
+
+ /**
+ * Call a function with the global object as "this"
+ */
+ v8::Local<v8::Value> ApplyFunction(
+ v8::Local<v8::Function> func,
+ AllocatedArray<v8::Local<v8::Value>> args);
+
+ /**
+ * Call a function with an arbitrary object as "this"
+ *
+ * Defined as a member of the engine class as part of v8 upgrade path.
+ * Newer versions of v8 require a context argument for `v8::Function::Call()`.
+ */
+ v8::Local<v8::Value> ApplyFunction(
+ v8::Local<v8::Object> thisObject,
+ v8::Local<v8::Function> func,
+ AllocatedArray<v8::Local<v8::Value>> args);
+};
+
+/**
+ * Sentry class setting up a multi-threaded v8 usage environment.
+ *
+ * The engine has the responsibility for maintaining an isolate and a context.
+ * This class maintains the following:
+ * - v8 lock to ensure single-threaded JS evaluation.
+ * - v8 scopes for isolate, handle, and scope.
+ * - shared_ptr to engine
+ */
+class V8ExecutionScope
+{
+ /**
+ * Multithread lock for v8.
+ * Declared first to ensure acquiring a lock before anything else happens.
+ */
+ const v8::Locker lock;
+ /**
+ * Isolate scope required for Isolate::GetCurrent() to work.
+ * Probably not needed as we upgrade our v8 version.
+ */
+ const v8::Isolate::Scope isolateScope;
+ /**
+ * Handle scope must be declared before any member that uses handles.
+ * Required to obtain the local context handle to initialize context scope.
+ */
+ const v8::HandleScope handleScope;
+ const v8::Context::Scope contextScope;
+public:
+ V8ExecutionScope(JsEngineInternal* engine);
+};
+
+
+
+#endif
« src/JsEngine.cpp ('K') | « src/JsEngine.cpp ('k') | src/JsEngineTransition.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld