2011-12-12 9 views
6

मैं जावा बाइटकोड में कुछ त्रुटि प्रबंधन करने की कोशिश कर रहा हूं। मैं पहली बार कुछ पकड़ने की तरह सबरूटीन्स, जहाँ मैं त्रुटि स्थिति के लिए जाँच करेगा लागू, और उचित सबरूटीन, एक छोटे से की तरह करने के लिए कूदने की कोशिश की:जावा बाइटकोड में कोशिश/पकड़ अपवादों से निपटना? ("स्टैक ऊंचाई असंगत")

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 

ऊपर के साथ समस्या यह है कि मैं कई निर्देश है जब जो इस सबराउटिन पर कूदता है, बाइटकोड चलाते समय मुझे एक त्रुटि संदेश मिलता है, कहता है कि ढेर की ऊंचाई असंगत है।

शायद अपवादों का उपयोग करना इस के आसपास जाने का सबसे अच्छा तरीका है?

कुछ Googling से मैं ने पाया है कि आप अपवाद वर्गों के उदाहरण बना सकते हैं और की तरह कुछ के साथ आरंभ कर सकते हैं:

new java/lang/Exception 
dup 
ldc "exception message!" 
invokespecial java/lang/Exception/<init>(Ljava/lang/String;)V 

मैंने यह भी पाया है कि आप उन्हें athrow साथ फेंक कर सकते हैं और यह ठीक लगता है।

मुझे भ्रमित करने वाला क्या है, हालांकि वास्तव में अपवाद कैसे पकड़े जाते हैं। ऐसा लगता है कि एक जादुई "अपवाद तालिका" है जो एक साथ अपवादों को फेंकने और पकड़ने का संकेत देती है, लेकिन मुझे नहीं पता कि इनमें से एक को कैसे स्क्रैच से बाइटकोड लिखना है (और जैस्मीन का उपयोग करके संयोजन करना)। क्या कोई मुझे अपवाद तालिका बनाने का रहस्य बता सकता है? और संभवतः मुझे अपवाद हैंडलिंग का एक उदाहरण दें जो जैस्मीन के साथ इकट्ठा होगा?

उत्तर

2

अंत में मैं अब तक आया jsr से ईटर समाधान - जैस्मीन में .method का उपयोग करके एक विधि को परिभाषित करना। एक बार जब मुझे त्रुटि मिली तो मैंने अपने त्रुटि हैंडलर को कॉल करने के लिए invokestatic का उपयोग किया।

वास्तविक अपवाद हैंडलिंग की तलाश करने वालों के लिए - मुझे लगता है कि जैस्मीन में अपवाद तालिका को परिभाषित करने के लिए .catch का उपयोग करके किया जा सकता है, लेकिन मैंने इसकी समस्या को हल करने की विधि परिभाषा के रूप में इसे नहीं देखा है।

संपादित करें:

मैं अंत में .catch को देखने की क्या ज़रूरत थी, और इसका इस्तेमाल करने में आसान है पाया। यह here दस्तावेज है।

0

संस्करण 51.0 से कक्षा फ़ाइलों में जेएसआर निर्देश नहीं हो सकता है, इसके पहले यह इंगित करने के लायक है। कोड दोहराएं या एक विधि का प्रयोग करें।

बाइटकोड में हर बिंदु पर, फ्रेम में प्रत्येक तत्व का स्थिर प्रकार ज्ञात होना चाहिए। प्रत्येक फ्रेम कॉल स्टैक नहीं है।

आम तौर पर आप बड़े बड़े ढेर के साथ खेलना नहीं चाहते हैं। चीज़ों को सरल रखने के लिए स्थानीय चरों में अस्थायी स्टोर करें।

यदि कोई अपवाद फेंक दिया गया है तो जाहिर है कि फ्रेम में किसी भी स्थान से अपवाद हो सकता है। तो सामग्री को त्याग दिया जाता है और अपवाद द्वारा प्रतिस्थापित किया जाता है। आप वैसे भी फ्रेम सामग्री का उपयोग करने के लिए वापस जाने और फिर से शुरू करने में सक्षम नहीं होंगे।

0

jsr सत्यापित करने के नियम बहुत जटिल हैं, और जैसा कि टॉम ने इंगित किया कि ऑपोड को बहिष्कृत किया गया है। तो यह सबसे अच्छा बचा है।

jsr पर मेरी स्मृति थोड़ा अस्पष्ट है, लेकिन ...

