The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



"Доступен Emscripten 4.0, компилятор из C/C++ в WebAssembly "
Вариант для распечатки  
Пред. тема | След. тема 
Форум Разговоры, обсуждение новостей
Изначальное сообщение [ Отслеживать ]

"Доступен Emscripten 4.0, компилятор из C/C++ в WebAssembly "  +/
Сообщение от opennews (??), 14-Янв-25, 10:05 
Опубликован  выпуск инструментария Emscripten 4.0, позволяющего компилировать код на C/C++ и других языках, для которых имеются фронтэнды на базе LLVM,  в универсальный низкоуровневый промежуточный код WebAssembly. Полученный результат можно использовать для интеграции с JavaScript-проектами, запуска в web-браузере, использования в Node.js или создания   обособленных многоплатформенных приложений, запускаемых при помощи wasm runtime. Код проекта распространяется под лицензией MIT. В компиляторе используются наработки проекта LLVM, а для генерации WebAssembly  и оптимизации задействована библиотека Binaryen...

Подробнее: https://www.opennet.ru/opennews/art.shtml?num=62553

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения [Сортировка по ответам | RSS]

2. Сообщение от Аноним (2), 14-Янв-25, 10:06   +1 +/
Качественный?
Ответить | Правка | Наверх | Cообщить модератору
Ответы: #3, #4, #5, #53, #66, #93

3. Сообщение от нитгитлистер (?), 14-Янв-25, 10:20   +2 +/
сам не пробовал, но слышал что вполне себе норм
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #2

4. Сообщение от воробушек (?), 14-Янв-25, 10:27   –5 +/
на базе шланга качественного не бывает. кое-как работает и ладно - офф девиз шланга.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #2 Ответы: #8, #24

5. Сообщение от Аноним (12), 14-Янв-25, 10:28   +2 +/
Количественный.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #2

6. Сообщение от Аноним (12), 14-Янв-25, 10:29   –1 +/
Почему нельзя было просто сделать джаваскрипт быстрым? Это же так просто.
Ответить | Правка | Наверх | Cообщить модератору
Ответы: #9, #15, #20, #55, #58

8. Сообщение от воробушек (?), 14-Янв-25, 10:40   +/
https://godbolt.org/z/rofYEcYqr - пример подхода в шланге. дело здесь даже не в Werror по дефолту. они просто захардкодили "s" как особый случай.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #4 Ответы: #12, #44

9. Сообщение от НяшМяш (ok), 14-Янв-25, 10:44   +5 +/
Ждём пулл реквест в V8 и SpiderMonkey.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #6 Ответы: #11

10. Сообщение от ryoken (ok), 14-Янв-25, 10:45   +1 +/
>>"-sWASM_LEAGCY_EXCEPTIONS"

...

Ответить | Правка | Наверх | Cообщить модератору

11. Сообщение от Аноним (12), 14-Янв-25, 10:49   –2 +/
А чего тут ждать. Если вебасмембли такой быстрый почему джаваскрипт не может быть точно таким же.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #9 Ответы: #21, #25, #28

12. Сообщение от Аноним (12), 14-Янв-25, 10:50   –1 +/
Но ведь так работает значит все правильно сделали.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #8

15. Сообщение от myster (ok), 14-Янв-25, 11:41   –3 +/
В старом движке Opera Presto (2012 года) он был быстрый, но проект свернули.

Любая математическая операция (синтетический тест) в JavaScript консоли старой Opera обгоняла в сотни раз по производительности тогдашний Chrome, а Firefox и подавно. Я не думаю что и сейчас ситуация изменилась, если протестировать.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #6 Ответы: #18

16. Сообщение от anonymouse (?), 14-Янв-25, 11:43   +/
Есть тулкит на wasm для экспериментов с фильтрами ffmpeg в браузере. Если не перебарщивать со сложностью, wasm вполне полезная технология.
Ответить | Правка | Наверх | Cообщить модератору

18. Сообщение от вебмакака (?), 14-Янв-25, 11:51   +5 +/
> В старом движке Opera Presto (2012 года) он был быстрый, но проект свернули.

В твоих фантазиях.

> обгоняла в сотни раз по производительности

В тысячи раз. Правда в фантазиях.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #15 Ответы: #29

20. Сообщение от Аноним (20), 14-Янв-25, 11:57   –1 +/
Быстрым, наверное, можно сделать не JS, а TS. И то, если его компилять сразу в машинные коды. Ага, прямо из браузера компилер вызывать, а то как же кроссплатформенность.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #6 Ответы: #27

