Assemblyscript: ¿Cómo compartir u16/u32/f64... ect en la memoria?

Creado en 12 dic. 2018  ·  4Comentarios  ·  Fuente: AssemblyScript/assemblyscript

Solo uso códigos como MDN Example para acceder a la memoria de AS y JS.
Pero excepto u8/i8, todos los patrones de prueba fallaron y vi que los datos que muestra JS son diferentes de los que muestra AS.

¿Cómo puedo almacenar datos en float?

Mis códigos como:

```index.ts
// ensamblado/index.ts

función de exportación readMemoryU8 (desplazamiento: tamaño de uso): u8 {
carga de retorno(compensar)
}

función de exportación writeMemoryU8(offset: usize, value: u8): void {
Tienda(compensación, valor)
}

Función de exportación readMemoryU16 (desplazamiento: tamaño de uso): u16 {
carga de retorno(compensar)
}

función de exportación writeMemoryU16(offset: usize, value: u16): void {
Tienda(compensación, valor)
}

función de exportación readMemoryF64 (desplazamiento: tamaño de uso): f64 {
carga de retorno(compensar)
}

función de exportación writeMemoryF64(offset: usize, valor: f64): void {
Tienda(compensación, valor)
}

// ...

```index.js
// index.js

const fs = require("fs");
const compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/optimized.wasm"));
const imports = {};
Object.defineProperty(module, "exports", {
  get: () => new WebAssembly.Instance(compiled, imports).exports
});

```index.test.js
// __pruebas__/index.test.js

const wasm = require('../index');
const memoria = wasm.memoria;

describe('Prueba WASM', () => {
antes deTodo(() => {
const mem = new Uint8Array(memoria.buffer);
if (mem.longitud < 1) {
memoria.crecer(1);
}
wasm.memoria.crecer(1);
});

prueba('leer/escribir uint8', () => {
const mem = new Uint8Array(memoria.buffer);

mem.set([1, 3, 5]);
console.log([0, 1, 2, 3, 4, 5].map(wasm.readMemoryU8));
// [ 1, 3, 5, 0, 0, 0 ]
console.log(mem.subarray(0, 6));
//Uint8Array [ 1, 3, 5, 0, 0, 0 ]
expect(wasm.readMemoryU8(1)).toBe(3);
wasm.writeMemoryU8(1, 6);
expect(wasm.readMemoryU8(1)).toBe(6);
expect(mem[1]).toBe(6);
expect(wasm.readMemoryU8(0)).toBe(1);
expect(wasm.readMemoryU8(2)).toBe(5);

});

prueba('leer/escribir uint16', () => {
const mem = new Uint16Array(memoria.buffer);

mem.set([1, 3, 257]);
console.log([0, 1, 2, 3, 4, 5].map(wasm.readMemoryU16)); 
// [ 1, 768, 3, 256, 257 ]
console.log(mem.subarray(0, 6)); 
// Uint16Array [ 1, 3, 257, 0, 0, 0 ]
expect(wasm.readMemoryU16(0)).toBe(1);
expect(wasm.readMemoryU16(1)).toBe(3); // failed
wasm.writeMemoryU16(1, 6);
expect(wasm.readMemoryU16(1)).toBe(6);
expect(mem[1]).toBe(6);
expect(wasm.readMemoryU16(2)).toBe(5);

});

prueba('leer/escribir float64', () => {
const mem = new Float64Array(memoria.buffer);

mem.set([1, -3.2, 25.8]);

console.log([0, 1, 2, 3, 4, 5].map(wasm.readMemoryF64));
// [ 1,
//  -3.0065162379579438e-182,
//  -2.413170169815393e-185,
//  -2.3536706995205933e-185,
//  -2.3534382797147542e-185,
//  -2.3534373718248877e-185 ]
console.log(mem.subarray(0, 6));
// Float64Array [ 1, -3.2, 25.8, 0, 0, 0 ]
expect(wasm.readMemoryF64(0)).toBe(1);
expect(wasm.readMemoryF64(1)).toBe(-3.2); // failed
wasm.writeMemoryI16(1, -6.5);
expect(wasm.readMemoryF64(1)).toBe(-6.5);
expect(mem[1]).toBe(-6.5);
expect(wasm.readMemoryI16(2)).toBe(25.8);

});
});

```

Comentario más útil

El offset en su caso es la posición exacta de la memoria, pero está pasando el índice, que debe multiplicarse. Cuando use f64 , tendrá que incrementar el desplazamiento en 8 bytes (este es un valor de 64 bits) para que los valores no se sobrescriban entre sí, por ejemplo

export function readMemoryF64(index: u32): f64 {
  return load<f64>(index << alignof<f64>());
}

export function writeMemoryF64(index: u32, value: f64): void {
  store<f64>(index << alignof<f64>(), value);
}

Todos 4 comentarios

Parece que el incremento es siempre 1 para el desplazamiento, lo cual es correcto para valores de 8 bits, pero debería ser 2 para valores de 16 bits y 4 para valores de 32 bits etc., lo que da como resultado una situación en la que los valores se sobrescriben entre sí.

@dcodeIO
Ese es el verdadero problema. cuando store<f64>(0, 1.5) , entonces store<f64>(1, 2.7) , en este momento load<f64>(0) devolverá un valor extraño. Pero load<f64>(1) devolverá 2.7 .

El offset en su caso es la posición exacta de la memoria, pero está pasando el índice, que debe multiplicarse. Cuando use f64 , tendrá que incrementar el desplazamiento en 8 bytes (este es un valor de 64 bits) para que los valores no se sobrescriban entre sí, por ejemplo

export function readMemoryF64(index: u32): f64 {
  return load<f64>(index << alignof<f64>());
}

export function writeMemoryF64(index: u32, value: f64): void {
  store<f64>(index << alignof<f64>(), value);
}

@dcodeIO
¡Prueba aprobada!
¡Muchas gracias!

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

Iainmon picture Iainmon  ·  3Comentarios

DanielMazurkiewicz picture DanielMazurkiewicz  ·  4Comentarios

emil14 picture emil14  ·  3Comentarios

DuncanUszkay1 picture DuncanUszkay1  ·  3Comentarios

kungfooman picture kungfooman  ·  5Comentarios