Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Концепция указателей в JavaScript (https://javascript.ru/forum/project/57714-koncepciya-ukazatelejj-v-javascript.html)

acterhd 16.08.2015 10:42

Концепция указателей в JavaScript
 
Я недавно решил попытаться реализовать типизированные переменные в JS. Но вместо этого получил указатели, а точнее их подобие. Получилось на мой взгляд довольно не плохо. Все расписано в example.js. Пока что проект находится на самой ранней стадии. Но уже сейчас можно испытывать код в действии.

Недавно провел полную перепись кода, избавил от всего г...а.
https://github.com/acterhd/array-pointer-js

Восстановил репозитории.

kobezzza 16.08.2015 10:56

http://lljs.org/
http://asmjs.org/

acterhd 16.08.2015 11:01

Окей, я обязательно подумаю над полным слиянием с asm.js. Хотя уже сейчас можно использовать асму.
Но я вижу что asm и lljs довольно интересный продукт.

Но кажись lljs уже мертв.
https://github.com/mbebenita/LLJS

Соответственно остается ASM.
Но и его спецификации уже 1 год исполнилось.

Впрочем основная задумка теперь - это псевдо указатели! Но реализовано и другие фичи, таких как выделение памяти. Пожалуй это основная фича после оборачивания массивов в указатели.

1.
В C чтобы выделить память используется malloc и указатель.
int * mem;
mem = (int *)malloc(10);


В JavaScript чтобы выделить память нужно хотя объявить пустой псевдо-указатель.
var mem = PRIM.Int.var();
PRIM.Int.alloc(mem, 10);


2.
В C можно сделать указатель на переменную.
int val = 1;
int * ptr = &val;


В JavaScript точного эквивалента данной операции нету.
//Первый вариант
var ptr = PRIM.Int.var(1);

//Второй вариант
var val = [1|0]; //ASM.js
var ptr = PRIM.Pointer.array(val); //Следует оборачивать через Pointer.array

//Второй точка один вариант
var val = new Int32Array([1]); //Через типизированный массив
var ptr = PRIM.Pointer.array(val);



Вот они "преимущества" JavaScript.

kobezzza 16.08.2015 11:10

Я добавил ссылки, просто как возможную справку :)

Вообще ASM.js - это промежуточный этап, т.к. будущее за WebAssembly. Но ASM.js уже сейчас поддерживается в FF и Edge (новый IE) и частично в Chrome, а также в него умеют компилиться проекты из UnrealEngine и Unity. Производительность очень близка к нативной.

Rise 16.08.2015 11:37

acterhd, а зачем это надо?

acterhd 16.08.2015 11:37

А как вы смотрите на TypeScript? Стоит ли для него писать библиотеку указателей?

Rise, надо обычно если вы разрабатываете приложение, например требующее работы с бинарными файлами. Также неплохо подойдет и для WebGL приложений (поскольку там используются буферы).

Сегодня думаю интегрироваться под Node.JS, поскольку большая часть всех JS проектов пишется под него.

kobezzza 16.08.2015 11:52

Цитата:

А как вы смотрите на TypeScript? Стоит ли для него писать библиотеку указателей?
Ну, мне кажется более правильным не тянуть такие низкоуровневые как указатели штуки в JS (всё таки у нас язык с GC), а использовать для этого более предпочтительные языки как C/C++ и компилить их в ASM.js (http://kripken.github.io/emscripten-site/). А без использования ASM.js / WebAssembly вообще не вижу смысла в таких вещах.

Цитата:

Сегодня думаю интегрироваться под Node.JS
https://nodejs.org/api/smalloc.html

Хотя вроде эту возможность удалят в новых версиях.

acterhd 16.08.2015 12:11

Ну если удалят, тогда тем более будет повод нажиться :)
Жалко что до крупного проекта еще очень далеко. Еще нужно красивый сайт с документацией сделать.

kobezzza 16.08.2015 13:02

Цитата:

Ну если удалят, тогда тем более будет повод нажиться
Тогда делай АПИ такое же, как у Node.js, чтобы можно было использовать без переработки старой кодовой базы.

Цитата:

Еще нужно красивый сайт с документацией сделать.
Имхо, для такой либы - это лишнее :)

PS: в IOJS3 уже удалили smalloc api:

Цитата:

smalloc: The smalloc module has been removed as it is no longer possible to provide the API due to changes in V8 (Ben Noordhuis) #2022.

acterhd 16.08.2015 13:08

Вот теперь IOJS и библиотека primitive друзья :)

В C чтобы использовать элемент массива достаточно:
int * array = {0, 1, 2, 3};
int a = array[0]; //Очень просто


В JS чтобы так сделать нужно:
var array = PRIM.Int.array([0, 1, 2, 3]);

var a = array.get(0); //Получить нулевой индекс - да такие вот операторы на JS
var a = array.get(); //Для нулевого индекса можно так
var a = array.add(0).ptr; //Через геттер, создавая при этом еще один экземпляр pointer


Однако есть и отличия:

var a = 1;
var array = PRIM.Int.array([0, 1, 2, 3]);

array.set(a, 0); //Установить так
array.add(0).ptr = a; //Большая разница
array.add(0).set(a); //Можно и так


И мало кто знает. В primitive.js сеттеры, геттеры и функции, которые встроены в классы не являются основными. Основными являются именно static функции. Я этот фарш решил добавить для удобочитаемости кода.

Кстати, новые экземпляры (классы) не содержать многого. Они содержат всего 2 переменные (1 из которых ссылка). Остальное это либо прототипы либо статики.



За основу стиля я взял именно стиль как у SIMD. Да и сам SIMD можно использовать (скажу позже как). У данной библиотеки есть еще ".mem" геттер и сеттер. Его и можно отправлять в плаванье.

kobezzza 16.08.2015 13:14

Цитата:

var a = array.get(0); //Получить нулевой индекс - да такие вот операторы на JS
Что мешает сделать просто array[0] ?

acterhd 16.08.2015 14:05

В JS нет operator overload. Так просто нельзя.
Ведь это классы а не массивы. Вот ты представь себе что будет если сделать?
extends Array

Я потеряю возможность адресации. Нельзя будет просто так двигать изначальный адрес. Да к тому же надо будет реализовать для всех массивов, включая типизированные. Так нельзя будет передавать указатель в указатель (т.е. приравнивание). Мне такое не надо.

kobezzza 16.08.2015 14:15

Цитата:

В JS нет operator overload.
Есть. Proxy (nodejs и iojs нужно запускать с флагом --harmony_proxies)

acterhd 16.08.2015 14:30

Прокси это прокси, это отдельная фича (обертка поверх класса).
Да и в хроме нету.
Также я не вижу в Proxy столь важной функции как замещение скалярных операторов.

kobezzza 16.08.2015 14:35

Цитата:

Да и в хроме нету.
Есть, просто скрыта за флагом в about:flags.

Цитата:

Также я не вижу в Proxy столь важной функции как замещение скалярных операторов.
Поясни. Можно повесить слушатель на получение/установку значения (get/set) и как раз реализовать array[0] вместо array.get(0).

acterhd 16.08.2015 15:04

Провожу доработку, довожу до ума.

cyber 17.08.2015 13:13

Цитата:

Сообщение от kobezzza
и как раз реализовать array[0] вместо array.get(0).

Я знаю только один хак)

var arr = [];

Object.defineProperty ( arr, 0, {
	get: function () {
          alert();
    	  return 0;
        }
        set: function (val) {
          alert(val);
        }
}  );

arr [0] = 5;

console.log( arr [0] )

acterhd 17.08.2015 14:34

Cyber, Я реализовал через Proxy.
Вот обработчик для Proxy.

let _indexer = {
        get: function(obj, prop){
            return (!isNaN(prop) ? obj.get(parseInt(prop)) : obj[prop]);
        },
        set: function(obj, prop, val){
            if(!isNaN(prop)){
                obj.set(val, parseInt(prop));
            } else {
                obj[prop] = val;
            }
        }
    };


Проверяет, является ли переменная prop числом или нет. Если да, то извлечь ячейку памяти.

cyber 17.08.2015 15:02

acterhd, учитывая поддержку прокси браузерами то не особо полезно тогда)

acterhd 17.08.2015 18:13

Работает библиотека во всех браузерах, кроме Firefox.

cyber 17.08.2015 19:16

Цитата:

Сообщение от acterhd
Работает библиотека во всех браузерах, кроме Firefox.

Как она работает в хроме без прокси?

kobezzza 17.08.2015 22:07

Цитата:

кроме Firefox.
Оо как так? ФФ сейчас лучше всех поддерживает ES6 и прокси там 100% есть (говорю как юзер ФФ).

Цитата:

Как она работает в хроме без прокси?
В хроме есть прокси, просто скрыты за спец-флагом в настройках, и в ноде тоже самое (--harmony_proxies)

kobezzza 17.08.2015 22:11

https://github.com/acterhd/primitive...rimitive.js#L3

acterhd, ты же в курсе, что у тебя не ASM.js код, поэтому данная инструкция ничего не даст :)

И почему у тебя такой странный способ экспорта модуля? Это не будет работать в ноде и более того, раз ты юзаешь ES6, то логичнее заюзать Babel и сделать UMD экспорт.

Также, почему у тебя не оформлен пакет для NPM и Bower?

UPD: Увидел, https://github.com/acterhd/primitive...mitive.js#L470. Нагугли UMD :)

cyber 17.08.2015 22:58

Цитата:

Сообщение от kobezzza
В хроме есть прокси, просто скрыты за спец-флагом в настройках, и в ноде тоже самое

В смысле в продакшен его нельзя, только нода/io

acterhd 18.08.2015 15:55

Что я сделал?
- перешел на typescript
- подготовил проект на visual studio
- демонстрация пока в iframe, и ведет в visual studio проекту
- отказались от Proxy

cyber, я еще пока не забил на primitive.js, а о браузерах я позаботился
kobezzza, пока что ситуация с ecmascript 6 очень плачевна. Это одна из причин перехода на typescript, чтобы сохранить обратную совместимость.

http://acterhd.github.io/primitive-js/

kobezzza 18.08.2015 19:51

Цитата:

kobezzza, пока что ситуация с ecmascript 6 очень плачевна. Это одна из причин перехода на typescript, чтобы сохранить обратную совместимость.
Если цель использования ТС только как транслятор для ЕС6, то надо было юзать Babel, т.к. ТС пока умеет только где то 40% из ЕС6.

acterhd 18.08.2015 19:53

Проект буду переделывать.

Вот сырой проект. На чистом ES6. Убрал весь хлам. Оставил только самое необходимое для указателя. Основная суть - работа с массивами, а так же выделении собственной памяти (создание нового массива).
https://github.com/acterhd/array-pointer-js

Ту библиотеку временно оставлю на память, потом удалю.

acterhd 06.09.2015 00:31

Слушайте, я порылся в Emscripten, и понял. Так вот где бы она понадобилась бы!

acterhd 23.09.2015 22:13

Провел полный рефакторинг библиотеки!


Часовой пояс GMT +3, время: 22:42.