Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better metadata #97

Merged
merged 3 commits into from
Mar 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/walt-compiler/src/flow/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ export type TokenType = {
value: string,
};

export type MetadataType = { type: string, payload: any };
export type MetadataType = { [string]: any };

export type NodeType = {
range: Marker[],
Type: string,
type: string | null,
value: string,
meta: MetadataType[],
meta: MetadataType,
params: NodeType[],
};

Expand Down
6 changes: 3 additions & 3 deletions packages/walt-compiler/src/generator/array-subscript.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
import opcode from "../emitter/opcode";
import mergeBlock from "./merge-block";
import type { GeneratorType } from "./flow/types";
import { get, TYPE_ARRAY } from "../semantics/metadata";
import { TYPE_ARRAY } from "../semantics/metadata";
import mapSyntax from "./map-syntax";

const generateArraySubscript: GeneratorType = (node, parent) => {
const identifier = node.params[0];
const isArray = get(TYPE_ARRAY, identifier);
const isArray = identifier.meta[TYPE_ARRAY];
const block = node.params.map(mapSyntax(parent)).reduce(mergeBlock, []);
let type = node.type;

Expand All @@ -18,7 +18,7 @@ const generateArraySubscript: GeneratorType = (node, parent) => {
{ kind: opcode.i32Const, params: [2] },
{ kind: opcode.i32Shl, params: [] },
]);
type = isArray.payload;
type = isArray;
}

// The sequence of opcodes to perfrom a memory load is
Expand Down
10 changes: 4 additions & 6 deletions packages/walt-compiler/src/generator/declaration.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// @flow
import { i32 } from "../Syntax";
import invariant from "invariant";
import generateExpression from "./expression";
import { isBuiltinType } from "./utils";
import opcode from "../emitter/opcode";
import { get, LOCAL_INDEX } from "../semantics/metadata";
import { LOCAL_INDEX } from "../semantics/metadata";
import type { GeneratorType } from "./flow/types";

const generateDeclaration: GeneratorType = (
Expand All @@ -14,17 +13,16 @@ const generateDeclaration: GeneratorType = (
const initNode = node.params[0];

if (initNode) {
const metaIndex = get(LOCAL_INDEX, node);
invariant(metaIndex, `Local Index is undefined. Node: ${node.value}`);
const metaIndex = node.meta[LOCAL_INDEX];

const type = isBuiltinType(node.type) ? node.type : i32;

return [
...generateExpression({ ...initNode, type }, parent),
{
kind: opcode.SetLocal,
params: [metaIndex.payload],
debug: `${node.value}<${node.type ? node.type : "?"}>`,
params: [metaIndex],
debug: `${node.value}<${String(node.type)}>`,
},
];
}
Expand Down
14 changes: 6 additions & 8 deletions packages/walt-compiler/src/generator/export.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
// @flow
import { get, GLOBAL_INDEX, FUNCTION_INDEX } from "../semantics/metadata";
import { GLOBAL_INDEX, FUNCTION_INDEX } from "../semantics/metadata";
import { EXTERN_GLOBAL, EXTERN_FUNCTION } from "../emitter/external_kind";
import invariant from "invariant";
import type { NodeType, IntermediateExportType } from "./flow/types";

export default function generateExport(node: NodeType): IntermediateExportType {
const functionIndexMeta = get(FUNCTION_INDEX, node);
const globalIndexMeta = get(GLOBAL_INDEX, node);
const functionIndexMeta = node.meta[FUNCTION_INDEX];
const globalIndexMeta = node.meta[GLOBAL_INDEX];

if (globalIndexMeta) {
if (globalIndexMeta != null) {
return {
index: globalIndexMeta.payload,
index: globalIndexMeta,
kind: EXTERN_GLOBAL,
field: node.value,
};
}

invariant(functionIndexMeta, "Unknown Export");
return {
index: functionIndexMeta.payload,
index: functionIndexMeta,
kind: EXTERN_FUNCTION,
field: node.value,
};
Expand Down
12 changes: 3 additions & 9 deletions packages/walt-compiler/src/generator/function-call.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,16 @@
import mapSyntax from "./map-syntax";
import opcode from "../emitter/opcode";
import mergeBlock from "./merge-block";
import invariant from "invariant";
import printNode from "../utils/print-node";
import { get, FUNCTION_INDEX } from "../semantics/metadata";
import { FUNCTION_INDEX } from "../semantics/metadata";
import type { GeneratorType } from "./flow/types";

const generateFunctionCall: GeneratorType = (node, parent) => {
const block = node.params.map(mapSyntax(parent)).reduce(mergeBlock, []);
const metaFunctionIndex = get(FUNCTION_INDEX, node);
invariant(
metaFunctionIndex,
"Undefined function index for node \n" + `${printNode(node)}`
);
const metaFunctionIndex = node.meta[FUNCTION_INDEX];

block.push({
kind: opcode.Call,
params: [metaFunctionIndex.payload],
params: [metaFunctionIndex],
debug: `${node.value}<${node.type ? node.type : "void"}>`,
});

Expand Down
6 changes: 3 additions & 3 deletions packages/walt-compiler/src/generator/import.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
EXTERN_GLOBAL,
EXTERN_TABLE,
} from "../emitter/external_kind";
import { get, TYPE_INDEX } from "../semantics/metadata";
import { TYPE_INDEX } from "../semantics/metadata";
import type { IntermediateImportType, NodeType } from "./flow/types";

export const getKindConstant = (value: string) => {
Expand Down Expand Up @@ -41,9 +41,9 @@ export default function generateImportFromNode(
const { value: importTypeValue } = typeOrIdentifierNode;
const kind = getKindConstant(importTypeValue);
const typeIndex = (() => {
const typeIndexMeta = get(TYPE_INDEX, typeOrIdentifierNode);
const typeIndexMeta = typeOrIdentifierNode.meta[TYPE_INDEX];
if (typeIndexMeta) {
return typeIndexMeta.payload;
return typeIndexMeta;
}
return null;
})();
Expand Down
31 changes: 15 additions & 16 deletions packages/walt-compiler/src/generator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ import generateType from "./type";
import { generateValueType } from "./utils";
import { generateImplicitFunctionType } from "./type";
import {
get,
GLOBAL_INDEX,
FUNCTION_INDEX,
FUNCTION_METADATA,
typeIndex as setMetaTypeIndex,
TYPE_INDEX,
} from "../semantics/metadata";

import type { NodeType, ProgramType } from "./flow/types";
Expand All @@ -34,11 +33,11 @@ export const generateCode = (
// eslint-disable-next-line
const [argsNode, resultNode, ...body] = func.params;

const metadata = get(FUNCTION_METADATA, func);
const metadata = func.meta[FUNCTION_METADATA];
invariant(body, "Cannot generate code for function without body");
invariant(metadata, "Cannot generate code for function without metadata");

const { locals, argumentsCount } = metadata.payload;
const { locals, argumentsCount } = metadata;

const block = {
code: [],
Expand Down Expand Up @@ -108,7 +107,7 @@ export default function generator(ast: NodeType): ProgramType {

typeNode = {
...node,
meta: [...node.meta, setMetaTypeIndex(typeIndex)],
meta: { ...node.meta, [TYPE_INDEX]: typeIndex },
};

typeMap[node.value] = { typeIndex, typeNode };
Expand All @@ -123,8 +122,8 @@ export default function generator(ast: NodeType): ProgramType {
program.Exports.push(generateExport(nodeToExport));
},
[Syntax.ImmutableDeclaration]: node => {
const globalMeta = get(GLOBAL_INDEX, node);
if (globalMeta !== null) {
const globalMeta = node.meta[GLOBAL_INDEX];
if (globalMeta != null) {
switch (node.type) {
case "Memory":
program.Memory.push(generateMemory(node));
Expand All @@ -138,8 +137,8 @@ export default function generator(ast: NodeType): ProgramType {
}
},
[Syntax.Declaration]: node => {
const globalMeta = get(GLOBAL_INDEX, node);
if (globalMeta !== null) {
const globalMeta = node.meta[GLOBAL_INDEX];
if (globalMeta != null) {
program.Globals.push(generateInitializer(node));
}
},
Expand All @@ -164,16 +163,16 @@ export default function generator(ast: NodeType): ProgramType {
if (userDefinedType != null) {
return {
...typeNode,
meta: [...typeNode.meta, setMetaTypeIndex(userDefinedType.index)],
meta: { ...typeNode.meta, [TYPE_INDEX]: userDefinedType.index },
};
}

return typeNode;
},
[Syntax.FunctionPointer]: pointer => {
const metaFunctionIndex = get(FUNCTION_INDEX, pointer);
const metaFunctionIndex = pointer.meta[FUNCTION_INDEX];
if (metaFunctionIndex) {
const functionIndex = metaFunctionIndex.payload;
const functionIndex = metaFunctionIndex;
let tableIndex = findTableIndex(functionIndex);
if (tableIndex < 0) {
tableIndex = program.Element.length;
Expand All @@ -186,12 +185,12 @@ export default function generator(ast: NodeType): ProgramType {

// Quick fix for shifting around function indices. These don't necessarily
// get written in the order they appear in the source code.
const index = get(FUNCTION_INDEX, node);
invariant(index, "Function index must be set");
const index = node.meta[FUNCTION_INDEX];
invariant(index != null, "Function index must be set");

program.Functions[index.payload] = typeIndex;
program.Functions[index] = typeIndex;
// We will need to filter out the empty slots later
program.Code[index.payload] = generateCode(patched);
program.Code[index] = generateCode(patched);
},
};

Expand Down
18 changes: 12 additions & 6 deletions packages/walt-compiler/src/generator/indirect-function-call.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,27 @@ import invariant from "invariant";
import mapSyntax from "./map-syntax";
import mergeBlock from "./merge-block";
import opcode from "../emitter/opcode";
import { get, LOCAL_INDEX, TYPE_INDEX } from "../semantics/metadata";
import { LOCAL_INDEX, TYPE_INDEX } from "../semantics/metadata";
import type { GeneratorType } from "./flow/types";

const generateIndirectFunctionCall: GeneratorType = (node, parent) => {
const block = node.params.map(mapSyntax(parent)).reduce(mergeBlock, []);
const localIndex = get(LOCAL_INDEX, node);
const typeIndexMeta = get(TYPE_INDEX, node);
invariant(localIndex, "Undefined local index, not a valid function pointer");
invariant(typeIndexMeta, "Variable is not of a valid function pointer type");
const localIndex = node.meta[LOCAL_INDEX];
const typeIndexMeta = node.meta[TYPE_INDEX];
invariant(
localIndex != null,
"Undefined local index, not a valid function pointer"
);
invariant(
typeIndexMeta != null,
"Variable is not of a valid function pointer type"
);

return [
...block,
{
kind: opcode.CallIndirect,
params: [typeIndexMeta.payload, 0],
params: [typeIndexMeta, 0],
},
];
};
Expand Down
6 changes: 3 additions & 3 deletions packages/walt-compiler/src/generator/memory-assignment.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
import mapSyntax from "./map-syntax";
import mergeBlock from "./merge-block";
import opcode from "../emitter/opcode";
import { get, TYPE_ARRAY } from "../semantics/metadata";
import { TYPE_ARRAY } from "../semantics/metadata";
import type { GeneratorType } from "./flow/types";

const generateMemoryAssignment: GeneratorType = (node, parent) => {
const targetNode = node.params[0];
const isArray = get(TYPE_ARRAY, targetNode.params[0]);
const isArray = targetNode.params[0].meta[TYPE_ARRAY];
let type = node.type;

const block = node.params[0].params
Expand All @@ -21,7 +21,7 @@ const generateMemoryAssignment: GeneratorType = (node, parent) => {
{ kind: opcode.i32Const, params: [2] },
{ kind: opcode.i32Shl, params: [] },
]);
type = isArray.payload;
type = isArray;
}

// The sequence of opcodes to perfrom a memory load is
Expand Down
6 changes: 3 additions & 3 deletions packages/walt-compiler/src/generator/typecast.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
import mapSyntax from "./map-syntax";
import mergeBlock from "./merge-block";
import { getTypecastOpcode } from "../emitter/opcode";
import { get, TYPE_CAST } from "../semantics/metadata";
import { TYPE_CAST } from "../semantics/metadata";
import invariant from "invariant";
import type { GeneratorType } from "./flow/types";

const generateTypecast: GeneratorType = (node, parent) => {
const metaTypecast = get(TYPE_CAST, node);
const metaTypecast = node.meta[TYPE_CAST];
invariant(
metaTypecast,
`Cannot generate typecast for node: ${JSON.stringify(node)}`
);

const { to, from } = metaTypecast.payload;
const { to, from } = metaTypecast;

const block = node.params.map(mapSyntax(parent)).reduce(mergeBlock, []);
return [
Expand Down
21 changes: 8 additions & 13 deletions packages/walt-compiler/src/generator/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import opcode from "../emitter/opcode";
import curry from "curry";
import invariant from "invariant";
import { I32, I64, F32, F64 } from "../emitter/value_type";
import {
get,
LOCAL_INDEX,
GLOBAL_INDEX,
TYPE_CONST,
} from "../semantics/metadata";
import { LOCAL_INDEX, GLOBAL_INDEX, TYPE_CONST } from "../semantics/metadata";
import type {
IntermediateVariableType,
IntermediateOpcodeType,
Expand All @@ -18,19 +13,19 @@ import type {
import type { NodeType } from "../flow/types";

export const scopeOperation = curry((op, node) => {
const local = get(LOCAL_INDEX, node);
const _global = get(GLOBAL_INDEX, node);
const index = local || _global;
const local = node.meta[LOCAL_INDEX];
const _global = node.meta[GLOBAL_INDEX];
const index = local != null ? local : _global;

invariant(
index,
index != null,
`Unefined index for scope Operation. Possibly missing metadata. op: ${JSON.stringify(
op
)} node: ${JSON.stringify(node, null, 2)}`
);

const kind = local ? op + "Local" : op + "Global";
const params = [Number(index.payload)];
const kind = local != null ? op + "Local" : op + "Global";
const params = [Number(index)];

return {
kind: opcode[kind],
Expand Down Expand Up @@ -75,7 +70,7 @@ export const isBuiltinType = (type: ?string): boolean => {
export const generateValueType = (
node: NodeType
): IntermediateVariableType => ({
mutable: get(TYPE_CONST, node) ? 0 : 1,
mutable: node.meta[TYPE_CONST] ? 0 : 1,
type: getType(node.type),
});
export const setInScope = scopeOperation("Set");
Expand Down
Loading