удаление & quot; -s ONLY_MY_CODE = 1 & quot; Аргумент компиляции приводит к сбою программы WebAssembly

У меня есть небольшая программа WebAssembly, которая работает правильно при компиляции с помощью следующего сценария bash:

source_list="../../src/cpp/main/main.cc"emcc -std=c++11 $source_list -o out/index.html -O1 -s WASM=1  -s ONLY_MY_CODE=1  -s EXPORTED_FUNCTIONS="['_go']"cp ../../src/html/index.html out/

Когда я загружаю программу в своем браузере, я вижу hi there выводится на консоль JS.

Однако при подготовке к использованию более интересного кода я изменяю свой сценарий компиляции, удаляя -s ONLY_MY_CODE=1 запись.

Без каких-либо дальнейших изменений в каких-либо файлах, когда я затем компилирую и запускаю программу, я вижу следующее сообщение об ошибке в браузере:

index.html:1 Uncaught (in promise) LinkError: WebAssembly Instantiation: Import #0 module="env" function="DYNAMICTOP_PTR" error: global import must be a number
at <anonymous>
Promise rejected (async)
(anonymous) @ index.html:35

Как я могу решить эту проблему?

main.cc

extern "C"{
extern void print(char *message);

void go()
{
print("hi there");
}
}

index.html

<script>

var webSocket;
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 });
const buffer = new Uint8Array(memory.buffer);
var exports;

function toJsStr(offset){
var s="";
for(;;){
var b = buffer[offset++];
if( b == 0 )
return s;
s += String.fromCharCode(b);
}
}

function print(offset){
console.log(toJsStr(offset));
}

fetch('index.wasm').then(response =>
response.arrayBuffer()
).then(bytes => {
var imports = {};
imports.env = {};
imports.env.memory = memory;
imports.env.memoryBase = 0;
imports.env.table = new WebAssembly.Table({ initial: 0, maximum: 0, element: 'anyfunc' });
imports.env.tableBase = 0;
imports.env._print = print;

return WebAssembly.instantiate(bytes, imports);
}
).then(module => {
exports = module.instance.exports;

exports._go();
}
);
</script>

3

Решение

Emscripten включает среду выполнения в сгенерированном коде WASM. Эта сгенерированная среда выполнения позволяет поддерживать широкий спектр функций C / C ++, что значительно упрощает перенос сложных кодовых баз. Эта среда выполнения также имеет аналог JavaScript, поэтому, когда вы компилируете кодовую базу C / C ++, вы увидите, что она выводит файл wasm, файл JavaScript и файл HTML. HTML-файл является шаблонным тестовым набором для вашего кода.

При компиляции с ONLY_MY_CODE вы удаляете большую часть этой среды выполнения, и в результате файлы JavaScript и HTML также больше не генерируются. Когда используешь ONLY_MY_CODE функции, которые вы можете использовать, действительно весьма ограничены, например, вы не можете использовать строки или возвращать что-либо, кроме числовых типов из экспортируемых функций.

В результате в вашем примере при удалении ONLY_MY_CODE вам нужно загрузить ваш файл wasm через сгенерированный файл JavaScript. Это загрузит код wasm, а также обработает экспорт / импорт / память, чтобы «объединить» сгенерированный код времени выполнения. Функция DYNAMICTOP_PTR то, что появляется в вашем сообщении об ошибке, является одной из составных частей этой среды выполнения.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]