Jacek Caban : jscript: Allow using reserved words as identifiers in ES5 mode.
Alexandre Julliard
julliard at winehq.org
Wed Apr 4 15:08:11 CDT 2018
Module: wine
Branch: master
Commit: 3263d51a1fd86abf195c5be224f6fdb4db284b53
URL: https://source.winehq.org/git/wine.git/?a=commit;h=3263d51a1fd86abf195c5be224f6fdb4db284b53
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Apr 4 21:43:19 2018 +0200
jscript: Allow using reserved words as identifiers in ES5 mode.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/jscript/lex.c | 2 +-
dlls/jscript/parser.y | 58 ++++++++++++++++++++++++++++++++++-----
dlls/mshtml/tests/documentmode.js | 18 ++++++++++++
dlls/mshtml/tests/es5.js | 43 ++++++++++++++++++++++++++++-
4 files changed, 112 insertions(+), 9 deletions(-)
diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c
index 3523958..b4f6d95 100644
--- a/dlls/jscript/lex.c
+++ b/dlls/jscript/lex.c
@@ -135,7 +135,7 @@ static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lva
return 1;
if(lval)
- *lval = ctx->ptr;
+ *lval = word;
ctx->ptr = p1;
return 0;
}
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y
index 59e6757..a40b813 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -164,11 +164,11 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
}
/* keywords */
-%token kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE kIF kFINALLY kFOR kIN
-%token kINSTANCEOF kNEW kNULL kRETURN kSWITCH kTHIS kTHROW kTRUE kFALSE kTRY kTYPEOF kVAR kVOID kWHILE kWITH
+%token <identifier> kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE kFUNCTION kIF kFINALLY kFOR kIN
+%token <identifier> kINSTANCEOF kNEW kNULL kRETURN kSWITCH kTHIS kTHROW kTRUE kFALSE kTRY kTYPEOF kVAR kVOID kWHILE kWITH
%token tANDAND tOROR tINC tDEC tHTMLCOMMENT kDIVEQ kDCOL
-%token <srcptr> kFUNCTION '}'
+%token <srcptr> '}'
/* tokens */
%token <identifier> tIdentifier
@@ -241,6 +241,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
%type <literal> BooleanLiteral
%type <srcptr> KFunction
%type <ival> AssignOper
+%type <identifier> IdentifierName ReservedAsIdentifier
%nonassoc LOWER_THAN_ELSE
%nonassoc kELSE
@@ -272,7 +273,7 @@ FunctionExpression
{ $$ = new_function_expression(ctx, $4, $6, $9, $2, $1, $10-$1+1); }
KFunction
- : kFUNCTION { $$ = $1; }
+ : kFUNCTION { $$ = ctx->ptr - 8; }
/* ECMA-262 3rd Edition 13 */
FunctionBody
@@ -711,7 +712,7 @@ MemberExpression
| FunctionExpression { $$ = $1; }
| MemberExpression '[' Expression ']'
{ $$ = new_binary_expression(ctx, EXPR_ARRAY, $1, $3); }
- | MemberExpression '.' tIdentifier
+ | MemberExpression '.' IdentifierName
{ $$ = new_member_expression(ctx, $1, $3); }
| kNEW MemberExpression Arguments
{ $$ = new_new_expression(ctx, $2, $3); }
@@ -724,7 +725,7 @@ CallExpression
{ $$ = new_call_expression(ctx, $1, $2); }
| CallExpression '[' Expression ']'
{ $$ = new_binary_expression(ctx, EXPR_ARRAY, $1, $3); }
- | CallExpression '.' tIdentifier
+ | CallExpression '.' IdentifierName
{ $$ = new_member_expression(ctx, $1, $3); }
/* ECMA-262 3rd Edition 11.2 */
@@ -787,7 +788,7 @@ PropertyNameAndValueList
/* ECMA-262 3rd Edition 11.1.5 */
PropertyName
- : tIdentifier { $$ = new_string_literal(ctx, $1); }
+ : IdentifierName { $$ = new_string_literal(ctx, $1); }
| tStringLiteral { $$ = new_string_literal(ctx, $1); }
| tNumericLiteral { $$ = $1; }
@@ -796,6 +797,49 @@ Identifier_opt
: /* empty*/ { $$ = NULL; }
| tIdentifier { $$ = $1; }
+/* ECMA-262 5.1 Edition 7.6 */
+IdentifierName
+ : tIdentifier { $$ = $1; }
+ | ReservedAsIdentifier
+ {
+ if(ctx->script->version < SCRIPTLANGUAGEVERSION_ES5) {
+ WARN("%s keyword used as an identifier in legacy mode.\n",
+ debugstr_w($1));
+ YYABORT;
+ }
+ $$ = $1;
+ }
+
+ReservedAsIdentifier
+ : kBREAK { $$ = $1; }
+ | kCASE { $$ = $1; }
+ | kCATCH { $$ = $1; }
+ | kCONTINUE { $$ = $1; }
+ | kDEFAULT { $$ = $1; }
+ | kDELETE { $$ = $1; }
+ | kDO { $$ = $1; }
+ | kELSE { $$ = $1; }
+ | kFALSE { $$ = $1; }
+ | kFINALLY { $$ = $1; }
+ | kFOR { $$ = $1; }
+ | kFUNCTION { $$ = $1; }
+ | kIF { $$ = $1; }
+ | kIN { $$ = $1; }
+ | kINSTANCEOF { $$ = $1; }
+ | kNEW { $$ = $1; }
+ | kNULL { $$ = $1; }
+ | kRETURN { $$ = $1; }
+ | kSWITCH { $$ = $1; }
+ | kTHIS { $$ = $1; }
+ | kTHROW { $$ = $1; }
+ | kTRUE { $$ = $1; }
+ | kTRY { $$ = $1; }
+ | kTYPEOF { $$ = $1; }
+ | kVAR { $$ = $1; }
+ | kVOID { $$ = $1; }
+ | kWHILE { $$ = $1; }
+ | kWITH { $$ = $1; }
+
/* ECMA-262 3rd Edition 7.8 */
Literal
: kNULL { $$ = new_null_literal(ctx); }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index b9ac40e..21a3582 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -116,6 +116,20 @@ function test_javascript() {
ok(!(func in obj), func + " found in " + obj);
}
+ function test_parses(code, expect) {
+ var success;
+ try {
+ eval(code);
+ success = true;
+ }catch(e) {
+ success = false;
+ }
+ if(expect)
+ ok(success === true, code + " did not parse");
+ else
+ ok(success === false, code + " parsed");
+ }
+
var v = document.documentMode;
test_exposed("ScriptEngineMajorVersion", g, true);
@@ -125,6 +139,10 @@ function test_javascript() {
test_exposed("isArray", Array, v >= 9);
test_exposed("indexOf", Array.prototype, v >= 9);
+ test_parses("if(false) { o.default; }", v >= 9);
+ test_parses("if(false) { o.with; }", v >= 9);
+ test_parses("if(false) { o.if; }", v >= 9);
+
next_test();
}
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js
index 9f87e99..9b0dc21 100644
--- a/dlls/mshtml/tests/es5.js
+++ b/dlls/mshtml/tests/es5.js
@@ -73,8 +73,49 @@ function test_isArray() {
next_test();
}
+function test_identifier_keywords() {
+ var o = {
+ if: 1,
+ default: 2,
+ function: 3,
+ break: true,
+ case: true,
+ catch: true,
+ continue: true,
+ delete: true,
+ do: true,
+ else: true,
+ finally: true,
+ for: true,
+ in: true,
+ instanceof: true,
+ new: true,
+ return: true,
+ switch: true,
+ throw: true,
+ try: true,
+ typeof: true,
+ var: true,
+ void: true,
+ while: true,
+ with: true,
+ true: true,
+ false: true,
+ null: true,
+ this: true
+ };
+ function ro() { return o; };
+
+ ok(o.if === 1, "o.if = " + o.if);
+ ok(ro().default === 2, "ro().default = " + ro().default);
+ ok(o.false === true, "o.false = " + o.false);
+
+ next_test();
+}
+
var tests = [
test_date_now,
test_indexOf,
- test_isArray
+ test_isArray,
+ test_identifier_keywords
];
More information about the wine-cvs
mailing list