Sto sostituendo alcuni componenti di generazione del codice in un programma Java con macro Scala e sto correndo nel limite della Java Virtual Machine sulla dimensione del codice byte generato per i singoli metodi (64 kilobyte).Scala macro e limite della dimensione del metodo JVM
Ad esempio, supponiamo di avere un file XML di grandi dimensioni che rappresenta un mapping da numeri interi a numeri interi che vogliamo utilizzare nel nostro programma. Vogliamo evitare il parsing questo file in fase di esecuzione, quindi dovremo scrivere una macro che farà il parsing in fase di compilazione e utilizzare il contenuto del file per creare il corpo del nostro metodo:
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))
}
}
In questo caso il metodo compilato sarebbe appena oltre il limite di dimensioni, ma invece di un errore piacevole che dice che, ci viene data una traccia di stack gigante con un sacco di chiamate a TreePrinter.printSeq
e ci viene detto che abbiamo ucciso il compilatore.
Ho a solution che comporta la suddivisione dei casi in gruppi di dimensioni fisse, la creazione di un metodo separato per ciascun gruppo e l'aggiunta di una corrispondenza di primo livello che invia il valore di input al metodo del gruppo appropriato. Funziona, ma è sgradevole, e preferirei non dover usare questo approccio ogni volta che scrivo una macro in cui la dimensione del codice generato dipende da qualche risorsa esterna.
C'è un modo più pulito per affrontare questo problema? Ancora più importante, c'è un modo per affrontare questo tipo di errore del compilatore più facilmente? Non mi piace l'idea che un utente di una libreria ottenga un messaggio di errore "Quella voce sembra aver ucciso il compilatore" solo perché alcuni file XML che vengono elaborati da una macro hanno attraversato alcune (piuttosto basse) dimensioni della soglia.
Questa domanda è stato contrassegnato come [ "già risposto"] (http://stackoverflow.com/q/6570343/334519), ma quello che sto chiedendo è completamente diverso da ciò che viene chiesto in che domanda.So che non è possibile modificare il limite di dimensioni del metodo della JVM: chiedo soluzioni alternative e la gestione degli errori nel contesto del nuovo sistema macro (2.10) di Scala. –
Naively provato-ottimizzato e 2,11 appena seduto lì a riflettere. Perché il mio tempo su questa terra è finito, lo so. Forse diventerà ovvio per me perché questo è dovuto finire male. –
@ som-snytt: Interessante, lo stesso qui, e non ho idea di cosa significhi. Senza '-optimize', 2.11.0-M3 fornisce un messaggio di errore ragionevole, almeno. –