Assemblyscript: Comment partager u16/u32/f64... ect sur la mémoire ?

Créé le 12 déc. 2018  ·  4Commentaires  ·  Source: AssemblyScript/assemblyscript

J'utilise simplement des codes comme MDN Example pour accéder à la mémoire d'AS et de JS.
Mais à l'exception de u8/i8, tous les modèles de test ont échoué et j'ai vu que les données affichées par JS sont différentes de celles affichées par AS.

Comment puis-je stocker des données dans float ?

Mes codes comme:

```index.ts
// assemblage/index.ts

fonction d'exportation readMemoryU8(offset : usize) : u8 {
charge de retour(décalage)
}

fonction d'exportation writeMemoryU8 (offset : usize, valeur : u8): void {
le magasin(décalage, valeur)
}

fonction d'exportation readMemoryU16(offset : usize) : u16 {
charge de retour(décalage)
}

fonction d'exportation writeMemoryU16 (offset : usize, valeur : u16): void {
le magasin(décalage, valeur)
}

fonction d'exportation readMemoryF64(offset : usize) : f64 {
charge de retour(décalage)
}

fonction d'exportation writeMemoryF64 (offset : usize, valeur : f64): void {
le magasin(décalage, valeur)
}

// ...

```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
// __tests__/index.test.js

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

describe('Tester WASM', () => {
avantTout(() => {
const mem = new Uint8Array(memory.buffer);
si (longueur mémoire < 1) {
mémoire.croissance(1);
}
wasm.memory.grow(1);
});

test('lire/écrire uint8', () => {
const mem = new Uint8Array(memory.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);

});

test('lire/écrire uint16', () => {
const mem = new Uint16Array(memory.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);

});

test('lire/écrire float64', () => {
const mem = new Float64Array(memory.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);

});
});

```

Commentaire le plus utile

Le offset dans votre cas est la position exacte de la mémoire, mais vous passez l'index, qui doit être multiplié. Lorsque vous utilisez un f64 , vous devrez incrémenter le décalage de 8 octets (il s'agit d'une valeur 64 bits) afin que les valeurs ne s'écrasent pas, par exemple

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);
}

Tous les 4 commentaires

On dirait que l'incrément est toujours 1 pour le décalage, ce qui est correct pour les valeurs 8 bits, mais devrait être 2 pour les valeurs 16 bits et 4 pour les valeurs 32 bits etc., aboutissant ici à une situation où les valeurs s'écrasent les unes les autres.

@dcodeIO
C'est le problème même. quand store<f64>(0, 1.5) , alors store<f64>(1, 2.7) , En ce moment load<f64>(0) renverra une valeur étrange. Mais load<f64>(1) renverra 2.7 .

Le offset dans votre cas est la position exacte de la mémoire, mais vous passez l'index, qui doit être multiplié. Lorsque vous utilisez un f64 , vous devrez incrémenter le décalage de 8 octets (il s'agit d'une valeur 64 bits) afin que les valeurs ne s'écrasent pas, par exemple

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
Test réussi!
Merci beaucoup!

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

DuncanUszkay1 picture DuncanUszkay1  ·  3Commentaires

MaxGraey picture MaxGraey  ·  3Commentaires

MaxGraey picture MaxGraey  ·  4Commentaires

DanielMazurkiewicz picture DanielMazurkiewicz  ·  4Commentaires

evgenykuzyakov picture evgenykuzyakov  ·  3Commentaires