Unified · Split
| @@ -25,6 +25,8 @@ JS_NORETURN static void jsP_error(js_State *J, const char *fmt, ...) JS_PRINTFLI · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #define INCREC() if (++J->astdepth > JS_ASTLIMIT) jsP_error(J, "too much recursion") |
| 27 | 27 | #define DECREC() --J->astdepth |
| 28 | +#define SAVEREC() int SAVE=J->astdepth | |
| 29 | +#define POPREC() J->astdepth=SAVE | |
| 28 | 30 | |
| 29 | 31 | static void jsP_error(js_State *J, const char *fmt, ...) |
| 30 | 32 | { |
| @@ -383,23 +385,26 @@ static js_Ast *newexp(js_State *J) · 352 unmodified lines | ||
| 383 | 385 | |
| 384 | 386 | static js_Ast *memberexp(js_State *J) |
| 385 | 387 | { |
| 386 | − js_Ast *a; | |
| 387 | − INCREC(); | |
| 388 | − a = newexp(J); | |
| 388 | + js_Ast *a = newexp(J); | |
| 389 | + SAVEREC(); | |
| 389 | 390 | loop: |
| 391 | + INCREC(); | |
| 390 | 392 | if (jsP_accept(J, '.')) { a = EXP2(MEMBER, a, identifiername(J)); goto loop; } |
| 391 | 393 | if (jsP_accept(J, '[')) { a = EXP2(INDEX, a, expression(J, 0)); jsP_expect(J, ']'); goto loop; } |
| 392 | − DECREC(); | |
| 394 | + POPREC(); | |
| 393 | 395 | return a; |
| 394 | 396 | } |
| 395 | 397 | |
| 396 | 398 | static js_Ast *callexp(js_State *J) |
| 397 | 399 | { |
| 398 | 400 | js_Ast *a = newexp(J); |
| 401 | + SAVEREC(); | |
| 399 | 402 | loop: |
| 403 | + INCREC(); | |
| 400 | 404 | if (jsP_accept(J, '.')) { a = EXP2(MEMBER, a, identifiername(J)); goto loop; } |
| 401 | 405 | if (jsP_accept(J, '[')) { a = EXP2(INDEX, a, expression(J, 0)); jsP_expect(J, ']'); goto loop; } |
| 402 | 406 | if (jsP_accept(J, '(')) { a = EXP2(CALL, a, arguments(J)); jsP_expect(J, ')'); goto loop; } |
| 407 | + POPREC(); | |
| 403 | 408 | return a; |
| 404 | 409 | } |
| 405 | 410 | |
| @@ -432,104 +437,139 @@ static js_Ast *unary(js_State *J) · 26 unmodified lines | ||
| 432 | 437 | static js_Ast *multiplicative(js_State *J) |
| 433 | 438 | { |
| 434 | 439 | js_Ast *a = unary(J); |
| 440 | + SAVEREC(); | |
| 435 | 441 | loop: |
| 442 | + INCREC(); | |
| 436 | 443 | if (jsP_accept(J, '*')) { a = EXP2(MUL, a, unary(J)); goto loop; } |
| 437 | 444 | if (jsP_accept(J, '/')) { a = EXP2(DIV, a, unary(J)); goto loop; } |
| 438 | 445 | if (jsP_accept(J, '%')) { a = EXP2(MOD, a, unary(J)); goto loop; } |
| 446 | + POPREC(); | |
| 439 | 447 | return a; |
| 440 | 448 | } |
| 441 | 449 | |
| 442 | 450 | static js_Ast *additive(js_State *J) |
| 443 | 451 | { |
| 444 | 452 | js_Ast *a = multiplicative(J); |
| 453 | + SAVEREC(); | |
| 445 | 454 | loop: |
| 455 | + INCREC(); | |
| 446 | 456 | if (jsP_accept(J, '+')) { a = EXP2(ADD, a, multiplicative(J)); goto loop; } |
| 447 | 457 | if (jsP_accept(J, '-')) { a = EXP2(SUB, a, multiplicative(J)); goto loop; } |
| 458 | + POPREC(); | |
| 448 | 459 | return a; |
| 449 | 460 | } |
| 450 | 461 | |
| 451 | 462 | static js_Ast *shift(js_State *J) |
| 452 | 463 | { |
| 453 | 464 | js_Ast *a = additive(J); |
| 465 | + SAVEREC(); | |
| 454 | 466 | loop: |
| 467 | + INCREC(); | |
| 455 | 468 | if (jsP_accept(J, TK_SHL)) { a = EXP2(SHL, a, additive(J)); goto loop; } |
| 456 | 469 | if (jsP_accept(J, TK_SHR)) { a = EXP2(SHR, a, additive(J)); goto loop; } |
| 457 | 470 | if (jsP_accept(J, TK_USHR)) { a = EXP2(USHR, a, additive(J)); goto loop; } |
| 471 | + POPREC(); | |
| 458 | 472 | return a; |
| 459 | 473 | } |
| 460 | 474 | |
| 461 | 475 | static js_Ast *relational(js_State *J, int notin) |
| 462 | 476 | { |
| 463 | 477 | js_Ast *a = shift(J); |
| 478 | + SAVEREC(); | |
| 464 | 479 | loop: |
| 480 | + INCREC(); | |
| 465 | 481 | if (jsP_accept(J, '<')) { a = EXP2(LT, a, shift(J)); goto loop; } |
| 466 | 482 | if (jsP_accept(J, '>')) { a = EXP2(GT, a, shift(J)); goto loop; } |
| 467 | 483 | if (jsP_accept(J, TK_LE)) { a = EXP2(LE, a, shift(J)); goto loop; } |
| 468 | 484 | if (jsP_accept(J, TK_GE)) { a = EXP2(GE, a, shift(J)); goto loop; } |
| 469 | 485 | if (jsP_accept(J, TK_INSTANCEOF)) { a = EXP2(INSTANCEOF, a, shift(J)); goto loop; } |
| 470 | 486 | if (!notin && jsP_accept(J, TK_IN)) { a = EXP2(IN, a, shift(J)); goto loop; } |
| 487 | + POPREC(); | |
| 471 | 488 | return a; |
| 472 | 489 | } |
| 473 | 490 | |
| 474 | 491 | static js_Ast *equality(js_State *J, int notin) |
| 475 | 492 | { |
| 476 | 493 | js_Ast *a = relational(J, notin); |
| 494 | + SAVEREC(); | |
| 477 | 495 | loop: |
| 496 | + INCREC(); | |
| 478 | 497 | if (jsP_accept(J, TK_EQ)) { a = EXP2(EQ, a, relational(J, notin)); goto loop; } |
| 479 | 498 | if (jsP_accept(J, TK_NE)) { a = EXP2(NE, a, relational(J, notin)); goto loop; } |
| 480 | 499 | if (jsP_accept(J, TK_STRICTEQ)) { a = EXP2(STRICTEQ, a, relational(J, notin)); goto loop; } |
| 481 | 500 | if (jsP_accept(J, TK_STRICTNE)) { a = EXP2(STRICTNE, a, relational(J, notin)); goto loop; } |
| 501 | + POPREC(); | |
| 482 | 502 | return a; |
| 483 | 503 | } |
| 484 | 504 | |
| 485 | 505 | static js_Ast *bitand(js_State *J, int notin) |
| 486 | 506 | { |
| 487 | 507 | js_Ast *a = equality(J, notin); |
| 488 | − while (jsP_accept(J, '&')) | |
| 508 | + SAVEREC(); | |
| 509 | + while (jsP_accept(J, '&')) { | |
| 510 | + INCREC(); | |
| 489 | 511 | a = EXP2(BITAND, a, equality(J, notin)); |
| 512 | + } | |
| 513 | + POPREC(); | |
| 490 | 514 | return a; |
| 491 | 515 | } |
| 492 | 516 | |
| 493 | 517 | static js_Ast *bitxor(js_State *J, int notin) |
| 494 | 518 | { |
| 495 | 519 | js_Ast *a = bitand(J, notin); |
| 496 | − while (jsP_accept(J, '^')) | |
| 520 | + SAVEREC(); | |
| 521 | + while (jsP_accept(J, '^')) { | |
| 522 | + INCREC(); | |
| 497 | 523 | a = EXP2(BITXOR, a, bitand(J, notin)); |
| 524 | + } | |
| 525 | + POPREC(); | |
| 498 | 526 | return a; |
| 499 | 527 | } |
| 500 | 528 | |
| 501 | 529 | static js_Ast *bitor(js_State *J, int notin) |
| 502 | 530 | { |
| 503 | 531 | js_Ast *a = bitxor(J, notin); |
| 504 | − while (jsP_accept(J, '|')) | |
| 532 | + SAVEREC(); | |
| 533 | + while (jsP_accept(J, '|')) { | |
| 534 | + INCREC(); | |
| 505 | 535 | a = EXP2(BITOR, a, bitxor(J, notin)); |
| 536 | + } | |
| 537 | + POPREC(); | |
| 506 | 538 | return a; |
| 507 | 539 | } |
| 508 | 540 | |
| 509 | 541 | static js_Ast *logand(js_State *J, int notin) |
| 510 | 542 | { |
| 511 | 543 | js_Ast *a = bitor(J, notin); |
| 512 | − if (jsP_accept(J, TK_AND)) | |
| 544 | + if (jsP_accept(J, TK_AND)) { | |
| 545 | + INCREC(); | |
| 513 | 546 | a = EXP2(LOGAND, a, logand(J, notin)); |
| 547 | + DECREC(); | |
| 548 | + } | |
| 514 | 549 | return a; |
| 515 | 550 | } |
| 516 | 551 | |
| 517 | 552 | static js_Ast *logor(js_State *J, int notin) |
| 518 | 553 | { |
| 519 | 554 | js_Ast *a = logand(J, notin); |
| 520 | − if (jsP_accept(J, TK_OR)) | |
| 555 | + if (jsP_accept(J, TK_OR)) { | |
| 556 | + INCREC(); | |
| 521 | 557 | a = EXP2(LOGOR, a, logor(J, notin)); |
| 558 | + DECREC(); | |
| 559 | + } | |
| 522 | 560 | return a; |
| 523 | 561 | } |
| 524 | 562 | |
| 525 | 563 | static js_Ast *conditional(js_State *J, int notin) |
| 526 | 564 | { |
| 527 | − js_Ast *a, *b, *c; | |
| 528 | − a = logor(J, notin); | |
| 565 | + js_Ast *a = logor(J, notin); | |
| 529 | 566 | if (jsP_accept(J, '?')) { |
| 567 | + js_Ast *b, *c; | |
| 568 | + INCREC(); | |
| 530 | 569 | b = assignment(J, 0); |
| 531 | 570 | jsP_expect(J, ':'); |
| 532 | 571 | c = assignment(J, notin); |
| 572 | + DECREC(); | |
| 533 | 573 | return EXP3(COND, a, b, c); |
| 534 | 574 | } |
| 535 | 575 | return a; |
| @@ -537,9 +577,8 @@ static js_Ast *conditional(js_State *J, int notin) · 1 unmodified line | ||
| 537 | 577 | |
| 538 | 578 | static js_Ast *assignment(js_State *J, int notin) |
| 539 | 579 | { |
| 540 | − js_Ast *a; | |
| 580 | + js_Ast *a = conditional(J, notin); | |
| 541 | 581 | INCREC(); |
| 542 | − a = conditional(J, notin); | |
| 543 | 582 | if (jsP_accept(J, '=')) a = EXP2(ASS, a, assignment(J, notin)); |
| 544 | 583 | else if (jsP_accept(J, TK_MUL_ASS)) a = EXP2(ASS_MUL, a, assignment(J, notin)); |
| 545 | 584 | else if (jsP_accept(J, TK_DIV_ASS)) a = EXP2(ASS_DIV, a, assignment(J, notin)); |
| @@ -558,12 +597,13 @@ static js_Ast *assignment(js_State *J, int notin) · 12 unmodified lines | ||
| 558 | 597 | |
| 559 | 598 | static js_Ast *expression(js_State *J, int notin) |
| 560 | 599 | { |
| 561 | − js_Ast *a; | |
| 562 | − INCREC(); | |
| 563 | − a = assignment(J, notin); | |
| 564 | − while (jsP_accept(J, ',')) | |
| 600 | + js_Ast *a = assignment(J, notin); | |
| 601 | + SAVEREC(); | |
| 602 | + while (jsP_accept(J, ',')) { | |
| 603 | + INCREC(); | |
| 565 | 604 | a = EXP2(COMMA, a, assignment(J, notin)); |
| 566 | − DECREC(); | |
| 605 | + } | |
| 606 | + POPREC(); | |
| 567 | 607 | return a; |
| 568 | 608 | } |
| 569 | 609 | |