Tôi đang cố gắng thực hiện một số xử lý lỗi trong bytecode java. đầu tiên tôi cố gắng thực hiện một số chương trình con bắt giống như, nơi tôi sẽ kiểm tra các điều kiện lỗi, và nhảy đến chương trình con thích hợp, một chút như:Xử lý các ngoại lệ Thử/Bắt trong mã Java bytecode? ("stack height inconsistent")
iconst_1
iconst_0
dup
ifeq calldiverr
goto enddivtest
calldiverr:
jsr divError
enddivtest:
idiv
...More instructions...
divError:
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Oh dear you divided by 0!"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
Vấn đề với bên trên là khi tôi có nhiều hướng dẫn nhảy đến chương trình con này, tôi nhận được một thông báo lỗi khi chạy bytecode, nói rằng chiều cao ngăn xếp không phù hợp.
Có thể sử dụng ngoại lệ là cách tốt nhất để giải quyết vấn đề này?
Từ một số googling tôi đã phát hiện ra rằng bạn có thể tạo thể hiện của lớp Exception và khởi chúng với một cái gì đó như:
new java/lang/Exception
dup
ldc "exception message!"
invokespecial java/lang/Exception/<init>(Ljava/lang/String;)V
Tôi cũng đã phát hiện ra rằng bạn có thể ném chúng với athrow
và điều này có vẻ ok.
Điều khiến tôi khó hiểu là chính xác cách ngoại lệ bị bắt. Dường như có một "bảng ngoại lệ" ma thuật, gắn kết việc ném và bắt các ngoại lệ với nhau, nhưng tôi không biết cách xác định một trong số này khi viết bytecode từ đầu (và lắp ráp bằng cách sử dụng Jasmin). Ai đó có thể cho tôi biết bí mật của việc tạo ra một bảng ngoại lệ? Và có thể cho tôi một ví dụ về xử lý ngoại lệ sẽ tập hợp với jasmin?
Thực ra, hoàn toàn hợp pháp để có một 'jsr' không bao giờ' đọc lại. Các hạn chế về các chương trình con là 1) mỗi chương trình con có thể chứa chỉ một lần thử lại (vì vậy bạn không thể truy xuất cả hai nhánh của một nếu không tham gia chúng). 2) các cuộc gọi chương trình con phải tạo thành một cây. Ngoài ra, không có giới hạn bên cạnh những người áp đặt kiểm tra loại. – Antimony
Phần thực sự phức tạp là định nghĩa chính xác về những gì được coi là nội dung của chương trình con, vì điều này phụ thuộc vào các chi tiết của thuật toán kiểm tra kiểu. May mắn thay, Hotspot là nguồn mở và bạn có thể tự xác định điều này như tôi có nếu bạn quan tâm. Đây là tệp có liên quan http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/native/common/check_code.c. Rõ ràng, điều này phụ thuộc vào việc triển khai thực hiện, vì vậy nếu bạn quan tâm đến vms không phải là Hotspot, bạn nên đảm bảo rằng các trình con của bạn được cấu trúc tốt để tránh những sự mơ hồ như vậy. – Antimony
@Antimony - Giống như tôi đã nói, bộ nhớ của tôi về các quy tắc cho jsr là mờ - chưa được nhét với người xác minh trong 5-6 năm nay. IIRC, mặc dù, các quy tắc cho những gì bên trong một chương trình con là khá thẳng về phía trước - để ở trong chương trình con, một điểm phải có thể truy cập được từ điểm vào và phải truy cập lại từ điểm được đề cập. Không nên có bất kỳ sự mơ hồ nào về điều đó. –