Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
ddbb40c
working spread but no initializer
bnbarak Apr 5, 2021
a6647b6
working with a extra statement
bnbarak Apr 5, 2021
05f021b
working when the RHS is an explicit array
bnbarak Apr 5, 2021
ed1ed68
working with real expressions
bnbarak Apr 5, 2021
a01ff10
change const and let to var
bnbarak Apr 5, 2021
f752893
refactor parseDestructedVariable
bnbarak Apr 6, 2021
74363af
remove NA fom ast types
bnbarak Apr 6, 2021
f84773a
clean
bnbarak Apr 6, 2021
2fafa3f
evert format changes
bnbarak Apr 6, 2021
6fbe86f
update compiler test
bnbarak Apr 6, 2021
aeccff7
Remove the need to add a new ast statement DestructVariableStatement
bnbarak Apr 9, 2021
e964621
rename arrayExpression -> expression in parseVariable
bnbarak Apr 10, 2021
5e42cf2
try to cache the return value of a callable ElementAccessExprerssion
bnbarak Apr 12, 2021
0f4ba45
working cached value!
bnbarak Apr 12, 2021
bbad4dd
little tests change
bnbarak Apr 12, 2021
70fedc9
destructingKey cleanups
bnbarak Apr 12, 2021
d7f0a4e
clean ts
bnbarak Apr 12, 2021
b033d8d
self PR review
bnbarak Apr 12, 2021
68ddd7d
try to fix tests
bnbarak Apr 12, 2021
746372e
try to fix tests
bnbarak Apr 12, 2021
8349af3
check if the randomId function messing up the CICD tests
bnbarak Apr 13, 2021
ba5d08b
remove randomId func
bnbarak Apr 13, 2021
aebc9c2
recreate array-destructuring.untouched.wat
bnbarak Apr 13, 2021
0e8b6ec
debug inconsistency in compiling test result in CICD
bnbarak Apr 13, 2021
f5f7466
recreate array-destructuring.untouched.wat
bnbarak Apr 13, 2021
a1e531d
recreate array-destructuring.untouched.wat
bnbarak Apr 13, 2021
d65f62a
recreate array-destructuring.untouched.wat
bnbarak Apr 13, 2021
8a15ed8
clean and add assert trying to cache an expression
bnbarak Apr 15, 2021
e84b645
test the same code without invoking the destruction
bnbarak Apr 15, 2021
9031ef9
test the code without caching
bnbarak Apr 15, 2021
818ca0c
revert caching and tests
bnbarak Apr 15, 2021
ce2d72e
create intermediate variable similar to how TS downgrade es-next to es5
bnbarak Apr 16, 2021
1a34b8a
revert all changes in compiler.ts
bnbarak Apr 16, 2021
f9cfd59
clean
bnbarak Apr 16, 2021
0c5a8d0
pass compiler test
bnbarak Apr 16, 2021
b128afb
remove function counter in the test
bnbarak Apr 16, 2021
3f20244
remove undefined from code and check for name duplicates
bnbarak Apr 19, 2021
3252c6e
comment the code
bnbarak Apr 19, 2021
5821544
add compile/array-destructuring.untouched.wat
bnbarak Apr 19, 2021
f4ba23a
Merge pull request #1 from AssemblyScript/master
bnbarak Apr 19, 2021
1bbd988
Merge branch 'master' of github.com:bnbarak/assemblyscript into bug-1473
bnbarak Apr 19, 2021
005ae7f
rebase from master
bnbarak Apr 19, 2021
6037c6d
revert local js var to old wasm var
bnbarak Apr 21, 2021
e683699
revert local js var to old wasm var
bnbarak Apr 21, 2021
c5cb784
Merge branch 'master' of github.com:bnbarak/assemblyscript into bug-1473
bnbarak Apr 21, 2021
d5e799a
update tests
bnbarak Apr 21, 2021
d0b2417
revert changes - local wasm var instead of local js var
bnbarak Apr 21, 2021
57f4a4a
Merge remote-tracking branch 'origin/bug-1473' into bug-1473
bnbarak Apr 21, 2021
fe88d43
revert changes - local wasm var instead of local js var
bnbarak Apr 21, 2021
7db9b72
revert changes - local wasm var instead of local js var
bnbarak Apr 21, 2021
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
16 changes: 13 additions & 3 deletions src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,10 @@ export abstract class Node {
static createElementAccessExpression(
expression: Expression,
elementExpression: Expression,
range: Range
range: Range,
expressionRefCacheKey: string | null
): ElementAccessExpression {
return new ElementAccessExpression(expression, elementExpression, range);
return new ElementAccessExpression(expression, elementExpression, range, expressionRefCacheKey);
}

static createFalseExpression(
Expand Down Expand Up @@ -721,6 +722,13 @@ export abstract class Node {
return new VariableStatement(decorators, declarations, range);
}

static createDestructedVariableStatement(
decorators: DecoratorNode[] | null,
declarations: VariableDeclaration[],
): VariableStatement {
return new VariableStatement(decorators, declarations, new Range(-1, -1));
}

static createVariableDeclaration(
name: IdentifierExpression,
decorators: DecoratorNode[] | null,
Expand Down Expand Up @@ -1267,7 +1275,9 @@ export class ElementAccessExpression extends Expression {
/** Element of the expression being accessed. */
public elementExpression: Expression,
/** Source range. */
range: Range
range: Range,
/** Key to cache the expressionRef */
public expressionRefCacheKey: string | null
) {
super(NodeKind.ELEMENTACCESS, range);
}
Expand Down
24 changes: 21 additions & 3 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7340,13 +7340,33 @@ export class Compiler extends DiagnosticEmitter {
return this.module.flatten(exprs, this.currentType.toNativeType());
}

private compileExpressionMaybeCached (targetExpression: Expression, type: Type, expressionRefCacheKey: string | null) {
if(expressionRefCacheKey !== null) {
var cachedValue = this.currentFlow.getScopedLocal(expressionRefCacheKey);
if(cachedValue === null) {
var expressionRef = this.currentFlow.addScopedDummyLocalWithIntegerValue(
expressionRefCacheKey,
type,
i64_new(this.compileExpression(targetExpression, type, Constraints.CONV_IMPLICIT))
).constantIntegerValue;
return Number(
expressionRef
);
} else {
return Number(cachedValue.constantIntegerValue);
}
}
return this.compileExpression(targetExpression, type, Constraints.CONV_IMPLICIT);
}

private compileElementAccessExpression(
expression: ElementAccessExpression,
contextualType: Type,
constraints: Constraints
): ExpressionRef {
var module = this.module;
var targetExpression = expression.expression;
var expressionRefCacheKey = expression.expressionRefCacheKey;
var targetType = this.resolver.resolveExpression(targetExpression, this.currentFlow); // reports
if (targetType) {
let classReference = targetType.getClassOrWrapper(this.program);
Expand All @@ -7355,9 +7375,7 @@ export class Compiler extends DiagnosticEmitter {
let indexedGet = classReference.lookupOverload(OperatorKind.INDEXED_GET, isUnchecked);
if (indexedGet) {
let thisType = assert(indexedGet.signature.thisType);
let thisArg = this.compileExpression(targetExpression, thisType,
Constraints.CONV_IMPLICIT
);
let thisArg = this.compileExpressionMaybeCached(targetExpression, thisType, expressionRefCacheKey);
if (!isUnchecked && this.options.pedantic) {
this.pedantic(
DiagnosticCode.Indexed_access_may_involve_bounds_checking,
Expand Down
9 changes: 8 additions & 1 deletion src/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,13 @@ export class Flow {
return scopedDummy;
}

/** Adds a new scoped dummy local of the specified name and initiate a integer value. */
addScopedDummyLocalWithIntegerValue(name: string, type: Type, integerValue: i64): Local {
var local = this.addScopedLocal(name,type);
local.setConstantIntegerValue(integerValue, type);
return local;
}

/** Adds a new scoped alias for the specified local. For example `super` aliased to the `this` local. */
addScopedAlias(name: string, type: Type, index: i32, reportNode: Node | null = null): Local {
var scopedLocals = this.scopedLocals;
Expand Down Expand Up @@ -912,7 +919,7 @@ export class Flow {
let key = _keys[i];
let leftFlags = changetype<FieldFlags>(leftFieldFlags.get(key));
if (
(leftFlags & FieldFlags.INITIALIZED) != 0 && rightFieldFlags.has(key) &&
(leftFlags & FieldFlags.INITIALIZED) != 0 && rightFieldFlags.has(key) &&
(changetype<FieldFlags>(rightFieldFlags.get(key)) & FieldFlags.INITIALIZED)
) {
newFieldFlags.set(key, FieldFlags.INITIALIZED);
Expand Down
79 changes: 66 additions & 13 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*
* @license Apache-2.0
*/

import {
CommonFlags,
LIBRARY_PREFIX,
Expand Down Expand Up @@ -901,6 +900,51 @@ export class Parser extends DiagnosticEmitter {
return null;
}

parseDestructedVariableDeclaration(
tn: Tokenizer,
flags: CommonFlags,
decorators: DecoratorNode[] | null,
startPos: i32,
isFor: bool = false
): VariableStatement | null {
var declarations = new Array<VariableDeclaration>();
if(!tn.skip(Token.OPENBRACKET)) {
return null;
}
do {
const declaration = this.parseVariableDeclaration(tn, flags, decorators, isFor, true);
if(declaration) {
declarations.push(declaration);
} else {
throw new Error("Failed to get declaration");
}
} while (tn.skip(Token.COMMA));
if(!tn.skip(Token.CLOSEBRACKET)){
throw new Error("Destructuring must end with a closing bracket");
}
if(tn.skip(Token.EQUALS)) {
let expression = this.parseExpression(tn);
if(!expression) return null;
expression = this.maybeParseCallExpression(tn, expression);
var expressionRefCacheKey = expression.kind === NodeKind.CALL ?
"_" + ((expression as CallExpression).expression as IdentifierExpression).text : null;

for(let index = 0; index < declarations.length; index++) {
var declaration = declarations[index];
var arrayIndexExpression = Node.createIntegerLiteralExpression(i64_new(index), tn.range());
declaration.initializer = Node.createElementAccessExpression(
expression,
arrayIndexExpression,
tn.range(startPos, tn.pos),
expressionRefCacheKey
);
}
return Node.createDestructedVariableStatement(decorators, declarations);
} else {
throw new Error("RHS does not include =");
}
}

parseVariable(
tn: Tokenizer,
flags: CommonFlags,
Expand All @@ -912,13 +956,18 @@ export class Parser extends DiagnosticEmitter {
// at ('const' | 'let' | 'var'): VariableDeclaration (',' VariableDeclaration)* ';'?

var declarations = new Array<VariableDeclaration>();
do {
let declaration = this.parseVariableDeclaration(tn, flags, decorators, isFor);
if (!declaration) return null;
declarations.push(declaration);
} while (tn.skip(Token.COMMA));
var ret = null;
if(tn.peek() == Token.OPENBRACKET && !isFor) {
ret = this.parseDestructedVariableDeclaration(tn, flags, decorators, startPos, isFor);
} else {
do {
let declaration = this.parseVariableDeclaration(tn, flags, decorators, isFor);
if (!declaration) return null;
declarations.push(declaration);
} while (tn.skip(Token.COMMA));
ret = Node.createVariableStatement(decorators, declarations, tn.range(startPos, tn.pos));
}

var ret = Node.createVariableStatement(decorators, declarations, tn.range(startPos, tn.pos));
tn.skip(Token.SEMICOLON);
return ret;
}
Expand All @@ -927,11 +976,14 @@ export class Parser extends DiagnosticEmitter {
tn: Tokenizer,
parentFlags: CommonFlags,
parentDecorators: DecoratorNode[] | null,
isFor: bool = false
isFor: bool = false,
skipInitializer: boolean = false
): VariableDeclaration | null {

// before: Identifier (':' Type)? ('=' Expression)?

if(tn.peek() == Token.OPENBRACKET) {
return null;
}
if (!tn.skipIdentifier()) {
this.error(
DiagnosticCode.Identifier_expected,
Expand Down Expand Up @@ -965,10 +1017,10 @@ export class Parser extends DiagnosticEmitter {
); // recoverable
}
initializer = this.parseExpression(tn, Precedence.COMMA + 1);
if (!initializer) return null;
if (!initializer && !skipInitializer) return null;
} else if (!isFor) {
if (flags & CommonFlags.CONST) {
if (!(flags & CommonFlags.AMBIENT)) {
if (!skipInitializer && !(flags & CommonFlags.AMBIENT)) {
this.error(
DiagnosticCode._const_declarations_must_be_initialized,
identifier.range
Expand All @@ -982,7 +1034,7 @@ export class Parser extends DiagnosticEmitter {
}
}
var range = Range.join(identifier.range, tn.range());
if (initializer !== null && (flags & CommonFlags.DEFINITELY_ASSIGNED) != 0) {
if (!skipInitializer && initializer !== null && (flags & CommonFlags.DEFINITELY_ASSIGNED) != 0) {
this.error(
DiagnosticCode.A_definite_assignment_assertion_is_not_permitted_in_this_context,
range
Expand Down Expand Up @@ -3996,7 +4048,8 @@ export class Parser extends DiagnosticEmitter {
expr = Node.createElementAccessExpression(
expr,
next,
tn.range(startPos, tn.pos)
tn.range(startPos, tn.pos),
null
);
expr = this.maybeParseCallExpression(tn, expr);
break;
Expand Down
11 changes: 11 additions & 0 deletions src/util/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,3 +405,14 @@ export function indent(sb: string[], level: i32): void {
sb.push(indentX1);
}
}


export function randomId(): string {
var size = 10;
var key = "";
var characters = 'abcdefghijklmnopqrstuvwxyz';
for (var i = 0; i < size; i++ ) {
key += characters.charAt(Math.floor(Math.random() * 26));
}
return key;
}
Loading