21. Сообщение от вебмакака (?), 14-Янв-25, 11:58   +6 +/
Потому что скриптуха без типизации.

А вообще впечатляют масштабы, в которых расплодились клоуны, требующие чтобы им дали ресурсов нахаляву. Даже если это в принципе невозможно - кого интересуют такие мелочи.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #11

24. Сообщение от Аноним (24), 14-Янв-25, 12:05   +/
> на базе шланга качественного не бывает. кое-как работает и ладно - офф девиз шланга.

А как ты вообще представляешь себе качественный релиз либы весом 70 мегабайт бинарного кода? Это LLVM столько весит если что.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #4

25. Сообщение от Аноним (24), 14-Янв-25, 12:07   +3 +/
> А чего тут ждать. Если вебасмембли такой быстрый почему джаваскрипт
> не может быть точно таким же.

Динамическая типизация видите ли идет в комплекте с нехилым оверхедом. Надо все время трекать тип и следить что он не изменился. И быть готовым ко всему.

А вон то - простой, низкоуровневый рантайм, не снабженный таким факапом. Намного более простая и потому шустрая абстракция.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #11 Ответы: #34

27. Сообщение от Анонем (?), 14-Янв-25, 12:27   +/
Это называется JIT и давным-давно используется в браузерах.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #20 Ответы: #38

28. Сообщение от Аноним324 (ok), 14-Янв-25, 12:28   +2 +/
он может быть таким же, но никто не платит чтобы с этим заморачиваться. Будут платить за джаваскрипт 15 тысяч зелени в месяц, будут делать быстрее, а пока платят нищие 4000 пусть в баню идут, за такие копейки, ещё над чем-то думать.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #11

29. Сообщение от myster (ok), 14-Янв-25, 12:33   –3 +/
проверь умник, она же доступна для загрузки ещё, если нужно подсказать, что вводить в консоли - пиши, помогу, но по сути любая вычислительная операция с циклами, с массивами.

Кстати, в долгих операциях и "в тысячи раз" превышать будет, т.к. там разница в производительности увеличивается по нарастающей.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #18 Ответы: #79

34. Сообщение от Bottle (?), 14-Янв-25, 13:04   +1 +/
Причём, что забавно - строгая типизация это такая абстракция, которая позволяет компилятору генерировать быстрый код. Потому что pointer aliasing.
Очень часто находятся "умники", которые заявляют, что всякая абстракция лишь замедляет код. Отнюдь.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #25 Ответы: #36, #51

36. Сообщение от вебмакака (?), 14-Янв-25, 13:08   –2 +/
Это не абстракция, обезьяныч. И никакой "pointer aliasing" тебе не поможет. Как и никакой "строгой" типизации не существует.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #34

38. Сообщение от Аноним (20), 14-Янв-25, 13:34   –1 +/
Я сказал в машинные коды - _инструкции_CPU_, а не какой-то там языковой виртуальной машины. Мы же хотим, чтобы быстро. Да и нет необходимости языку со статической типизацией в этих JIT.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #27 Ответы: #46, #47

44. Сообщение от Аноним (44), 14-Янв-25, 13:51   +/
https://en.cppreference.com/w/cpp/string/basic_string/operat...
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #8 Ответы: #59

46. Сообщение от Аноним (46), 14-Янв-25, 14:33   +1 +/
>> Это называется JIT и давным-давно используется в браузерах
> Я сказал в машинные коды - _инструкции_CPU_

Чел, JIT *буквально* транслирует в машинные коды 🤦

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #38 Ответы: #83

47. Сообщение от Анонем (?), 14-Янв-25, 14:39   +/
> Я сказал в машинные коды - _инструкции_CPU_, а не какой-то там языковой
> виртуальной машины. Мы же хотим, чтобы быстро. Да и нет необходимости
> языку со статической типизацией в этих JIT.

* Just-In-Time (JIT) компиляция в Java — это механизм, который позволяет ускорить интерпретацию байт-кода виртуальной машиной.  1

Простыми словами, механизм JIT компиляции заключается в следующем: если в программе присутствуют части кода, которые выполняются много раз, то их можно скомпилировать один раз в машинный код, чтобы в будущем ускорить их выполнение.

* Java — это статически типизированный язык.

(с) Яндекс Нейро

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #38 Ответы: #48, #84

