Skip to content

Commit

Permalink
fix compile issue for v8 version 7.4~13.0
Browse files Browse the repository at this point in the history
  • Loading branch information
LanderlYoung committed Sep 20, 2024
1 parent 19a639c commit c450010
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 94 deletions.
142 changes: 72 additions & 70 deletions backend/V8/V8Engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,9 @@ Local<Value> V8Engine::eval(const Local<String>& script, const Local<Value>& sou
throw Exception("can't eval script");
}
v8::ScriptOrigin origin(
#if SCRIPTX_V8_VERSION_GE(9, 0)
#if SCRIPTX_V8_VERSION_BETWEEN(9, 0, 12, 0)
// V8 9.0 add isolate param for external API
// V8 12.1 deprecated the isolate version, and introduced the one without isolation
isolate_,
#endif
sourceFile.isNull() || !sourceFile.isString() ? v8::Local<v8::String>()
Expand All @@ -180,17 +181,18 @@ Local<Value> V8Engine::eval(const Local<String>& script) { return eval(script, {
void V8Engine::registerNativeClassStatic(v8::Local<v8::FunctionTemplate> funcT,
const internal::StaticDefine* staticDefine) {
for (auto& prop : staticDefine->properties) {
using PropDefPtr = internal::StaticDefine::PropertyDefine*;

StackFrameScope stack;
auto name = String::newString(prop.name);

v8::AccessorGetterCallback getter = nullptr;
v8::AccessorSetterCallback setter = nullptr;
v8::AccessorNameGetterCallback getter = nullptr;
v8::AccessorNameSetterCallback setter = nullptr;

if (prop.getter) {
getter = [](v8::Local<v8::String> /*property*/,
getter = [](v8::Local<v8::Name> /*property*/,
const v8::PropertyCallbackInfo<v8::Value>& info) {
auto ptr = static_cast<internal::StaticDefine::PropertyDefine*>(
info.Data().As<v8::External>()->Value());
auto ptr = static_cast<PropDefPtr>(info.Data().As<v8::External>()->Value());
Tracer trace(EngineScope::currentEngine(), ptr->traceName);
Local<Value> ret = ptr->getter();
try {
Expand All @@ -202,10 +204,9 @@ void V8Engine::registerNativeClassStatic(v8::Local<v8::FunctionTemplate> funcT,
}

if (prop.setter) {
setter = [](v8::Local<v8::String> /*property*/, v8::Local<v8::Value> value,
setter = [](v8::Local<v8::Name> /*property*/, v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<void>& info) {
auto ptr = static_cast<internal::StaticDefine::PropertyDefine*>(
info.Data().As<v8::External>()->Value());
auto ptr = static_cast<PropDefPtr>(info.Data().As<v8::External>()->Value());
Tracer trace(EngineScope::currentEngine(), ptr->traceName);
try {
ptr->setter(make<Local<Value>>(value));
Expand All @@ -216,25 +217,26 @@ void V8Engine::registerNativeClassStatic(v8::Local<v8::FunctionTemplate> funcT,
} else {
// v8 requires setter to be present, otherwise, a real js set code with create a new
// property...
setter = [](v8::Local<v8::String> property, v8::Local<v8::Value> value,
setter = [](v8::Local<v8::Name> property, v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<void>& info) {};
}

funcT->SetNativeDataProperty(
toV8(isolate_, name), getter, setter,
v8::External::New(isolate_, const_cast<internal::StaticDefine::PropertyDefine*>(&prop)),
v8::PropertyAttribute::DontDelete);
// SetNativeDataProperty with Local<String> and AccessControl is deprecated
funcT->SetNativeDataProperty(v8::Local<v8::Name>::Cast(toV8(isolate_, name)), getter, setter,
v8::External::New(isolate_, const_cast<PropDefPtr>(&prop)),
v8::PropertyAttribute::DontDelete);
}

for (auto& func : staticDefine->functions) {
using FuncDefPtr = internal::StaticDefine::FunctionDefine*;

StackFrameScope stack;
auto name = String::newString(func.name);

auto fn = v8::FunctionTemplate::New(
isolate_,
[](const v8::FunctionCallbackInfo<v8::Value>& info) {
auto funcDef = reinterpret_cast<internal::StaticDefine::FunctionDefine*>(
info.Data().As<v8::External>()->Value());
auto funcDef = reinterpret_cast<FuncDefPtr>(info.Data().As<v8::External>()->Value());
auto engine = v8_backend::currentEngine();
Tracer trace(engine, funcDef->traceName);

Expand All @@ -245,8 +247,8 @@ void V8Engine::registerNativeClassStatic(v8::Local<v8::FunctionTemplate> funcT,
v8_backend::rethrowException(e);
}
},
v8::External::New(isolate_, const_cast<internal::StaticDefine::FunctionDefine*>(&func)), {},
0, v8::ConstructorBehavior::kThrow);
v8::External::New(isolate_, const_cast<FuncDefPtr>(&func)), {}, 0,
v8::ConstructorBehavior::kThrow);
if (!fn.IsEmpty()) {
funcT->Set(toV8(isolate_, name), fn, v8::PropertyAttribute::DontDelete);
} else {
Expand Down Expand Up @@ -453,67 +455,67 @@ void V8Engine::registerNativeClassInstance(v8::Local<v8::FunctionTemplate> funcT
// instance
auto instanceT = funcT->PrototypeTemplate();
auto signature = v8::Signature::New(isolate_, funcT);

for (auto& prop : classDefine->instanceDefine.properties) {
// Template::SetAccessor is removed in 12.8
// using Template::SetAccessorProperty is recommended

using PropDefPtr = typename internal::InstanceDefine::PropertyDefine*;
StackFrameScope stack;
auto name = String::newString(prop.name);

v8::AccessorGetterCallback getter = nullptr;
v8::AccessorSetterCallback setter = nullptr;
auto data = v8::External::New(isolate_, const_cast<PropDefPtr>(&prop));
v8::Local<v8::FunctionTemplate> getter;
v8::Local<v8::FunctionTemplate> setter;

if (prop.getter) {
getter = [](v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
auto ptr = static_cast<decltype(&prop)>(info.Data().As<v8::External>()->Value());
auto thiz = static_cast<void*>(info.This()->GetAlignedPointerFromInternalField(
kInstanceObjectAlignedPointer_PolymorphicPointer));
auto scriptClass =
static_cast<ScriptClass*>(info.This()->GetAlignedPointerFromInternalField(
kInstanceObjectAlignedPointer_ScriptClass));
auto& getter = ptr->getter;

Tracer trace(scriptClass->getScriptEngine(), ptr->traceName);

Local<Value> ret = (getter)(thiz);
try {
info.GetReturnValue().Set(toV8(info.GetIsolate(), ret));
} catch (const Exception& e) {
v8_backend::rethrowException(e);
}
};
getter = v8::FunctionTemplate::New(
isolate_,
[](const v8::FunctionCallbackInfo<v8::Value>& info) {
auto ptr = static_cast<PropDefPtr>(info.Data().As<v8::External>()->Value());
auto thiz = static_cast<void*>(info.This()->GetAlignedPointerFromInternalField(
kInstanceObjectAlignedPointer_PolymorphicPointer));
auto scriptClass =
static_cast<ScriptClass*>(info.This()->GetAlignedPointerFromInternalField(
kInstanceObjectAlignedPointer_ScriptClass));
auto& getter = ptr->getter;

Tracer trace(scriptClass->getScriptEngine(), ptr->traceName);

Local<Value> ret = (getter)(thiz);
try {
info.GetReturnValue().Set(toV8(info.GetIsolate(), ret));
} catch (const Exception& e) {
v8_backend::rethrowException(e);
}
},
data, signature);
}

if (prop.setter) {
setter = [](v8::Local<v8::String> property, v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<void>& info) {
auto ptr = static_cast<decltype(&prop)>(info.Data().As<v8::External>()->Value());
auto thiz = static_cast<void*>(info.This()->GetAlignedPointerFromInternalField(
kInstanceObjectAlignedPointer_PolymorphicPointer));
auto scriptClass =
static_cast<ScriptClass*>(info.This()->GetAlignedPointerFromInternalField(
kInstanceObjectAlignedPointer_ScriptClass));
auto& setter = ptr->setter;

Tracer trace(scriptClass->getScriptEngine(), ptr->traceName);

try {
(setter)(thiz, make<Local<Value>>(value));
} catch (const Exception& e) {
v8_backend::rethrowException(e);
}
};
setter = v8::FunctionTemplate::New(
isolate_,
[](const v8::FunctionCallbackInfo<v8::Value>& info) {
auto ptr = static_cast<PropDefPtr>(info.Data().As<v8::External>()->Value());
auto thiz = static_cast<void*>(info.This()->GetAlignedPointerFromInternalField(
kInstanceObjectAlignedPointer_PolymorphicPointer));
auto scriptClass =
static_cast<ScriptClass*>(info.This()->GetAlignedPointerFromInternalField(
kInstanceObjectAlignedPointer_ScriptClass));
auto& setter = ptr->setter;

Tracer trace(scriptClass->getScriptEngine(), ptr->traceName);

try {
(setter)(thiz, make<Local<Value>>(info[0]));
} catch (const Exception& e) {
v8_backend::rethrowException(e);
}
},
data, signature);
}

auto v8Name = toV8(isolate_, name);
auto data = v8::External::New(
isolate_, const_cast<typename internal::InstanceDefine::PropertyDefine*>(&prop));

#if SCRIPTX_V8_VERSION_LE(10, 1) // SetAccessor AccessorSignature deprecated in 10.2 a8beac
auto accessSignature = v8::AccessorSignature::New(isolate_, funcT);
instanceT->SetAccessor(v8Name, getter, setter, data, v8::AccessControl::DEFAULT,
v8::PropertyAttribute::DontDelete, accessSignature);
#else
instanceT->SetAccessor(v8Name, getter, setter, data, v8::AccessControl::DEFAULT,
v8::PropertyAttribute::DontDelete);
#endif
instanceT->SetAccessorProperty(v8::Local<v8::Name>::Cast(toV8(isolate_, name)), getter, setter,
v8::PropertyAttribute::DontDelete);
}

for (auto& func : classDefine->instanceDefine.functions) {
Expand Down Expand Up @@ -541,7 +543,7 @@ void V8Engine::registerNativeClassInstance(v8::Local<v8::FunctionTemplate> funcT
},
v8::External::New(isolate_, const_cast<FuncDefPtr>(&func)), signature);
if (!fn.IsEmpty()) {
funcT->PrototypeTemplate()->Set(toV8(isolate_, name), fn, v8::PropertyAttribute::DontDelete);
instanceT->Set(toV8(isolate_, name), fn, v8::PropertyAttribute::DontDelete);
} else {
throw Exception("can't create function for instance");
}
Expand Down
45 changes: 42 additions & 3 deletions backend/V8/V8Platform.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
*/

#include "V8Platform.h"
#include <libplatform/libplatform.h>
#include <type_traits>
#include <utility>
#include "../../src/Utils.h"
#include "V8Engine.h"
#include "V8Helper.hpp"
Expand Down Expand Up @@ -52,6 +52,39 @@ class MessageQueueTaskRunner : public v8::TaskRunner {

void setEngine(V8Engine* engine) { engine_ = engine; }

#if SCRIPTX_V8_VERSION_GE(12, 4) // changed to PostTaskImpl
protected:
void PostTaskImpl(std::unique_ptr<v8::Task> task, const v8::SourceLocation& location) override {
defaultTaskRunner_->PostTask(std::move(task));
schedulePump();
}

void PostDelayedTaskImpl(std::unique_ptr<v8::Task> task, double delay_in_seconds,
const v8::SourceLocation& location) override {
defaultTaskRunner_->PostDelayedTask(std::move(task), delay_in_seconds);
schedulePump(delay_in_seconds);
}

void PostIdleTaskImpl(std::unique_ptr<v8::IdleTask> task,
const v8::SourceLocation& location) override {
defaultTaskRunner_->PostIdleTask(std::move(task));
schedulePump();
}

void PostNonNestableTaskImpl(std::unique_ptr<v8::Task> task,
const v8::SourceLocation& location) override {
defaultTaskRunner_->PostNonNestableTask(std::move(task));
schedulePump();
}

void PostNonNestableDelayedTaskImpl(std::unique_ptr<v8::Task> task, double delay_in_seconds,
const v8::SourceLocation& location) override {
defaultTaskRunner_->PostNonNestableDelayedTask(std::move(task), delay_in_seconds);
schedulePump(delay_in_seconds);
}

public:
#else
void PostTask(std::unique_ptr<v8::Task> task) override {
defaultTaskRunner_->PostTask(std::move(task));
schedulePump();
Expand All @@ -67,12 +100,13 @@ class MessageQueueTaskRunner : public v8::TaskRunner {
schedulePump();
}

bool IdleTasksEnabled() override { return defaultTaskRunner_->IdleTasksEnabled(); }

void PostNonNestableTask(std::unique_ptr<v8::Task> task) override {
defaultTaskRunner_->PostNonNestableTask(std::move(task));
schedulePump();
}
#endif

bool IdleTasksEnabled() override { return defaultTaskRunner_->IdleTasksEnabled(); }

bool NonNestableTasksEnabled() const override {
return defaultTaskRunner_->NonNestableTasksEnabled();
Expand Down Expand Up @@ -183,7 +217,12 @@ V8Platform::~V8Platform() {
#endif
}

#if SCRIPTX_V8_VERSION_GE(13, 0)
std::shared_ptr<v8::TaskRunner> V8Platform::GetForegroundTaskRunner(v8::Isolate* isolate,
v8::TaskPriority priority) {
#else
std::shared_ptr<v8::TaskRunner> V8Platform::GetForegroundTaskRunner(v8::Isolate* isolate) {
#endif
std::lock_guard<std::mutex> lock(lock_);
auto queueRunner = engineMap_[isolate].messageQueueRunner;
if (!queueRunner->hasRunner()) {
Expand Down
46 changes: 38 additions & 8 deletions backend/V8/V8Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "../../src/foundation.h"

SCRIPTX_BEGIN_INCLUDE_LIBRARY
#include <libplatform/libplatform.h>
#include <v8-platform.h>
SCRIPTX_END_INCLUDE_LIBRARY

Expand All @@ -44,7 +45,12 @@ class V8Platform : public v8::Platform {

public:
// this method is used in v8 internally, we should handle it properly, since V8 7.1.1
#if SCRIPTX_V8_VERSION_GE(13, 0)
std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(v8::Isolate* isolate,
v8::TaskPriority priority) override;
#else
std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(v8::Isolate* isolate) override;
#endif

// call in V8Engine
bool pumpMessageQueue(v8::Isolate* isolate);
Expand All @@ -57,17 +63,18 @@ class V8Platform : public v8::Platform {
bool OnCriticalMemoryPressure(size_t length) override;
#endif

public:
// directly delegate to default platform
int NumberOfWorkerThreads() override { return defaultPlatform_->NumberOfWorkerThreads(); }

#if SCRIPTX_V8_VERSION_LE(11, 3) // added default impl to call PostTaskOnWorkerThreadImpl in 11.4
void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override {
return defaultPlatform_->CallOnWorkerThread(std::move(task));
}

void CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task, double delay_in_seconds) override {
return defaultPlatform_->CallDelayedOnWorkerThread(std::move(task), delay_in_seconds);
}
#endif

double MonotonicallyIncreasingTime() override {
return defaultPlatform_->MonotonicallyIncreasingTime();
Expand All @@ -86,27 +93,50 @@ class V8Platform : public v8::Platform {
// NOTE: not available in node 14.x (node.js modified v8 code...)
// https://nodejs.org/en/download/releases/
// and node 15.x uses v8 8.6+
#if defined(BUILDING_NODE_EXTENSION) ? SCRIPTX_V8_VERSION_GE(8, 6) : SCRIPTX_V8_VERSION_GE(8, 4)

// V8 12.2 make it none-virtual by delegate to CreateJobImpl
#if defined(BUILDING_NODE_EXTENSION) ? SCRIPTX_V8_VERSION_BETWEEN(8, 6, 12, 1) \
: SCRIPTX_V8_VERSION_BETWEEN(8, 4, 12, 1)
virtual std::unique_ptr<v8::JobHandle> PostJob(v8::TaskPriority priority,
std::unique_ptr<v8::JobTask> job_task) override {
return defaultPlatform_->PostJob(priority, std::move(job_task));
}

#endif

#if SCRIPTX_V8_VERSION_GE(10, 5) // added in 10.5 1e0d18
#if SCRIPTX_V8_VERSION_BETWEEN(10, 5, 11, 3)
// added pure-virtual in 10.5 1e0d18
// added default impl to CreateJobImpl in 11.4
std::unique_ptr<v8::JobHandle> CreateJob(v8::TaskPriority priority,
std::unique_ptr<v8::JobTask> job_task) override {
return defaultPlatform_->CreateJob(priority, std::move(job_task));
}
#endif

#if SCRIPTX_V8_VERSION_BETWEEN(7, 9, 8, 1)
// v8 7.9 added pure virtual function
// v8 8.0 added default impl
// v8 8.2 removed
#if SCRIPTX_V8_VERSION_GE(11, 4)
protected:
virtual std::unique_ptr<v8::JobHandle> CreateJobImpl(
v8::TaskPriority priority, std::unique_ptr<v8::JobTask> job_task,
const v8::SourceLocation& location) override {
return defaultPlatform_->CreateJob(priority, std::move(job_task));
}

virtual void PostTaskOnWorkerThreadImpl(v8::TaskPriority priority, std::unique_ptr<v8::Task> task,
const v8::SourceLocation& location) override {
defaultPlatform_->CallOnWorkerThread(std::move(task)); // TODO
}

virtual void PostDelayedTaskOnWorkerThreadImpl(v8::TaskPriority priority,
std::unique_ptr<v8::Task> task,
double delay_in_seconds,
const v8::SourceLocation& location) override {
// TODO
defaultPlatform_->CallDelayedOnWorkerThread(std::move(task), delay_in_seconds);
}

public:
#endif

#if SCRIPTX_V8_VERSION_LE(8, 0) // removed in 8.1
void CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) override {
return GetForegroundTaskRunner(isolate)->PostTask(std::unique_ptr<v8::Task>(task));
}
Expand Down
Loading

0 comments on commit c450010

Please sign in to comment.