Skip to content

Commit 8770f7b

Browse files
committed
New ArrayBuffer/TypedArray; Stdlib restructure; Fix importing stdlib in stdlib; Traverse constructors; Allow initialization of readonly instance fields in constructors
1 parent 6268b92 commit 8770f7b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+5182
-2147
lines changed

bin/asc.js

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,54 @@ exports.main = function main(argv, options, callback) {
187187
// Set up base directory
188188
const baseDir = args.baseDir ? path.resolve(args.baseDir) : ".";
189189

190-
// Include custom library components (with or without stdlib)
191-
const customLibDirs = [];
190+
// Begin parsing
191+
var parser = null;
192+
193+
// Include library files
194+
if (!args.noLib) { // bundled
195+
Object.keys(exports.libraryFiles).forEach(libPath => {
196+
if (libPath.indexOf("/") >= 0) return; // in sub-directory: imported on demand
197+
stats.parseCount++;
198+
stats.parseTime += measure(() => {
199+
parser = assemblyscript.parseFile(
200+
exports.libraryFiles[libPath],
201+
exports.libraryPrefix + libPath + ".ts",
202+
false,
203+
parser
204+
);
205+
});
206+
});
207+
}
192208
if (args.lib) {
209+
const customLibDirs = [];
193210
if (typeof args.lib === "string") args.lib = args.lib.split(",");
194211
Array.prototype.push.apply(customLibDirs, args.lib.map(lib => lib.trim()));
212+
for (let i = 0, k = customLibDirs.length; i < k; ++i) { // custom
213+
let libDir = customLibDirs[i];
214+
let libFiles;
215+
if (libDir.endsWith(".ts")) {
216+
libFiles = [ path.basename(libDir) ];
217+
libDir = path.dirname(libDir);
218+
} else {
219+
libFiles = listFiles(libDir);
220+
}
221+
for (let j = 0, l = libFiles.length; j < l; ++j) {
222+
let libPath = libFiles[j];
223+
let libText = readFile(path.join(libDir, libPath));
224+
if (libText === null) return callback(Error("Library file '" + libPath + "' not found."));
225+
stats.parseCount++;
226+
stats.parseTime += measure(() => {
227+
parser = assemblyscript.parseFile(
228+
libText,
229+
exports.libraryPrefix + libPath,
230+
false,
231+
parser
232+
);
233+
});
234+
}
235+
}
195236
}
196237

197-
// Begin parsing
198-
var parser = null;
199-
200238
// Include entry files
201239
for (let i = 0, k = args._.length; i < k; ++i) {
202240
const filename = args._[i];
@@ -221,6 +259,7 @@ exports.main = function main(argv, options, callback) {
221259
parser = assemblyscript.parseFile(sourceText, sourcePath, true, parser);
222260
});
223261

262+
// Process backlog
224263
while ((sourcePath = parser.nextFile()) != null) {
225264
let found = false;
226265

@@ -240,12 +279,10 @@ exports.main = function main(argv, options, callback) {
240279
sourceText = readFile(path.join(dir, plainName + ".ts"));
241280
if (sourceText !== null) {
242281
sourcePath = exports.libraryPrefix + plainName + ".ts";
243-
break;
244282
} else {
245283
sourceText = readFile(path.join(dir, indexName + ".ts"));
246284
if (sourceText !== null) {
247285
sourcePath = exports.libraryPrefix + indexName + ".ts";
248-
break;
249286
}
250287
}
251288
}
@@ -275,12 +312,10 @@ exports.main = function main(argv, options, callback) {
275312
sourceText = readFile(path.join(dir, plainName + ".ts"));
276313
if (sourceText !== null) {
277314
sourcePath = exports.libraryPrefix + plainName + ".ts";
278-
break;
279315
} else {
280316
sourceText = readFile(path.join(dir, indexName + ".ts"));
281317
if (sourceText !== null) {
282318
sourcePath = exports.libraryPrefix + indexName + ".ts";
283-
break;
284319
}
285320
}
286321
}
@@ -301,45 +336,6 @@ exports.main = function main(argv, options, callback) {
301336
}
302337
}
303338

304-
// Include (other) library components
305-
if (!args.noLib) // bundled
306-
Object.keys(exports.libraryFiles).forEach(libPath => {
307-
if (libPath.indexOf("/") >= 0) return; // in sub-directory: imported on demand
308-
stats.parseCount++;
309-
stats.parseTime += measure(() => {
310-
parser = assemblyscript.parseFile(
311-
exports.libraryFiles[libPath],
312-
exports.libraryPrefix + libPath + ".ts",
313-
false,
314-
parser
315-
);
316-
});
317-
});
318-
for (let i = 0, k = customLibDirs.length; i < k; ++i) { // custom
319-
let libDir = customLibDirs[i];
320-
let libFiles;
321-
if (libDir.endsWith(".ts")) {
322-
libFiles = [ path.basename(libDir) ];
323-
libDir = path.dirname(libDir);
324-
} else {
325-
libFiles = listFiles(libDir);
326-
}
327-
for (let j = 0, l = libFiles.length; j < l; ++j) {
328-
let libPath = libFiles[j];
329-
let libText = readFile(path.join(libDir, libPath));
330-
if (libText === null) return callback(Error("Library file '" + libPath + "' not found."));
331-
stats.parseCount++;
332-
stats.parseTime += measure(() => {
333-
parser = assemblyscript.parseFile(
334-
libText,
335-
exports.libraryPrefix + libPath,
336-
false,
337-
parser
338-
);
339-
});
340-
}
341-
}
342-
343339
// Finish parsing
344340
const program = assemblyscript.finishParsing(parser);
345341

dist/asc.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/asc.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/compiler.ts

Lines changed: 39 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ import {
4646
FlowFlags,
4747
CommonFlags,
4848
ConstantValueKind,
49+
Flow,
4950

5051
PATH_DELIMITER,
51-
LIBRARY_PREFIX,
52-
Flow
52+
INNER_DELIMITER
5353
} from "./program";
5454

5555
import {
@@ -220,8 +220,6 @@ export class Compiler extends DiagnosticEmitter {
220220
functionTable: Function[] = new Array();
221221
/** Argument count helper global. */
222222
argumentCountRef: GlobalRef = 0;
223-
/** Already processed file names. */
224-
files: Set<string> = new Set();
225223

226224
/** Compiles a {@link Program} to a {@link Module} using the specified options. */
227225
static compile(program: Program, options: Options | null = null): Module {
@@ -272,16 +270,14 @@ export class Compiler extends DiagnosticEmitter {
272270
var startFunctionBody = this.startFunctionBody;
273271
if (startFunctionBody.length) {
274272
let typeRef = this.ensureFunctionType(startFunctionInstance.signature);
275-
let funcRef: FunctionRef;
276-
module.setStart(
277-
funcRef = module.addFunction(
278-
startFunctionInstance.internalName,
279-
typeRef,
280-
typesToNativeTypes(startFunctionInstance.additionalLocals),
281-
module.createBlock(null, startFunctionBody)
282-
)
273+
let funcRef = module.addFunction(
274+
startFunctionInstance.internalName,
275+
typeRef,
276+
typesToNativeTypes(startFunctionInstance.additionalLocals),
277+
module.createBlock(null, startFunctionBody)
283278
);
284279
startFunctionInstance.finalize(module, funcRef);
280+
module.setStart(funcRef);
285281
}
286282

287283
// set up static memory segments and the heap base pointer
@@ -319,26 +315,26 @@ export class Compiler extends DiagnosticEmitter {
319315
}
320316

321317
// import memory if requested
322-
if (options.importMemory) {
323-
module.addMemoryImport("0", "env", "memory");
324-
}
318+
if (options.importMemory) module.addMemoryImport("0", "env", "memory");
325319

326320
// set up function table
327321
var functionTable = this.functionTable;
328322
var functionTableSize = functionTable.length;
323+
var functionTableExported = false;
329324
if (functionTableSize) {
330325
let entries = new Array<FunctionRef>(functionTableSize);
331326
for (let i = 0; i < functionTableSize; ++i) {
332327
entries[i] = functionTable[i].ref;
333328
}
334329
module.setFunctionTable(entries);
335330
module.addTableExport("0", "table");
331+
functionTableExported = true;
336332
}
337333

338334
// import table if requested
339335
if (options.importTable) {
340336
module.addTableImport("0", "env", "table");
341-
if (!functionTableSize) module.addTableExport("0", "table");
337+
if (!functionTableExported) module.addTableExport("0", "table");
342338
}
343339

344340
return module;
@@ -347,49 +343,20 @@ export class Compiler extends DiagnosticEmitter {
347343
// sources
348344

349345
compileSourceByPath(normalizedPathWithoutExtension: string, reportNode: Node): void {
350-
var sources = this.program.sources;
351-
352-
// try file.ts
353-
var expected = normalizedPathWithoutExtension + ".ts";
354-
for (let i = 0, k = sources.length; i < k; ++i) {
355-
let source = sources[i];
356-
if (source.normalizedPath == expected) {
357-
this.compileSource(source);
358-
return;
359-
}
360-
}
361-
362-
// try file/index.ts
363-
expected = normalizedPathWithoutExtension + "/index.ts";
364-
for (let i = 0, k = sources.length; i < k; ++i) {
365-
let source = sources[i];
366-
if (source.normalizedPath == expected) {
367-
this.compileSource(source);
368-
return;
369-
}
370-
}
371-
372-
// try ~lib/file.ts
373-
expected = LIBRARY_PREFIX + normalizedPathWithoutExtension + ".ts";
374-
for (let i = 0, k = sources.length; i < k; ++i) {
375-
let source = sources[i];
376-
if (source.normalizedPath == expected) {
377-
this.compileSource(source);
378-
return;
379-
}
346+
var source = this.program.lookupSourceByPath(normalizedPathWithoutExtension);
347+
if (!source) {
348+
this.error(
349+
DiagnosticCode.File_0_not_found,
350+
reportNode.range, normalizedPathWithoutExtension
351+
);
352+
return;
380353
}
381-
382-
this.error(
383-
DiagnosticCode.File_0_not_found,
384-
reportNode.range, normalizedPathWithoutExtension
385-
);
354+
this.compileSource(source);
386355
}
387356

388357
compileSource(source: Source): void {
389-
var files = this.files;
390-
var normalizedPath = source.normalizedPath;
391-
if (files.has(normalizedPath)) return;
392-
files.add(normalizedPath);
358+
if (source.is(CommonFlags.COMPILED)) return;
359+
source.set(CommonFlags.COMPILED);
393360

394361
// compile top-level statements
395362
var noTreeShaking = this.options.noTreeShaking;
@@ -1294,11 +1261,11 @@ export class Compiler extends DiagnosticEmitter {
12941261
// otherwise fall-through
12951262
}
12961263
default: {
1297-
assert(false);
12981264
this.error(
12991265
DiagnosticCode.Operation_not_supported,
13001266
statement.range
13011267
);
1268+
assert(false);
13021269
expr = module.createUnreachable();
13031270
break;
13041271
}
@@ -4161,7 +4128,15 @@ export class Compiler extends DiagnosticEmitter {
41614128
}
41624129
}
41634130
case ElementKind.FIELD: {
4164-
if ((<Field>target).is(CommonFlags.READONLY)) {
4131+
const declaration = (<Field>target).declaration;
4132+
if (
4133+
(<Field>target).is(CommonFlags.READONLY) &&
4134+
!(
4135+
this.currentFunction.is(CommonFlags.CONSTRUCTOR) ||
4136+
declaration == null ||
4137+
declaration.initializer != null
4138+
)
4139+
) {
41654140
this.error(
41664141
DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property,
41674142
expression.range, (<Field>target).internalName
@@ -4863,7 +4838,7 @@ export class Compiler extends DiagnosticEmitter {
48634838
var prototype = new FunctionPrototype(
48644839
this.program,
48654840
simpleName,
4866-
currentFunction.internalName + "~" + simpleName,
4841+
currentFunction.internalName + INNER_DELIMITER + simpleName,
48674842
declaration
48684843
);
48694844
var instance = this.compileFunctionUsingTypeArguments(
@@ -5385,7 +5360,13 @@ export class Compiler extends DiagnosticEmitter {
53855360
if (!classInstance) return module.createUnreachable();
53865361

53875362
var expr: ExpressionRef;
5363+
5364+
// traverse to the first matching constructor
5365+
var currentClassInstance: Class | null = classInstance;
53885366
var constructorInstance = classInstance.constructorInstance;
5367+
while (!constructorInstance && (currentClassInstance = classInstance.base)) {
5368+
constructorInstance = currentClassInstance.constructorInstance;
5369+
}
53895370

53905371
// if a constructor is present, call it with a zero `this`
53915372
if (constructorInstance) {

src/index.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,7 @@ import {
4141
export function parseFile(text: string, path: string, isEntry: bool = false,
4242
parser: Parser | null = null
4343
): Parser {
44-
if (!parser) {
45-
parser = new Parser();
46-
isEntry = true;
47-
}
44+
if (!parser) parser = new Parser();
4845
parser.parseFile(text, path, isEntry);
4946
return parser;
5047
}

0 commit comments

Comments
 (0)