Skip to content
Draft
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
6 changes: 3 additions & 3 deletions src/framework/Framework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class Framework {
const result: SuiteResult = new SuiteResult(suite);

const first: TestScenario = order[0];
await timeout<Object | void>('Initialize testbed', testee.connector.timeout, testee.initialize(first.program, first.args ?? []).catch((e: Error) => result.error(e.message)));
await timeout<Object | void>('Initialize testbed', testee.connector.timeout, testee.initialize(first.program, first.args ?? [], first.compilerOptions).catch((e: Error) => result.error(e.message)));

await this.runSuite(result, testee, order);
this.reporter.report(result);
Expand All @@ -100,7 +100,7 @@ export class Framework {
const result: SuiteResult = new SuiteResult(suite);

const first: TestScenario = order[0];
await timeout<Object | void>('Initialize testbed', testee.connector.timeout, testee.initialize(first.program, first.args ?? []).catch((e: Error) => result.error(e.message)));
await timeout<Object | void>('Initialize testbed', testee.connector.timeout, testee.initialize(first.program, first.args ?? [], first.compilerOptions).catch((e: Error) => result.error(e.message)));

await this.runSuite(result, testee, order);
this.reporter.report(result);
Expand Down Expand Up @@ -128,7 +128,7 @@ export class Framework {
const result: SuiteResult = new SuiteResult(suite);

const first: TestScenario = order[i][0];
await timeout<Object | void>('Initialize testbed', testee.connector.timeout, testee.initialize(first.program, first.args ?? []).catch((e: Error) => result.error(e.message)));
await timeout<Object | void>('Initialize testbed', testee.connector.timeout, testee.initialize(first.program, first.args ?? [], first.compilerOptions).catch((e: Error) => result.error(e.message)));

for (let j = i; j < order.length; j += suite.testees.length) {
await this.runSuite(result, testee, order[j]);
Expand Down
18 changes: 9 additions & 9 deletions src/framework/Testee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {Kind} from './scenario/Step';
import {SourceMapFactory} from '../sourcemap/SourceMapFactory';
import {TestScenario} from './scenario/TestScenario';
import {OutofPlaceSpecification, PlatformType, TestbedSpecification} from '../testbeds/TestbedSpecification';
import {CompileOutput, CompilerFactory} from '../manage/Compiler';
import {CompileOutput, CompilerFactory, CompilerOptions} from '../manage/Compiler';
import {WABT} from '../util/env';
import {Outcome} from '../reporter/describers/Describer';
import {WASM} from '../sourcemap/Wasm';
Expand Down Expand Up @@ -90,11 +90,11 @@ export class Testee { // TODO unified with testbed interface
return target == Target.proxy ? this.proxy : this.testbed;
}

public async initialize(program: string, args: string[] = []): Promise<Testee> {
public async initialize(program: string, args: string[] = [], compilerOptions?: CompilerOptions): Promise<Testee> {
return new Promise(async (resolve, reject) => {
if (this.specification.type === PlatformType.emu2emu) {
const spec = (this.specification as OutofPlaceSpecification).proxy;
const proxy: Testbed | void = await this.connector.initialize(spec, program, args ?? []).catch((e) => {
const proxy: Testbed | void = await this.connector.initialize(spec, program, args ?? [], compilerOptions).catch((e) => {
reject(e)
});

Expand All @@ -109,14 +109,14 @@ export class Testee { // TODO unified with testbed interface
await this.proxy.sendRequest(new SourceMap.Mapping(), Message.proxifyRequest);
args = args.concat(['--proxy', `${spec.dummy.port}`]);

const testbed: Testbed | void = await this.connector.initialize(this.specification, program, args).catch((e) => {
const testbed: Testbed | void = await this.connector.initialize(this.specification, program, args, compilerOptions).catch((e) => {
reject(e);
});
if (testbed) {
this.testbed = testbed;
}
} else {
const testbed: Testbed | void = await this.connector.initialize(this.specification, program, args).catch((e) => {
const testbed: Testbed | void = await this.connector.initialize(this.specification, program, args, compilerOptions).catch((e) => {
reject(e)
});
if (testbed) {
Expand Down Expand Up @@ -168,12 +168,12 @@ export class Testee { // TODO unified with testbed interface
return;
}

const compiled: CompileOutput = await new CompilerFactory(WABT).pickCompiler(description.program).compile(description.program);
const compiled: CompileOutput = await new CompilerFactory(WABT).pickCompiler(description.program).compile(description.program, description.compilerOptions);
try {
await timeout<object | void>(`uploading module`, testee.timeout, testee.bed()!.sendRequest(new SourceMap.Mapping(), Message.updateModule(compiled.file))).catch((e) => Promise.reject(e));
testee.current = description.program;
} catch {
await testee.initialize(description.program, description.args ?? []).catch((o) => Promise.reject(o));
await testee.initialize(description.program, description.args ?? [], description.compilerOptions).catch((o) => Promise.reject(o));
}
}).catch((e: Error | string) => {
if (typeof e === 'string') {
Expand All @@ -184,7 +184,7 @@ export class Testee { // TODO unified with testbed interface
});

await this.run('Get source mapping', testee.connector.timeout, async function () {
map = await testee.mapper.map(description.program);
map = await testee.mapper.map(description.program, description.compilerOptions);
}).catch((e: Error | string) => {
if (typeof e === 'string') {
scenarioResult.error(e);
Expand Down Expand Up @@ -231,7 +231,7 @@ export class Testee { // TODO unified with testbed interface
(testee, req, map) => timeout<object | void>(`sending instruction ${req.type}`, testee.timeout,
testee.bed(step.target ?? Target.supervisor)!.sendRequest(map, req)),
(testee) => testee.run(`Recover: re-initialize ${testee.testbed?.name}`, testee.connector.timeout, async function () {
await testee.initialize(description.program, description.args ?? []).catch((o) => {
await testee.initialize(description.program, description.args ?? [], description.compilerOptions).catch((o) => {
return Promise.reject(o)
});
}), 1).catch((e: Error) => {
Expand Down
7 changes: 5 additions & 2 deletions src/framework/scenario/TestScenario.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Breakpoint} from "../../debug/Breakpoint";
import {Step} from "./Step";
import { Breakpoint } from "../../debug/Breakpoint";
import { CompilerOptions } from "../../manage/Compiler";
import { Step } from "./Step";

/** A series of scenario to perform on a single instance of the vm */
export interface TestScenario {
Expand All @@ -19,4 +20,6 @@ export interface TestScenario {
skip?: boolean;

dependencies?: TestScenario[];

compilerOptions?: CompilerOptions;
}
50 changes: 28 additions & 22 deletions src/manage/Compiler.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { exec, ExecException } from 'child_process';
import { EventEmitter } from 'events';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import {exec, ExecException} from 'child_process';
import {SourceMap} from '../sourcemap/SourceMap';
import * as readline from 'readline';
import {EventEmitter} from 'events';
import {find, getFileExtension} from '../util/util';
import {AsScriptMapper} from '../sourcemap/SourceMapper';
import { SourceMap } from '../sourcemap/SourceMap';
import { AsScriptMapper } from '../sourcemap/SourceMapper';
import { find, getFileExtension } from '../util/util';
import SourceLine = SourceMap.SourceLine;

enum CompilationEvents {
Expand Down Expand Up @@ -45,12 +45,16 @@ export class CompilerFactory {
}
}

export interface CompilerOptions {
disableBulkMemory?: boolean;
}

export abstract class Compiler extends EventEmitter {
// compiles program to WAT
abstract compile(program: string): Promise<CompileOutput>;
abstract compile(program: string, options?: CompilerOptions): Promise<CompileOutput>;

// generates a sourceMap
abstract map(program: string): Promise<CompileOutput>;
abstract map(program: string, compilerOptions: CompilerOptions): Promise<CompileOutput>;

protected makeTmpDir(): Promise<string> {
return new Promise((resolve, reject) => {
Expand All @@ -75,17 +79,17 @@ export class WatCompiler extends Compiler {
this.wabt = wabt.length > 0 ? wabt + "/" : "";
}

public async compile(program: string, dir?: string): Promise<CompileOutput> {
public async compile(program: string, compilerOptions?: CompilerOptions, dir?: string): Promise<CompileOutput> {
if (dir) {
return this.wasm(program, dir);
return this.wasm(program, compilerOptions, dir);
}

return this.makeTmpDir().then((dir: string) => {
return this.wasm(program, dir);
return this.wasm(program, compilerOptions, dir);
});
}

private wasm(program: string, dir: string): Promise<CompileOutput> {
private wasm(program: string, compilerOptions?: CompilerOptions, dir?: string): Promise<CompileOutput> {
// do not recompiled previous compilations
// if (this.compiled.has(program)) {
// return Promise.resolve(this.compiled.get(program)!);
Expand All @@ -94,7 +98,8 @@ export class WatCompiler extends Compiler {
// compile WAT to Wasm
return new Promise<CompileOutput>((resolve, reject) => {
const file = `${dir}/upload.wasm`;
const command = `${this.wabt}wat2wasm --no-canonicalize-leb128s --disable-bulk-memory --debug-names -v -o ${file} ${program}`;
const disableBulkMemory = compilerOptions?.disableBulkMemory ?? true;
const command = `${this.wabt}wat2wasm --no-canonicalize-leb128s ${disableBulkMemory ? '--disable-bulk-memory' : ''} --debug-names -v -o ${file} ${program}`;
let out: string = '';
let err: string = '';

Expand Down Expand Up @@ -139,8 +144,8 @@ export class WatCompiler extends Compiler {
});
}

public async map(program: string): Promise<CompileOutput> {
return this.compile(program).then((output) => {
public async map(program: string, compilerOptions: CompilerOptions): Promise<CompileOutput> {
return this.compile(program, compilerOptions).then((output) => {
return this.dump(output);
});
}
Expand All @@ -160,15 +165,15 @@ export class AsScriptCompiler extends Compiler {
this.wabt = wabt;
}

public async compile(program: string): Promise<CompileOutput> {
public async compile(program: string, compilerOptions?: CompilerOptions): Promise<CompileOutput> {
return this.makeTmpDir().then((dir) => {
return this.wasm(program, dir);
return this.wasm(program, dir, compilerOptions);
});
}

public async map(program: string): Promise<CompileOutput> {
public async map(program: string, compilerOptions?: CompilerOptions): Promise<CompileOutput> {
const emitter = this;
return this.compile(program).then(async function (output: CompileOutput) {
return this.compile(program, compilerOptions).then(async function (output: CompileOutput) {
output.map = await new AsScriptMapper(program, path.dirname(output.file)).mapping();
emitter.emit(CompilationEvents.sourcemap);
return Promise.resolve(output);
Expand Down Expand Up @@ -202,7 +207,7 @@ export class AsScriptCompiler extends Compiler {
});
}

private async wasm(program: string, dir: string): Promise<CompileOutput> {
private async wasm(program: string, dir: string, compilerOptions?: CompilerOptions): Promise<CompileOutput> {
// do not recompiled previous compilations
// if (this.compiled.has(program)) {
// return Promise.resolve(this.compiled.get(program)!);
Expand All @@ -211,7 +216,7 @@ export class AsScriptCompiler extends Compiler {
// compile AS to Wasm and WAT
return new Promise<CompileOutput>(async (resolve, reject) => {
const file = `${dir}/upload.wasm`;
const command = await this.getCompilationCommand(program, file);
const command = await this.getCompilationCommand(program, file, compilerOptions);
let out: string = '';
let err: string = '';

Expand All @@ -234,11 +239,12 @@ export class AsScriptCompiler extends Compiler {
});
}

private getCompilationCommand(program: string, output: string): Promise<string> {
private getCompilationCommand(program: string, output: string, compilerOptions?: CompilerOptions): Promise<string> {
// builds asc command based on the version of asc
return new Promise<string>(async (resolve) => {
const version: Version = await AsScriptCompiler.retrieveVersion();
resolve(`npx asc ${program} --exportTable --disable bulk-memory --sourceMap --debug ` +
const disableBulkMemory = compilerOptions?.disableBulkMemory ?? true;
resolve(`npx asc ${program} --exportTable ${disableBulkMemory ? '--disable bulk-memory' : ''} --sourceMap --debug ` +
`${(version.major > 0 || +version.minor >= 20) ? '--outFile' : '--binaryFile'} ${output}`);
});
}
Expand Down
20 changes: 10 additions & 10 deletions src/messaging/Message.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {WARDuino} from '../debug/WARDuino';
import {ackParser, breakpointParser, invokeParser, stateParser} from './Parsers';
import {Breakpoint} from '../debug/Breakpoint';
import {WASM} from '../sourcemap/Wasm';
import { readFileSync } from 'fs';
import ieee754 from 'ieee754';
import {SourceMap} from '../sourcemap/SourceMap';
import {readFileSync} from 'fs';
import {CompileOutput, CompilerFactory} from '../manage/Compiler';
import {WABT} from '../util/env';
import { Breakpoint } from '../debug/Breakpoint';
import { WARDuino } from '../debug/WARDuino';
import { CompileOutput, CompilerFactory, CompilerOptions } from '../manage/Compiler';
import { SourceMap } from '../sourcemap/SourceMap';
import { WASM } from '../sourcemap/Wasm';
import { WABT } from '../util/env';
import { ackParser, breakpointParser, invokeParser, stateParser } from './Parsers';
import Interrupt = WARDuino.Interrupt;
import State = WARDuino.State;
import Value = WASM.Value;
Expand Down Expand Up @@ -130,8 +130,8 @@ export namespace Message {
}
}

export async function uploadFile(program: string): Promise<Request<Ack>> {
const compiled: CompileOutput = await new CompilerFactory(WABT).pickCompiler(program).compile(program);
export async function uploadFile(program: string, compilerOptions: CompilerOptions): Promise<Request<Ack>> {
const compiled: CompileOutput = await new CompilerFactory(WABT).pickCompiler(program).compile(program, compilerOptions);
return updateModule(compiled.file);
}

Expand Down
6 changes: 3 additions & 3 deletions src/sourcemap/SourceMapFactory.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {getFileExtension} from '../util/util';
import {CompileOutput, CompilerFactory} from '../manage/Compiler';
import {CompileOutput, CompilerFactory, CompilerOptions} from '../manage/Compiler';
import {AsScriptMapper, WatMapper} from './SourceMapper';
import {WABT} from '../util/env';
import {SourceMap} from './SourceMap';
Expand All @@ -13,12 +13,12 @@ export class SourceMapFactory {
this.compilerFactory = new CompilerFactory(WABT);
}

public async map(source: string, tmpdir?: string): Promise<SourceMap.Mapping> {
public async map(source: string, compilerOptions?: CompilerOptions, tmpdir?: string): Promise<SourceMap.Mapping> {
let compiled: CompileOutput;
switch (getFileExtension(source)) {
case 'wast' :
case 'wat' :
compiled = await this.compilerFactory.pickCompiler(source).compile(source);
compiled = await this.compilerFactory.pickCompiler(source).compile(source, compilerOptions);
return new WatMapper(compiled.out ?? '', tmpdir ?? path.dirname(compiled.file), WABT).mapping();
case 'ts' :
return new AsScriptMapper(source ?? '', tmpdir ?? path.dirname(source)).mapping();
Expand Down
6 changes: 3 additions & 3 deletions src/testbeds/TestbedFactory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Testbed} from './Testbed';
import {ARDUINO, EMULATOR, WABT} from '../util/env';
import {CompileOutput, CompilerFactory} from '../manage/Compiler';
import {CompileOutput, CompilerFactory, CompilerOptions} from '../manage/Compiler';
import {DummyProxy, Emulator} from './Emulator';
import {UploaderFactory} from '../manage/Uploader';
import {Connection} from '../bridge/Connection';
Expand All @@ -20,8 +20,8 @@ export class TestbedFactory {
this.uploaderFactory = new UploaderFactory(EMULATOR, ARDUINO);
}

public async initialize(specification: TestbedSpecification, program: string, args: string[]): Promise<Testbed> {
const compiled: CompileOutput = await this.compilerFactory.pickCompiler(program).compile(program).catch((e) => Promise.reject(e));
public async initialize(specification: TestbedSpecification, program: string, args: string[], compilerOptions?: CompilerOptions): Promise<Testbed> {
const compiled: CompileOutput = await this.compilerFactory.pickCompiler(program).compile(program, compilerOptions).catch((e) => Promise.reject(e));
const connection: Connection = await this.uploaderFactory.pickUploader(specification, args).upload(compiled).catch((e) => Promise.reject(e));

switch (specification.type) {
Expand Down
Loading