Note that there are some explanatory texts on larger screens.

plurals
  1. POScala macros and the JVM's method size limit
    primarykey
    data
    text
    <p>I'm replacing some code generation components in a Java program with Scala macros, and am running into the Java Virtual Machine's limit on the size of the generated byte code for individual methods (64 kilobytes).</p> <p>For example, suppose we have a large-ish XML file that represents a mapping from integers to integers that we want to use in our program. We want to avoid parsing this file at run time, so we'll write a macro that will do the parsing at compile time and use the contents of the file to create the body of our method:</p> <pre><code>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 =&gt; (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) =&gt; CaseDef(c.literal(k).tree, EmptyTree, c.literal(v).tree) } c.Expr(Match(Annotated(switch, i.tree), cases)) } } </code></pre> <p>In this case the compiled method would be just over the size limit, but instead of a nice error saying that, we're given a giant stack trace with a lot of calls to <code>TreePrinter.printSeq</code> and are told that we've slain the compiler.</p> <p>I have <a href="https://gist.github.com/travisbrown/5736883">a solution</a> that involves splitting the cases into fixed-sized groups, creating a separate method for each group, and adding a top-level match that dispatches the input value to the appropriate group's method. It works, but it's unpleasant, and I'd prefer not to have to use this approach every time I write a macro where the size of the generated code depends on some external resource.</p> <p>Is there a cleaner way to tackle this problem? More importantly, is there a way to deal with this kind of compiler error more gracefully? I don't like the idea of a library user getting an unintelligible "That entry seems to have slain the compiler" error message just because some XML file that's being processed by a macro has crossed some (fairly low) size threshhold.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload