lex.c (660f7b90) lex.c (3e2d6582)
1/*
2 * Copyright 2008 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
1/*
2 * Copyright 2008 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include "config.h"
20#include "wine/port.h"
21
22#include <limits.h>
19
20#include <limits.h>
21#include <math.h>
23
24#include "jscript.h"
25#include "activscp.h"
26#include "objsafe.h"
27#include "engine.h"
28#include "parser.h"
29
30#include "parser.tab.h"
31
32#include "wine/debug.h"
22
23#include "jscript.h"
24#include "activscp.h"
25#include "objsafe.h"
26#include "engine.h"
27#include "parser.h"
28
29#include "parser.tab.h"
30
31#include "wine/debug.h"
33#include "wine/unicode.h"
34
32
35#ifdef __REACTOS__
36/* FIXME: Inspect - For some reason these exist in the generated header but are not picked up */
37#define kGET (270)
38#define kSET (272)
39#endif
40
41WINE_DEFAULT_DEBUG_CHANNEL(jscript);
42
33WINE_DEFAULT_DEBUG_CHANNEL(jscript);
34
43static const WCHAR breakW[] = {'b','r','e','a','k',0};
44static const WCHAR caseW[] = {'c','a','s','e',0};
45static const WCHAR catchW[] = {'c','a','t','c','h',0};
46static const WCHAR continueW[] = {'c','o','n','t','i','n','u','e',0};
47static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
48static const WCHAR deleteW[] = {'d','e','l','e','t','e',0};
49static const WCHAR doW[] = {'d','o',0};
50static const WCHAR elseW[] = {'e','l','s','e',0};
51static const WCHAR falseW[] = {'f','a','l','s','e',0};
52static const WCHAR finallyW[] = {'f','i','n','a','l','l','y',0};
53static const WCHAR forW[] = {'f','o','r',0};
54static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
55static const WCHAR getW[] = {'g','e','t',0};
56static const WCHAR ifW[] = {'i','f',0};
57static const WCHAR inW[] = {'i','n',0};
58static const WCHAR instanceofW[] = {'i','n','s','t','a','n','c','e','o','f',0};
59static const WCHAR newW[] = {'n','e','w',0};
60static const WCHAR nullW[] = {'n','u','l','l',0};
61static const WCHAR returnW[] = {'r','e','t','u','r','n',0};
62static const WCHAR setW[] = {'s','e','t',0};
63static const WCHAR switchW[] = {'s','w','i','t','c','h',0};
64static const WCHAR thisW[] = {'t','h','i','s',0};
65static const WCHAR throwW[] = {'t','h','r','o','w',0};
66static const WCHAR trueW[] = {'t','r','u','e',0};
67static const WCHAR tryW[] = {'t','r','y',0};
68static const WCHAR typeofW[] = {'t','y','p','e','o','f',0};
69static const WCHAR varW[] = {'v','a','r',0};
70static const WCHAR voidW[] = {'v','o','i','d',0};
71static const WCHAR whileW[] = {'w','h','i','l','e',0};
72static const WCHAR withW[] = {'w','i','t','h',0};
73
74static const WCHAR elifW[] = {'e','l','i','f',0};
75static const WCHAR endW[] = {'e','n','d',0};
76
77static const struct {
78 const WCHAR *word;
79 int token;
80 BOOL no_nl;
81 unsigned min_version;
82} keywords[] = {
35static const struct {
36 const WCHAR *word;
37 int token;
38 BOOL no_nl;
39 unsigned min_version;
40} keywords[] = {
83 {breakW, kBREAK, TRUE},
84 {caseW, kCASE},
85 {catchW, kCATCH},
86 {continueW, kCONTINUE, TRUE},
87 {defaultW, kDEFAULT},
88 {deleteW, kDELETE},
89 {doW, kDO},
90 {elseW, kELSE},
91 {falseW, kFALSE},
92 {finallyW, kFINALLY},
93 {forW, kFOR},
94 {functionW, kFUNCTION},
95 {getW, kGET, FALSE, SCRIPTLANGUAGEVERSION_ES5},
96 {ifW, kIF},
97 {inW, kIN},
98 {instanceofW, kINSTANCEOF},
99 {newW, kNEW},
100 {nullW, kNULL},
101 {returnW, kRETURN, TRUE},
102 {setW, kSET, FALSE, SCRIPTLANGUAGEVERSION_ES5},
103 {switchW, kSWITCH},
104 {thisW, kTHIS},
105 {throwW, kTHROW},
106 {trueW, kTRUE},
107 {tryW, kTRY},
108 {typeofW, kTYPEOF},
109 {varW, kVAR},
110 {voidW, kVOID},
111 {whileW, kWHILE},
112 {withW, kWITH}
41 {L"break", kBREAK, TRUE},
42 {L"case", kCASE},
43 {L"catch", kCATCH},
44 {L"continue", kCONTINUE, TRUE},
45 {L"default", kDEFAULT},
46 {L"delete", kDELETE},
47 {L"do", kDO},
48 {L"else", kELSE},
49 {L"false", kFALSE},
50 {L"finally", kFINALLY},
51 {L"for", kFOR},
52 {L"function", kFUNCTION},
53 {L"get", kGET, FALSE, SCRIPTLANGUAGEVERSION_ES5},
54 {L"if", kIF},
55 {L"in", kIN},
56 {L"instanceof", kINSTANCEOF},
57 {L"new", kNEW},
58 {L"null", kNULL},
59 {L"return", kRETURN, TRUE},
60 {L"set", kSET, FALSE, SCRIPTLANGUAGEVERSION_ES5},
61 {L"switch", kSWITCH},
62 {L"this", kTHIS},
63 {L"throw", kTHROW},
64 {L"true", kTRUE},
65 {L"try", kTRY},
66 {L"typeof", kTYPEOF},
67 {L"var", kVAR},
68 {L"void", kVOID},
69 {L"while", kWHILE},
70 {L"with", kWITH}
113};
114
115static int lex_error(parser_ctx_t *ctx, HRESULT hres)
116{
117 ctx->hres = hres;
118 ctx->lexer_error = TRUE;
119 return -1;
120}
121
122/* ECMA-262 3rd Edition 7.6 */
123BOOL is_identifier_char(WCHAR c)
124{
71};
72
73static int lex_error(parser_ctx_t *ctx, HRESULT hres)
74{
75 ctx->hres = hres;
76 ctx->lexer_error = TRUE;
77 return -1;
78}
79
80/* ECMA-262 3rd Edition 7.6 */
81BOOL is_identifier_char(WCHAR c)
82{
125 return isalnumW(c) || c == '$' || c == '_' || c == '\\';
83 return iswalnum(c) || c == '$' || c == '_' || c == '\\';
126}
127
128static BOOL is_identifier_first_char(WCHAR c)
129{
84}
85
86static BOOL is_identifier_first_char(WCHAR c)
87{
130 return isalphaW(c) || c == '$' || c == '_' || c == '\\';
88 return iswalpha(c) || c == '$' || c == '_' || c == '\\';
131}
132
133static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lval)
134{
135 const WCHAR *p1 = ctx->ptr;
136 const WCHAR *p2 = word;
137
138 while(p1 < ctx->end && *p2) {

--- 39 unchanged lines hidden (view full) ---

178 while(min <= max) {
179 i = (min+max)/2;
180
181 r = check_keyword(ctx, keywords[i].word, lval);
182 if(!r) {
183 if(ctx->script->version < keywords[i].min_version) {
184 TRACE("ignoring keyword %s in incompatible mode\n",
185 debugstr_w(keywords[i].word));
89}
90
91static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lval)
92{
93 const WCHAR *p1 = ctx->ptr;
94 const WCHAR *p2 = word;
95
96 while(p1 < ctx->end && *p2) {

--- 39 unchanged lines hidden (view full) ---

136 while(min <= max) {
137 i = (min+max)/2;
138
139 r = check_keyword(ctx, keywords[i].word, lval);
140 if(!r) {
141 if(ctx->script->version < keywords[i].min_version) {
142 TRACE("ignoring keyword %s in incompatible mode\n",
143 debugstr_w(keywords[i].word));
186 ctx->ptr -= strlenW(keywords[i].word);
144 ctx->ptr -= lstrlenW(keywords[i].word);
187 return 0;
188 }
189 ctx->implicit_nl_semicolon = keywords[i].no_nl;
190 return keywords[i].token;
191 }
192
193 if(r > 0)
194 min = i+1;

--- 58 unchanged lines hidden (view full) ---

253 return FALSE;
254 }
255
256 return TRUE;
257}
258
259static BOOL skip_spaces(parser_ctx_t *ctx)
260{
145 return 0;
146 }
147 ctx->implicit_nl_semicolon = keywords[i].no_nl;
148 return keywords[i].token;
149 }
150
151 if(r > 0)
152 min = i+1;

--- 58 unchanged lines hidden (view full) ---

211 return FALSE;
212 }
213
214 return TRUE;
215}
216
217static BOOL skip_spaces(parser_ctx_t *ctx)
218{
261 while(ctx->ptr < ctx->end && (isspaceW(*ctx->ptr) || *ctx->ptr == 0xFEFF /* UTF16 BOM */)) {
219 while(ctx->ptr < ctx->end && (iswspace(*ctx->ptr) || *ctx->ptr == 0xFEFF /* UTF16 BOM */)) {
262 if(is_endline(*ctx->ptr++))
263 ctx->nl = TRUE;
264 }
265
266 return ctx->ptr != ctx->end;
267}
268
220 if(is_endline(*ctx->ptr++))
221 ctx->nl = TRUE;
222 }
223
224 return ctx->ptr != ctx->end;
225}
226
269BOOL unescape(WCHAR *str)
227BOOL unescape(WCHAR *str, size_t *len)
270{
228{
271 WCHAR *pd, *p, c;
229 WCHAR *pd, *p, c, *end = str + *len;
272 int i;
273
274 pd = p = str;
230 int i;
231
232 pd = p = str;
275 while(*p) {
233 while(p < end) {
276 if(*p != '\\') {
277 *pd++ = *p++;
278 continue;
279 }
280
234 if(*p != '\\') {
235 *pd++ = *p++;
236 continue;
237 }
238
281 p++;
239 if(++p == end)
240 return FALSE;
282
283 switch(*p) {
284 case '\'':
285 case '\"':
286 case '\\':
287 c = *p;
288 break;
289 case 'b':

--- 7 unchanged lines hidden (view full) ---

297 break;
298 case 'f':
299 c = '\f';
300 break;
301 case 'r':
302 c = '\r';
303 break;
304 case 'x':
241
242 switch(*p) {
243 case '\'':
244 case '\"':
245 case '\\':
246 c = *p;
247 break;
248 case 'b':

--- 7 unchanged lines hidden (view full) ---

256 break;
257 case 'f':
258 c = '\f';
259 break;
260 case 'r':
261 c = '\r';
262 break;
263 case 'x':
264 if(p + 2 >= end)
265 return FALSE;
305 i = hex_to_int(*++p);
306 if(i == -1)
307 return FALSE;
308 c = i << 4;
309
310 i = hex_to_int(*++p);
311 if(i == -1)
312 return FALSE;
313 c += i;
314 break;
315 case 'u':
266 i = hex_to_int(*++p);
267 if(i == -1)
268 return FALSE;
269 c = i << 4;
270
271 i = hex_to_int(*++p);
272 if(i == -1)
273 return FALSE;
274 c += i;
275 break;
276 case 'u':
277 if(p + 4 >= end)
278 return FALSE;
316 i = hex_to_int(*++p);
317 if(i == -1)
318 return FALSE;
319 c = i << 12;
320
321 i = hex_to_int(*++p);
322 if(i == -1)
323 return FALSE;

--- 5 unchanged lines hidden (view full) ---

329 c += i << 4;
330
331 i = hex_to_int(*++p);
332 if(i == -1)
333 return FALSE;
334 c += i;
335 break;
336 default:
279 i = hex_to_int(*++p);
280 if(i == -1)
281 return FALSE;
282 c = i << 12;
283
284 i = hex_to_int(*++p);
285 if(i == -1)
286 return FALSE;

--- 5 unchanged lines hidden (view full) ---

292 c += i << 4;
293
294 i = hex_to_int(*++p);
295 if(i == -1)
296 return FALSE;
297 c += i;
298 break;
299 default:
337 if(isdigitW(*p)) {
300 if(iswdigit(*p)) {
338 c = *p++ - '0';
301 c = *p++ - '0';
339 if(isdigitW(*p)) {
302 if(p < end && iswdigit(*p)) {
340 c = c*8 + (*p++ - '0');
303 c = c*8 + (*p++ - '0');
341 if(isdigitW(*p))
304 if(p < end && iswdigit(*p))
342 c = c*8 + (*p++ - '0');
343 }
344 p--;
345 }
346 else
347 c = *p;
348 }
349
350 *pd++ = c;
351 p++;
352 }
353
305 c = c*8 + (*p++ - '0');
306 }
307 p--;
308 }
309 else
310 c = *p;
311 }
312
313 *pd++ = c;
314 p++;
315 }
316
354 *pd = 0;
317 *len = pd - str;
355 return TRUE;
356}
357
358static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
359{
360 const WCHAR *ptr = ctx->ptr++;
361 WCHAR *wstr;
362 int len;

--- 6 unchanged lines hidden (view full) ---

369 *ret = wstr = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
370 memcpy(wstr, ptr, len*sizeof(WCHAR));
371 wstr[len] = 0;
372
373 /* FIXME: unescape */
374 return tIdentifier;
375}
376
318 return TRUE;
319}
320
321static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
322{
323 const WCHAR *ptr = ctx->ptr++;
324 WCHAR *wstr;
325 int len;

--- 6 unchanged lines hidden (view full) ---

332 *ret = wstr = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
333 memcpy(wstr, ptr, len*sizeof(WCHAR));
334 wstr[len] = 0;
335
336 /* FIXME: unescape */
337 return tIdentifier;
338}
339
377static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret, WCHAR endch)
340static int parse_string_literal(parser_ctx_t *ctx, jsstr_t **ret, WCHAR endch)
378{
341{
379 const WCHAR *ptr = ++ctx->ptr;
380 WCHAR *wstr;
381 int len;
342 const WCHAR *ptr = ++ctx->ptr, *ret_str = ptr;
343 BOOL needs_unescape = FALSE;
344 WCHAR *unescape_str;
345 size_t len;
382
383 while(ctx->ptr < ctx->end && *ctx->ptr != endch) {
346
347 while(ctx->ptr < ctx->end && *ctx->ptr != endch) {
384 if(*ctx->ptr++ == '\\')
348 if(*ctx->ptr++ == '\\') {
385 ctx->ptr++;
349 ctx->ptr++;
350 needs_unescape = TRUE;
351 }
386 }
387
388 if(ctx->ptr == ctx->end)
389 return lex_error(ctx, JS_E_UNTERMINATED_STRING);
390
352 }
353
354 if(ctx->ptr == ctx->end)
355 return lex_error(ctx, JS_E_UNTERMINATED_STRING);
356
391 len = ctx->ptr-ptr;
392
393 *ret = wstr = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
394 memcpy(wstr, ptr, len*sizeof(WCHAR));
395 wstr[len] = 0;
396
357 len = ctx->ptr - ptr;
397 ctx->ptr++;
398
358 ctx->ptr++;
359
399 if(!unescape(wstr)) {
400 WARN("unescape failed\n");
401 return lex_error(ctx, E_FAIL);
360 if(needs_unescape) {
361 ret_str = unescape_str = parser_alloc(ctx, len * sizeof(WCHAR));
362 if(!unescape_str)
363 return lex_error(ctx, E_OUTOFMEMORY);
364 memcpy(unescape_str, ptr, len * sizeof(WCHAR));
365 if(!unescape(unescape_str, &len)) {
366 WARN("unescape failed\n");
367 return lex_error(ctx, E_FAIL);
368 }
402 }
403
369 }
370
371 if(!(*ret = compiler_alloc_string_len(ctx->compiler, ret_str, len)))
372 return lex_error(ctx, E_OUTOFMEMORY);
373
374 /* FIXME: leaking string */
404 return tStringLiteral;
405}
406
407static literal_t *new_double_literal(parser_ctx_t *ctx, DOUBLE d)
408{
409 literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
410
411 ret->type = LT_DOUBLE;

--- 12 unchanged lines hidden (view full) ---

424}
425
426HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
427{
428 const WCHAR *ptr = *iter;
429 LONGLONG d = 0, hlp;
430 int exp = 0;
431
375 return tStringLiteral;
376}
377
378static literal_t *new_double_literal(parser_ctx_t *ctx, DOUBLE d)
379{
380 literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
381
382 ret->type = LT_DOUBLE;

--- 12 unchanged lines hidden (view full) ---

395}
396
397HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
398{
399 const WCHAR *ptr = *iter;
400 LONGLONG d = 0, hlp;
401 int exp = 0;
402
432 while(ptr < end && isdigitW(*ptr)) {
403 while(ptr < end && iswdigit(*ptr)) {
433 hlp = d*10 + *(ptr++) - '0';
434 if(d>MAXLONGLONG/10 || hlp<0) {
435 exp++;
436 break;
437 }
438 else
439 d = hlp;
440 }
404 hlp = d*10 + *(ptr++) - '0';
405 if(d>MAXLONGLONG/10 || hlp<0) {
406 exp++;
407 break;
408 }
409 else
410 d = hlp;
411 }
441 while(ptr < end && isdigitW(*ptr)) {
412 while(ptr < end && iswdigit(*ptr)) {
442 exp++;
443 ptr++;
444 }
445
446 if(*ptr == '.') {
447 ptr++;
448
413 exp++;
414 ptr++;
415 }
416
417 if(*ptr == '.') {
418 ptr++;
419
449 while(ptr < end && isdigitW(*ptr)) {
420 while(ptr < end && iswdigit(*ptr)) {
450 hlp = d*10 + *(ptr++) - '0';
451 if(d>MAXLONGLONG/10 || hlp<0)
452 break;
453
454 d = hlp;
455 exp--;
456 }
421 hlp = d*10 + *(ptr++) - '0';
422 if(d>MAXLONGLONG/10 || hlp<0)
423 break;
424
425 d = hlp;
426 exp--;
427 }
457 while(ptr < end && isdigitW(*ptr))
428 while(ptr < end && iswdigit(*ptr))
458 ptr++;
459 }
460
461 if(ptr < end && (*ptr == 'e' || *ptr == 'E')) {
462 int sign = 1, e = 0;
463
464 if(++ptr < end) {
465 if(*ptr == '+') {
466 ptr++;
467 }else if(*ptr == '-') {
468 sign = -1;
469 ptr++;
429 ptr++;
430 }
431
432 if(ptr < end && (*ptr == 'e' || *ptr == 'E')) {
433 int sign = 1, e = 0;
434
435 if(++ptr < end) {
436 if(*ptr == '+') {
437 ptr++;
438 }else if(*ptr == '-') {
439 sign = -1;
440 ptr++;
470 }else if(!isdigitW(*ptr)) {
441 }else if(!iswdigit(*ptr)) {
471 WARN("Expected exponent part\n");
472 return E_FAIL;
473 }
474 }
475
476 if(ptr == end) {
477 WARN("unexpected end of file\n");
478 return E_FAIL;
479 }
480
442 WARN("Expected exponent part\n");
443 return E_FAIL;
444 }
445 }
446
447 if(ptr == end) {
448 WARN("unexpected end of file\n");
449 return E_FAIL;
450 }
451
481 while(ptr < end && isdigitW(*ptr)) {
452 while(ptr < end && iswdigit(*ptr)) {
482 if(e > INT_MAX/10 || (e = e*10 + *ptr++ - '0')<0)
483 e = INT_MAX;
484 }
485 e *= sign;
486
487 if(exp<0 && e<0 && e+exp>0) exp = INT_MIN;
488 else if(exp>0 && e>0 && e+exp<0) exp = INT_MAX;
489 else exp += e;

--- 34 unchanged lines hidden (view full) ---

524 lex_error(ctx, JS_E_MISSING_SEMICOLON);
525 return FALSE;
526 }
527
528 *ret = r;
529 return TRUE;
530 }
531
453 if(e > INT_MAX/10 || (e = e*10 + *ptr++ - '0')<0)
454 e = INT_MAX;
455 }
456 e *= sign;
457
458 if(exp<0 && e<0 && e+exp>0) exp = INT_MIN;
459 else if(exp>0 && e>0 && e+exp<0) exp = INT_MAX;
460 else exp += e;

--- 34 unchanged lines hidden (view full) ---

495 lex_error(ctx, JS_E_MISSING_SEMICOLON);
496 return FALSE;
497 }
498
499 *ret = r;
500 return TRUE;
501 }
502
532 if(isdigitW(*ctx->ptr)) {
503 if(iswdigit(*ctx->ptr)) {
533 unsigned base = 8;
534 const WCHAR *ptr;
535 double val = 0;
536
504 unsigned base = 8;
505 const WCHAR *ptr;
506 double val = 0;
507
537 for(ptr = ctx->ptr; ptr < ctx->end && isdigitW(*ptr); ptr++) {
508 for(ptr = ctx->ptr; ptr < ctx->end && iswdigit(*ptr); ptr++) {
538 if(*ptr > '7') {
539 base = 10;
540 break;
541 }
542 }
543
544 do {
545 val = val*base + *ctx->ptr-'0';
509 if(*ptr > '7') {
510 base = 10;
511 break;
512 }
513 }
514
515 do {
516 val = val*base + *ctx->ptr-'0';
546 }while(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr));
517 }while(++ctx->ptr < ctx->end && iswdigit(*ctx->ptr));
547
548 /* FIXME: Do we need it here? */
549 if(ctx->ptr < ctx->end && (is_identifier_char(*ctx->ptr) || *ctx->ptr == '.')) {
550 WARN("wrong char after octal literal: '%c'\n", *ctx->ptr);
551 lex_error(ctx, JS_E_MISSING_SEMICOLON);
552 return FALSE;
553 }
554

--- 25 unchanged lines hidden (view full) ---

580 }while(skip_comment(ctx) || skip_html_comment(ctx));
581
582 if(ctx->implicit_nl_semicolon) {
583 if(ctx->nl)
584 return ';';
585 ctx->implicit_nl_semicolon = FALSE;
586 }
587
518
519 /* FIXME: Do we need it here? */
520 if(ctx->ptr < ctx->end && (is_identifier_char(*ctx->ptr) || *ctx->ptr == '.')) {
521 WARN("wrong char after octal literal: '%c'\n", *ctx->ptr);
522 lex_error(ctx, JS_E_MISSING_SEMICOLON);
523 return FALSE;
524 }
525

