[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-devel
Subject: [PATCH 3/4] jscript: Add parser support for getters and setters in object initializer.
From: Jacek Caban <jacek () codeweavers ! com>
Date: 2018-11-30 21:44:32
Message-ID: 85c9dda9-7462-780b-872b-13e02988673a () codeweavers ! com
[Download RAW message or body]
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
---
dlls/jscript/engine.h | 6 ++++++
dlls/jscript/lex.c | 17 ++++++++++++++---
dlls/jscript/parser.h | 1 +
dlls/jscript/parser.y | 29 +++++++++++++++++++++--------
dlls/jscript/tests/lang.js | 2 ++
5 files changed, 44 insertions(+), 11 deletions(-)
["0003-jscript-Add-parser-support-for-getters-and-setters-in.diff" (text/x-patch)]
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index d3fd3d776c..d0c419a094 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -129,6 +129,12 @@ typedef struct {
} u;
} instr_t;
+typedef enum {
+ PROPERTY_DEFINITION_VALUE,
+ PROPERTY_DEFINITION_GETTER,
+ PROPERTY_DEFINITION_SETTER
+} property_definition_type_t;
+
typedef struct {
BSTR name;
int ref;
diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c
index 7ef2112dc8..be20e99a3d 100644
--- a/dlls/jscript/lex.c
+++ b/dlls/jscript/lex.c
@@ -46,12 +46,14 @@ static const WCHAR falseW[] = {'f','a','l','s','e',0};
static const WCHAR finallyW[] = {'f','i','n','a','l','l','y',0};
static const WCHAR forW[] = {'f','o','r',0};
static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
+static const WCHAR getW[] = {'g','e','t',0};
static const WCHAR ifW[] = {'i','f',0};
static const WCHAR inW[] = {'i','n',0};
static const WCHAR instanceofW[] = {'i','n','s','t','a','n','c','e','o','f',0};
static const WCHAR newW[] = {'n','e','w',0};
static const WCHAR nullW[] = {'n','u','l','l',0};
static const WCHAR returnW[] = {'r','e','t','u','r','n',0};
+static const WCHAR setW[] = {'s','e','t',0};
static const WCHAR switchW[] = {'s','w','i','t','c','h',0};
static const WCHAR thisW[] = {'t','h','i','s',0};
static const WCHAR throwW[] = {'t','h','r','o','w',0};
@@ -70,11 +72,12 @@ static const struct {
const WCHAR *word;
int token;
BOOL no_nl;
+ unsigned min_version;
} keywords[] = {
- {breakW, kBREAK, TRUE},
+ {breakW, kBREAK, TRUE},
{caseW, kCASE},
{catchW, kCATCH},
- {continueW, kCONTINUE, TRUE},
+ {continueW, kCONTINUE, TRUE},
{defaultW, kDEFAULT},
{deleteW, kDELETE},
{doW, kDO},
@@ -83,12 +86,14 @@ static const struct {
{finallyW, kFINALLY},
{forW, kFOR},
{functionW, kFUNCTION},
+ {getW, kGET, FALSE, SCRIPTLANGUAGEVERSION_ES5},
{ifW, kIF},
{inW, kIN},
{instanceofW, kINSTANCEOF},
{newW, kNEW},
{nullW, kNULL},
- {returnW, kRETURN, TRUE},
+ {returnW, kRETURN, TRUE},
+ {setW, kSET, FALSE, SCRIPTLANGUAGEVERSION_ES5},
{switchW, kSWITCH},
{thisW, kTHIS},
{throwW, kTHROW},
@@ -169,6 +174,12 @@ static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval)
r = check_keyword(ctx, keywords[i].word, lval);
if(!r) {
+ if(ctx->script->version < keywords[i].min_version) {
+ TRACE("ignoring keyword %s in incompatible mode\n",
+ debugstr_w(keywords[i].word));
+ ctx->ptr -= strlenW(keywords[i].word);
+ return 0;
+ }
ctx->implicit_nl_semicolon = keywords[i].no_nl;
return keywords[i].token;
}
diff --git a/dlls/jscript/parser.h b/dlls/jscript/parser.h
index 908d6b6a02..03f504f5b5 100644
--- a/dlls/jscript/parser.h
+++ b/dlls/jscript/parser.h
@@ -359,6 +359,7 @@ typedef struct {
} array_literal_expression_t;
typedef struct _property_definition_t {
+ unsigned type;
literal_t *name;
expression_t *value;
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y
index 47ac1bcce6..157bc187b1 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -45,8 +45,8 @@ typedef struct _property_list_t {
property_definition_t *tail;
} property_list_t;
-static property_definition_t *new_property_definition(parser_ctx_t *ctx, literal_t \
*name,
- expression_t *value);
+static property_definition_t *new_property_definition(parser_ctx_t *ctx, \
property_definition_type_t, + \
literal_t *name, expression_t *value); static property_list_t \
*new_property_list(parser_ctx_t*,property_definition_t*); static property_list_t \
*property_list_add(parser_ctx_t*,property_list_t*,property_definition_t*);
@@ -167,7 +167,7 @@ static source_elements_t \
*source_elements_add_statement(source_elements_t*,state }
/* keywords */
-%token <identifier> kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE \
kFUNCTION kIF kFINALLY kFOR kIN +%token <identifier> kBREAK kCASE kCATCH kCONTINUE \
kDEFAULT kDELETE kDO kELSE kFUNCTION kIF kFINALLY kFOR kGET kIN kSET %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
@@ -224,6 +224,7 @@ static source_elements_t \
*source_elements_add_statement(source_elements_t*,state %type <expr> CallExpression
%type <expr> MemberExpression
%type <expr> PrimaryExpression
+%type <expr> GetterSetterMethod
%type <identifier> Identifier_opt
%type <variable_list> VariableDeclarationList
%type <variable_list> VariableDeclarationListNoIn
@@ -243,7 +244,7 @@ static source_elements_t \
*source_elements_add_statement(source_elements_t*,state %type <property_definition> \
PropertyDefinition %type <literal> PropertyName
%type <literal> BooleanLiteral
-%type <srcptr> KFunction
+%type <srcptr> KFunction left_bracket
%type <ival> AssignOper
%type <identifier> IdentifierName ReservedAsIdentifier
@@ -800,9 +801,17 @@ PropertyNameAndValueList
/* ECMA-262 5.1 Edition 12.2.6 */
PropertyDefinition
: PropertyName ':' AssignmentExpression
- { $$ = new_property_definition(ctx, $1, $3); }
+ { $$ = new_property_definition(ctx, \
PROPERTY_DEFINITION_VALUE, $1, $3); } + | kGET PropertyName GetterSetterMethod
+ { $$ = new_property_definition(ctx, \
PROPERTY_DEFINITION_GETTER, $2, $3); } + | kSET PropertyName \
GetterSetterMethod + { $$ = \
new_property_definition(ctx, PROPERTY_DEFINITION_SETTER, $2, $3); }
-/* ECMA-262 3rd Edition 11.1.5 */
+GetterSetterMethod
+ : left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}'
+ { $$ = new_function_expression(ctx, NULL, $2, $5, \
NULL, $1, $6-$1); } +
+/* Ecma-262 3rd Edition 11.1.5 */
PropertyName
: IdentifierName { $$ = new_string_literal(ctx, $1); }
| tStringLiteral { $$ = new_string_literal(ctx, $1); }
@@ -839,12 +848,14 @@ ReservedAsIdentifier
| kFINALLY { $$ = $1; }
| kFOR { $$ = $1; }
| kFUNCTION { $$ = $1; }
+ | kGET { $$ = $1; }
| kIF { $$ = $1; }
| kIN { $$ = $1; }
| kINSTANCEOF { $$ = $1; }
| kNEW { $$ = $1; }
| kNULL { $$ = $1; }
| kRETURN { $$ = $1; }
+ | kSET { $$ = $1; }
| kSWITCH { $$ = $1; }
| kTHIS { $$ = $1; }
| kTHROW { $$ = $1; }
@@ -878,7 +889,7 @@ semicolon_opt
| error { if(!allow_auto_semicolon(ctx)) {YYABORT;} }
left_bracket
- : '('
+ : '(' { $$ = ctx->ptr; }
| error { set_error(ctx, JS_E_MISSING_LBRACKET); YYABORT; }
right_bracket
@@ -929,10 +940,12 @@ static literal_t *new_null_literal(parser_ctx_t *ctx)
return ret;
}
-static property_definition_t *new_property_definition(parser_ctx_t *ctx, literal_t \
*name, expression_t *value) +static property_definition_t \
*new_property_definition(parser_ctx_t *ctx, property_definition_type_t type, + \
literal_t *name, expression_t *value) {
property_definition_t *ret = parser_alloc(ctx, sizeof(property_definition_t));
+ ret->type = type;
ret->name = name;
ret->value = value;
ret->next = NULL;
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index 1cd5668e25..2a30ea35a7 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -1832,6 +1832,8 @@ ok(tmp, "tmp = " + tmp);
ok(x === undefined, "x = " + x);
})();
+var get, set;
+
/* NoNewline rule parser tests */
while(true) {
if(true) break
[Attachment #4 (text/plain)]
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic