mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-06-12 18:42:14 +00:00
converted workermain to ts, needs loader.js
This commit is contained in:
parent
398103c3b9
commit
c687006684
|
@ -50,7 +50,7 @@ var TOOL_TO_SOURCE_STYLE = {
|
||||||
}
|
}
|
||||||
|
|
||||||
function newWorker() : Worker {
|
function newWorker() : Worker {
|
||||||
return new Worker("./src/worker/workermain.js");
|
return new Worker("./src/worker/loader.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
var userPaused : boolean; // did user explicitly pause?
|
var userPaused : boolean; // did user explicitly pause?
|
||||||
|
|
5
src/worker/loader.js
Normal file
5
src/worker/loader.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var exports = {};
|
||||||
|
importScripts("../../gen/worker/workermain.js");
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
|
import { WorkerResult, WorkerFileUpdate, WorkerBuildStep, WorkerMessage, WorkerError, Dependency } from "../workertypes";
|
||||||
|
|
||||||
|
const emglobal : any = this['window'] || this['global'] || this;
|
||||||
|
declare var WebAssembly;
|
||||||
|
declare function importScripts(path:string);
|
||||||
|
declare function postMessage(msg);
|
||||||
|
|
||||||
var ENVIRONMENT_IS_WEB = typeof window === 'object';
|
var ENVIRONMENT_IS_WEB = typeof window === 'object';
|
||||||
var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
|
var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
|
||||||
|
|
||||||
|
@ -8,7 +14,7 @@ var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
|
||||||
// TODO: leaks memory even when disabled...
|
// TODO: leaks memory even when disabled...
|
||||||
var _WASM_module_cache = {};
|
var _WASM_module_cache = {};
|
||||||
var CACHE_WASM_MODULES = true;
|
var CACHE_WASM_MODULES = true;
|
||||||
function getWASMModule(module_id) {
|
function getWASMModule(module_id:string) {
|
||||||
var module = _WASM_module_cache[module_id];
|
var module = _WASM_module_cache[module_id];
|
||||||
if (!module) {
|
if (!module) {
|
||||||
starttime();
|
starttime();
|
||||||
|
@ -22,7 +28,7 @@ function getWASMModule(module_id) {
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
// function for use with instantiateWasm
|
// function for use with instantiateWasm
|
||||||
function moduleInstFn(module_id) {
|
function moduleInstFn(module_id:string) {
|
||||||
return function(imports,ri) {
|
return function(imports,ri) {
|
||||||
var mod = getWASMModule(module_id);
|
var mod = getWASMModule(module_id);
|
||||||
var inst = new WebAssembly.Instance(mod, imports);
|
var inst = new WebAssembly.Instance(mod, imports);
|
||||||
|
@ -176,32 +182,46 @@ var PLATFORM_PARAMS = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// shim out window and document objects for security
|
|
||||||
// https://github.com/mbostock/d3/issues/1053
|
|
||||||
var noop = function() { return new Function(); };
|
|
||||||
var window = noop();
|
|
||||||
window.CSSStyleDeclaration = noop();
|
|
||||||
window.CSSStyleDeclaration.setProperty = noop();
|
|
||||||
window.Element = noop();
|
|
||||||
window.Element.setAttribute = noop();
|
|
||||||
window.Element.setAttributeNS = noop();
|
|
||||||
window.navigator = noop();
|
|
||||||
var document = noop();
|
|
||||||
document.documentElement = noop();
|
|
||||||
document.documentElement.style = noop();
|
|
||||||
|
|
||||||
var _t1;
|
var _t1;
|
||||||
function starttime() { _t1 = new Date(); }
|
function starttime() { _t1 = new Date(); }
|
||||||
function endtime(msg) { var _t2 = new Date(); console.log(msg, _t2.getTime() - _t1.getTime(), "ms"); }
|
function endtime(msg) { var _t2 = new Date(); console.log(msg, _t2.getTime() - _t1.getTime(), "ms"); }
|
||||||
|
|
||||||
/// working file store and build steps
|
/// working file store and build steps
|
||||||
|
|
||||||
var buildsteps = [];
|
type FileData = string | Uint8Array;
|
||||||
var buildstartseq = 0;
|
|
||||||
var workfs = {};
|
|
||||||
var workerseq = 0;
|
|
||||||
|
|
||||||
function compareData(a,b) {
|
type FileEntry = {
|
||||||
|
path: string
|
||||||
|
encoding: string
|
||||||
|
data: FileData
|
||||||
|
ts: number
|
||||||
|
};
|
||||||
|
|
||||||
|
type BuildOptions = {
|
||||||
|
mainFilePath : string
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
interface BuildStep extends WorkerBuildStep {
|
||||||
|
files? : string[]
|
||||||
|
args? : string[]
|
||||||
|
nextstep? : BuildStep
|
||||||
|
linkstep? : BuildStep
|
||||||
|
params?
|
||||||
|
result?
|
||||||
|
code?
|
||||||
|
generated?
|
||||||
|
prefix?
|
||||||
|
maxts?
|
||||||
|
dependencies?
|
||||||
|
};
|
||||||
|
|
||||||
|
var buildsteps : BuildStep[] = [];
|
||||||
|
var buildstartseq : number = 0;
|
||||||
|
var workfs : {[path:string]:FileEntry} = {};
|
||||||
|
var workerseq : number = 0;
|
||||||
|
|
||||||
|
function compareData(a:FileData, b:FileData) : boolean {
|
||||||
if (a.length != b.length) return false;
|
if (a.length != b.length) return false;
|
||||||
if (typeof a === 'string' && typeof b === 'string')
|
if (typeof a === 'string' && typeof b === 'string')
|
||||||
return a==b;
|
return a==b;
|
||||||
|
@ -214,7 +234,7 @@ function compareData(a,b) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function putWorkFile(path, data) {
|
function putWorkFile(path:string, data:FileData) {
|
||||||
var encoding = (typeof data === 'string') ? 'utf8' : 'binary';
|
var encoding = (typeof data === 'string') ? 'utf8' : 'binary';
|
||||||
var entry = workfs[path];
|
var entry = workfs[path];
|
||||||
if (!entry || !compareData(entry.data, data) || entry.encoding != encoding) {
|
if (!entry || !compareData(entry.data, data) || entry.encoding != encoding) {
|
||||||
|
@ -225,18 +245,18 @@ function putWorkFile(path, data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if file changed during this build step
|
// returns true if file changed during this build step
|
||||||
function wasChanged(entry) {
|
function wasChanged(entry:FileEntry) : boolean {
|
||||||
return entry.ts > buildstartseq;
|
return entry.ts > buildstartseq;
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateEntry(fs, path, entry) {
|
function populateEntry(fs, path:string, entry:FileEntry) {
|
||||||
fs.writeFile(path, entry.data, {encoding:entry.encoding});
|
fs.writeFile(path, entry.data, {encoding:entry.encoding});
|
||||||
fs.utime(path, entry.ts, entry.ts);
|
fs.utime(path, entry.ts, entry.ts);
|
||||||
console.log("<<<", path, entry.data.length);
|
console.log("<<<", path, entry.data.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// can call multiple times (from populateFiles)
|
// can call multiple times (from populateFiles)
|
||||||
function gatherFiles(step, options) {
|
function gatherFiles(step:BuildStep, options?:BuildOptions) {
|
||||||
var maxts = 0;
|
var maxts = 0;
|
||||||
if (step.files) {
|
if (step.files) {
|
||||||
for (var i=0; i<step.files.length; i++) {
|
for (var i=0; i<step.files.length; i++) {
|
||||||
|
@ -246,7 +266,7 @@ function gatherFiles(step, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (step.code) {
|
else if (step.code) {
|
||||||
var path = step.path ? step.path : options.mainFilePath;
|
var path = step.path ? step.path : options.mainFilePath; // TODO: what if options null
|
||||||
if (!path) throw "need path or mainFilePath";
|
if (!path) throw "need path or mainFilePath";
|
||||||
var code = step.code;
|
var code = step.code;
|
||||||
var entry = putWorkFile(path, code);
|
var entry = putWorkFile(path, code);
|
||||||
|
@ -267,7 +287,7 @@ function gatherFiles(step, options) {
|
||||||
return maxts;
|
return maxts;
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateFiles(step, fs, options) {
|
function populateFiles(step:BuildStep, fs, options?:BuildOptions) {
|
||||||
gatherFiles(step, options);
|
gatherFiles(step, options);
|
||||||
if (!step.files) throw "call gatherFiles() first";
|
if (!step.files) throw "call gatherFiles() first";
|
||||||
for (var i=0; i<step.files.length; i++) {
|
for (var i=0; i<step.files.length; i++) {
|
||||||
|
@ -276,7 +296,7 @@ function populateFiles(step, fs, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateExtraFiles(step, fs) {
|
function populateExtraFiles(step:BuildStep, fs) {
|
||||||
// TODO: cache extra files
|
// TODO: cache extra files
|
||||||
var extrafiles = step.params.extrafiles;
|
var extrafiles = step.params.extrafiles;
|
||||||
if (extrafiles) {
|
if (extrafiles) {
|
||||||
|
@ -298,7 +318,7 @@ function populateExtraFiles(step, fs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function staleFiles(step, targets) {
|
function staleFiles(step:BuildStep, targets:string[]) {
|
||||||
if (!step.maxts) throw "call populateFiles() first";
|
if (!step.maxts) throw "call populateFiles() first";
|
||||||
// see if any target files are more recent than inputs
|
// see if any target files are more recent than inputs
|
||||||
for (var i=0; i<targets.length; i++) {
|
for (var i=0; i<targets.length; i++) {
|
||||||
|
@ -310,7 +330,7 @@ function staleFiles(step, targets) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function anyTargetChanged(step, targets) {
|
function anyTargetChanged(step:BuildStep, targets:string[]) {
|
||||||
if (!step.maxts) throw "call populateFiles() first";
|
if (!step.maxts) throw "call populateFiles() first";
|
||||||
// see if any target files are more recent than inputs
|
// see if any target files are more recent than inputs
|
||||||
for (var i=0; i<targets.length; i++) {
|
for (var i=0; i<targets.length; i++) {
|
||||||
|
@ -322,7 +342,7 @@ function anyTargetChanged(step, targets) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function execMain(step, mod, args) {
|
function execMain(step:BuildStep, mod, args:string[]) {
|
||||||
starttime();
|
starttime();
|
||||||
mod.callMain(args);
|
mod.callMain(args);
|
||||||
endtime(step.tool);
|
endtime(step.tool);
|
||||||
|
@ -334,40 +354,43 @@ var fsMeta = {};
|
||||||
var fsBlob = {};
|
var fsBlob = {};
|
||||||
var wasmBlob = {};
|
var wasmBlob = {};
|
||||||
|
|
||||||
|
const PSRC = "../../src/";
|
||||||
|
const PWORKER = PSRC+"worker/";
|
||||||
|
|
||||||
// load filesystems for CC65 and others asynchronously
|
// load filesystems for CC65 and others asynchronously
|
||||||
function loadFilesystem(name) {
|
function loadFilesystem(name:string) {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.responseType = 'blob';
|
xhr.responseType = 'blob';
|
||||||
xhr.open("GET", "fs/fs"+name+".data", false); // synchronous request
|
xhr.open("GET", PWORKER+"fs/fs"+name+".data", false); // synchronous request
|
||||||
xhr.send(null);
|
xhr.send(null);
|
||||||
fsBlob[name] = xhr.response;
|
fsBlob[name] = xhr.response;
|
||||||
xhr = new XMLHttpRequest();
|
xhr = new XMLHttpRequest();
|
||||||
xhr.responseType = 'json';
|
xhr.responseType = 'json';
|
||||||
xhr.open("GET", "fs/fs"+name+".js.metadata", false); // synchronous request
|
xhr.open("GET", PWORKER+"fs/fs"+name+".js.metadata", false); // synchronous request
|
||||||
xhr.send(null);
|
xhr.send(null);
|
||||||
fsMeta[name] = xhr.response;
|
fsMeta[name] = xhr.response;
|
||||||
console.log("Loaded "+name+" filesystem", fsMeta[name].files.length, 'files', fsBlob[name].size, 'bytes');
|
console.log("Loaded "+name+" filesystem", fsMeta[name].files.length, 'files', fsBlob[name].size, 'bytes');
|
||||||
}
|
}
|
||||||
|
|
||||||
var loaded = {}
|
var loaded = {}
|
||||||
function load(modulename, debug) {
|
function load(modulename:string, debug?:boolean) {
|
||||||
if (!loaded[modulename]) {
|
if (!loaded[modulename]) {
|
||||||
importScripts('asmjs/'+modulename+(debug?"."+debug+".js":".js"));
|
importScripts(PWORKER+'asmjs/'+modulename+(debug?"."+debug+".js":".js"));
|
||||||
loaded[modulename] = 1;
|
loaded[modulename] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function loadGen(modulename) {
|
function loadGen(modulename:string) {
|
||||||
if (!loaded[modulename]) {
|
if (!loaded[modulename]) {
|
||||||
importScripts('../../gen/'+modulename+".js");
|
importScripts('../../gen/'+modulename+".js");
|
||||||
loaded[modulename] = 1;
|
loaded[modulename] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function loadWASM(modulename, debug) {
|
function loadWASM(modulename:string, debug?:boolean) {
|
||||||
if (!loaded[modulename]) {
|
if (!loaded[modulename]) {
|
||||||
importScripts("wasm/" + modulename+(debug?"."+debug+".js":".js"));
|
importScripts(PWORKER+"wasm/" + modulename+(debug?"."+debug+".js":".js"));
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.responseType = 'arraybuffer';
|
xhr.responseType = 'arraybuffer';
|
||||||
xhr.open("GET", "wasm/"+modulename+".wasm", false); // synchronous request
|
xhr.open("GET", PWORKER+"wasm/"+modulename+".wasm", false); // synchronous request
|
||||||
xhr.send(null);
|
xhr.send(null);
|
||||||
if (xhr.response) {
|
if (xhr.response) {
|
||||||
wasmBlob[modulename] = new Uint8Array(xhr.response);
|
wasmBlob[modulename] = new Uint8Array(xhr.response);
|
||||||
|
@ -378,7 +401,7 @@ function loadWASM(modulename, debug) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function loadNative(modulename, debug) {
|
function loadNative(modulename:string) {
|
||||||
// detect WASM
|
// detect WASM
|
||||||
if (CACHE_WASM_MODULES && typeof WebAssembly === 'object') {
|
if (CACHE_WASM_MODULES && typeof WebAssembly === 'object') {
|
||||||
loadWASM(modulename);
|
loadWASM(modulename);
|
||||||
|
@ -388,7 +411,7 @@ function loadNative(modulename, debug) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// mount the filesystem at /share
|
// mount the filesystem at /share
|
||||||
function setupFS(FS, name) {
|
function setupFS(FS, name:string) {
|
||||||
var WORKERFS = FS.filesystems['WORKERFS']
|
var WORKERFS = FS.filesystems['WORKERFS']
|
||||||
FS.mkdir('/share');
|
FS.mkdir('/share');
|
||||||
FS.mount(WORKERFS, {
|
FS.mount(WORKERFS, {
|
||||||
|
@ -414,7 +437,7 @@ function setupFS(FS, name) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var print_fn = function(s) {
|
var print_fn = function(s:string) {
|
||||||
console.log(s);
|
console.log(s);
|
||||||
//console.log(new Error().stack);
|
//console.log(new Error().stack);
|
||||||
}
|
}
|
||||||
|
@ -425,15 +448,15 @@ var print_fn = function(s) {
|
||||||
var re_msvc = /[/]*([^( ]+)\s*[(](\d+)[)]\s*:\s*(.+?):\s*(.*)/;
|
var re_msvc = /[/]*([^( ]+)\s*[(](\d+)[)]\s*:\s*(.+?):\s*(.*)/;
|
||||||
var re_msvc2 = /\s*(at)\s+(\d+)\s*(:)\s*(.*)/;
|
var re_msvc2 = /\s*(at)\s+(\d+)\s*(:)\s*(.*)/;
|
||||||
|
|
||||||
function msvcErrorMatcher(errors) {
|
function msvcErrorMatcher(errors:WorkerError[]) {
|
||||||
return function(s) {
|
return function(s:string) {
|
||||||
var matches = re_msvc.exec(s) || re_msvc2.exec(s);
|
var matches = re_msvc.exec(s) || re_msvc2.exec(s);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
var errline = parseInt(matches[2]);
|
var errline = parseInt(matches[2]);
|
||||||
errors.push({
|
errors.push({
|
||||||
line:errline,
|
line:errline,
|
||||||
path:matches[1],
|
path:matches[1],
|
||||||
type:matches[3],
|
//type:matches[3],
|
||||||
msg:matches[4]
|
msg:matches[4]
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -442,7 +465,7 @@ function msvcErrorMatcher(errors) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeErrorMatcher(errors, regex, iline, imsg, path) {
|
function makeErrorMatcher(errors:WorkerError[], regex, iline:number, imsg:number, path:string) {
|
||||||
return function(s) {
|
return function(s) {
|
||||||
var matches = regex.exec(s);
|
var matches = regex.exec(s);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
|
@ -457,7 +480,7 @@ function makeErrorMatcher(errors, regex, iline, imsg, path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractErrors(regex, strings, path) {
|
function extractErrors(regex, strings:string[], path:string) {
|
||||||
var errors = [];
|
var errors = [];
|
||||||
var matcher = makeErrorMatcher(errors, regex, 1, 2, path);
|
var matcher = makeErrorMatcher(errors, regex, 1, 2, path);
|
||||||
for (var i=0; i<strings.length; i++) {
|
for (var i=0; i<strings.length; i++) {
|
||||||
|
@ -470,7 +493,7 @@ function extractErrors(regex, strings, path) {
|
||||||
|
|
||||||
var re_crlf = /\r?\n/;
|
var re_crlf = /\r?\n/;
|
||||||
|
|
||||||
function parseListing(code, lineMatch, iline, ioffset, iinsns) {
|
function parseListing(code:string, lineMatch, iline:number, ioffset:number, iinsns:number) {
|
||||||
var lines = [];
|
var lines = [];
|
||||||
for (var line of code.split(re_crlf)) {
|
for (var line of code.split(re_crlf)) {
|
||||||
var linem = lineMatch.exec(line);
|
var linem = lineMatch.exec(line);
|
||||||
|
@ -490,7 +513,7 @@ function parseListing(code, lineMatch, iline, ioffset, iinsns) {
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseSourceLines(code, lineMatch, offsetMatch) {
|
function parseSourceLines(code:string, lineMatch, offsetMatch) {
|
||||||
var lines = [];
|
var lines = [];
|
||||||
var lastlinenum = 0;
|
var lastlinenum = 0;
|
||||||
for (var line of code.split(re_crlf)) {
|
for (var line of code.split(re_crlf)) {
|
||||||
|
@ -512,7 +535,7 @@ function parseSourceLines(code, lineMatch, offsetMatch) {
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseDASMListing(code, unresolved, mainFilename) {
|
function parseDASMListing(code:string, unresolved:{}, mainFilename:string) {
|
||||||
// 4 08ee a9 00 start lda #01workermain.js:23:5
|
// 4 08ee a9 00 start lda #01workermain.js:23:5
|
||||||
var lineMatch = /\s*(\d+)\s+(\S+)\s+([0-9a-f]+)\s+([?0-9a-f][?0-9a-f ]+)?\s+(.+)?/i;
|
var lineMatch = /\s*(\d+)\s+(\S+)\s+([0-9a-f]+)\s+([?0-9a-f][?0-9a-f ]+)?\s+(.+)?/i;
|
||||||
var equMatch = /\bequ\b/i;
|
var equMatch = /\bequ\b/i;
|
||||||
|
@ -594,11 +617,12 @@ function parseDASMListing(code, unresolved, mainFilename) {
|
||||||
return {lines:lines, macrolines:macrolines, errors:errors};
|
return {lines:lines, macrolines:macrolines, errors:errors};
|
||||||
}
|
}
|
||||||
|
|
||||||
function assembleDASM(step) {
|
function assembleDASM(step:BuildStep) {
|
||||||
load("dasm");
|
load("dasm");
|
||||||
var re_usl = /(\w+)\s+0000\s+[?][?][?][?]/;
|
var re_usl = /(\w+)\s+0000\s+[?][?][?][?]/;
|
||||||
var unresolved = {};
|
var unresolved = {};
|
||||||
var errors = [];
|
var errors = [];
|
||||||
|
var errorMatcher = msvcErrorMatcher(errors);
|
||||||
function match_fn(s) {
|
function match_fn(s) {
|
||||||
var matches = re_usl.exec(s);
|
var matches = re_usl.exec(s);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
|
@ -608,9 +632,11 @@ function assembleDASM(step) {
|
||||||
}
|
}
|
||||||
} else if (s.startsWith("Warning:")) {
|
} else if (s.startsWith("Warning:")) {
|
||||||
errors.push({line:0, msg:s.substr(9)});
|
errors.push({line:0, msg:s.substr(9)});
|
||||||
|
} else {
|
||||||
|
errorMatcher(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var Module = DASM({
|
var Module = emglobal.DASM({
|
||||||
noInitialRun:true,
|
noInitialRun:true,
|
||||||
print:match_fn
|
print:match_fn
|
||||||
});
|
});
|
||||||
|
@ -663,7 +689,7 @@ function assembleDASM(step) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupStdin(fs, code) {
|
function setupStdin(fs, code:string) {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
fs.init(
|
fs.init(
|
||||||
function() { return i<code.length ? code.charCodeAt(i++) : null; }
|
function() { return i<code.length ? code.charCodeAt(i++) : null; }
|
||||||
|
@ -722,7 +748,7 @@ function parseCA65Listing(code, symbols, params, dbg) {
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
function assembleCA65(step) {
|
function assembleCA65(step:BuildStep) {
|
||||||
loadNative("ca65");
|
loadNative("ca65");
|
||||||
var errors = [];
|
var errors = [];
|
||||||
gatherFiles(step, {mainFilePath:"main.s"});
|
gatherFiles(step, {mainFilePath:"main.s"});
|
||||||
|
@ -730,7 +756,7 @@ function assembleCA65(step) {
|
||||||
var lstpath = step.prefix+".lst";
|
var lstpath = step.prefix+".lst";
|
||||||
if (staleFiles(step, [objpath, lstpath])) {
|
if (staleFiles(step, [objpath, lstpath])) {
|
||||||
var objout, lstout;
|
var objout, lstout;
|
||||||
var CA65 = ca65({
|
var CA65 = emglobal.ca65({
|
||||||
instantiateWasm: moduleInstFn('ca65'),
|
instantiateWasm: moduleInstFn('ca65'),
|
||||||
noInitialRun:true,
|
noInitialRun:true,
|
||||||
//logReadFiles:true,
|
//logReadFiles:true,
|
||||||
|
@ -755,7 +781,7 @@ function assembleCA65(step) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function linkLD65(step) {
|
function linkLD65(step:BuildStep) {
|
||||||
loadNative("ld65");
|
loadNative("ld65");
|
||||||
var params = step.params;
|
var params = step.params;
|
||||||
var platform = step.platform;
|
var platform = step.platform;
|
||||||
|
@ -764,7 +790,7 @@ function linkLD65(step) {
|
||||||
if (staleFiles(step, [binpath])) {
|
if (staleFiles(step, [binpath])) {
|
||||||
var errors = [];
|
var errors = [];
|
||||||
var errmsg = '';
|
var errmsg = '';
|
||||||
var LD65 = ld65({
|
var LD65 = emglobal.ld65({
|
||||||
instantiateWasm: moduleInstFn('ld65'),
|
instantiateWasm: moduleInstFn('ld65'),
|
||||||
noInitialRun:true,
|
noInitialRun:true,
|
||||||
//logReadFiles:true,
|
//logReadFiles:true,
|
||||||
|
@ -833,7 +859,7 @@ function linkLD65(step) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function compileCC65(step) {
|
function compileCC65(step:BuildStep) {
|
||||||
load("cc65");
|
load("cc65");
|
||||||
var params = step.params;
|
var params = step.params;
|
||||||
// stderr
|
// stderr
|
||||||
|
@ -854,7 +880,7 @@ function compileCC65(step) {
|
||||||
gatherFiles(step, {mainFilePath:"main.c"});
|
gatherFiles(step, {mainFilePath:"main.c"});
|
||||||
var destpath = step.prefix + '.s';
|
var destpath = step.prefix + '.s';
|
||||||
if (staleFiles(step, [destpath])) {
|
if (staleFiles(step, [destpath])) {
|
||||||
var CC65 = cc65({
|
var CC65 = emglobal.cc65({
|
||||||
noInitialRun:true,
|
noInitialRun:true,
|
||||||
//logReadFiles:true,
|
//logReadFiles:true,
|
||||||
print:print_fn,
|
print:print_fn,
|
||||||
|
@ -911,7 +937,7 @@ function parseIHX(ihx, rom_start, rom_size) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
function assembleSDASZ80(step) {
|
function assembleSDASZ80(step:BuildStep) {
|
||||||
loadNative("sdasz80");
|
loadNative("sdasz80");
|
||||||
var objout, lstout, symout;
|
var objout, lstout, symout;
|
||||||
var errors = [];
|
var errors = [];
|
||||||
|
@ -927,7 +953,7 @@ function assembleSDASZ80(step) {
|
||||||
var match_asm_re2 = / <\w> (.+)/; // TODO
|
var match_asm_re2 = / <\w> (.+)/; // TODO
|
||||||
var errline = 0;
|
var errline = 0;
|
||||||
var errpath = step.path;
|
var errpath = step.path;
|
||||||
function match_asm_fn(s) {
|
var match_asm_fn = (s:string) => {
|
||||||
var m = match_asm_re1.exec(s);
|
var m = match_asm_re1.exec(s);
|
||||||
if (m) {
|
if (m) {
|
||||||
errline = parseInt(m[1]);
|
errline = parseInt(m[1]);
|
||||||
|
@ -943,7 +969,7 @@ function assembleSDASZ80(step) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var ASZ80 = sdasz80({
|
var ASZ80 = emglobal.sdasz80({
|
||||||
instantiateWasm: moduleInstFn('sdasz80'),
|
instantiateWasm: moduleInstFn('sdasz80'),
|
||||||
noInitialRun:true,
|
noInitialRun:true,
|
||||||
//logReadFiles:true,
|
//logReadFiles:true,
|
||||||
|
@ -969,7 +995,7 @@ function assembleSDASZ80(step) {
|
||||||
//symout = FS.readFile("main.sym", {encoding:'utf8'});
|
//symout = FS.readFile("main.sym", {encoding:'utf8'});
|
||||||
}
|
}
|
||||||
|
|
||||||
function linkSDLDZ80(step)
|
function linkSDLDZ80(step:BuildStep)
|
||||||
{
|
{
|
||||||
loadNative("sdldz80");
|
loadNative("sdldz80");
|
||||||
var errors = [];
|
var errors = [];
|
||||||
|
@ -978,7 +1004,7 @@ function linkSDLDZ80(step)
|
||||||
if (staleFiles(step, [binpath])) {
|
if (staleFiles(step, [binpath])) {
|
||||||
//?ASlink-Warning-Undefined Global '__divsint' referenced by module 'main'
|
//?ASlink-Warning-Undefined Global '__divsint' referenced by module 'main'
|
||||||
var match_aslink_re = /\?ASlink-(\w+)-(.+)/;
|
var match_aslink_re = /\?ASlink-(\w+)-(.+)/;
|
||||||
function match_aslink_fn(s) {
|
var match_aslink_fn = (s:string) => {
|
||||||
var matches = match_aslink_re.exec(s);
|
var matches = match_aslink_re.exec(s);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
errors.push({
|
errors.push({
|
||||||
|
@ -988,7 +1014,7 @@ function linkSDLDZ80(step)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var params = step.params;
|
var params = step.params;
|
||||||
var LDZ80 = sdldz80({
|
var LDZ80 = emglobal.sdldz80({
|
||||||
instantiateWasm: moduleInstFn('sdldz80'),
|
instantiateWasm: moduleInstFn('sdldz80'),
|
||||||
noInitialRun:true,
|
noInitialRun:true,
|
||||||
//logReadFiles:true,
|
//logReadFiles:true,
|
||||||
|
@ -1055,7 +1081,7 @@ function linkSDLDZ80(step)
|
||||||
}
|
}
|
||||||
|
|
||||||
var sdcc;
|
var sdcc;
|
||||||
function compileSDCC(step) {
|
function compileSDCC(step:BuildStep) {
|
||||||
|
|
||||||
gatherFiles(step, {
|
gatherFiles(step, {
|
||||||
mainFilePath:"main.c" // not used
|
mainFilePath:"main.c" // not used
|
||||||
|
@ -1076,7 +1102,7 @@ function compileSDCC(step) {
|
||||||
var FS = SDCC['FS'];
|
var FS = SDCC['FS'];
|
||||||
populateFiles(step, FS);
|
populateFiles(step, FS);
|
||||||
// load source file and preprocess
|
// load source file and preprocess
|
||||||
var code = workfs[step.path].data; // TODO
|
var code = workfs[step.path].data as string; // TODO
|
||||||
var preproc = preprocessMCPP(step);
|
var preproc = preprocessMCPP(step);
|
||||||
if (preproc.errors) return preproc;
|
if (preproc.errors) return preproc;
|
||||||
else code = preproc.code;
|
else code = preproc.code;
|
||||||
|
@ -1115,7 +1141,7 @@ function compileSDCC(step) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function preprocessMCPP(step) {
|
function preprocessMCPP(step:BuildStep) {
|
||||||
load("mcpp");
|
load("mcpp");
|
||||||
var platform = step.platform;
|
var platform = step.platform;
|
||||||
var params = PLATFORM_PARAMS[platform];
|
var params = PLATFORM_PARAMS[platform];
|
||||||
|
@ -1123,7 +1149,7 @@ function preprocessMCPP(step) {
|
||||||
// <stdin>:2: error: Can't open include file "foo.h"
|
// <stdin>:2: error: Can't open include file "foo.h"
|
||||||
var errors = [];
|
var errors = [];
|
||||||
var match_fn = makeErrorMatcher(errors, /<stdin>:(\d+): (.+)/, 1, 2, step.path);
|
var match_fn = makeErrorMatcher(errors, /<stdin>:(\d+): (.+)/, 1, 2, step.path);
|
||||||
var MCPP = mcpp({
|
var MCPP = emglobal.mcpp({
|
||||||
noInitialRun:true,
|
noInitialRun:true,
|
||||||
noFSInit:true,
|
noFSInit:true,
|
||||||
print:print_fn,
|
print:print_fn,
|
||||||
|
@ -1166,21 +1192,21 @@ function preprocessMCPP(step) {
|
||||||
|
|
||||||
// TODO: must be a better way to do all this
|
// TODO: must be a better way to do all this
|
||||||
|
|
||||||
function detectModuleName(code) {
|
function detectModuleName(code:string) {
|
||||||
var m = /^\s*module\s+(\w+_top)\b/m.exec(code)
|
var m = /^\s*module\s+(\w+_top)\b/m.exec(code)
|
||||||
|| /^\s*module\s+(top)\b/m.exec(code)
|
|| /^\s*module\s+(top)\b/m.exec(code)
|
||||||
|| /^\s*module\s+(\w+)\b/m.exec(code);
|
|| /^\s*module\s+(\w+)\b/m.exec(code);
|
||||||
return m ? m[1] : null;
|
return m ? m[1] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectTopModuleName(code) {
|
function detectTopModuleName(code:string) {
|
||||||
var topmod = detectModuleName(code) || "top";
|
var topmod = detectModuleName(code) || "top";
|
||||||
var m = /^\s*module\s+(\w+?_top)/m.exec(code);
|
var m = /^\s*module\s+(\w+?_top)/m.exec(code);
|
||||||
if (m && m[1]) topmod = m[1];
|
if (m && m[1]) topmod = m[1];
|
||||||
return topmod;
|
return topmod;
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeDependencies(depends, FS, errors, callback) {
|
function writeDependencies(depends:Dependency[], FS, errors:WorkerError[], callback?) {
|
||||||
if (depends) {
|
if (depends) {
|
||||||
for (var i=0; i<depends.length; i++) {
|
for (var i=0; i<depends.length; i++) {
|
||||||
var d = depends[i];
|
var d = depends[i];
|
||||||
|
@ -1197,9 +1223,9 @@ var jsasm_module_top;
|
||||||
var jsasm_module_output;
|
var jsasm_module_output;
|
||||||
var jsasm_module_key;
|
var jsasm_module_key;
|
||||||
|
|
||||||
function compileJSASM(asmcode, platform, options, is_inline) {
|
function compileJSASM(asmcode:string, platform, options, is_inline) {
|
||||||
loadGen("worker/assembler");
|
loadGen("worker/assembler");
|
||||||
var asm = new Assembler();
|
var asm = new (Assembler as any)();
|
||||||
var includes = [];
|
var includes = [];
|
||||||
asm.loadJSON = function(filename) {
|
asm.loadJSON = function(filename) {
|
||||||
// TODO: what if it comes from dependencies?
|
// TODO: what if it comes from dependencies?
|
||||||
|
@ -1228,7 +1254,7 @@ function compileJSASM(asmcode, platform, options, is_inline) {
|
||||||
var main_filename = includes[includes.length-1];
|
var main_filename = includes[includes.length-1];
|
||||||
var code = '`include "' + main_filename + '"\n';
|
var code = '`include "' + main_filename + '"\n';
|
||||||
code += "/*\nmodule " + top_module + "\n*/\n";
|
code += "/*\nmodule " + top_module + "\n*/\n";
|
||||||
var voutput = compileVerilator({code:code, platform:platform, dependencies:options.dependencies, path:options.path}); // TODO
|
var voutput = compileVerilator({code:code, platform:platform, dependencies:options.dependencies, path:options.path, tool:'verilator'}); // TODO
|
||||||
if (voutput.errors.length)
|
if (voutput.errors.length)
|
||||||
return voutput.errors[0].msg;
|
return voutput.errors[0].msg;
|
||||||
jsasm_module_output = voutput;
|
jsasm_module_output = voutput;
|
||||||
|
@ -1248,14 +1274,14 @@ function compileJSASM(asmcode, platform, options, is_inline) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function compileJSASMStep(step) {
|
function compileJSASMStep(step:BuildStep) {
|
||||||
// TODO
|
// TODO
|
||||||
var code = step.code;
|
var code = step.code;
|
||||||
var platform = step.platform || 'verilog';
|
var platform = step.platform || 'verilog';
|
||||||
return compileJSASM(code, platform, step); // TODO
|
return compileJSASM(code, platform, step, false); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
function compileInlineASM(code, platform, options, errors, asmlines) {
|
function compileInlineASM(code:string, platform, options, errors, asmlines) {
|
||||||
code = code.replace(/__asm\b([\s\S]+?)\b__endasm\b/g, function(s,asmcode,index) {
|
code = code.replace(/__asm\b([\s\S]+?)\b__endasm\b/g, function(s,asmcode,index) {
|
||||||
var firstline = code.substr(0,index).match(/\n/g).length;
|
var firstline = code.substr(0,index).match(/\n/g).length;
|
||||||
var asmout = compileJSASM(asmcode, platform, options, true);
|
var asmout = compileJSASM(asmcode, platform, options, true);
|
||||||
|
@ -1266,7 +1292,7 @@ function compileInlineASM(code, platform, options, errors, asmlines) {
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
} else if (asmout.output) {
|
} else if (asmout.output) {
|
||||||
var s = "";
|
let s = "";
|
||||||
var out = asmout.output;
|
var out = asmout.output;
|
||||||
for (var i=0; i<out.length; i++) {
|
for (var i=0; i<out.length; i++) {
|
||||||
if (i>0) s += ",";
|
if (i>0) s += ",";
|
||||||
|
@ -1286,7 +1312,7 @@ function compileInlineASM(code, platform, options, errors, asmlines) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make compliant with standard msg format
|
// TODO: make compliant with standard msg format
|
||||||
function compileVerilator(step) {
|
function compileVerilator(step:BuildStep) {
|
||||||
loadNative("verilator_bin");
|
loadNative("verilator_bin");
|
||||||
loadGen("worker/verilator2js");
|
loadGen("worker/verilator2js");
|
||||||
var platform = step.platform || 'verilog';
|
var platform = step.platform || 'verilog';
|
||||||
|
@ -1297,8 +1323,8 @@ function compileVerilator(step) {
|
||||||
return {errors:errors};
|
return {errors:errors};
|
||||||
}
|
}
|
||||||
var code = step.code;
|
var code = step.code;
|
||||||
var match_fn = makeErrorMatcher(errors, /%(.+?): (.+?:)?(\d+)?[:]?\s*(.+)/i, 3, 4);
|
var match_fn = makeErrorMatcher(errors, /%(.+?): (.+?:)?(\d+)?[:]?\s*(.+)/i, 3, 4, step.path);
|
||||||
var verilator_mod = verilator_bin({
|
var verilator_mod = emglobal.verilator_bin({
|
||||||
instantiateWasm: moduleInstFn('verilator_bin'),
|
instantiateWasm: moduleInstFn('verilator_bin'),
|
||||||
noInitialRun:true,
|
noInitialRun:true,
|
||||||
print:print_fn,
|
print:print_fn,
|
||||||
|
@ -1336,13 +1362,16 @@ function compileVerilator(step) {
|
||||||
putWorkFile("main.js", rtn.output.code);
|
putWorkFile("main.js", rtn.output.code);
|
||||||
if (!anyTargetChanged(step, ["main.js"]))
|
if (!anyTargetChanged(step, ["main.js"]))
|
||||||
return;
|
return;
|
||||||
rtn.errors = errors;
|
//rtn.intermediate = {listing:h_file + cpp_file}; // TODO
|
||||||
rtn.intermediate = {listing:h_file + cpp_file}; // TODO
|
var listings = {};
|
||||||
rtn.listings = {};
|
|
||||||
// TODO: what if found in non-top-module?
|
// TODO: what if found in non-top-module?
|
||||||
if (asmlines.length)
|
if (asmlines.length)
|
||||||
rtn.listings[step.path] = {lines:asmlines};
|
listings[step.path] = {lines:asmlines};
|
||||||
return rtn;
|
return {
|
||||||
|
output: rtn.output,
|
||||||
|
errors: errors,
|
||||||
|
listings: {},
|
||||||
|
};
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
return {errors:errors};
|
return {errors:errors};
|
||||||
|
@ -1350,13 +1379,13 @@ function compileVerilator(step) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test
|
// TODO: test
|
||||||
function compileYosys(step) {
|
function compileYosys(step:BuildStep) {
|
||||||
loadNative("yosys");
|
loadNative("yosys");
|
||||||
var code = step.code;
|
var code = step.code;
|
||||||
var errors = [];
|
var errors = [];
|
||||||
var match_fn = makeErrorMatcher(errors, /ERROR: (.+?) in line (.+?[.]v):(\d+)[: ]+(.+)/i, 3, 4);
|
var match_fn = makeErrorMatcher(errors, /ERROR: (.+?) in line (.+?[.]v):(\d+)[: ]+(.+)/i, 3, 4, step.path);
|
||||||
starttime();
|
starttime();
|
||||||
var yosys_mod = yosys({
|
var yosys_mod = emglobal.yosys({
|
||||||
instantiateWasm: moduleInstFn('yosys'),
|
instantiateWasm: moduleInstFn('yosys'),
|
||||||
noInitialRun:true,
|
noInitialRun:true,
|
||||||
print:print_fn,
|
print:print_fn,
|
||||||
|
@ -1389,7 +1418,7 @@ function compileYosys(step) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function assembleZMAC(step) {
|
function assembleZMAC(step:BuildStep) {
|
||||||
loadNative("zmac");
|
loadNative("zmac");
|
||||||
var hexout, lstout, binout;
|
var hexout, lstout, binout;
|
||||||
var errors = [];
|
var errors = [];
|
||||||
|
@ -1406,7 +1435,7 @@ error1.asm(11): warning: 'foobar' treated as label (instruction typo?)
|
||||||
Add a colon or move to first column to stop this warning.
|
Add a colon or move to first column to stop this warning.
|
||||||
1 errors (see listing if no diagnostics appeared here)
|
1 errors (see listing if no diagnostics appeared here)
|
||||||
*/
|
*/
|
||||||
var ZMAC = zmac({
|
var ZMAC = emglobal.zmac({
|
||||||
instantiateWasm: moduleInstFn('zmac'),
|
instantiateWasm: moduleInstFn('zmac'),
|
||||||
noInitialRun:true,
|
noInitialRun:true,
|
||||||
//logReadFiles:true,
|
//logReadFiles:true,
|
||||||
|
@ -1490,7 +1519,7 @@ var TOOL_PRELOADFS = {
|
||||||
'sccz80': 'sccz80',
|
'sccz80': 'sccz80',
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyDefaultErrorPath(errors, path) {
|
function applyDefaultErrorPath(errors:WorkerError[], path:string) {
|
||||||
if (!path) return;
|
if (!path) return;
|
||||||
for (var i=0; i<errors.length; i++) {
|
for (var i=0; i<errors.length; i++) {
|
||||||
var err = errors[i];
|
var err = errors[i];
|
|
@ -49,8 +49,16 @@ export interface Dependency {
|
||||||
data:FileData // TODO: or binary?
|
data:FileData // TODO: or binary?
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WorkerFileUpdate { path:string, data:FileData };
|
export interface WorkerFileUpdate {
|
||||||
export interface WorkerBuildStep { path:string, platform:string, tool:string, mainfile?:boolean };
|
path:string,
|
||||||
|
data:FileData
|
||||||
|
};
|
||||||
|
export interface WorkerBuildStep {
|
||||||
|
path?:string
|
||||||
|
platform:string
|
||||||
|
tool:string
|
||||||
|
mainfile?:boolean
|
||||||
|
};
|
||||||
|
|
||||||
export interface WorkerMessage {
|
export interface WorkerMessage {
|
||||||
updates:WorkerFileUpdate[],
|
updates:WorkerFileUpdate[],
|
||||||
|
|
|
@ -5,13 +5,16 @@ var vm = require('vm');
|
||||||
|
|
||||||
var worker = {};
|
var worker = {};
|
||||||
|
|
||||||
|
global.window = global;
|
||||||
|
global.exports = {};
|
||||||
|
|
||||||
global.includeInThisContext = function(path) {
|
global.includeInThisContext = function(path) {
|
||||||
var code = fs.readFileSync(path);
|
var code = fs.readFileSync(path);
|
||||||
vm.runInThisContext(code, path);
|
vm.runInThisContext(code, path);
|
||||||
};
|
};
|
||||||
|
|
||||||
global.importScripts = function(path) {
|
global.importScripts = function(path) {
|
||||||
includeInThisContext('src/worker/'+path);
|
includeInThisContext('gen/worker/'+path);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Blob(blob) {
|
function Blob(blob) {
|
||||||
|
@ -58,7 +61,7 @@ global.FileReaderSync = function() {
|
||||||
global.onmessage = null;
|
global.onmessage = null;
|
||||||
global.postMessage = null;
|
global.postMessage = null;
|
||||||
|
|
||||||
includeInThisContext("src/worker/workermain.js");
|
includeInThisContext("gen/worker/workermain.js");
|
||||||
|
|
||||||
global.ab2str = function(buf) {
|
global.ab2str = function(buf) {
|
||||||
return String.fromCharCode.apply(null, new Uint16Array(buf));
|
return String.fromCharCode.apply(null, new Uint16Array(buf));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user