Есть ли спецы по V8?
От: dosik Россия www.dosik.ru
Дата: 16.08.17 09:32
Оценка:
Накидал вот такой тестовый примерчик для обучения "проброса" функций и классов:
  С++ Код
#include <iostream>
#include <fstream>

#include <libplatform/libplatform.h>
#include <v8.h>

using namespace v8;

void print(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    if (args.Length() < 1) {
        isolate->ThrowException(String::NewFromUtf8(isolate, "Too few parameters"));
        return;
    }
    String::Utf8Value value(args[0]);
    std::cout << std::string(*value) << std::endl;
}

class some {
    std::string _value;
public:
    some(const std::string &value) : _value(value) {
        std::cout << "Construct " << _value << std::endl;
    }
    ~some() {
        std::cout << "Destcruct " << _value << std::endl;
    }
    std::string test(const std::string &value) {
        return _value + " class : " + value;
    }
    std::string getValue() {
        return _value;
    }
    void setValue(const std::string& value) {
        _value.assign(value);
    }
};

some* UnwrapSome(Local<Object> obj) {
    Local<External> field = Local<External>::Cast(obj->GetInternalField(0));
    return static_cast<some*>(field->Value());
}

void SomeTest(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    if (args.Length() < 1) {
        isolate->ThrowException(String::NewFromUtf8(isolate, "Too few parameters"));
        return;
    }

    some *s = UnwrapSome(args.This());

    String::Utf8Value value(args[0]);
    std::string result = s->test(std::string(*value));
    args.GetReturnValue().Set(String::NewFromUtf8(isolate, result.c_str()));
}

void SomeValueGet(Local<String> property, const PropertyCallbackInfo<Value>& args) {
    some *s = UnwrapSome(args.This());
    args.GetReturnValue().Set(String::NewFromUtf8(args.GetIsolate(), s->getValue().c_str()));
}

void SomeValueSet(Local<String> property, Local<Value> value, const PropertyCallbackInfo<void>& args) {
    some *s = UnwrapSome(args.This());
    s->setValue(std::string(*String::Utf8Value(value)));
}


Local<ObjectTemplate> MakeSomeTemplate(Isolate* isolate) {
    EscapableHandleScope handle_scope(isolate);

    Local<ObjectTemplate> result = ObjectTemplate::New(isolate);
    result->SetInternalFieldCount(1);
    result->Set(String::NewFromUtf8(isolate, "test"), FunctionTemplate::New(isolate, SomeTest));
    result->SetAccessor(String::NewFromUtf8(isolate, "value"), SomeValueGet, SomeValueSet);

    return handle_scope.Escape(result);
}

void callback(const WeakCallbackInfo<some>& data) {
    some *s = static_cast<some*>(data.GetInternalField(0));
    delete s;
}

Global<ObjectTemplate> SomeTemplate;

