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} |