(अद्यतन) वहाँ जावा बाईटकोड सत्यापन में एक नियम यह है कि जहाँ भी दो नियंत्रण प्रवाह एक साथ शामिल ढेर गहराई दोनों शाखाओं के साथ एक समान होना चाहिए। jsr सबराउटिन को इस नियम से एक बिंदु तक छूट दी गई है - विभिन्न स्टैक गहराई के साथ कई अपवाद बिंदु jsr दिनचर्या तक "पहुंच" सकते हैं, लेकिन jsr से स्टैक गहराई में शुद्ध परिवर्तन ret को नियमित प्रविष्टि शून्य होना चाहिए (या वास्तव में शून्य 1 , क्योंकि अपवाद कारण हमेशा नियमित रूप से प्रवेश पर धकेल दिया जाता है)।

आगे, जबकि jsr दिनचर्या "भागने" और नियमित नियंत्रण प्रवाह में वापस शाखा कर सकती है, अगर ऐसा होता है तो jsr को अंक में शामिल होने के लिए स्टैक गहराई नियम से छूट नहीं दी जाती है। यह उन परिस्थितियों को गंभीर रूप से सीमित करता है जहां आप ऐसा कर सकते हैं, क्योंकि jsr दिनचर्या संभावित रूप से विभिन्न स्टैक गहराई के साथ दर्ज की जा सकती है।

(और मुझे कोई संदेह नहीं अभी भी है कि गलत में से कुछ मिल गया है, लेकिन यह सबसे अच्छा मैं कर सकता है।)

(मैं काफी समझ में नहीं आता कि कैसे आप अपने jsr "आसपास" की योजना बना रहे अपवादों के साथ समस्या।)

(इसके अलावा, सूर्य ने बाइटकोड को 4 या 5 के साथ अधिक जटिल बना दिया है (जिसे याद नहीं किया जा सकता है), जिससे हाथ-कोड बाइटकोड्स के लिए यह बहुत असंभव हो गया। उन्होंने ऐसा इसलिए किया क्योंकि उन्होंने ऐसा नहीं किया अन्यथा आईबीएम के सत्यापनकर्ता को हरा करने के लिए पर्याप्त तेज़ी से सत्यापन कैसे करें, लेकिन यह एक और मामला है।)

+0

वास्तव में, यह एक 'jsr' है जो कभी नहीं' ret's के लिए पूरी तरह से कानूनी है। Subroutines पर प्रतिबंध 1) प्रत्येक subroutine केवल एक ही ret हो सकता है (तो आप उदाहरण के लिए उन्हें शामिल किए बिना अगर दोनों की शाखाओं पर ret ret नहीं कर सकते हैं)। 2) subroutine कॉल एक पेड़ बनाना चाहिए। इसके अलावा, टाइपिंग द्वारा लगाए गए लोगों के बगल में कोई प्रतिबंध नहीं है। – Antimony

+0

वास्तव में जटिल हिस्सा सबराउटिन के शरीर के रूप में माना जाता है की सटीक परिभाषा है, क्योंकि यह प्रकार की जांच एल्गोरिदम के विवरण पर निर्भर करता है। सौभाग्य से, हॉटस्पॉट ओपन सोर्स है और यदि आप रुचि रखते हैं तो आप इसे स्वयं निर्धारित कर सकते हैं। यहां प्रासंगिक फ़ाइल http://hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/native/common/check_code.c है। जाहिर है, यह कार्यान्वयन निर्भर है, इसलिए यदि आप गैर-हॉटस्पॉट वीएमएस के बारे में परवाह करते हैं, तो आपको यह सुनिश्चित करना चाहिए कि इस तरह की अस्पष्टताओं से बचने के लिए आपके सबराउटिन अच्छी तरह से संरचित हैं। – Antimony

+0

@ एंटीमोनी - जैसा कि मैंने कहा, जेएसआर के नियमों की मेरी याददाश्त अस्पष्ट है - अब 5-6 साल के लिए सत्यापनकर्ता के साथ नहीं मिला है। आईआईआरसी, हालांकि, सबराउटिन के अंदर के नियमों के लिए नियम काफी सीधे हैं - सबराउटिन में होने के लिए एक बिंदु प्रविष्टि बिंदु से पहुंच योग्य होना चाहिए, और एक बिंदु प्रश्न से बिंदु तक पहुंच योग्य होना चाहिए। उस पर कोई अस्पष्टता नहीं होनी चाहिए। –