diff --git a/.gitignore b/.gitignore index f6a45d3d..0a493439 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,10 @@ pids *.pid *.seed +# docs/gatsbyjs +.cache +public/ + # Directory for instrumented libs generated by jscoverage/JSCover lib-cov diff --git a/packages/walt-compiler/src/__tests__/__snapshots__/memory-spec.js.md b/packages/walt-compiler/src/__tests__/__snapshots__/memory-spec.js.md index fc66ff77..8fc35add 100644 --- a/packages/walt-compiler/src/__tests__/__snapshots__/memory-spec.js.md +++ b/packages/walt-compiler/src/__tests__/__snapshots__/memory-spec.js.md @@ -4,677 +4,8 @@ The actual snapshot is saved in `memory-spec.js.snap`. Generated by [AVA](https://ava.li). -## memory parser +## wide array offsets > Snapshot 1 - { - Type: 'FunctionDeclaration', - meta: [], - params: [ - { - Type: 'FunctionArguments', - meta: [], - params: [ - undefined, - ], - range: [ - { - col: 14, - line: 1, - sourceLine: 'function test(): i32 {', - }, - { - col: 15, - line: 1, - sourceLine: 'function test(): i32 {', - }, - ], - type: null, - value: 'FUNCTION_ARGUMENTS', - }, - { - Type: 'FunctionResult', - meta: [], - params: [], - range: [ - { - col: 15, - line: 1, - sourceLine: 'function test(): i32 {', - }, - { - col: 22, - line: 1, - sourceLine: 'function test(): i32 {', - }, - ], - type: 'i32', - value: 'i32', - }, - { - Type: 'Declaration', - meta: [], - params: [ - { - Type: 'Constant', - meta: [], - params: [], - range: [ - { - col: 19, - line: 2, - sourceLine: ' let x: i32[] = 0;', - }, - { - col: 20, - line: 2, - sourceLine: ' let x: i32[] = 0;', - }, - ], - type: 'i32', - value: '0', - }, - ], - range: [ - { - col: 4, - line: 2, - sourceLine: ' let x: i32[] = 0;', - }, - { - col: 21, - line: 2, - sourceLine: ' let x: i32[] = 0;', - }, - ], - type: 'i32[]', - value: 'x', - }, - { - Type: 'Declaration', - meta: [], - params: [ - { - Type: 'Constant', - meta: [], - params: [], - range: [ - { - col: 17, - line: 3, - sourceLine: ' let y: i32 = 5;', - }, - { - col: 18, - line: 3, - sourceLine: ' let y: i32 = 5;', - }, - ], - type: 'i32', - value: '5', - }, - ], - range: [ - { - col: 4, - line: 3, - sourceLine: ' let y: i32 = 5;', - }, - { - col: 19, - line: 3, - sourceLine: ' let y: i32 = 5;', - }, - ], - type: 'i32', - value: 'y', - }, - { - Type: 'MemoryAssignment', - meta: [], - params: [ - { - Type: 'ArraySubscript', - meta: [], - params: [ - { - Type: 'Identifier', - meta: [], - params: [], - range: [ - { - col: 4, - line: 4, - sourceLine: ' x[0] = 21;', - }, - { - col: 6, - line: 4, - sourceLine: ' x[0] = 21;', - }, - ], - type: null, - value: 'x', - }, - { - Type: 'Constant', - meta: [], - params: [], - range: [ - { - col: 6, - line: 4, - sourceLine: ' x[0] = 21;', - }, - { - col: 7, - line: 4, - sourceLine: ' x[0] = 21;', - }, - ], - type: 'i32', - value: '0', - }, - ], - range: [ - { - col: 4, - line: 4, - sourceLine: ' x[0] = 21;', - }, - { - col: 6, - line: 4, - sourceLine: ' x[0] = 21;', - }, - { - col: 8, - line: 4, - sourceLine: ' x[0] = 21;', - }, - ], - type: null, - value: 'x', - }, - { - Type: 'Constant', - meta: [], - params: [], - range: [ - { - col: 11, - line: 4, - sourceLine: ' x[0] = 21;', - }, - { - col: 13, - line: 4, - sourceLine: ' x[0] = 21;', - }, - ], - type: 'i32', - value: '21', - }, - ], - range: [ - { - col: 4, - line: 4, - sourceLine: ' x[0] = 21;', - }, - { - col: 6, - line: 4, - sourceLine: ' x[0] = 21;', - }, - { - col: 8, - line: 4, - sourceLine: ' x[0] = 21;', - }, - { - col: 14, - line: 4, - sourceLine: ' x[0] = 21;', - }, - { - col: 14, - line: 4, - sourceLine: ' x[0] = 21;', - }, - ], - type: null, - value: '=', - }, - { - Type: 'MemoryAssignment', - meta: [], - params: [ - { - Type: 'ArraySubscript', - meta: [], - params: [ - { - Type: 'Identifier', - meta: [], - params: [], - range: [ - { - col: 4, - line: 5, - sourceLine: ' x[y] = 2;', - }, - { - col: 6, - line: 5, - sourceLine: ' x[y] = 2;', - }, - ], - type: null, - value: 'x', - }, - { - Type: 'Identifier', - meta: [], - params: [], - range: [ - { - col: 6, - line: 5, - sourceLine: ' x[y] = 2;', - }, - { - col: 8, - line: 5, - sourceLine: ' x[y] = 2;', - }, - ], - type: null, - value: 'y', - }, - ], - range: [ - { - col: 4, - line: 5, - sourceLine: ' x[y] = 2;', - }, - { - col: 6, - line: 5, - sourceLine: ' x[y] = 2;', - }, - { - col: 8, - line: 5, - sourceLine: ' x[y] = 2;', - }, - ], - type: null, - value: 'x', - }, - { - Type: 'Constant', - meta: [], - params: [], - range: [ - { - col: 11, - line: 5, - sourceLine: ' x[y] = 2;', - }, - { - col: 12, - line: 5, - sourceLine: ' x[y] = 2;', - }, - ], - type: 'i32', - value: '2', - }, - ], - range: [ - { - col: 4, - line: 5, - sourceLine: ' x[y] = 2;', - }, - { - col: 6, - line: 5, - sourceLine: ' x[y] = 2;', - }, - { - col: 8, - line: 5, - sourceLine: ' x[y] = 2;', - }, - { - col: 13, - line: 5, - sourceLine: ' x[y] = 2;', - }, - { - col: 13, - line: 5, - sourceLine: ' x[y] = 2;', - }, - ], - type: null, - value: '=', - }, - { - Type: 'ReturnStatement', - meta: [], - params: [ - { - Type: 'BinaryExpression', - meta: [], - params: [ - { - Type: 'ArraySubscript', - meta: [], - params: [ - { - Type: 'Identifier', - meta: [], - params: [], - range: [ - { - col: 11, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 13, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - ], - type: null, - value: 'x', - }, - { - Type: 'Constant', - meta: [], - params: [], - range: [ - { - col: 13, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 14, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - ], - type: 'i32', - value: '0', - }, - ], - range: [ - { - col: 11, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 13, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 15, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - ], - type: null, - value: 'x', - }, - { - Type: 'ArraySubscript', - meta: [], - params: [ - { - Type: 'Identifier', - meta: [], - params: [], - range: [ - { - col: 18, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 20, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - ], - type: null, - value: 'x', - }, - { - Type: 'Identifier', - meta: [], - params: [], - range: [ - { - col: 20, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 22, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - ], - type: null, - value: 'y', - }, - ], - range: [ - { - col: 18, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 20, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 22, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - ], - type: null, - value: 'x', - }, - ], - range: [ - { - col: 11, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 13, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 15, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 23, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - ], - type: null, - value: '*', - }, - ], - range: [ - { - col: 4, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - { - col: 23, - line: 6, - sourceLine: ' return x[0] * x[y];', - }, - ], - type: null, - value: 'return', - }, - ], - range: [ - { - col: 9, - line: 1, - sourceLine: 'function test(): i32 {', - }, - { - col: 3, - line: 7, - sourceLine: ' }', - }, - ], - type: null, - value: 'test', - } - -## memory store on float arrays - -> Snapshot 1 - - { - Type: 'MemoryAssignment', - meta: [], - params: [ - { - Type: 'ArraySubscript', - meta: [], - params: [ - { - Type: 'Identifier', - meta: [], - params: [], - range: [ - { - col: 0, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - { - col: 2, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - ], - type: null, - value: 'x', - }, - { - Type: 'Constant', - meta: [], - params: [], - range: [ - { - col: 2, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - { - col: 3, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - ], - type: 'i32', - value: '0', - }, - ], - range: [ - { - col: 0, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - { - col: 2, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - { - col: 4, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - ], - type: null, - value: 'x', - }, - { - Type: 'Constant', - meta: [], - params: [], - range: [ - { - col: 7, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - { - col: 10, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - ], - type: 'f32', - value: '2.0', - }, - ], - range: [ - { - col: 0, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - { - col: 2, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - { - col: 4, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - { - col: 11, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - { - col: 11, - line: 1, - sourceLine: 'x[0] = 2.0;', - }, - ], - type: null, - value: '=', - } + '10,42,20,42,30,42,40,42,50,42' diff --git a/packages/walt-compiler/src/__tests__/__snapshots__/memory-spec.js.snap b/packages/walt-compiler/src/__tests__/__snapshots__/memory-spec.js.snap index 090151aa..fec3e904 100644 Binary files a/packages/walt-compiler/src/__tests__/__snapshots__/memory-spec.js.snap and b/packages/walt-compiler/src/__tests__/__snapshots__/memory-spec.js.snap differ diff --git a/packages/walt-compiler/src/__tests__/memory-spec.js b/packages/walt-compiler/src/__tests__/memory-spec.js index 42944334..5647ee4c 100644 --- a/packages/walt-compiler/src/__tests__/memory-spec.js +++ b/packages/walt-compiler/src/__tests__/memory-spec.js @@ -45,3 +45,32 @@ test('memory of any shape can be imported', t => { { env: { memory } } ).then(outputIs(t, 42)); }); + +test('wide array offsets', t => { + const SAFE_OFFSET = 65536; + return WebAssembly.instantiate( + compile(` + export const memory: Memory<{initial: ${1 + (SAFE_OFFSET >> 16)}}>; + export function populateArray(): f64 { + const array: f64[] = ${SAFE_OFFSET}; + array[0] = 10 :f64; + array[2] = 20 :f64; + array[4] = 30 :f64; + array[6] = 40 :f64; + array[8] = 50 :f64; + + return array[4]; + } + `).buffer(), + {} + ).then(({ instance }) => { + const typedArray = new Float64Array( + instance.exports.memory.buffer, + SAFE_OFFSET, + 10 + ).fill(42); + const result = instance.exports.populateArray(); + t.is(result, 30); + t.snapshot(typedArray.toString()); + }); +}); diff --git a/packages/walt-compiler/src/generator/array-subscript.js b/packages/walt-compiler/src/generator/array-subscript.js index f45209ba..a56c0531 100644 --- a/packages/walt-compiler/src/generator/array-subscript.js +++ b/packages/walt-compiler/src/generator/array-subscript.js @@ -5,6 +5,12 @@ import type { GeneratorType } from './flow/types'; import { TYPE_ARRAY } from '../semantics/metadata'; import mapSyntax from './map-syntax'; +const shiftAmount = { + i32: 2, + f32: 2, + i64: 3, + f64: 3, +}; const generateArraySubscript: GeneratorType = (node, parent) => { const identifier = node.params[0]; const type = identifier.meta[TYPE_ARRAY]; @@ -12,7 +18,7 @@ const generateArraySubscript: GeneratorType = (node, parent) => { // For array types, the index is multiplied by the contained object size block.push.apply(block, [ - { kind: opcode.i32Const, params: [2] }, + { kind: opcode.i32Const, params: [shiftAmount[type]] }, { kind: opcode.i32Shl, params: [] }, ]); diff --git a/packages/walt-compiler/src/generator/memory-assignment.js b/packages/walt-compiler/src/generator/memory-assignment.js index 7f6a6209..7acbd2d5 100644 --- a/packages/walt-compiler/src/generator/memory-assignment.js +++ b/packages/walt-compiler/src/generator/memory-assignment.js @@ -5,6 +5,13 @@ import opcode from '../emitter/opcode'; import { TYPE_ARRAY } from '../semantics/metadata'; import type { GeneratorType } from './flow/types'; +const shiftAmount = { + i32: 2, + f32: 2, + i64: 3, + f64: 3, +}; + const generateMemoryAssignment: GeneratorType = (node, parent) => { const targetNode = node.params[0]; const isArray = targetNode.params[0].meta[TYPE_ARRAY]; @@ -18,7 +25,7 @@ const generateMemoryAssignment: GeneratorType = (node, parent) => { // For array types, the index is multiplied by the contained object size block.push.apply(block, [ // TODO: fix this for user-defined types - { kind: opcode.i32Const, params: [2] }, + { kind: opcode.i32Const, params: [shiftAmount[isArray]] }, { kind: opcode.i32Shl, params: [] }, ]); type = isArray; diff --git a/packages/walt-compiler/src/index.js b/packages/walt-compiler/src/index.js index dc5134b5..787809af 100644 --- a/packages/walt-compiler/src/index.js +++ b/packages/walt-compiler/src/index.js @@ -30,7 +30,7 @@ export { walkNode, mapNode, }; -export const VERSION = '0.17.0'; +export const VERSION = '0.18.0'; // Used for debugging purposes export const getIR = (source: string, config: ConfigType) => {