Implementation notes: Compilation and analysis within JShell
Robert Field
robert.field at oracle.com
Wed Sep 2 06:32:46 UTC 2015
> On Sep 1, 2015, at 7:59 PM, Sundararajan Athijegannathan <sundararajan.athijegannathan at oracle.com> wrote:
>
> Nice! Thanks for the summary. Will you please put this notes in the repo itself? yes, it is difficult to keep it up to date with code -- but it is easy to miss this email in the kulla-dev archive.
True.
Is there a standard place/form for such a document, I haven’t run across this yet.
-Robert
>
> Thanks,
> -Sundar
>
> On 9/2/2015 4:31 AM, Robert Field wrote:
>> Compilation in JShell goes through three stages: parsing, wrapping & analysis, and code generation. Parsing is of one snippet (declaration, statement, expression, …) of Java source. The most important result of parsing is determination of the kind of snippet. In wrapping & analysis, each kind of snippet is handled differently. The snippet is wrapped to make a valid Java source file. At a minimum, each snippet is wrapped in a class. Note that even class definitions are wrapped in a class, this is critical to replacing the snippet if overwritten. Each wrap starts with a package definition (always “REPL”) followed by a set of imports that defines the complete context, including explicit imports of all previous active snippets. Wrapping uses information from the parse including tree structure, source positions and names. Once wrapped, the snippet may be analyzed and possibly rewrapped based on that analysis. Once the final wrap in determined, the wrapped source is compiled to an in-memory class file. That class file is shipped to the backend over a socket, loaded or redefined, and, if executable, executed.
>>
>> Classes and methods are just wrapped in a generated class. Statements are wrapped in a doit method within the class. Variable declarations are separated into their declaration part, which becomes a field, and their initializer which becomes an assignment in a doit method. Expressions become synthetic temporary variables in the same general form as variables. Imports follow a completely different mechanism, after being verified, they are simply recorded for use with subsequent snippets.
>>
>> Parsing uses the compiler API’s parse functionality, with one method in the parser overridden to allow stand-alone snippets as input. Analysis and compilation use the compiler API unmodified. JShell has its own FileManager so that input comes from Strings and output class files go to byte arrays.
>>
>> JShell’s interface to compiler API tasks is though the TaskManager, with separate subclasses of BaseTask for the cases above. Wrapping is accomplished with nested wraps that track location translation. Wrap is the abstract base class and holds its subclasses and other functionality. Nesting is with CompoundWrap which holds a sequence of Strings and Wraps. RangeWrap is the base wrap of user snippet sections. Information about the snippet, including its Wrap, found during parsing and analysis, is stored in subclasses of Snippet. Eval orchestrates these components. The JShell class is the entry point for JShell which delegates the whole eval() process to Eval.
>>
>> Please let me know if there are questions or areas I did not cover.
>>
>> Enjoy,
>> Robert
>>
>
>
More information about the kulla-dev
mailing list