Приготовьте себя, так как этот пост будет немного менее простым, чем последние, так как мы собираемся поговорить о том, как читать/написать строки 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, мы должны использовать на его стороне AVEC
(Подробнее здесь ); Наконец на уровне 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”