48. Сообщение от отец_нашей_демократии (?), 14-Янв-25, 15:03   –1 +/
из того же источника:

>[оверквотинг удален]
> rust не имеет статической типизации
>> Rust имеет статическую типизацию. Когда разработчик создаёт переменную в Rust, он должен сразу указать, какого она типа — что будет в ней храниться.
> в rust нет переменных, это скриптуха с gc и ссылками вместо переменных
>> В Rust есть переменные. Для их объявления используется ключевое слово let. По умолчанию переменные неизменяемы, но их можно сделать изменяемыми, добавив перед именем ключевое слово mut. Ссылки в Rust используются для управления памятью. В языке есть два типа ссылок: ссылки на чтение (shared reference) и изменяемые (мутабельные) ссылки. Ссылки подчиняются двум правилам: не должны жить дольше, чем данные, на которые они ссылаются, и мутабельная ссылка должна быть уникальна. Таким образом, Rust сочетает в себе особенности языка с ручным управлением памятью и сборщиком мусора: код получается чистым, как в языке с GC, но в то же время все ресурсы освобождаются максимально быстро, как в языке с ручным управлением.
> покажи мне sizeof от переменной в rust без испоьзования stdlib
>> Для получения размера переменной в Rust используется функция size_of_val. Пример использования: ```let a = 10i32; println!("{}", size_of_val(&a));```. Также для получения размера типа в байтах в Rust можно использовать функцию size_of из пакета std::mem.
> без испоьзования stdlib
>> Не удалось найти информацию о том, как получить sizeof от переменной в Rust без использования stdlib.
> правильно, потому что это невозможно. rust не знает ничего о переменных и их свойствах
>> Да, получить sizeof от переменной в Rust без использования stdlib невозможно, так как для этого используется специальная функция — size_of_val.

с жавой будет то же самое. как и с любой другой скриптухой.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #47 Ответы: #49

49. Сообщение от Аноним (46), 14-Янв-25, 15:10   +/
Не совсем понятно, что ты хотел сказать.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #48

51. Сообщение от Аноним (51), 14-Янв-25, 15:25   +1 +/
> Причём, что забавно - строгая типизация это такая абстракция,

Это некий набор правил и/или гарантий когда компилер при генерации кода явно знает что сие и чем оно будет далее. И не должен генерить кучу кода проверяющего на каждый пшик что тип остался прежний.

То-есть при остром желании можно скастовать тип в другой тип - но и это тоже - декларация намерений ДО компиляции. Когда ВСЕ известно заранее. И не надо лепить кучу проверок что тип именно такой, а не что-то еще.

> которая позволяет компилятору генерировать быстрый код. Потому что pointer aliasing.

Это не главное. Главное - если компилер скажем знает что это uint32 - он его вообще в регистр проца впихает, и будет фигачить быстрыми операциями регистр-регистр, за 1 такт. А что либо с pointer там будет вообще только если эта абстракция кому-то где-то в другом месте потребовалась. Иначе это может быть нечто вообще не имеющее никаких адресов в памяти, если все абстракции оговоренные правилами - удерживаются.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #34 Ответы: #70

53. Сообщение от Аноним (-), 14-Янв-25, 15:57   +/
Да и давно. На нем в игры можно в браузере играть. Например в Quake. Когда-то давно была демка. Зададим вопрос по другому - только сейчас о нем узнали?
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #2

54. Сообщение от Аноним (-), 14-Янв-25, 15:59    Скрыто ботом-модератором+/
Ответить | Правка | Наверх | Cообщить модератору
Ответы: #57

55. Сообщение от Аноним (-), 14-Янв-25, 16:03   –1 +/
А ты замерь насколько он быстрый. Не знаю как проверяют бенчмарки, но мои замеры показывали производительность почти такую же как и на С. Конечно ты можешь вспомнить что-то про многопоточность, но я тоже могу вспомнить про воркеры. Конечно всё-равно это не многопоточность и тем не менее.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #6

57. Сообщение от Аноним (57), 14-Янв-25, 16:28   +/
Нечего тут пропагандировать свои извращения.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #54

58. Сообщение от 12yoexpert (ok), 14-Янв-25, 16:35   +/
в qml и espruino как-то сделали
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #6

59. Сообщение от Аноним (59), 14-Янв-25, 16:41   +1 +/
типа статья про std::literals::string_literals::operator""s есть и потому ошибки нет, а про std::literals::string_literals::operator""x нету и потому ошибка есть? Ты это сказать хотел?

