mirror of
https://github.com/enso-org/enso.git
synced 2024-11-29 16:02:25 +03:00
69 lines
2.9 KiB
Markdown
69 lines
2.9 KiB
Markdown
|
---
|
||
|
layout: developer-doc
|
||
|
title: Technology Analysis
|
||
|
category: syntax
|
||
|
tags: [parser, tech-analysis]
|
||
|
order: 1
|
||
|
---
|
||
|
|
||
|
# Parser Technology Analysis
|
||
|
As the Enso parser has some fairly unique requirements placed upon it, the
|
||
|
choice of implementation technology is of paramount importance. Choosing the
|
||
|
correct technology ensures that we can meet all of the requirements placed upon
|
||
|
the parser.
|
||
|
|
||
|
<!-- MarkdownTOC levels="2,3" autolink="true" -->
|
||
|
|
||
|
- [Technology Requirements for the Parser](#technology-requirements-for-the-parser)
|
||
|
- [Issues With the Previous Implementation](#issues-with-the-previous-implementation)
|
||
|
- [Choosing Rust](#choosing-rust)
|
||
|
- [Downsides of Rust](#downsides-of-rust)
|
||
|
|
||
|
<!-- /MarkdownTOC -->
|
||
|
|
||
|
## Technology Requirements for the Parser
|
||
|
As the parser has to work both for the Engine and for the IDE, it has a strange
|
||
|
set of requirements:
|
||
|
|
||
|
- The implementation language must be able to run on native platforms, as well
|
||
|
as in the browser via WASM (not JavaScript due to the marshalling overhead).
|
||
|
- The implementation language should permit _excellent_ native performance on
|
||
|
both native and web platforms, by giving implementers fine-grained control
|
||
|
over memory usage.
|
||
|
- The implementation language must be able to target all primary platforms:
|
||
|
macOS, Linux and Windows.
|
||
|
|
||
|
## Issues With the Previous Implementation
|
||
|
The previous implementation of the parser was implemented in Scala, and had some
|
||
|
serious issues that have necessitated this rewrite:
|
||
|
|
||
|
- **Performance:** The structures used to implement the parser proved inherently
|
||
|
difficult for a JIT to optimise, making performance far worse than expected on
|
||
|
the JVM.
|
||
|
- **ScalaJS Sub-Optimal Code Generation:** The JavaScript generated by ScalaJS
|
||
|
was very suboptimal for these structures, making the parser _even_ slower when
|
||
|
run in the browser.
|
||
|
- **JS as a Browser Target:** To transfer textual data between WASM and JS
|
||
|
incurs a significant marshalling overhead. As the IDE primarily works with
|
||
|
textual operations under the hood, this proved to be a significant slowdown.
|
||
|
|
||
|
## Choosing Rust
|
||
|
Rust, then, is an obvious choice for the following reasons:
|
||
|
|
||
|
- It can be compiled _natively_ into the IDE binary, providing them with
|
||
|
excellent performance.
|
||
|
- As a native language it can use JNI to directly create JVM objects on the JVM
|
||
|
heap, for use by the compiler.
|
||
|
- As a native language it can be called directly via JNI.
|
||
|
- There is potential in the future for employing Graal's LLVM bitcode
|
||
|
interpreter to execute the parser safely in a non-native context.
|
||
|
|
||
|
### Downsides of Rust
|
||
|
This is not to say that choosing rust doesn't come with some compromises:
|
||
|
|
||
|
- It significantly complicates the CI pipeline for the engine, as we will have
|
||
|
to build native artefacts for use by the runtime itself.
|
||
|
- As a non-JVM language, the complexity of working with it from Scala and Java
|
||
|
is increased. We will need to maintain a full definition of the AST in Scala
|
||
|
to permit the compiler to work properly with it.
|