-
Notifications
You must be signed in to change notification settings - Fork 77
How to Avoid Breaking the Rascal Bootstrap
We are currently at the brink of switching to a development cycle where we critically depend on previously compiled code (e.g. Kernel
, ParserGenerator
). This page is intended to get an overall picture of changes which break compatibility of the language and/or the runtime. Either the automated bootstrap process can cater for such breaking changes, or it can not. In the latter case we explain how to workaround the issue manually.
Please:
- Add missing scenarios
- Correct scenarios
- Add validation per scenario (how has this scenario been tested?)
✔️ means we validated the scenario indeed breaks the bootstrap and we need a workaround
- Make any test fail *
Any failing test will make the bootstrap halt. There is no other way then to fix the bug or adapt the test such that it makes sense again.
- Remove a Rascal language feature which is used by the compiler or type checker code itself
That is just not possible. You have to first rewrite the source code of the compiler to avoid using the deprecated feature. The previous compiler will not help of course, so it would be good to introduce first an analysis to the type checker to mark the deprecated feature. That way you and other users can be helped by the IDE to remove the old feature before it becomes unsupported.
- Changing parameters of commandline tools
rascalc
,compileMuLibrary
Since the Bootstrap script depends on these parameters, and it calls both the previous versions from the jar and the new versions in the bin folder, the commandline parameters must never change without an intermediate step.
Workaround:
- Support transition in Bootstrap script by case distinction of phase 1 and phase 2 (to use old parameters) and phase 3 and phase 4 to use the new parameters.
- Bootstrap and release
- Change Bootstrap script to remove case distinctions
- Bootstrap and release
- Changing parameters of the Kernel function
compile
without leaving the older version in tact.
We need the old version of the compile
function at least a while longer to be able to run the tests of phase 1 and to start phase 2 of the bootstrap process. The reason is that the new compiler with the new compile
signature will be combined using an older jar folder with the RVM which includes an older version of the RascalC command which still hardwires the old signature of compile
.
Workaround:
- One can use a keyword parameter to change the signature rather than a real parameter, or:
- Leave the old definition in and mark it deprecated.
- Bootstrap and release
- Remove the old definition
- Bootstrap again
- Rename a class name in a vital library like
org.rascalmpl.values
(nowio.usethesource.vallang
)
It looks so simple, renaming a class name using an Eclipse refactoring. Unfortunately, life is less simple since the old class name may occur in string templates or generated byte code.
Before you decide to rename:
- Convince yourself that the renaming is really necessary.
- Search the Rascal code base (
*.java
,*.src
,*.xml
) for the old name and watch out for occurrences in- BytecodeGenerator
- String templates
- Configuration files
- Be aware of test data that may be affected.
Workarounds:
- Perform renamings in small steps and test and bootstrap in between, this will expose problems as soon as possible.
- If the renamed class names can occur in generated byte code, activate the class renaming in
Execute.rsc
. and make sure inBootstrap.java
that old and new names are both available during compilation.
Here is a list of dangerous names that require special attention when renamed.
Used by BytecodeGenerator:
io.usethesource.vallang.type.Type
IValue
IValueFactory
IString
IBool
IList
IInteger
ISet
IMap
ITuple
RVMExecutable
RascalExecutionContext
RVMonJVM
Frame
Function
RascalPrimitive
MuPrimitive
Reference
Coroutine
Thrown
Generated by parsergenerator:
io.usethesource.vallang.type.TypeFactory
io.usethesource.vallang.IConstructor
io.usethesource.vallang.ISourceLocation
io.usethesource.vallang.IValue
io.usethesource.vallang.IValueFactory
io.usethesource.vallang.exceptions.FactTypeUseException
- `io.usethesource.vallang.io.StandardTextReader
org.rascalmpl.parser.gtd.stack.*
org.rascalmpl.parser.gtd.stack.filter.*
org.rascalmpl.parser.gtd.stack.filter.follow.*
org.rascalmpl.parser.gtd.stack.filter.match.*
org.rascalmpl.parser.gtd.stack.filter.precede.*
org.rascalmpl.parser.gtd.preprocessing.ExpectBuilder
org.rascalmpl.parser.gtd.util.IntegerKeyedHashMap
org.rascalmpl.parser.gtd.util.IntegerList
org.rascalmpl.parser.gtd.util.IntegerMap
org.rascalmpl.values.ValueFactoryFactory
org.rascalmpl.values.uptr.RascalValueFactory
org.rascalmpl.values.uptr.ITree
✔️ means we tested this scenario and indeed the bootstrap script will work around a language-breaking or virtual machine-breaking change by using the previously released version of the Rascal compiler:
- renaming a MuPrimitive; ok if you change the compiler to generate the new name and the MuPrimitive name as well
- renaming a RascalPrimitive;
- changing the signature of a MuPrimitive
- changing the signature of a RascalPrimitive
- Changing Rascal functions other than Kernel functions
- Changing Java code that is unrelated to serialization
- Adding a Rascal language feature (e.g. coroutines) Note: any changes to the existing implementation should be handled according to the above approaches.
- Changing IValue or Type internally, i.e. no API changes
- Adding new
IValue
s orType
s - Change signature of Kernel function
rascalTests
- Adding field to a serialized Java class, e.g. RVMExecutable
- Delete a field from a serialized class
- Changing name or signature of Kernel function
compile
orcompileAndLink
- Change a constructor in the RVM datatype
- Switching to automatic compression:
|compressed+file:///.../Fac.rvm.ser.gz|
to|file:///.../Fac.rvm.ser.gz|
- Switching serialization format
- Moving the compiler sources to another location
- Removing a Rascal language feature which is not used by the compiler or any of the tests