Здравствуйте, korzhik, Вы писали:
K>Здравствуйте, nixxxin, Вы писали:
N>>Здравствуйте, korzhik, Вы писали:
N>>http://www.mozilla.org/js/spidermonkey
N>>Удовлетворяет всем пунктам.
K>Спасибо. K>Правда этот движок уже здесь упоменался. K>Слышал, что тормозной он. В любом случае надо проверять.
Павел, в вашем случае в первую очередь должна интересовать лицензия.
MPL не подходит насколько я знаю для вас.
Боюсь как бы вообще не с нуля все писать придется.
Здравствуйте, kliff, Вы писали:
K>Здравствуйте, c-smile, Вы писали:
CS>>PS: Spider Monkey можно не смотреть. Старый проект — куча культурных слоев. Расширямости — ноль. CS>>Также не надо смотреть на KDE JS (http://developer.kde.org/documentation/library/3.0-api/classref/kjs/) CS>>и SEE: Simple ECMAScript Engine (http://www.adaptive-enterprises.com.au/~d/software/see/) CS>>ибо писано это детьми Герберта Шилдта в стиле наивной прямой интепретации source code — "что вижу то пою".
K>А чем дети Шилдта отличаются?
Есть три способа интерпретации:
1) прямая, синтаксический разбор совмещен с исполнением:
3) компиляция в байткод и исполнение байткода на стеке:
void parse_exp1(bytecodes)
{
parse_exp2(value);
byte bc;
switch(get_token())
{ /* perform the relational operation */case '<':
bc = CODE_LT; break;
case '>':
bc = CODE_GT; break;
default:
push_back_token();
return;
}
bytecodes.append(CODE_PUSH);
parse_exp2(bytecodes);
bytecodes.append(bc);
}
value exec(bytecodes)
{
byte* pc = &bytecodes[0];
for(;;) /* for all bytecodes */
{
switch(*pc)
{
...
case CODE_LT: v = *stack[1] < *stack[0]; --stack; *stack = t; ++pc; break;
case CODE_GT: v = *stack[1] > *stack[0]; --stack; *stack = t; ++pc; break;
}
}
}
Третий метод самый правильный — в смысле эффективный, поддается формальной оптимизации и не
использует C stack.
1 или 2 метод используют KJS, SEE и по-моему Mozilla (уже не помню)
3 метод используют NJS, DMDScript, MS JS (по косвенным данным), BOB, c-smile, tiscript.
Вот примерно так.
Re[6]: Scripting engine for С++
От:
Аноним
Дата:
09.01.06 15:17
Оценка:
Здравствуйте, c-smile, Вы писали:
CS>Третий метод самый правильный — в смысле эффективный, поддается формальной оптимизации и не CS>использует C stack.
CS>1 или 2 метод используют KJS, SEE и по-моему Mozilla (уже не помню) CS>3 метод используют NJS, DMDScript, MS JS (по косвенным данным), BOB, c-smile, tiscript.
В Mozilla JS (по крайней мере в последней версии) используется как раз 3-й подход. Т.е. компиляция в байткод. Там можно явно скомпилировать скрипт, и потом многократно его вызывать на исполнение.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, c-smile, Вы писали:
CS>>Третий метод самый правильный — в смысле эффективный, поддается формальной оптимизации и не CS>>использует C stack.
CS>>1 или 2 метод используют KJS, SEE и по-моему Mozilla (уже не помню) CS>>3 метод используют NJS, DMDScript, MS JS (по косвенным данным), BOB, c-smile, tiscript.
А>В Mozilla JS (по крайней мере в последней версии) используется как раз 3-й подход. Т.е. компиляция в байткод. Там можно явно скомпилировать скрипт, и потом многократно его вызывать на исполнение.
Да, промашка вышла с моей стороны. Там действиельно BC interpretter.
А>IMHO Mozilla — это как раз оптимальный выбор.
Здравствуйте, korzhik, Вы писали:
K>Здравствуйте,
K>мне нужно принять решение какой scripting engine использовать в проекте. K>Прошу у вас совета.
K>Требования такие: K>1. Кроссплатформенность K>2. Работа с ECMAScript, но с возможностью расширения до синтаксиса близкого к C# K>3. Лёгкость интегрирования в существующий C++ проект K>4. Лёгкость самого scripting engine, то есть малый размер и скорость работы.
K>Спасибо.
K>Требования такие: K>1. Кроссплатформенность K>2. Работа с ECMAScript, но с возможностью расширения до синтаксиса близкого к C# K>3. Лёгкость интегрирования в существующий C++ проект K>4. Лёгкость самого scripting engine, то есть малый размер и скорость работы.
Возник аналогичный вопрос. Требования (1 и 2) не нужно, кроме (3 и 4), нужна поддержка ActiveX\COM объектов а-ля VB или Java скрипт. Безусловно, можно сделать врапперы-интерфейсы для С++ объектов и сделать все на WSH, но как то это муторно, хотелось бы попроще. Может, какие из перечисленных или других скриптовых движков поддерживают ActiveX\COM? Кроме WSH, я других вариантов не нашел
Здравствуйте, Andrew S, Вы писали:
K>>Требования такие: K>>1. Кроссплатформенность K>>2. Работа с ECMAScript, но с возможностью расширения до синтаксиса близкого к C# K>>3. Лёгкость интегрирования в существующий C++ проект K>>4. Лёгкость самого scripting engine, то есть малый размер и скорость работы.
AS>Возник аналогичный вопрос. Требования (1 и 2) не нужно, кроме (3 и 4), нужна поддержка ActiveX\COM объектов а-ля VB или Java скрипт. Безусловно, можно сделать врапперы-интерфейсы для С++ объектов и сделать все на WSH, но как то это муторно, хотелось бы попроще. Может, какие из перечисленных или других скриптовых движков поддерживают ActiveX\COM? Кроме WSH, я других вариантов не нашел
Что-то я тебя не понимаю.
Скриптинг-энжин, это такая штуковина (dll, lib или даже просто cpp), которую всовываешь в проект, и уже можешь исполнять c ее помощью скриптовый код. Так?
Так вот, в микрософтовском подходе (ActiveScript) это разрезано напополам, на Scripting Engine и Scripting Host, причем так, что умея скриптинг-хост ты можешь цеплять к нему по COM-у разные энжины.
Если тебе нужно это всандалить в свой проект, то скриптинг хост либо нужно реализовать самому, либо воспользоваться имеющимся, например Scripting Control.
А WSH — это отдельностоящий хост, включить его в проект на С++ нельзя, в том смысле, что если можно то он будет одельным процессом.
Если тебе нужна поддержка COM, то я бы использовал ActiveScript. Собственно говоря, я другой просто не знаю.
GS>Если тебе нужно это всандалить в свой проект, то скриптинг хост либо нужно реализовать самому, либо воспользоваться имеющимся, например Scripting Control.
GS>А WSH — это отдельностоящий хост, включить его в проект на С++ нельзя, в том смысле, что если можно то он будет одельным процессом.
GS>Если тебе нужна поддержка COM, то я бы использовал ActiveScript. Собственно говоря, я другой просто не знаю.
Это проблематично, поскольку придется писать кучу COM врапперов и иметь проблемы с контролем времени жизни объектов, либо вообще делать все внутри в виде интерфейсов. Логика и структура имеющегося код довольно сложна, этого хотелось бы по возможности избежать, создание подобных врапперов будет задачей, сравнимой по сложности с уже имеющимся функционалом.
Здравствуйте, Andrew S, Вы писали:
GS>>Если тебе нужна поддержка COM, то я бы использовал ActiveScript. Собственно говоря, я другой просто не знаю.
AS>Это проблематично, поскольку придется писать кучу COM врапперов и иметь проблемы с контролем времени жизни объектов,
Придется. COM-ли врапперов, или врапперов для другого скриптинга. Проблемы c контролем времени жизни преувеличены. Достаточно их просто привязать смарт-пойнтерами к объектам скриптинга.
AS>либо вообще делать все внутри в виде интерфейсов.
Да. Но кто ж знал заранее...
AS>Логика и структура имеющегося код довольно сложна, этого хотелось бы по возможности избежать, создание подобных врапперов будет задачей, сравнимой по сложности с уже имеющимся функционалом.
Я сейчас занимаюсь чем-то подобным. Имею ужасающий код в который нужно впыжить скриптинг. Сделано, в конце концов, так: выписан промежуточный абстрактный слой (см. сигу Анатоликса), этот промежуточный абстрактный слой определяет объектную модель, экспортируюмую в скриптинг, и используется в качестве метаданных при генерации врапперов. Врапперы генерируются одновременно и для ActiveScript и для SpiderMonkey.
ActiveScript очень удобен тем, что его можно дебагать на скриптовом уровне. Также можно переключиться, к примеру, c jscript на vbscript. Также влегкую реализовался внешний скриптинг и вообще управление приложением извне по COM интерфейсам.
То есть получается (мета)программироваие на смеси XSLT/C++/JavaScript.
AS>>Это проблематично, поскольку придется писать кучу COM врапперов и иметь проблемы с контролем времени жизни объектов,
GS>Придется. COM-ли врапперов, или врапперов для другого скриптинга. Проблемы c контролем времени жизни преувеличены. Достаточно их просто привязать смарт-пойнтерами к объектам скриптинга.
Например, есть некий класс, в котором есть набор итемов std::vector<CItem *> или std::list<CItem>. Кроме того, на эти же итемы могут ссылаться внешние по отношению к этому объекты. Т.о. для актив скриптинга возникает проблема времени жизни объектов CItem. И сделать это все по-нормальному без переделки CItem на ком интерфейс будет очень непросто — ведь сейчас класс-контейнер контролирует время жизни экземпляра CItem, а для Com время жизни определяется счетчиком ссылок. Плюс возникает проблема эффективного создания подобных объектов. В случае list аллокатор может быть сколь угодно оптимизирован на создание мелких объектов, в отличие от стандартной фабрики интерфейсов, которую я вижу вариант сделать только по new.
Т.о. получается, что если есть хоть какие то минимальные зависимости между объектами, враппер сделать практически невозможно — возникают проблемы времени жизни. Придется именно внутри все делать на интерфейсах. Т.е. полный рефакторинг кода
В том же луа или ангел скрипт эти проблемы решаются генерацией врапперов, причем для сих целей существуют утилиты. Для актив скриптинга я потобных утилит, как ни странно, не обнаружил.
Здравствуйте, Andrew S, Вы писали:
GS>>Придется. COM-ли врапперов, или врапперов для другого скриптинга. Проблемы c контролем времени жизни преувеличены. Достаточно их просто привязать смарт-пойнтерами к объектам скриптинга.
AS>Например, есть некий класс, в котором есть набор итемов std::vector<CItem *> или std::list<CItem>. Кроме того, на эти же итемы могут ссылаться внешние по отношению к этому объекты.
Ну вижу проблемы. И в контейнерах, и во внешних объектах держишь смарт-пойнтер.
AS>В том же луа или ангел скрипт эти проблемы решаются генерацией врапперов, причем для сих целей существуют утилиты. Для актив скриптинга я потобных утилит, как ни странно, не обнаружил.
Какие проблемы-то? Че-то я не понял. Утилиты из луа и а.с. я посмотрю, но идею не осознал.
AS>>В том же луа или ангел скрипт эти проблемы решаются генерацией врапперов, причем для сих целей существуют утилиты. Для актив скриптинга я потобных утилит, как ни странно, не обнаружил.
GS>Какие проблемы-то? Че-то я не понял. Утилиты из луа и а.с. я посмотрю, но идею не осознал.
Идея проста — подсунул генератору набор классов — и получил на выходе набор классов, пригодных для скриптинга. Будь это врапперы или же модифицированные исходные классы. Вручную это делать ну как то глупо Впрочем, других вариантов, кроме как переделать все вообще внутри, я пока не вижу. И этот вариант мне совсем не нравится
Здравствуйте, George Seryakov, Вы писали:
GS>Здравствуйте, Andrew S, Вы писали:
GS>>>Если тебе нужна поддержка COM, то я бы использовал ActiveScript. Собственно говоря, я другой просто не знаю.
Врапперы генерируются одновременно и для ActiveScript и для SpiderMonkey.
GS>ActiveScript очень удобен тем, что его можно дебагать на скриптовом уровне. Также можно переключиться, к примеру, c jscript на vbscript. Также влегкую реализовался внешний скриптинг и вообще управление приложением извне по COM интерфейсам.
GS>То есть получается (мета)программироваие на смеси XSLT/C++/JavaScript.
Плюс поддержка этого всего в WindowsCE, что немаловажно в силу разности в стоимости лицензий, — порядок
AS>Например, есть некий класс, в котором есть набор итемов std::vector<CItem *> или std::list<CItem>. Кроме того, на эти же итемы могут ссылаться внешние по отношению к этому объекты. Т.о. для актив скриптинга возникает проблема времени жизни объектов CItem. И сделать это все по-нормальному без переделки CItem на ком интерфейс будет очень непросто — ведь сейчас класс-контейнер контролирует время жизни экземпляра CItem, а для Com время жизни определяется счетчиком ссылок. Плюс возникает проблема эффективного создания подобных объектов. В случае list аллокатор может быть сколь угодно оптимизирован на создание мелких объектов, в отличие от стандартной фабрики интерфейсов, которую я вижу вариант сделать только по new.
Ну, не так всё и страшно на самом деле. Для того чтобы прицепить COM к такой системе делаешь врапперы следующим образом:
1. "Главный" обьект — в твоём случае обьект который имеет набор итемов std::vector<CItem *> — управляется через счётчик ссылок.
2. Для "подобьектов" — в твоём случае CItem — делаешь специальный класс, который имеет 2 итема — смартпоинтер на "Главный" обьект и индекс в массиве std::vector<CItem *> (как вариант — id обьекта). При каждом вызове функции получаешь указатель на CItem из "главного" обьекта по индексу.
Решение, конечно, не самое элегантное — но вполне рабочее. И не сказал бы что слишком сложное в имплементации.
AS>>Например, есть некий класс, в котором есть набор итемов std::vector<CItem *> или std::list<CItem>. Кроме того, на эти же итемы могут ссылаться внешние по отношению к этому объекты. Т.о. для актив скриптинга возникает проблема времени жизни объектов CItem. И сделать это все по-нормальному без переделки CItem на ком интерфейс будет очень непросто — ведь сейчас класс-контейнер контролирует время жизни экземпляра CItem, а для Com время жизни определяется счетчиком ссылок. Плюс возникает проблема эффективного создания подобных объектов. В случае list аллокатор может быть сколь угодно оптимизирован на создание мелких объектов, в отличие от стандартной фабрики интерфейсов, которую я вижу вариант сделать только по new.
L>Ну, не так всё и страшно на самом деле. Для того чтобы прицепить COM к такой системе делаешь врапперы следующим образом: L>1. "Главный" обьект — в твоём случае обьект который имеет набор итемов std::vector<CItem *> — управляется через счётчик ссылок. L>2. Для "подобьектов" — в твоём случае CItem — делаешь специальный класс, который имеет 2 итема — смартпоинтер на "Главный" обьект и индекс в массиве std::vector<CItem *> (как вариант — id обьекта). При каждом вызове функции получаешь указатель на CItem из "главного" обьекта по индексу.
L>Решение, конечно, не самое элегантное — но вполне рабочее. И не сказал бы что слишком сложное в имплементации.
В этом случае, как уже говорилось, проще запользовать смарт поинтер с семантикой владения (например, shared_ptr из буста). Объект будет жить, пока жив COM враппер. Другое дело, что почти наверняка удобнее и логичнее будет собственно сами объекты сделать COM. В этом случае они сами будут управлять временем жизни, а хранить в массиве можно те же CComPtr. Проблемы начинаются, когда объекты храняться в контейнере по значению. Например, list<CItem>. Вот тут уже менять придется кардинально все — и сам контейнер, и классы, которые его пользуют. В общем, это _очень_ большая проблема. Почему я и ищу варианты кроме актив скрипта.
AS>В этом случае, как уже говорилось, проще запользовать смарт поинтер с семантикой владения (например, shared_ptr из буста). Объект будет жить, пока жив COM враппер. Другое дело, что почти наверняка удобнее и логичнее будет собственно сами объекты сделать COM.
Решение которое я предлагал заточено на мимнимальные изменения уже существующего кода.
AS>В этом случае они сами будут управлять временем жизни, а хранить в массиве можно те же CComPtr. Проблемы начинаются, когда объекты храняться в контейнере по значению. Например, list<CItem>. Вот тут уже менять придется кардинально все — и сам контейнер, и классы, которые его пользуют.
Хм. Насколько я понимаю в этом случае решение которое я предлагаю тоже будет работать.
AS>В общем, это _очень_ большая проблема. Почему я и ищу варианты кроме актив скрипта.