मैं जावा प्रोग्राम में स्कैला मैक्रोज़ के साथ कुछ कोड जनरेटिंग घटकों को प्रतिस्थापित कर रहा हूं, और व्यक्तिगत तरीकों के लिए जेनरेट बाइट कोड के आकार पर जावा वर्चुअल मशीन की सीमा में चल रहा हूं (64 किलोबाइट्स)।स्कैला मैक्रोज़ और जेवीएम की विधि आकार सीमा
उदाहरण के लिए, मान लें कि हमारे पास एक बड़ी-आईएसएम एक्सएमएल फ़ाइल है जो पूर्णांक से पूर्णांक तक मैपिंग का प्रतिनिधित्व करती है जिसे हम अपने कार्यक्रम में उपयोग करना चाहते हैं। हम रन टाइम पर इस फ़ाइल को पार्स से बचना चाहते हैं, तो हम उस मैक्रो संकलन समय पर पार्स करना होगा लिख सकते हैं और हमारे विधि के शरीर बनाने के लिए फ़ाइल की सामग्री का उपयोग करेंगे:
import scala.language.experimental.macros
import scala.reflect.macros.Context
object BigMethod {
// For this simplified example we'll just make some data up.
val mapping = List.tabulate(7000)(i => (i, i + 1))
def lookup(i: Int): Int = macro lookup_impl
def lookup_impl(c: Context)(i: c.Expr[Int]): c.Expr[Int] = {
import c.universe._
val switch = reify(new scala.annotation.switch).tree
val cases = mapping map {
case (k, v) => CaseDef(c.literal(k).tree, EmptyTree, c.literal(v).tree)
}
c.Expr(Match(Annotated(switch, i.tree), cases))
}
}
इस में यदि संकलित विधि आकार सीमा से अधिक हो, लेकिन यह कहने में एक अच्छी त्रुटि के बजाय, हमें TreePrinter.printSeq
पर कई कॉल के साथ एक विशाल स्टैक ट्रेस दिया गया है और कहा जाता है कि हमने कंपाइलर को मार दिया है।
मेरे पास a solution है जिसमें मामलों को निश्चित आकार के समूहों में विभाजित करना, प्रत्येक समूह के लिए एक अलग विधि बनाना, और एक शीर्ष-स्तर का मिलान जोड़ना जो उपयुक्त समूह की विधि में इनपुट मान भेजता है। यह काम करता है, लेकिन यह अप्रिय है, और जब भी मैं एक मैक्रो लिखता हूं, तो मैं इस दृष्टिकोण का उपयोग नहीं करना चाहूंगा जहां जेनरेट कोड का आकार कुछ बाहरी संसाधनों पर निर्भर करता है।
क्या इस समस्या से निपटने के लिए एक क्लीनर तरीका है? सबसे महत्वपूर्ण बात यह है कि इस प्रकार की कंपाइलर त्रुटि से अधिक सावधानीपूर्वक निपटने का कोई तरीका है? मुझे लाइब्रेरी उपयोगकर्ता को एक अनजान समझने का विचार पसंद नहीं है "उस प्रविष्टि ने कंपाइलर को मार डाला है" त्रुटि संदेश सिर्फ इसलिए कि कुछ एक्सएमएल फ़ाइल जो मैक्रो द्वारा संसाधित की जा रही है, ने कुछ (काफी कम) आकार थ्रेसहोल्ड पार कर लिया है।
इस सवाल के रूप में [ "पहले से ही उत्तर"] (http://stackoverflow.com/q/6570343/334519), लेकिन क्या मैं पूछ रहा हूँ क्या है कि में कहा जा रहा है से पूरी तरह अलग है चिह्नित किया गया है सवाल।मुझे पता है कि जेवीएम की विधि आकार सीमा को बदलना संभव नहीं है- मैं स्कैला के नए (2.10) मैक्रो सिस्टम के संदर्भ में वर्कअराउंड और त्रुटि प्रबंधन के बारे में पूछ रहा हूं। –
नैतिक कोशिश की गई - ऑप्टिमाइज़ और 2.11 बस वहां बैठे बैठे। क्योंकि इस धरती पर मेरा समय सीमित है, मैं ctl-c'd। शायद यह मेरे लिए स्पष्ट हो जाएगा कि इसे बुरी तरह खत्म क्यों करना पड़ा। –
@ सोम-स्नीट: दिलचस्प-यहां, और इसका कोई मतलब नहीं है इसका मतलब है। 'ऑप्टिमाइज़' के बिना, 2.11.0-एम 3 कम से कम एक उचित त्रुटि संदेश देता है। –