Ответы пользователя по тегу WebAssembly
  • Почему wasm код не генерируется при компиляции rust кода с сырыми указателями?

    bingo347
    @bingo347
    Crazy on performance...
    Начну пожалуй с того, что в первом примере у Вас UB (undefined behavior):
    #[no_mangle]
    pub fn test() {
        // Вот тут на стеке выделено 4 байта
        let mut idx: i32 = 10;
        // Указатель на эти 4 байта
        let ptr = &mut idx as *mut i32;
    
        // По сути указатель на те же 4 байта, но на деле указатель на 40 байт
        let buffer = unsafe { core::slice::from_raw_parts_mut(ptr, 10) };
    
        // И тут мы работаем с этими 40 байтами,
        // но нормальные из них только 4 байта в начале,
        // а остальные смотрят в глубь стека и меняют его
        // то есть перетирают адрес возврата и данные на стеке вызвавшей функции
        for pixel in buffer.iter_mut() {
            *pixel = 0x7d2b7500;
        }
    }
    То есть после завершения данная функция должна не вернуться в вызывающую функцию, а передать управление непонятно куда.

    Ну и еще один момент, это оптимизация, данная функция не имеет сайд эффектов и ничего не возвращает. После инлайна функции core::slice::from_raw_parts_mut и метода Iterator::iter_mut компилятор вполне может понять, что данный код не имеет сайд эффектов, а значит бесполезен и его можно вырезать. Вот собственно он его и вырезает.
    Во втором же примере у нас есть сайд эффект - изменение данных по указателю пришедшему извне через аргументы.

    P.S. Во втором примере кстати тоже можно увидеть работу оптимизации, цикл из 10 итераций, пишущих i32 в смещение по указателю, был заменен на обычные 5 записей i64 в смещение по указателю.
    Ответ написан
    1 комментарий