И судя по набору имен, на которые не ругается (h/min/s/ms/us/ns), авторы костыля читали доку по хроно, а не про строки

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #44

60. Сообщение от htmldevelob (?), 14-Янв-25, 16:42   –1 +/
Вопрос глупый но всё же, зачем нужен этот ваш wasm? не проще былоб в браузеры встроить qemu\kvm
Ответить | Правка | Наверх | Cообщить модератору
Ответы: #63, #67, #72, #85, #90

63. Сообщение от Аноним (66), 14-Янв-25, 17:44   +/
Google Native Client (NaCl)
кстати, где он (с)
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #60

66. Сообщение от Аноним (66), 14-Янв-25, 18:00   +/
ну так себе

https://framagit.org/fperrad/lua.wasm
261kB wasm + 77kB js

А без использования их стандартной библиотеки и всевозможных обёрток для fileIO, просто голым шлангом получилось собрать в два раза меньший объём.

Для какого-нибудь многомегабайтного ffmpeg или quake в браузер притащить лишние 100кБ не заметно, а для совсем мелочи слишком много ненужных обёрток, чтобы стандартная библиотека в браузере прозрачно работала.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #2 Ответы: #82

67. Сообщение от Аноним (67), 14-Янв-25, 18:08   +1 +/
Ну целую операционную систему с сервера грузить это наверное уже слишком. Но создать ABI для запуска блобов с доступом лишь к тому, что разрешили, можно. В хроме оно даже и было, но разрабы лисы надули щеки и сказали, что не будут запускать блобы и предложили asm.js. Но в конечном итоге пришли к wasm, но как бы лишь для реализации быстрых алгоритмов.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #60 Ответы: #68

68. Сообщение от Аноним (68), 14-Янв-25, 18:16   +/
> Ну целую операционную систему с сервера грузить это наверное уже слишком.

Вообще можете загуглить jslinux. Если дело делает профессионал как Фабрис - то и линух загрузить в браузере - не так уж ужасно как может показаться.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #67

70. Сообщение от Bottle (?), 14-Янв-25, 18:45   +1 +/
Понимаешь ли, процессор не увидит разниц между указателями на int_32_t и строковым типом такой же длины, а вот компилятор, который в одном методе видит разные типы, как раз воспользуется данным преимуществом.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #51 Ответы: #73

72. Сообщение от Аноним (72), 14-Янв-25, 18:55   +1 +/
чтобы в нём заустить линукс в котором запустить браузер в котором запустить qemu-kvm .....
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #60

73. Сообщение от Аноним (-), 14-Янв-25, 19:51   +1 +/
> Понимаешь ли, процессор не увидит разниц между указателями на int_32_t и строковым
> типом такой же длины,

Как вы поняли - дереференс указателей вообще не самый быстрый способ работы. Быстрее всего - вгрузить нечто типа:
// a + b, псевдокод на манер асма
(uint32 a) -> r0
(uint32 b) -> r1
add r0, r1

И тут вообще - никаких указателей могло не быть. И обращений к потенциально-тормозной памяти. Операции регистр-регистр самые быстрые. А значения операндов могут вообще непосредственно вкодированы - в формате этих команд. Так что не надо никаких дополнительных действий, операнды уже тут.

> а вот компилятор, который в одном методе
> видит разные типы, как раз воспользуется данным преимуществом.

Лучший дереференс указателей - которого не было. Лучшая математика - которую вообще не считали (предвычислили все компилтайм). А то и вовсе - заметили что блок кода не имел side effects, вообще аннулировали. Если в том примере a и b заранее известны, компилер сделает mov r0, #10 (a + b == 10). Заскипав действо совсем. А если #10 в r0 никогда никому не надо было - то и это - заскипает! Вообще выпилив блок кода.

...но как вы понимаете, при динамической типизации просчитать подобные вещи заранее будет менее реалистично. Вариантов поведения программы - многократно больше, гарантий поведения тех или иных кусков - сильно меньше. И проситчать все компил тайм, без оверхеда и лишних проверок - да щас.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #70

76. Сообщение от maxis11 (ok), 14-Янв-25, 20:15   +/
А кто-нибудь начал конвертор пилить из Vulkan в Web GPU для EMS (или пока все только мечты)?
Ответить | Правка | Наверх | Cообщить модератору
Ответы: #78