void SomeConstructor(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    if (!args.IsConstructCall()) {
        isolate->ThrowException(String::NewFromUtf8(isolate, "Cannot call constructor as function"));
        return;
    }
    if (args.Length() < 1) {
        isolate->ThrowException(String::NewFromUtf8(isolate, "Too few parameters"));
        return;
    }

    EscapableHandleScope handle_scope(isolate);
    if (SomeTemplate.IsEmpty()) {
        Local<ObjectTemplate> raw_template = MakeSomeTemplate(isolate);
        SomeTemplate.Reset(isolate, raw_template);
    }

    String::Utf8Value value(args[0]);
    some* new_some = new some(std::string(*value));

    Local<Object> result = Local<ObjectTemplate>::New(isolate, SomeTemplate)->NewInstance();
    result->SetInternalField(0, External::New(isolate, new_some));

    UniquePersistent<Object> persistent(isolate, result);
    persistent.SetWeak(new_some, callback, WeakCallbackType::kParameter);

    args.GetReturnValue().Set(handle_scope.Escape(result));
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cout << "input file name" << std::endl;
        return 2;
    }

    std::ifstream f(argv[1]);
    if (!f) {
        std::cout << "file " << argv[1] << " not found" << std::endl;
        return 2;
    }
    std::string src = std::string(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>());

    V8::InitializeICUDefaultLocation(argv[0]);
    V8::InitializeExternalStartupData(argv[0]);
    Platform* platform = platform::CreateDefaultPlatform();
    V8::InitializePlatform(platform);
    V8::Initialize();

    Isolate::CreateParams create_params;
    create_params.array_buffer_allocator = ArrayBuffer::Allocator::NewDefaultAllocator();
    Isolate* isolate = Isolate::New(create_params);
    {
        Isolate::Scope isolate_scope(isolate);
        HandleScope handle_scope(isolate);

        Local<ObjectTemplate> global = ObjectTemplate::New(isolate);
        global->Set(String::NewFromUtf8(isolate, "print"), FunctionTemplate::New(isolate, print));
        global->Set(String::NewFromUtf8(isolate, "some"), FunctionTemplate::New(isolate, SomeConstructor));

        Local<Context> context = Context::New(isolate, nullptr, global);
        Context::Scope context_scope(context);

        Local<String> source = String::NewFromUtf8(isolate, src.c_str());
        Local<Script> script = Script::Compile(context, source).ToLocalChecked();

        script->Run(context);
    }
    isolate->Dispose();
    V8::Dispose();
    V8::ShutdownPlatform();
    delete platform;
    delete create_params.array_buffer_allocator;
    return 0;
}


Выполняю на нем что-то типа этого:
  JS Код
var a = new some('First');
var b = new some('Second');
print(a.value);
print(b.value);
print(a.test('a'));
print(b.test('b'));


Но вот только деструктор не срабатывает. Вроде как по документам может и не сработать, но что-то мне подсказывает что я тут тоже накрутил лишнего?
Есть тут специалисты по V8, быть может по ругаете код?
Re: Есть ли спецы по V8?
От: PM  
Дата: 16.08.17 19:19
Оценка:
Здравствуйте, dosik, Вы писали:

D>Накидал вот такой тестовый примерчик для обучения "проброса" функций и классов:

><

D>Но вот только деструктор не срабатывает. Вроде как по документам может и не сработать, но что-то мне подсказывает что я тут тоже накрутил лишнего?

D>Есть тут специалисты по V8, быть может по ругаете код?

На первый взгляд все нормально. Да, weak handle callback может и не успеть вызваться. Для надежности попробуйте добавить после `script->Run()` такой код запуска принудительной сборки мусора:

std::string const v8_flags = "--expose_gc";
v8::V8::SetFlagsFromString(v8_flags.data(), (int)v8_flags.length());
isolate->RequestGarbageCollectionForTesting(v8::Isolate::GarbageCollectionType::kFullGarbageCollection);


Ну и прорекламирую свою библиотечку, позволяющую не писать такую кучу обвязочного кода для V8: https://github.com/pmed/v8pp
Re[2]: Есть ли спецы по V8?
От: dosik Россия www.dosik.ru
Дата: 16.08.17 19:25
Оценка:
Здравствуйте, PM, Вы писали:

PM>после `script->Run()` такой код запуска принудительной сборки мусора...


Вот это сегодня попробую, спасибо.

PM>Ну и прорекламирую свою библиотечку, позволяющую не писать такую кучу обвязочного кода для V8: https://github.com/pmed/v8pp


Я Вам отправлял личное сообщение с примером кода и ошибки, но видимо у Вас другой почтовый ящик (указан тут на RSDN). Как-то не запустилась у меня Ваша библиотечка, позже попробую еще раз, но боюсь ребята из google опять изменений навносили.
Re[3]: Есть ли спецы по V8?
От: PM  
Дата: 16.08.17 20:03
Оценка:
Здравствуйте, dosik, Вы писали:

PM>>Ну и прорекламирую свою библиотечку, позволяющую не писать такую кучу обвязочного кода для V8: https://github.com/pmed/v8pp


D>Я Вам отправлял личное сообщение с примером кода и ошибки, но видимо у Вас другой почтовый ящик (указан тут на RSDN). Как-то не запустилась у меня Ваша библиотечка, позже попробую еще раз, но боюсь ребята из google опять изменений навносили.


Не пользовался личными сообщениями на сайте, не знаю как они работают, но в почте ничего нет

Можно завести issue на github, там же есть актуальный адрес электронной почты.
Re[2]: Есть ли спецы по V8?
От: dosik Россия www.dosik.ru
Дата: 16.08.17 20:10
Оценка:
Здравствуйте, PM, Вы писали:

PM>На первый взгляд все нормально. Да, weak handle callback может и не успеть вызваться. Для надежности попробуйте добавить после `script->Run()` такой код запуска принудительной сборки мусора:


PM>
PM>std::string const v8_flags = "--expose_gc";
PM>v8::V8::SetFlagsFromString(v8_flags.data(), (int)v8_flags.length());
PM>isolate->RequestGarbageCollectionForTesting(v8::Isolate::GarbageCollectionType::kFullGarbageCollection);
PM>


Нет, деструкторы не вызвались, где-то что-то не так (((
Re[3]: Есть ли спецы по V8?
От: PM  
Дата: 16.08.17 20:29
Оценка:
Здравствуйте, dosik, Вы писали:

D>Нет, деструкторы не вызвались, где-то что-то не так (((


А callback вызывается? В нем берётся указатель на экземпляр some из внутреннего поля, хотя задается External. Попробуйте использовать SetAlignedPointerInInternalField вместо SetInternalField в SomeConstructor
Re[4]: Есть ли спецы по V8?
От: dosik Россия www.dosik.ru
Дата: 16.08.17 20:43
Оценка:
Здравствуйте, PM, Вы писали:


PM>А callback вызывается?

В том то и дело, что даже и callback не вызывается.

PM>В нем берётся указатель на экземпляр some из внутреннего поля, хотя задается External.


Все сделал, как завещал Google.

PM>Попробуйте использовать SetAlignedPointerInInternalField вместо SetInternalField в SomeConstructor


SomeTest и методы доступа адрес получают правильно, по этому дело, как мне кажется, не в SetInternalField.

SetAlignedPointerInInternalField эксперимента ради конечно попробовал (закоментировав все методы доступа) — callback не вызывается.

Мне кажется тут чушь:
    UniquePersistent<Object> persistent(isolate, result);
    persistent.SetWeak(new_some, callback, WeakCallbackType::kParameter);
Re[5]: Есть ли спецы по V8?
От: PM  
Дата: 16.08.17 22:14
Оценка:
Здравствуйте, dosik, Вы писали:

PM>>А callback вызывается?

D>В том то и дело, что даже и callback не вызывается.

Да уж, такова цена автоматической сборки мусора

Ещё идея: сделать `a = b = undefined` на стороне JavaScript после использования, поместить их в дополнительный {} блок, также позвать `RequestGarbageCollectionForTesting` перед isolate->Dispose() послы выхода из handle_scope на стороне C++


PM>>Попробуйте использовать SetAlignedPointerInInternalField вместо SetInternalField в SomeConstructor


D>SomeTest и методы доступа адрес получают правильно, по этому дело, как мне кажется, не в SetInternalField.

D>SetAlignedPointerInInternalField эксперимента ради конечно попробовал (закоментировав все методы доступа) — callback не вызывается.

Да, это я стормозил, SomConstructor и UnwrapSome заворачивают/разворачивают указатель на объект одинаковым способом. Но SetAlignedPointerInInternalField/GetAlignedPointerInInternalField без промежуточного External немного проще. У Google как обычно с актуальной документацией не очень, в примерах может быть устаревший код.

Но в callback лучше все-таки получать параметр, который был задан при вызове SetWeak, с помощью data.GetParameter()

D>Мне кажется тут чушь:

D>
D>    UniquePersistent<Object> persistent(isolate, result);
D>    persistent.SetWeak(new_some, callback, WeakCallbackType::kParameter);
D>


По идее, все тут должно быть нормально — единственная глобальная ссылка становится слабой, и функция callback должна вызываться, когда сборщик мусора подберёт остальные ссылки (а они в исходном примере остаются только в JavaScript для объектов a и b).

По крайне мере, у меня такой подход в тесте работает
Re[6]: Есть ли спецы по V8?
От: dosik Россия www.dosik.ru
Дата: 17.08.17 10:16
Оценка:
Здравствуйте, PM, Вы писали:

PM>Ещё идея: сделать `a = b = undefined` на стороне JavaScript после использования, поместить их в дополнительный {} блок, также позвать `RequestGarbageCollectionForTesting` перед isolate->Dispose() послы выхода из handle_scope на стороне C++


Не помогло.

PM>SetAlignedPointerInInternalField/GetAlignedPointerInInternalField без промежуточного External немного проще. У Google как обычно с актуальной документацией не очень, в примерах может быть устаревший код.

PM>Но в callback лучше все-таки получать параметр, который был задан при вызове SetWeak, с помощью data.GetParameter()

Переделал таким образом, действительно так экономнее и быстрее. Спасибо за подсказку.

PM>По идее, все тут должно быть нормально — единственная глобальная ссылка становится слабой, и функция callback должна вызываться, когда сборщик мусора подберёт остальные ссылки (а они в исходном примере остаются только в JavaScript для объектов a и b).


PM>По крайне мере, у меня такой подход в тесте работает


Сейчас пересоберу V8 на Windows без флага Debug, может чего изменится.
Пока с нашими доработками вот так:
  Код
#include <iostream>
#include <fstream>

#include <libplatform/libplatform.h>
#include <v8.h>

using namespace v8;

void print(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    if (args.Length() < 1) {
        isolate->ThrowException(String::NewFromUtf8(isolate, "Too few parameters"));
        return;
    }
    String::Utf8Value value(args[0]);
    std::cout << std::string(*value) << std::endl;
}

class some {
    std::string _value;
public:
    some(const std::string &value) : _value(value) {
        std::cout << "Construct " << _value << std::endl;
    }
    ~some() {
        std::cout << "Destcruct " << _value << std::endl;
    }
    std::string test(const std::string &value) {
        return _value + " class : " + value;
    }
    std::string getValue() {
        return _value;
    }
    void setValue(const std::string& value) {
        _value.assign(value);
    }
};

some* UnwrapSome(Local<Object> obj) {
    return static_cast<some*>(obj->GetAlignedPointerFromInternalField(0));
}

void SomeTest(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    if (args.Length() < 1) {
        isolate->ThrowException(String::NewFromUtf8(isolate, "Too few parameters"));
        return;
    }

    some *s = UnwrapSome(args.This());

    String::Utf8Value value(args[0]);
    std::string result = s->test(std::string(*value));
    args.GetReturnValue().Set(String::NewFromUtf8(isolate, result.c_str()));
}

void SomeValueGet(Local<String> property, const PropertyCallbackInfo<Value>& args) {
    some *s = UnwrapSome(args.This());
    args.GetReturnValue().Set(String::NewFromUtf8(args.GetIsolate(), s->getValue().c_str()));
}

void SomeValueSet(Local<String> property, Local<Value> value, const PropertyCallbackInfo<void>& args) {
    some *s = UnwrapSome(args.This());
    s->setValue(std::string(*String::Utf8Value(value)));
}


Local<ObjectTemplate> MakeSomeTemplate(Isolate* isolate) {
    EscapableHandleScope handle_scope(isolate);

    Local<ObjectTemplate> result = ObjectTemplate::New(isolate);
    result->SetInternalFieldCount(1);
    result->Set(String::NewFromUtf8(isolate, "test"), FunctionTemplate::New(isolate, SomeTest));
    result->SetAccessor(String::NewFromUtf8(isolate, "value"), SomeValueGet, SomeValueSet);

    return handle_scope.Escape(result);
}

void callback(const WeakCallbackInfo<some>& data) {
    std::cout << "enter callback function" << std::endl;
    delete data.GetParameter();
}

Global<ObjectTemplate> SomeTemplate;

void SomeConstructor(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    if (!args.IsConstructCall()) {
        isolate->ThrowException(String::NewFromUtf8(isolate, "Cannot call constructor as function"));
        return;
    }
    if (args.Length() < 1) {
        isolate->ThrowException(String::NewFromUtf8(isolate, "Too few parameters"));
        return;
    }

    EscapableHandleScope handle_scope(isolate);
    if (SomeTemplate.IsEmpty()) {
        Local<ObjectTemplate> raw_template = MakeSomeTemplate(isolate);
        SomeTemplate.Reset(isolate, raw_template);
    }

    String::Utf8Value value(args[0]);
    some* new_some = new some(std::string(*value));

    Local<Object> result = Local<ObjectTemplate>::New(isolate, SomeTemplate)->NewInstance();
    result->SetAlignedPointerInInternalField(0, new_some);

    UniquePersistent<Object> persistent(isolate, result);
    persistent.SetWeak(new_some, callback, WeakCallbackType::kParameter);

    args.GetReturnValue().Set(handle_scope.Escape(result));
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cout << "input file name" << std::endl;
        return 2;
    }

    std::ifstream f(argv[1]);
    if (!f) {
        std::cout << "file " << argv[1] << " not found" << std::endl;
        return 2;
    }
    std::string src = std::string(std::istreambuf_iterator<char>(f), std::istreambuf_iterator<char>());

    V8::InitializeICUDefaultLocation(argv[0]);
    V8::InitializeExternalStartupData(argv[0]);
    Platform* platform = platform::CreateDefaultPlatform();
    V8::InitializePlatform(platform);
    V8::Initialize();

    Isolate::CreateParams create_params;
    create_params.array_buffer_allocator = ArrayBuffer::Allocator::NewDefaultAllocator();
    Isolate* isolate = Isolate::New(create_params);
    {
        Isolate::Scope isolate_scope(isolate);
        HandleScope handle_scope(isolate);

        Local<ObjectTemplate> global = ObjectTemplate::New(isolate);
        global->Set(String::NewFromUtf8(isolate, "print"), FunctionTemplate::New(isolate, print));
        global->Set(String::NewFromUtf8(isolate, "some"), FunctionTemplate::New(isolate, SomeConstructor));

        Local<Context> context = Context::New(isolate, nullptr, global);
        Context::Scope context_scope(context);

        Local<String> source = String::NewFromUtf8(isolate, src.c_str());
        Local<Script> script = Script::Compile(context, source).ToLocalChecked();

        script->Run(context);
    }
    std::string const v8_flags = "--expose_gc";
    V8::SetFlagsFromString(v8_flags.c_str(), static_cast<int>(v8_flags.length()));
    isolate->RequestGarbageCollectionForTesting(v8::Isolate::GarbageCollectionType::kFullGarbageCollection);

    isolate->Dispose();
    V8::Dispose();
    V8::ShutdownPlatform();
    delete platform;
    delete create_params.array_buffer_allocator;
    return 0;
}
Re[7]: Есть ли спецы по V8?
От: PM  
Дата: 17.08.17 18:56
Оценка:
Здравствуйте, dosik, Вы писали:

D>Здравствуйте, PM, Вы писали:


PM>>Ещё идея: сделать `a = b = undefined` на стороне JavaScript после использования, поместить их в дополнительный {} блок, также позвать `RequestGarbageCollectionForTesting` перед isolate->Dispose() послы выхода из handle_scope на стороне C++


D>Не помогло.

D>Сейчас пересоберу V8 на Windows без флага Debug, может чего изменится.

Какую кстати версию V8 используете, может быть в последних что-то поменялось. Или наоборот, в отладочной версии попробовать зайти внутрь `RequestGarbageCollectionForTesting` и побродить по закоулкам V8, посмотреть что происходит?

Для Windows я иногда раньше собирал NuGet пакеты: https://github.com/pmed/v8-nuget
Re[8]: Есть ли спецы по V8?
От: dosik Россия www.dosik.ru
Дата: 21.08.17 12:21
Оценка:
Здравствуйте, PM, Вы писали:

PM>Какую кстати версию V8 используете, может быть в последних что-то поменялось. Или наоборот, в отладочной версии попробовать зайти внутрь `RequestGarbageCollectionForTesting` и побродить по закоулкам V8, посмотреть что происходит?


Хороший вопрос Вы мне задали. Я думаю, что 6.2.306 — по крайней мере самая старшая, из тех, что были в списке по запросу "git tag". Как иначе посмотреть, даже не знаю. Ставил и собирал вот так, полагая что по умолчанию будет "последняя стабильная".

Эксперимент со сборкой без флага "Debug" так же провалился — callback не вызывается.
Re[5]: Есть ли спецы по V8?
От: PM  
Дата: 21.08.17 20:39
Оценка:
Здравствуйте, dosik, Вы писали:

D>Мне кажется тут чушь:

D>
D>    UniquePersistent<Object> persistent(isolate, result);
D>    persistent.SetWeak(new_some, callback, WeakCallbackType::kParameter);
D>


Да, здесь чушь Деструктор UniquePersistent вызывает Reset() и в V8 не остается ссылок на объект, сборщику мусора не для чего вызывать callback.

Вам нужно где-то хранить этот UniquePersistent, варианты:

1. Внутри С++ класса

class some {
...

    v8::Global<v8::Object> v8_obj;
};

void SomeConstructor(const FunctionCallbackInfo<Value>& args)
{
    ...
    Local<Object> result = Local<ObjectTemplate>::New(isolate, SomeTemplate)->NewInstance();
    result->SetAlignedPointerInInternalField(0, new_some);

    // храним weak persistent в C++ объекте
    new_some->v8_obj.Reset(isolate, result);
    new_some->v8_obj.SetWeak(new_some, callback, WeakCallbackType::kParameter);

    args.GetReturnValue().Set(handle_scope.Escape(result));
}

void callback(const WeakCallbackInfo<some>& data)
{
    std::cout << "enter callback function" << std::endl;
    // всё будет хорошо, в деструкторе some сработает деструктор v8_obj
    delete data.GetParameter();
}


2. Вне С++ класса
2.1 Создавать динамически Persistent (не UniquePersistent) и вручную делать ему Reset() в callback
void SomeConstructor(const FunctionCallbackInfo<Value>& args)
{
    ...

    Local<Object> result = Local<ObjectTemplate>::New(isolate, SomeTemplate)->NewInstance();
    result->SetAlignedPointerInInternalField(0, new_some);

    Persistent<Object>* persistent = new Persistent<Object>(isolate, result);
    // используем относительно новую  часть V8 API, kInternalFields - в callback придут
    // также два внутренних поля объекта, из первого достанем new_some
    persistent->SetWeak(persistent, callback, WeakCallbackType::kInternalFields); 

    args.GetReturnValue().Set(handle_scope.Escape(result));

}

void callback(const WeakCallbackInfo<Persistent<Object>>& data)
{
    std::cout << "enter callback function" << std::endl;
    // delete C++ object
    some* obj = static_cast<some*>(data.GetInternalField(0));
    delete obj;
    // reset and delete weak Persistent object
    Persistent<Object>* pobj = data.GetParameter();
    pobj->Reset();
    delete pobj;
}


2.2 Внутри SomeConstructor добавлять в std::map<some*, UniquePersistent> и удалять в callback. Я так cделал в v8pp.

И кстати, для глобального объекта SomeTemplate нужно сделать Reset() где-то до isolate->Dispose()
Re[6]: Есть ли спецы по V8?
От: dosik Россия www.dosik.ru
Дата: 22.08.17 09:56
Оценка:
Здравствуйте, PM, Вы писали:

PM>Да, здесь чушь Деструктор UniquePersistent вызывает Reset() и в V8 не остается ссылок на объект, сборщику мусора не для чего вызывать callback.


PM>2.1 Создавать динамически Persistent (не UniquePersistent) и вручную делать ему Reset() в callback

PM> ......
PM>2.2 Внутри SomeConstructor добавлять в std::map<some*, UniquePersistent> и удалять в callback. Я так cделал в v8pp.

Да, все верно. Все заработало. Я тоже думал в сторону Persistent, но не динамического, не люблю new/delete, как и не люблю глобальные переменные. Но видимо придется с чем-то мириться )))

Если не секрет, где прочитали про "относительно новый" WeakCallbackType::kInternalFields? Вообще от куда черпаете информацию по V8? А то с документацией у гугла смотрю как-то не очень.

PM>И кстати, для глобального объекта SomeTemplate нужно сделать Reset() где-то до isolate->Dispose()


Тоже ваша правда, под MacOS все проходило норм, под Windows при выходе рушилась.

Спасибо!!!
Re[7]: Есть ли спецы по V8?
От: PM  
Дата: 22.08.17 19:51
Оценка:
Здравствуйте, dosik, Вы писали:


PM>>2.1 Создавать динамически Persistent (не UniquePersistent) и вручную делать ему Reset() в callback

PM>> ......
PM>>2.2 Внутри SomeConstructor добавлять в std::map<some*, UniquePersistent> и удалять в callback. Я так cделал в v8pp.

D>Да, все верно. Все заработало. Я тоже думал в сторону Persistent, но не динамического, не люблю new/delete, как и не люблю глобальные переменные. Но видимо придется с чем-то мириться )))


