| 764 | } |
| 765 | |
| 766 | object interpret3(Thread* t, const int base) |
| 767 | { |
| 768 | unsigned instruction = nop; |
| 769 | unsigned& ip = t->ip; |
| 770 | unsigned& sp = t->sp; |
| 771 | int& frame = t->frame; |
| 772 | GcCode*& code = t->code; |
| 773 | GcMethod* method = 0; |
| 774 | PROTECT(t, method); |
| 775 | GcThrowable*& exception = t->exception; |
| 776 | uintptr_t* stack = t->stack; |
| 777 | |
| 778 | code = frameMethod(t, frame)->code(); |
| 779 | |
| 780 | if (UNLIKELY(exception)) { |
| 781 | goto throw_; |
| 782 | } |
| 783 | |
| 784 | loop: |
| 785 | instruction = code->body()[ip++]; |
| 786 | |
| 787 | if (DebugRun) { |
| 788 | fprintf(stderr, |
| 789 | "ip: %d; instruction: 0x%x in %s.%s ", |
| 790 | ip - 1, |
| 791 | instruction, |
| 792 | frameMethod(t, frame)->class_()->name()->body().begin(), |
| 793 | frameMethod(t, frame)->name()->body().begin()); |
| 794 | |
| 795 | int line = findLineNumber(t, frameMethod(t, frame), ip); |
| 796 | switch (line) { |
| 797 | case NativeLine: |
| 798 | fprintf(stderr, "(native)\n"); |
| 799 | break; |
| 800 | case UnknownLine: |
| 801 | fprintf(stderr, "(unknown line)\n"); |
| 802 | break; |
| 803 | default: |
| 804 | fprintf(stderr, "(line %d)\n", line); |
| 805 | } |
| 806 | } |
| 807 | |
| 808 | switch (instruction) { |
| 809 | case aaload: { |
| 810 | int32_t index = popInt(t); |
| 811 | object array = popObject(t); |
| 812 | |
| 813 | if (LIKELY(array)) { |
| 814 | if (LIKELY(index >= 0 |
| 815 | and static_cast<uintptr_t>(index) |
| 816 | < objectArrayLength(t, array))) { |
| 817 | pushObject(t, objectArrayBody(t, array, index)); |
| 818 | } else { |
| 819 | exception = makeThrowable(t, |
| 820 | GcArrayIndexOutOfBoundsException::Type, |
| 821 | "%d not in [0,%d)", |
| 822 | index, |
| 823 | objectArrayLength(t, array)); |
no test coverage detected