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, быть может по ругаете код?
Здравствуйте, dosik, Вы писали:
D>Накидал вот такой тестовый примерчик для обучения "проброса" функций и классов: ><
D>Но вот только деструктор не срабатывает. Вроде как по документам может и не сработать, но что-то мне подсказывает что я тут тоже накрутил лишнего? D>Есть тут специалисты по V8, быть может по ругаете код?
На первый взгляд все нормально. Да, weak handle callback может и не успеть вызваться. Для надежности попробуйте добавить после `script->Run()` такой код запуска принудительной сборки мусора:
Здравствуйте, PM, Вы писали:
PM>после `script->Run()` такой код запуска принудительной сборки мусора...
Вот это сегодня попробую, спасибо.
PM>Ну и прорекламирую свою библиотечку, позволяющую не писать такую кучу обвязочного кода для V8: https://github.com/pmed/v8pp
Я Вам отправлял личное сообщение с примером кода и ошибки, но видимо у Вас другой почтовый ящик (указан тут на RSDN). Как-то не запустилась у меня Ваша библиотечка, позже попробую еще раз, но боюсь ребята из google опять изменений навносили.
Здравствуйте, dosik, Вы писали:
PM>>Ну и прорекламирую свою библиотечку, позволяющую не писать такую кучу обвязочного кода для V8: https://github.com/pmed/v8pp
D>Я Вам отправлял личное сообщение с примером кода и ошибки, но видимо у Вас другой почтовый ящик (указан тут на RSDN). Как-то не запустилась у меня Ваша библиотечка, позже попробую еще раз, но боюсь ребята из google опять изменений навносили.
Не пользовался личными сообщениями на сайте, не знаю как они работают, но в почте ничего нет
Можно завести issue на github, там же есть актуальный адрес электронной почты.
Здравствуйте, PM, Вы писали:
PM>На первый взгляд все нормально. Да, weak handle callback может и не успеть вызваться. Для надежности попробуйте добавить после `script->Run()` такой код запуска принудительной сборки мусора:
PM>
Здравствуйте, dosik, Вы писали:
D>Нет, деструкторы не вызвались, где-то что-то не так (((
А callback вызывается? В нем берётся указатель на экземпляр some из внутреннего поля, хотя задается External. Попробуйте использовать SetAlignedPointerInInternalField вместо SetInternalField в SomeConstructor
PM>А callback вызывается?
В том то и дело, что даже и callback не вызывается.
PM>В нем берётся указатель на экземпляр some из внутреннего поля, хотя задается External.
Все сделал, как завещал Google.
PM>Попробуйте использовать SetAlignedPointerInInternalField вместо SetInternalField в SomeConstructor
SomeTest и методы доступа адрес получают правильно, по этому дело, как мне кажется, не в SetInternalField.
SetAlignedPointerInInternalField эксперимента ради конечно попробовал (закоментировав все методы доступа) — callback не вызывается.
Здравствуйте, 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>
По идее, все тут должно быть нормально — единственная глобальная ссылка становится слабой, и функция callback должна вызываться, когда сборщик мусора подберёт остальные ссылки (а они в исходном примере остаются только в JavaScript для объектов a и b).
Здравствуйте, 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, может чего изменится.
Пока с нашими доработками вот так:
Здравствуйте, dosik, Вы писали:
D>Здравствуйте, PM, Вы писали:
PM>>Ещё идея: сделать `a = b = undefined` на стороне JavaScript после использования, поместить их в дополнительный {} блок, также позвать `RequestGarbageCollectionForTesting` перед isolate->Dispose() послы выхода из handle_scope на стороне C++
D>Не помогло. D>Сейчас пересоберу V8 на Windows без флага Debug, может чего изменится.
Какую кстати версию V8 используете, может быть в последних что-то поменялось. Или наоборот, в отладочной версии попробовать зайти внутрь `RequestGarbageCollectionForTesting` и побродить по закоулкам V8, посмотреть что происходит?
Здравствуйте, PM, Вы писали:
PM>Какую кстати версию V8 используете, может быть в последних что-то поменялось. Или наоборот, в отладочной версии попробовать зайти внутрь `RequestGarbageCollectionForTesting` и побродить по закоулкам V8, посмотреть что происходит?
Хороший вопрос Вы мне задали. Я думаю, что 6.2.306 — по крайней мере самая старшая, из тех, что были в списке по запросу "git tag". Как иначе посмотреть, даже не знаю. Ставил и собирал вот так, полагая что по умолчанию будет "последняя стабильная".
Эксперимент со сборкой без флага "Debug" так же провалился — callback не вызывается.
Здравствуйте, 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 при выходе рушилась.
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
Здравствуйте, PM, Вы писали:
PM>Если все классы которые нужно использовать в v8 ваши, то первый способ с хранением persistent в объектах выглядит проще всего. Именно так делается в Node.js — нужные классы наследуются от node::ObjectWrap
Здравствуйте, dosik, Вы писали:
>>Если все классы которые нужно использовать в v8 ваши, то первый способ с хранением persistent в объектах выглядит проще всего. Именно так делается в Node.js — нужные классы наследуются от node::ObjectWrap
D>Да, думаю будет самый оптимальный путь.
D>Еще раз огромное спасибо Вам за вашу помощь.