--- 25 unchanged lines hidden (view full) ---

551 }while(skip_comment(ctx) || skip_html_comment(ctx));
552
553 if(ctx->implicit_nl_semicolon) {
554 if(ctx->nl)
555 return ';';
556 ctx->implicit_nl_semicolon = FALSE;
557 }
558
588 if(isalphaW(*ctx->ptr)) {
559 if(iswalpha(*ctx->ptr)) {
589 int ret = check_keywords(ctx, lval);
590 if(ret)
591 return ret;
592
593 return parse_identifier(ctx, lval);
594 }
595
560 int ret = check_keywords(ctx, lval);
561 if(ret)
562 return ret;
563
564 return parse_identifier(ctx, lval);
565 }
566
596 if(isdigitW(*ctx->ptr)) {
567 if(iswdigit(*ctx->ptr)) {
597 double n;
598
599 if(!parse_numeric_literal(ctx, &n))
600 return -1;
601
602 *(literal_t**)lval = new_double_literal(ctx, n);
603 return tNumericLiteral;
604 }

--- 10 unchanged lines hidden (view full) ---

615 case '?':
616 return *ctx->ptr++;
617
618 case '}':
619 *(const WCHAR**)lval = ctx->ptr++;
620 return '}';
621
622 case '.':
568 double n;
569
570 if(!parse_numeric_literal(ctx, &n))
571 return -1;
572
573 *(literal_t**)lval = new_double_literal(ctx, n);
574 return tNumericLiteral;
575 }

