Рубрики
Без рубрики

Просмотры памяти: Обработка струн

Управление памятью Wasmer для струн Python. Tagged с Python, Rust, Webassembly, Wasmer.

Приготовьте себя, так как этот пост будет немного менее простым, чем последние, так как мы собираемся поговорить о том, как читать/написать строки UTF-8 из/до Webassembly (WASM) мнений!

не стесняйтесь пропустить следующий абзац, если вы думаете, что уже знакомы с

Даже если ржавчатка с трудом WASM и Python-очень разные языки во многих точках, они, вероятно, находятся в противоположности спектру для самых популярных языков программирования, они оба пользуются преимуществами Unicode Формат для сетевого взаимосвязи ; К счастью, в настоящее время общепринятый и хорошо поддерживаемый стандарт.

Некоторые основные дженерики о Unicode:

… он кодирует символ как последовательность от одного до четырех байтов [1]

… только самое короткое кодирование для любой заданной кодовой точки считается хорошо сформированным; Вы не можете потратить четыре байта, кодируя кодовую точку, которая бы соответствовала трем [1]

Каждая группа кодовых точек (для UTF-8, кодовая точка может быть такой малой, как 1 байт, до 4) в строке кодирует символ (другими словами UTF-8-8-битная ширина ширины для Unicode) ; Обычно есть базовая точка кода плюс кодовые точки после этого, которые добавляют детали в базу. Unicode версия 12.1 позволяет записывать 137 994 кодовых точек, которые охватывают все символы для большого количества языков.

UTF-8 поддерживает любой символ Unicode, который прагматически означает любой естественный язык (коптский, сингальский, фонекальный, чероки и т. Д.), А также многие не говорящие языки (музыкальные нотации, математические символы, APL) и эмотики [источник]

Более подробная информация об этом замечательном интернет-боевой инструменте в Консорциум Unicode Анкет

Что нам нужно знать для этого эксперимента, так это то, что мы можем представлять строки символов в виде списков 8-битных целых чисел, которые соответствуют кодовым точкам Unicode (или группе). Чтобы пройти строки из/до питона и wasm, используя Python-ext-Wasmer нам нужно знать:

  • В струнах Python Необываемые последовательности символов ; Откройте простаивание Python и попробуйте:
# a Unicode string containing non-ASCII chars
>>> st = 'ABW@☀CC☯'

# same string as bytestring encoded in UTF-8 (hex)
>>> bytes(st, 'UTF-8')
b'ABS@\xe2\x98\x80CC\xe2\x98\xaf'

# UTF-8 (decimal) represention of the same bytestring
>>> [b for b in bytes(st, 'UTF-8')]
# elements for Unicode code points as Python integers
[65, 66, 83, 64, 226, 152, 128, 67, 67, 226, 152, 175]

Черное солнце с лучами (U+2600) Кодовая точка представлена в кодировании UTF-8 с: 3 шестнадцатеричные значения или эквивалентно 3 положительных десятичных значений:

#
# same code point, same encoding (different formats)
#
\xe2\x98\x80 ----> ☀ as UTF-8 (hex)
226 152 128 ----> ☀ as UTF-8 (decimal)
  • Любая последовательность точек Unicode может быть представлена как Список [int] в питоне; В конкретном случае, если мы хотим использовать UTF-8 для взаимодействия с кодом в Rust, мы должны использовать на его стороне A VEC (Подробнее здесь ); Наконец на уровне WASM у нас есть линейная массива памяти ячеек, которые индексируют его элементы:
# pseudo-code
array_memory[0] = 226
array_memory[1] = 152
array_memory[2] = 128

Теперь очевидно, как мы можем хранить десятичные очки UTF-8 в линейной памяти WASM.

Мы можем думать, что в каждом экземпляре WASM как мини-санд-ящик со своими собственными абстракциями по памяти. Память представлена как «представления», в основном таблицы, которые управляют ссылками между значениями и их положением в линейной памяти.

Детали : Wasmer Runtime Core Обеспечивает эти очень мощные абстракции, которые позволяют использовать память WASM; В этом случае мы хотим взглянуть на Python-ext-Wasm Просмотры памяти ; Методы интерфейса генерируются с макроса для каждого примитивного типа.

Давайте введем основную часть эксперимента: Как мы можем использовать все эти мощные инструменты, чтобы питон свободно разговаривал с Rust/Wasm и получить обратно? Кратко:

  • Мы собираемся сказать от Python, что написать в память экземпляра, используя виды Wasmer
  • Мы собираемся вызвать функцию WASM (составленную из Rust), чтение из экспортируемых функций экземпляра экземпляра
  • Мы передадим результат обратно на Python

Весь этот процесс демонстрируется эта функция :

def test_reverse(instance, func, bytestr):

    # return a Wasmer Memory View for 8-bit integers
    mem_view = allocate_bytes(instance)

    # write the UTF-8 (decimal) code points to the view
    mem_view = write_to_memory(bytestr, mem_view, offset=0)

    # call the exported function by reading the offset of the
    # view for the length of the bytes string (b'...')
    result = func(0, len(bytestr))

    # read the result value at a given position in linear memory
    return address_to_utf8(mem_view, result, len(bytestr))

Используемые методы загружаются из этого Mini Python-to-Wasmer API Анкет

Результат легко показать этим кусок кода :

Reversing b'Test sTRing' >>>
b'gniRTs tseT'

Спасибо за внимание.

Источники: [1] О’Релли «Программирование ржавчины» ISBN-10: 9781491927281, pg. 392-393 [2] kunststube.net/encoding

Оригинал: “https://dev.to/tuned/memory-views-handling-strings-48h7”