V8 разработчик здесь. Краткий ответ: здесь нет преобразований, побитовые операции всегда выполняются с 32-разрядными целыми числами, а Int32Array
также хранит свои элементы в виде 32-разрядных целых чисел.
Более длинный ответ - «это зависит ». В неоптимизированном коде все значения используют унифицированное представление. В V8 это означает, что числовые значения либо представлены в виде «Smi» («маленькое целое число»), если они находятся в диапазоне (31 бит, включая знак, т. Е. Около -1 млрд. До +1 млрд.), Либо в виде «HeapNumbers» (64 -бит дважды с небольшим заголовком объекта) в противном случае. Таким образом, для загрузки элемента, такой как int32[0]
, 32-битное значение загружается из массива, проверяется на предмет диапазона, а затем либо помечается как Smi, либо помечается как HeapNumber. Следующая операция |
просматривает входные данные, преобразует их в 32-разрядное целое число (которое может быть таким же простым, как разметка Smi, или таким же сложным, как вызов .valueOf
для объекта), и выполняет побитовое «или» , Затем результат снова либо помечается как Smi, либо помечается как HeapNumber, чтобы следующая операция могла решить, что с ней делать.
Если функция выполняется достаточно часто, чтобы в конечном итоге оптимизироваться, то оптимизирующий компилятор использует обратную связь по типу (защищенную проверками типов при необходимости), чтобы исключить все эти преобразования, которые не нужны в этом случае, и простой ответ будет верным.