--- 10 unchanged lines hidden (view full) ---

586 case '?':
587 return *ctx->ptr++;
588
589 case '}':
590 *(const WCHAR**)lval = ctx->ptr++;
591 return '}';
592
593 case '.':
623 if(ctx->ptr+1 < ctx->end && isdigitW(ctx->ptr[1])) {
594 if(ctx->ptr+1 < ctx->end && iswdigit(ctx->ptr[1])) {
624 double n;
625 HRESULT hres;
626 hres = parse_decimal(&ctx->ptr, ctx->end, &n);
627 if(FAILED(hres)) {
628 lex_error(ctx, hres);
629 return -1;
630 }
631 *(literal_t**)lval = new_double_literal(ctx, n);

--- 223 unchanged lines hidden (view full) ---

855 heap_free(cc);
856}
857
858static BOOL new_cc_var(cc_ctx_t *cc, const WCHAR *name, int len, ccval_t v)
859{
860 cc_var_t *new_v;
861
862 if(len == -1)
595 double n;
596 HRESULT hres;
597 hres = parse_decimal(&ctx->ptr, ctx->end, &n);
598 if(FAILED(hres)) {
599 lex_error(ctx, hres);
600 return -1;
601 }
602 *(literal_t**)lval = new_double_literal(ctx, n);

--- 223 unchanged lines hidden (view full) ---

826 heap_free(cc);
827}
828
829static BOOL new_cc_var(cc_ctx_t *cc, const WCHAR *name, int len, ccval_t v)
830{
831 cc_var_t *new_v;
832
833 if(len == -1)
863 len = strlenW(name);
834 len = lstrlenW(name);
864
865 new_v = heap_alloc(sizeof(cc_var_t) + (len+1)*sizeof(WCHAR));
866 if(!new_v)
867 return FALSE;
868
869 new_v->val = v;
870 memcpy(new_v->name, name, (len+1)*sizeof(WCHAR));
871 new_v->name_len = len;

--- 13 unchanged lines hidden (view full) ---

885
886 return NULL;
887}
888
889static BOOL init_cc(parser_ctx_t *ctx)
890{
891 cc_ctx_t *cc;
892
835
836 new_v = heap_alloc(sizeof(cc_var_t) + (len+1)*sizeof(WCHAR));
837 if(!new_v)
838 return FALSE;
839
840 new_v->val = v;
841 memcpy(new_v->name, name, (len+1)*sizeof(WCHAR));
842 new_v->name_len = len;

--- 13 unchanged lines hidden (view full) ---

856
857 return NULL;
858}
859
860static BOOL init_cc(parser_ctx_t *ctx)
861{
862 cc_ctx_t *cc;
863
893 static const WCHAR _win32W[] = {'_','w','i','n','3','2',0};
894 static const WCHAR _win64W[] = {'_','w','i','n','6','4',0};
895 static const WCHAR _x86W[] = {'_','x','8','6',0};
896 static const WCHAR _amd64W[] = {'_','a','m','d','6','4',0};
897 static const WCHAR _jscriptW[] = {'_','j','s','c','r','i','p','t',0};
898 static const WCHAR _jscript_buildW[] = {'_','j','s','c','r','i','p','t','_','b','u','i','l','d',0};
899 static const WCHAR _jscript_versionW[] = {'_','j','s','c','r','i','p','t','_','v','e','r','s','i','o','n',0};
900
901 if(ctx->script->cc)
902 return TRUE;
903
904 cc = heap_alloc(sizeof(cc_ctx_t));
905 if(!cc) {
906 lex_error(ctx, E_OUTOFMEMORY);
907 return FALSE;
908 }
909
910 cc->vars = NULL;
911
864 if(ctx->script->cc)
865 return TRUE;
866
867 cc = heap_alloc(sizeof(cc_ctx_t));
868 if(!cc) {
869 lex_error(ctx, E_OUTOFMEMORY);
870 return FALSE;
871 }
872
873 cc->vars = NULL;
874
912 if(!new_cc_var(cc, _jscriptW, -1, ccval_bool(TRUE))
913 || !new_cc_var(cc, sizeof(void*) == 8 ? _win64W : _win32W, -1, ccval_bool(TRUE))
914 || !new_cc_var(cc, sizeof(void*) == 8 ? _amd64W : _x86W, -1, ccval_bool(TRUE))
915 || !new_cc_var(cc, _jscript_versionW, -1, ccval_num(JSCRIPT_MAJOR_VERSION + (DOUBLE)JSCRIPT_MINOR_VERSION/10.0))
916 || !new_cc_var(cc, _jscript_buildW, -1, ccval_num(JSCRIPT_BUILD_VERSION))) {
875 if(!new_cc_var(cc, L"_jscript", -1, ccval_bool(TRUE))
876 || !new_cc_var(cc, sizeof(void*) == 8 ? L"_win64" : L"_win32", -1, ccval_bool(TRUE))
877 || !new_cc_var(cc, sizeof(void*) == 8 ? L"_amd64" : L"_x86", -1, ccval_bool(TRUE))
878 || !new_cc_var(cc, L"_jscript_version", -1, ccval_num(JSCRIPT_MAJOR_VERSION + (DOUBLE)JSCRIPT_MINOR_VERSION/10.0))
879 || !new_cc_var(cc, L"_jscript_build", -1, ccval_num(JSCRIPT_BUILD_VERSION))) {
917 release_cc(cc);
918 lex_error(ctx, E_OUTOFMEMORY);
919 return FALSE;
920 }
921
922 ctx->script->cc = cc;
923 return TRUE;
924}

--- 16 unchanged lines hidden (view full) ---

941 return TRUE;
942}
943
944int try_parse_ccval(parser_ctx_t *ctx, ccval_t *r)
945{
946 if(!skip_spaces(ctx))
947 return -1;
948
880 release_cc(cc);
881 lex_error(ctx, E_OUTOFMEMORY);
882 return FALSE;
883 }
884
885 ctx->script->cc = cc;
886 return TRUE;
887}

