Implement the core of let/const statement. (#3239)

This patch implements the core part of let/const statements. Redeclarations are correctly
detected and separate contexts are correctly created for these statements. Register
optimizations are also emplyed whenever possible.

Lots of features are still missing:
 - checking the var statements in eval
 - const are treated as lets
 - single statement checks are missing
 - export declarations are exported as vars, let/const export is not supported

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2019-10-25 18:08:10 +02:00
committed by Dániel Bátyai
parent 4b352758c1
commit 3d797b8836
33 changed files with 1997 additions and 217 deletions
@@ -12,4 +12,4 @@
// See the License for the specific language governing permissions and
// limitations under the License.
var let = 1;
var package = 1;
+42
View File
@@ -0,0 +1,42 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var a = 5;
var a = 6;
let b = 7;
assert (a === 6);
assert (this.a === 6);
assert (b === 7);
assert (this.b === undefined);
{
let c;
c = 8;
{
let c = 9;
assert (c === 9);
}
{
function c() { return 10 }
assert (c() === 10);
}
assert (c === 8);
}
assert (typeof c === "undefined");
+44
View File
@@ -0,0 +1,44 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function check_syntax_error (code)
{
try {
eval (code);
assert (false);
} catch (e) {
assert (e instanceof SyntaxError);
}
}
check_syntax_error ("let a; let b; let a");
check_syntax_error ("let a, b, a");
check_syntax_error ("var a; let a;");
check_syntax_error ("var a; const a = 3;");
check_syntax_error ("let a; var a;");
check_syntax_error ("const a = 3; var x, y, a;");
check_syntax_error ("let a; { let b; { var a; } }");
check_syntax_error ("{ { var a = 4; } }; let a = 3");
check_syntax_error ("function a() {}; let a;");
check_syntax_error ("let a; function a() {};");
check_syntax_error ("{ { function a() {}; let a; } }");
check_syntax_error ("{ { let a; function a() {}; } }");
check_syntax_error ("let a = 1; const b = 5; const a = 2;");
check_syntax_error ("try {} catch (e) { let e; }");
check_syntax_error ("try {} catch (e) { const e = 1; }");
check_syntax_error ("let A; class A {}");
check_syntax_error ("const A; class A {}");
check_syntax_error ("class A {}; let A");
check_syntax_error ("class A {}; const A");
+68
View File
@@ -0,0 +1,68 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var g = -1;
function f1() {
/* Function hoisted as var. */
assert (g === undefined);
{
assert (g() === 1);
{
assert (g() === 2);
function g() { return 2 };
}
function g() { return 1 };
assert (g() === 2);
}
assert (g() === 2);
}
f1();
function f2() {
/* Function hoisted as let. */
assert (g === -1);
{
let g = 1;
{
if (true)
{
assert (g() === 2);
if (true)
{
assert (g() === 2);
}
function g() { return 2 };
}
assert (g === 1);
}
assert (g === 1);
}
assert (g === -1);
}
f2();
+68
View File
@@ -0,0 +1,68 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var g = -1;
function f1() {
/* Function hoisted as var. */
assert (g === undefined);
{
assert (g() === 1);
{
eval("assert (g() === 2)");
function g() { return 2 };
}
function g() { return 1 };
assert (g() === 2);
}
assert (g() === 2);
}
f1();
function f2() {
/* Function hoisted as let. */
assert (g === -1);
{
let g = 1;
{
if (true)
{
assert (g() === 2);
if (true)
{
eval("assert (g() === 2)");
}
function g() { return 2 };
}
assert (g === 1);
}
assert (g === 1);
}
assert (g === -1);
}
f2();
+35
View File
@@ -0,0 +1,35 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
let arr = [];
for (var a = 0; a < 10; a++)
{
let j = a;
var f;
{
f = function () { return j; }
let j = (a & 0x1) ? a + 10 : a + 100;
}
arr[j] = f;
}
for (var a = 0; a < 10; a++)
{
assert (arr[a]() == ((a & 0x1) ? a + 10 : a + 100))
}
+79
View File
@@ -0,0 +1,79 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
try {
let a = 1;
eval ("assert(a === 1)");
} catch (e) {
assert (false);
}
assert (typeof a === "undefined");
try {
let a = 2;
eval ("assert(a === 2)");
assert (typeof b === "undefined");
throw 3;
} catch (e) {
let b = e;
eval ("assert(b === 3)");
assert (typeof a === "undefined");
}
assert (typeof a === "undefined");
assert (typeof b === "undefined");
try {
let a = 4;
eval ("assert(a === 4)");
assert (typeof b === "undefined");
} finally {
let b = 5;
eval ("assert(b === 5)");
assert (typeof a === "undefined");
}
assert (typeof a === "undefined");
assert (typeof b === "undefined");
try {
let a = 6;
eval ("assert(a === 6)");
assert (typeof b === "undefined");
assert (typeof c === "undefined");
throw 7;
} catch (e) {
let b = e;
eval ("assert(b === 7)");
assert (typeof a === "undefined");
assert (typeof c === "undefined");
} finally {
let c = 8;
eval ("assert(c === 8)");
assert (typeof a === "undefined");
assert (typeof b === "undefined");
}
assert (typeof a === "undefined");
assert (typeof b === "undefined");
assert (typeof c === "undefined");
+68
View File
@@ -0,0 +1,68 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
assert (typeof f === "undefined");
function g() { return 6; }
switch (g()) {
case f():
let g = 9;
assert (g === 9);
function f() { return 6; }
break;
default:
assert (false);
}
assert (f() === 6);
switch (g()) {
case f() - 2:
let g = 9;
assert ((function() { return g + f(); })() === 17);
function f() { return 8; }
break;
default:
assert (false);
}
assert (f() === 8);
switch (g()) {
case g() * 2:
{
let g = 4;
assert (g == 4);
}
function g() { return 3; }
break;
default:
assert (false);
}
assert (g() === 3);
+58
View File
@@ -0,0 +1,58 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
assert (typeof A === "undefined");
{
class A {};
{
let A = 6;
assert (A === 6);
}
assert (typeof A === "function");
}
assert (typeof A === "undefined");
{
let A = 5;
{
{
class A {};
assert (typeof A === "function");
}
assert (A === 5);
}
}
assert (typeof A === "undefined");
{
let A = 5;
{
{
class A {};
eval ('assert (typeof A === "function")');
}
eval ('assert (A === 5)');
}
}
+25
View File
@@ -0,0 +1,25 @@
// Copyright JS Foundation and other contributors, http://js.foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
function f() {
return 'foo';
}
assert ((function() {
if (1 === 0) {
function f() {
return 'bar';
}
}
return f();
})() === 'bar');
+1 -1
View File
@@ -16,7 +16,7 @@ function f() {
return 'foo';
}
assert ((function() {
if (1 === 0) {
if (1 === 1) {
function f() {
return 'bar';
}
+3 -3
View File
@@ -223,15 +223,15 @@ main (void)
/* Check the snapshot data. Unused bytes should be filled with zeroes */
const uint8_t expected_data[] =
{
0x4A, 0x52, 0x52, 0x59, 0x19, 0x00, 0x00, 0x00,
0x4A, 0x52, 0x52, 0x59, 0x1A, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x03, 0x00, 0x01, 0x00, 0x21, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00,
0x28, 0x00, 0xB7, 0x45, 0x00, 0x00, 0x00, 0x00,
0x2C, 0x00, 0xBC, 0x4A, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x01, 0x00, 0x21, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x01, 0x07, 0x00, 0x00, 0x00,
0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x14, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x73, 0x6E,
0x61, 0x70, 0x73, 0x68, 0x6F, 0x74,