vak: (Default)
Serge Vakulenko ([personal profile] vak) wrote2025-02-20 02:07 pm

Из всех искусств для нас важнейшим является JavaScript

Какие скриптовые языки самые распространённые? Перл сходит со сцены, Питон нынче повсюду, про PHP уже забыли, но оказывается, Javascript незримо присутствует в каждом линуксе и маке. Гляньте файл:
$ ls -l /usr/lib/*/libjavascriptcoregtk*.so*
lrwxrwxrwx 1 root       36 Jan  6 04:34 /usr/lib/x86_64-linux-gnu/libjavascriptcoregtk-4.0.so.18 -> libjavascriptcoregtk-4.0.so.18.25.14
-rw-r--r-- 1 root 30609392 Jan  6 04:34 /usr/lib/x86_64-linux-gnu/libjavascriptcoregtk-4.0.so.18.25.14
Это может быть libjavascriptcoregtk-4.0.so как выше, или *-4.1.so, или *-6.0.so, но какой-нибудь да отыщется. Потому что веб-браузеры в нём нуждаются.

Это Джаваскрипт можно задействовать из Си программы. Есть документация. Понадобятся соответствующие include-файлы, для этого следует установить пакет нужной версии. Скажем, на последнем Дебиане это 6.0:
sudo apt install libjavascriptcoregtk-6.0-dev
Возьмём пример вычисления факториала:
#include <stdio.h>
#include <webkitgtk-6.0/jsc/jsc.h>

const char code[] = "\
function factorial(n) {\
    if (n === 0) {\
        return 1;\
    } else {\
        return n * factorial(n - 1);\
    }\
}\
\
factorial(10)";

int main()
{
    // Create a new JavaScript virtual machine.
    JSCContext *vm = jsc_context_new();

    // Evaluate arbitrary JavaScript code.
    JSCValue *result = jsc_context_evaluate(vm, code, -1);

    // Print the result.
    if (jsc_value_is_number(result)) {
        double value = jsc_value_to_double(result);
        printf("The result is: %f\n", value);
    } else {
        printf("The result is not a number.\n");
    }

    // Deallocate resources.
    g_object_unref(result);
    g_object_unref(vm);
}
Компилируем, запускаем:
$ cc demo.c -o demo `pkg-config --cflags --libs javascriptcoregtk-6.0`
$ ./demo
The result is: 3628800.000000
На маке тоже работает, но интерфейс выглядит несколько по другому:
#include <stdio.h>
#include <JavaScriptCore/JavaScriptCore.h>

const char code[] = "\
function factorial(n) {\
    if (n === 0) {\
        return 1;\
    } else {\
        return n * factorial(n - 1);\
    }\
}\
\
factorial(10)";

int main()
{
    // Create a new JavaScript virtual machine.
    JSGlobalContextRef vm = JSGlobalContextCreate(NULL);

    // Evaluate arbitrary JavaScript code.
    JSStringRef script = JSStringCreateWithUTF8CString(code);
    JSValueRef result = JSEvaluateScript(vm, script, NULL, NULL, 0, NULL);

    // Print the result.
    if (JSValueIsNumber(vm, result)) {
        double value = JSValueToNumber(vm, result, NULL);
        printf("The result is: %f\n", value);
    } else {
        printf("The result is not a number.\n");
    }

    // Deallocate resources.
    JSStringRelease(script);
    JSGlobalContextRelease(vm);
}
Запускаем:
$ cc demo.c -o demo -framework JavaScriptCore
$ ./demo
The result is: 3628800.000000
henry_flower: A melancholy wolf (Default)

[personal profile] henry_flower 2025-02-21 12:16 am (UTC)(link)
gtk4 має ув комплекті варіянт мозіловского spidermonkey

деякі декстопні аплікації (foliate, наприклад) написані суто на джаваскрипті gjs, використовуючи gtk віджети

шо цікаво, така аплікація не тягає зі собою 2^16 .js хфайлів, а динамічно імпортить їх з 1 байнарного gresource бандла, де, окрім .js, зберігаються всі айконки, .css і т.і.
henry_flower: A melancholy wolf (Default)

[personal profile] henry_flower 2025-02-21 08:41 am (UTC)(link)
gjs використовує spidermonkey, а не вебкіт (тут можна сплутати libjavascriptcoregtk належить до WebKitGTK, але до віджетів gtk4 (з якими дружить gjs) воно не відноситься)

але так, лінукс це їх основна тарґет в обоїх випадках
spamsink: (Default)

[personal profile] spamsink 2025-02-21 04:43 am (UTC)(link)
Для отчуждаемого продукта плохо годится, к сожалению. DLL hell в топку.
henry_flower: A melancholy wolf (Default)

[personal profile] henry_flower 2025-02-21 08:12 am (UTC)(link)
можна було би з собою тягати, але йому увесь glib2 потрібен та icu

$ ldd /usr/lib64/libjavascriptcoregtk-4.1.so.0 | awk '{print $3}' | xargs rpm -qf | sort -u
glib2-2.82.2-1.fc41.x86_64
glibc-2.40-21.fc41.x86_64
libatomic-14.2.1-7.fc41.x86_64
libblkid-2.40.4-1.fc41.x86_64
libcap-2.70-4.fc41.x86_64
libffi-3.4.6-3.fc41.x86_64
libgcc-14.2.1-7.fc41.x86_64
libicu-74.2-2.fc41.x86_64
libmount-2.40.4-1.fc41.x86_64
libselinux-3.7-5.fc41.x86_64
libstdc++-14.2.1-7.fc41.x86_64
pcre2-10.44-1.fc41.1.x86_64
systemd-libs-256.11-1.fc41.x86_64
zlib-ng-compat-2.2.3-1.fc41.x86_64


забагато бібліотек, як на мене. краще тоді quickjs (від автора ffmpeg) взяти, як потрібна embeddable скриптова мова
spamsink: (Default)

[personal profile] spamsink 2025-02-21 08:51 am (UTC)(link)
краще тоді quickjs (від автора ffmpeg) взяти, як потрібна embeddable скриптова мова

цiкаво, дякую
juan_gandhi: (Default)

[personal profile] juan_gandhi 2025-02-21 06:51 am (UTC)(link)
Забавно. С какой целью это всё, интересно?
henry_flower: A melancholy wolf (Default)

[personal profile] henry_flower 2025-02-21 07:53 am (UTC)(link)
> общую для всех реализацию

цього ніколи не існувало, не існує і навряд з'явиться

є стандарт--ecmascript (лише тому шо оракл тримає трейдмарка на ім'я джаваскрипт і не бажає його дарувати ком'юніті) і є 3 головні реалізації: spidermonkey (мозіловська найстаріша), епловська javascriptcore (у прикладі цього поста, але з Гноумівського порта вебкіта) і гооглівська v8

ecmascript еволюціонує доволі швидко, і всі 3х реалізації мають трохи різну відповідність стандарту; гооглівська зазвичай отримує найновіші фічі, а епловська завжди пасе задніх