Skip to content

Commit

Permalink
fix this in closure error (#141)
Browse files Browse the repository at this point in the history
Signed-off-by: Su Yihan <[email protected]>
  • Loading branch information
yviansu authored Jan 8, 2024
1 parent ab15023 commit 153bc69
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 13 deletions.
14 changes: 8 additions & 6 deletions src/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,16 +436,18 @@ export class Scope {

getRootFunctionScope(): FunctionScope | null {
let currentScope: Scope | null = this;
const flattenScopes: FunctionScope[] = [];
while (currentScope !== null) {
if (
currentScope instanceof FunctionScope &&
currentScope.parent instanceof GlobalScope
) {
return currentScope;
if (currentScope instanceof FunctionScope) {
flattenScopes.push(currentScope);
}
currentScope = currentScope.parent;
}
return null;
if (flattenScopes.length === 0) {
return null;
} else {
return flattenScopes[flattenScopes.length - 1];
}
}

public addDeclareName(name: string) {
Expand Down
15 changes: 8 additions & 7 deletions src/semantics/builder_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,20 +333,21 @@ export class BuildContext {
const var_decl = value.ref as VarDeclareNode;
var_decl.setUsedByClosureFunction();

/* The found varDeclareNode needs a deep copy, since the arribute is different between various scopes */
const new_var_decl = var_decl.copy();
new_var_decl.setUsedByClosureFunction();

new_var_decl.curCtx = curFunc.varList![0];
const newValue = value.copy();
newValue.ref = new_var_decl;
let new_var_decl = var_decl;
let newValue = value;

ownScope = ownScope.getRootFunctionScope()!;
for (let i = env_idx + 1; i < this.stackEnv.length; i++) {
const env = this.stackEnv[i];
if (env.function) {
/* Closure variables can only be used within the same rootFunction */
if (env.scope.getRootFunctionScope()! === ownScope) {
/* The found varDeclareNode needs a deep copy, since the arribute is different between various scopes */
new_var_decl = var_decl.copy();
new_var_decl.setUsedByClosureFunction();
new_var_decl.curCtx = env.function.varList![0];
newValue = value.copy();
newValue.ref = new_var_decl;
env.function.pushClosureVarDeclare(new_var_decl);
if (!env.closures)
env.closures = new Map<SymbolKey, VarValue>();
Expand Down
29 changes: 29 additions & 0 deletions tests/samples/this_in_closure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2023 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/

class Home {
printTag(str:string){
console.log(str);
}
element(id: number) {
console.log(id);
}
render() {
const arr: string[] = ['start', 'stop', 'pause', 'resume']
arr.forEach((val, index, arr) => {
const node_event = {
event: (text: string, hh: number) => {
this.element(hh);
}
}
this.printTag(val);
});
}
}

export function useThisInClosure() {
let home = new Home();
home.render();
}
10 changes: 10 additions & 0 deletions tools/validate/wamr/validation.json
Original file line number Diff line number Diff line change
Expand Up @@ -3799,6 +3799,16 @@
}
]
},
{
"module": "this_in_closure",
"entries": [
{
"name": "useThisInClosure",
"args": [],
"result": "start\nstop\npause\nresume"
}
]
},
{
"module": "this_in_method",
"entries": [
Expand Down

0 comments on commit 153bc69

Please sign in to comment.