Если все классы которые нужно использовать в v8 ваши, то первый способ с хранением persistent в объектах выглядит проще всего. Именно так делается в Node.js — нужные классы наследуются от node::ObjectWrap

D>Если не секрет, где прочитали про "относительно новый" WeakCallbackType::kInternalFields? Вообще от куда черпаете информацию по V8? А то с документацией у гугла смотрю как-то не очень.


Я раньше участвовал в нескольких проектах с использованием V8 и Node.js, следил за изменениями в v8.h, которые иногда были не совместимыми с предыдущими версиями. Но примерно с середины 4-ых версий Google перестал сильно что-то менять. А так в Release Notes к каждой версии есть ссылка на изменения в API: http://bit.ly/v8-api-changes
Re[8]: Есть ли спецы по V8?
От: dosik Россия www.dosik.ru
Дата: 22.08.17 22:34
Оценка:
Здравствуйте, PM, Вы писали:

PM>Если все классы которые нужно использовать в v8 ваши, то первый способ с хранением persistent в объектах выглядит проще всего. Именно так делается в Node.js — нужные классы наследуются от node::ObjectWrap


Да, думаю будет самый оптимальный путь.

Еще раз огромное спасибо Вам за вашу помощь.
Re[9]: Есть ли спецы по V8?
От: PM  
Дата: 23.08.17 05:19
Оценка:
Здравствуйте, dosik, Вы писали:

>>Если все классы которые нужно использовать в v8 ваши, то первый способ с хранением persistent в объектах выглядит проще всего. Именно так делается в Node.js — нужные классы наследуются от node::ObjectWrap


D>Да, думаю будет самый оптимальный путь.


D>Еще раз огромное спасибо Вам за вашу помощь.


Рад был помочь, удачи с V8
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.