--- 16 unchanged lines hidden (view full) ---

904 return TRUE;
905}
906
907int try_parse_ccval(parser_ctx_t *ctx, ccval_t *r)
908{
909 if(!skip_spaces(ctx))
910 return -1;
911
949 if(isdigitW(*ctx->ptr)) {
912 if(iswdigit(*ctx->ptr)) {
950 double n;
951
952 if(!parse_numeric_literal(ctx, &n))
953 return -1;
954
955 *r = ccval_num(n);
956 return 1;
957 }

--- 6 unchanged lines hidden (view full) ---

964 if(!parse_cc_identifier(ctx, &ident, &ident_len))
965 return -1;
966
967 cc_var = find_cc_var(ctx->script->cc, ident, ident_len);
968 *r = cc_var ? cc_var->val : ccval_num(NAN);
969 return 1;
970 }
971
913 double n;
914
915 if(!parse_numeric_literal(ctx, &n))
916 return -1;
917
918 *r = ccval_num(n);
919 return 1;
920 }

--- 6 unchanged lines hidden (view full) ---

927 if(!parse_cc_identifier(ctx, &ident, &ident_len))
928 return -1;
929
930 cc_var = find_cc_var(ctx->script->cc, ident, ident_len);
931 *r = cc_var ? cc_var->val : ccval_num(NAN);
932 return 1;
933 }
934
972 if(!check_keyword(ctx, trueW, NULL)) {
935 if(!check_keyword(ctx, L"true", NULL)) {
973 *r = ccval_bool(TRUE);
974 return 1;
975 }
976
936 *r = ccval_bool(TRUE);
937 return 1;
938 }
939
977 if(!check_keyword(ctx, falseW, NULL)) {
940 if(!check_keyword(ctx, L"false", NULL)) {
978 *r = ccval_bool(FALSE);
979 return 1;
980 }
981
982 return 0;
983}
984
985static int skip_code(parser_ctx_t *ctx, BOOL exec_else)
986{
987 int if_depth = 1;
988 const WCHAR *ptr;
989
990 while(1) {
941 *r = ccval_bool(FALSE);
942 return 1;
943 }
944
945 return 0;
946}
947
948static int skip_code(parser_ctx_t *ctx, BOOL exec_else)
949{
950 int if_depth = 1;
951 const WCHAR *ptr;
952
953 while(1) {
991 ptr = strchrW(ctx->ptr, '@');
954 ptr = wcschr(ctx->ptr, '@');
992 if(!ptr) {
993 WARN("No @end\n");
994 return lex_error(ctx, JS_E_EXPECTED_CCEND);
995 }
996 ctx->ptr = ptr+1;
997
955 if(!ptr) {
956 WARN("No @end\n");
957 return lex_error(ctx, JS_E_EXPECTED_CCEND);
958 }
959 ctx->ptr = ptr+1;
960
998 if(!check_keyword(ctx, endW, NULL)) {
961 if(!check_keyword(ctx, L"end", NULL)) {
999 if(--if_depth)
1000 continue;
1001 return 0;
1002 }
1003
962 if(--if_depth)
963 continue;
964 return 0;
965 }
966
1004 if(exec_else && !check_keyword(ctx, elifW, NULL)) {
967 if(exec_else && !check_keyword(ctx, L"elif", NULL)) {
1005 if(if_depth > 1)
1006 continue;
1007
1008 if(!skip_spaces(ctx) || *ctx->ptr != '(')
1009 return lex_error(ctx, JS_E_MISSING_LBRACKET);
1010
1011 if(!parse_cc_expr(ctx))
1012 return -1;
1013
1014 if(!get_ccbool(ctx->ccval))
1015 continue; /* skip block of code */
1016
1017 /* continue parsing */
1018 ctx->cc_if_depth++;
1019 return 0;
1020 }
1021
968 if(if_depth > 1)
969 continue;
970
971 if(!skip_spaces(ctx) || *ctx->ptr != '(')
972 return lex_error(ctx, JS_E_MISSING_LBRACKET);
973
974 if(!parse_cc_expr(ctx))
975 return -1;
976
977 if(!get_ccbool(ctx->ccval))
978 continue; /* skip block of code */
979
980 /* continue parsing */
981 ctx->cc_if_depth++;
982 return 0;
983 }
984
1022 if(exec_else && !check_keyword(ctx, elseW, NULL)) {
985 if(exec_else && !check_keyword(ctx, L"else", NULL)) {
1023 if(if_depth > 1)
1024 continue;
1025
1026 /* parse else block */
1027 ctx->cc_if_depth++;
1028 return 0;
1029 }
1030
986 if(if_depth > 1)
987 continue;
988
989 /* parse else block */
990 ctx->cc_if_depth++;
991 return 0;
992 }
993
1031 if(!check_keyword(ctx, ifW, NULL)) {
994 if(!check_keyword(ctx, L"if", NULL)) {
1032 if_depth++;
1033 continue;
1034 }
1035
1036 ctx->ptr++;
1037 }
1038}
1039
1040static int cc_token(parser_ctx_t *ctx, void *lval)
1041{
1042 unsigned id_len = 0;
1043 cc_var_t *var;
1044
995 if_depth++;
996 continue;
997 }
998
999 ctx->ptr++;
1000 }
1001}
1002
1003static int cc_token(parser_ctx_t *ctx, void *lval)
1004{
1005 unsigned id_len = 0;
1006 cc_var_t *var;
1007
1045 static const WCHAR cc_onW[] = {'c','c','_','o','n',0};
1046 static const WCHAR setW[] = {'s','e','t',0};
1047
1048 ctx->ptr++;
1049
1008 ctx->ptr++;
1009
1050 if(!check_keyword(ctx, cc_onW, NULL))
1010 if(!check_keyword(ctx, L"cc_on", NULL))
1051 return init_cc(ctx) ? 0 : -1;
1052
1011 return init_cc(ctx) ? 0 : -1;
1012
1053 if(!check_keyword(ctx, setW, NULL)) {
1013 if(!check_keyword(ctx, L"set", NULL)) {
1054 const WCHAR *ident;
1055 unsigned ident_len;
1056 cc_var_t *var;
1057
1058 if(!init_cc(ctx))
1059 return -1;
1060
1061 if(!skip_spaces(ctx))

--- 17 unchanged lines hidden (view full) ---

1079 }else {
1080 if(!new_cc_var(ctx->script->cc, ident, ident_len, ctx->ccval))
1081 return lex_error(ctx, E_OUTOFMEMORY);
1082 }
1083
1084 return 0;
1085 }
1086
1014 const WCHAR *ident;
1015 unsigned ident_len;
1016 cc_var_t *var;
1017
1018 if(!init_cc(ctx))
1019 return -1;
1020
1021 if(!skip_spaces(ctx))

--- 17 unchanged lines hidden (view full) ---

1039 }else {
1040 if(!new_cc_var(ctx->script->cc, ident, ident_len, ctx->ccval))
1041 return lex_error(ctx, E_OUTOFMEMORY);
1042 }
1043
1044 return 0;
1045 }
1046
1087 if(!check_keyword(ctx, ifW, NULL)) {
1047 if(!check_keyword(ctx, L"if", NULL)) {
1088 if(!init_cc(ctx))
1089 return -1;
1090
1091 if(!skip_spaces(ctx) || *ctx->ptr != '(')
1092 return lex_error(ctx, JS_E_MISSING_LBRACKET);
1093
1094 if(!parse_cc_expr(ctx))
1095 return -1;
1096
1097 if(get_ccbool(ctx->ccval)) {
1098 /* continue parsing block inside if */
1099 ctx->cc_if_depth++;
1100 return 0;
1101 }
1102
1103 return skip_code(ctx, TRUE);
1104 }
1105
1048 if(!init_cc(ctx))
1049 return -1;
1050
1051 if(!skip_spaces(ctx) || *ctx->ptr != '(')
1052 return lex_error(ctx, JS_E_MISSING_LBRACKET);
1053
1054 if(!parse_cc_expr(ctx))
1055 return -1;
1056
1057 if(get_ccbool(ctx->ccval)) {
1058 /* continue parsing block inside if */
1059 ctx->cc_if_depth++;
1060 return 0;
1061 }
1062
1063 return skip_code(ctx, TRUE);
1064 }
1065
1106 if(!check_keyword(ctx, elifW, NULL) || !check_keyword(ctx, elseW, NULL)) {
1066 if(!check_keyword(ctx, L"elif", NULL) || !check_keyword(ctx, L"else", NULL)) {
1107 if(!ctx->cc_if_depth)
1108 return lex_error(ctx, JS_E_SYNTAX);
1109
1110 return skip_code(ctx, FALSE);
1111 }
1112
1067 if(!ctx->cc_if_depth)
1068 return lex_error(ctx, JS_E_SYNTAX);
1069
1070 return skip_code(ctx, FALSE);
1071 }
1072
1113 if(!check_keyword(ctx, endW, NULL)) {
1073 if(!check_keyword(ctx, L"end", NULL)) {
1114 if(!ctx->cc_if_depth)
1115 return lex_error(ctx, JS_E_SYNTAX);
1116
1117 ctx->cc_if_depth--;
1118 return 0;
1119 }
1120
1121 if(!ctx->script->cc)

--- 66 unchanged lines hidden (view full) ---

1188 if(ctx->ptr == ctx->end || *ctx->ptr != '/') {
1189 WARN("pre-parsing failed\n");
1190 return NULL;
1191 }
1192
1193 re_len = ctx->ptr-re;
1194
1195 flags_ptr = ++ctx->ptr;
1074 if(!ctx->cc_if_depth)
1075 return lex_error(ctx, JS_E_SYNTAX);
1076
1077 ctx->cc_if_depth--;
1078 return 0;
1079 }
1080
1081 if(!ctx->script->cc)

--- 66 unchanged lines hidden (view full) ---

1148 if(ctx->ptr == ctx->end || *ctx->ptr != '/') {
1149 WARN("pre-parsing failed\n");
1150 return NULL;
1151 }
1152
1153 re_len = ctx->ptr-re;
1154
1155 flags_ptr = ++ctx->ptr;
1196 while(ctx->ptr < ctx->end && isalnumW(*ctx->ptr))
1156 while(ctx->ptr < ctx->end && iswalnum(*ctx->ptr))
1197 ctx->ptr++;
1198
1199 hres = parse_regexp_flags(flags_ptr, ctx->ptr-flags_ptr, &flags);
1200 if(FAILED(hres))
1201 return NULL;
1202
1203 ret = parser_alloc(ctx, sizeof(literal_t));
1204 ret->type = LT_REGEXP;
1157 ctx->ptr++;
1158
1159 hres = parse_regexp_flags(flags_ptr, ctx->ptr-flags_ptr, &flags);
1160 if(FAILED(hres))
1161 return NULL;
1162
1163 ret = parser_alloc(ctx, sizeof(literal_t));
1164 ret->type = LT_REGEXP;
1205 ret->u.regexp.str = re;
1206 ret->u.regexp.str_len = re_len;
1165 ret->u.regexp.str = compiler_alloc_string_len(ctx->compiler, re, re_len);
1207 ret->u.regexp.flags = flags;
1208 return ret;
1209}
1166 ret->u.regexp.flags = flags;
1167 return ret;
1168}