Language semantics¶
In general, the semantics of the Scala Native language are the same asScala on the JVM. However, a few differences exist, which we mentionhere.
Interop extensions¶
Annotations and types definedscala.scalanative.unsafe may modifysemantics of the language for sake of interoperability with C libraries,read more about those ininteropsection.
Multithreading¶
Scala Native supports parallel multi-threaded programming and assumesmulti-threaded execution by default. Upon the absence of system threadsin the linked program, Scala Native can automatically switch tosingle-threaded mode, allowing to get rid of redundant synchronization,as the state is never shared between threads.
Scala Native tries to follow the Java Memory Model, but by default usesmore relaxed semantics in some areas. Due to the majority of immutableshared states in most Scala programs, Scala Native does not follow Javafinal fields semantics. Safe publication of final fields (vals inScala) can be enabled by annotating fields or the whole class with@scala.scalanative.annotation.safePublish, thisbehaviour can be also enabled on whole project scope by providing aScala compiler plugin options-Pscalanative:forceStrictFinalFields. Semantics of finalfields can be also overridden at linktime usingNativeConfig.semanticsConfig - it can be configured tooverride default relaxed memory model, allowing to replace it withstrict JMM semantics or disable synchronization entirely.
Scala Native ensures that all class field operations would be executedatomically, but does not impose any synchronization or happens-beforeguarantee.
When executing extern functions Garbage Collector needs to be notified about the internal state of the calling thread. This notification is required to correctly track reachable objects and skip waiting for threads executing unmanaged code - these may block (e.g. waiting on socket connection) for long time leading to deadlocks during GC.By default only calls to methods annotated with@scala.scalanative.unsafe.blocking would notify the GC - it allows to reduce overhead of extern method calls, but might lead to deadlocks or longer GC pauses when waiting for unannotated blocking function call.This behaviour can be changed by enablingNativeConfig.strictExternCallSemantics. Under this mode every invocation of foreign function would notify the GC about the thread state which guarantees no deadlocks introduced by waiting for threads executing foreign code, but might reduce overall performance.
Finalization¶
Finalize method fromjava.lang.Object is never called in Scala Native.
Undefined behavior¶
Generally, Scala Native follows most of the special error conditionssimilarly to JVM:
Arrays throw
IndexOutOfBoundsExceptionon out-of-bounds access.Casts throw
ClassCastExceptionon incorrect casts.Accessing a field or method on
null, throwingnullexception,throwsNullPointerException.Integer division by zero throws
ArithmeticException.
There are a few exceptions:
Stack overflows are undefined behavior and would typically segfaulton supported architectures instead of throwing
StackOverflowError.Exhausting a heap space results in crash with a stack trace insteadof throwing
OutOfMemoryError.
Continue tointerop.
