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