78. Сообщение от Аноним (-), 14-Янв-25, 21:09   +/
Эти планы, запланированы они или нет можно вычитывать вот тут: https://www.khronos.org/
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #76 Ответы: #94

79. Сообщение от Аноним (79), 14-Янв-25, 21:13   +1 +/
Даже если они могли что-то стоищее создать, но они опустились до вранья своим пользователям, а потом вообще продали браузер.
А адекватные разработчики ушли в Vivaldi
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #29

82. Сообщение от Аноним (-), 14-Янв-25, 22:17   +/
Для современного веба, с современными скоростями это не проблема
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #66 Ответы: #87

83. Сообщение от Аноним (83), 15-Янв-25, 00:20   +/
Но быстро, это когда AOT.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #46

84. Сообщение от Аноним (83), 15-Янв-25, 00:22   –1 +/
Да-да, знаем, слышали: "Java способна обогнать код на C++".
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #47

85. Сообщение от Аноним (85), 15-Янв-25, 00:46   +/
Чтобы зум и куча других вредоносных сайтов запустились, а не предложили просто проваливать. Компиляция в код, близкий к нативному, сильно осложняет реверс-инжиниринг. Это обфускация с виртуальной машиной: совмещает недостатки и нативного кода, и скриптов. Для кого-то это является достоинством.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #60 Ответы: #91

86. Сообщение от chdlb (?), 15-Янв-25, 02:53   +/
искал либу для xxhash64 под WASM, нашел, автор перешел с Emscripten на шланг

я не знаю точной причины, может кто и расскажет нам

Ответить | Правка | Наверх | Cообщить модератору
Ответы: #88

87. Сообщение от Аноним (66), 15-Янв-25, 12:10   +/
вот поэтому современный веб и выглядит так, как он выгдядит
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #82

88. Сообщение от Аноним (66), 15-Янв-25, 12:16   +/
потому что, чтобы обернуть стандартную библиотеку, чтобы она абсолютно прозрачно работала в wasm там столько костылей, что что-то небольшое проще голым шлангом собрать с nostdlib подставив свои простенькие костылики где надо.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #86

89. Сообщение от Аноним (89), 15-Янв-25, 14:51   +/
Жаль что готовых сборок компилятора на github не выкладывают. Предлагают какие-то скрипты запускать для скачивания и инсталяции - это не удобно.
Ответить | Правка | Наверх | Cообщить модератору

90. Сообщение от Аноним (-), 15-Янв-25, 16:19   +/
Не проще. Софтварная виртуализация позволяет гораздо более гранулярно ограничивать код. Мало того, что возможно (в качестве глупого примера) ограничить количество операций с памятью в секунду, доступных программе, так ведь ещё и применять эти ограничения можно очень выборочно, для тех частей кода применять, для этих не применять.

qemu умеет в софтварную виртуализацию, но он виртуализует огромные и сложные архитектуры, которые заточены под выполнение на железном CPU, а не под jit-компиляцию. Одно только декодирование x86 команд софтварно, это уже само по себе заморока. Это приводит к огромной ненужной (в случае браузера) сложности виртуальной машины.

Кроме этого, qemu не заточен под то, чтобы гонять инородный код в адресном пространстве процессора-хоста, а это значит что либо его надо перетачивать, либо биться с IPC, который мееееедлеееееннныый.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #60

91. Сообщение от Аноним (-), 15-Янв-25, 16:21   +/
> Компиляция в код, близкий к нативному, сильно осложняет реверс-инжиниринг.

Не сильно. Просто для ревёрс-инжиниринга бинарного кода тебе нужны другие инструменты. Обфусцированный js ты будешь разбирать одними тулзами, бинарный wasm код ты будешь разбирать другими. А по-сути одно и то же.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #85

93. Сообщение от Вася (??), 16-Янв-25, 08:05   +/
Реально работает. Я знаю контору, у них достаточно популярная и сложная в реализации мобильная игра (десятки миллионов скачиваний), написана на С с минимум зависимостей.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #2

94. Сообщение от maxis11 (ok), 17-Янв-25, 14:13   +/
> Эти планы, запланированы они или нет можно вычитывать вот тут: https://www.khronos.org/

1. WebGPU не является частью Khronos, иди учи матчасть;
2. С транслятором GL ES -> WebGL или же тот же ANGLE как-то без помощи хроносовцев обошлись;
3. А они бы что сделали, написали стандарт на трансляцию команд?

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #78


Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру