CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scala-native--nativelib-native0-5-3

Native interoperability library for Scala Native providing unsafe operations, C-style data types, and memory management primitives for direct interaction with native code

Pending
Overview
Eval results
Files

annotations.mddocs/

Annotations

Scala Native provides specialized annotations for optimization control, memory layout, and external interface declarations to fine-tune native code generation and interoperability.

Optimization Annotations

Inlining Control

class alwaysinline extends scala.annotation.StaticAnnotation
class noinline extends scala.annotation.StaticAnnotation
class nooptimize extends scala.annotation.StaticAnnotation
class nospecialize extends scala.annotation.StaticAnnotation

Optimization annotations:

  • @alwaysinline - Force method inlining even in debug mode
  • @noinline - Prevent method from being inlined
  • @nooptimize - Disable all optimizations (implies noinline and nospecialize)
  • @nospecialize - Disable generic specialization for this method

Memory Layout and Alignment

Alignment Control

class align(size: Int, group: String = "") extends scala.annotation.StaticAnnotation

Alignment annotation:

  • @align(size) - Control memory alignment for fields and structures
  • @align(size, group) - Group-based alignment compatible with JVM @Contended

Parameters:

  • size: Int - Alignment size in bytes (must be power of 2)
  • group: String - Optional group name for organizing related fields

External Interface Annotations

Native Interoperability

class extern extends scala.annotation.StaticAnnotation  
class blocking extends scala.annotation.StaticAnnotation
class exported(name: String = "") extends scala.annotation.StaticAnnotation
class name(n: String) extends scala.annotation.StaticAnnotation
class link(name: String) extends scala.annotation.StaticAnnotation
class linkCppRuntime extends scala.annotation.StaticAnnotation
class define(name: String, value: String) extends scala.annotation.StaticAnnotation
class resolvedAtLinktime extends scala.annotation.StaticAnnotation

External interface annotations:

  • @extern - Mark objects containing externally-defined members
  • @blocking - Mark methods as potentially blocking (for threading)
  • @exported - Export Scala function to be callable from C
  • @name - Specify external symbol name
  • @link - Link with external library
  • @linkCppRuntime - Link with C++ runtime
  • @define - Set preprocessor define
  • @resolvedAtLinktime - Mark values resolved during linking

Memory Model and Threading

Memory Consistency

class safePublish extends scala.annotation.StaticAnnotation

Memory model annotation:

  • @safePublish - Follow Java Memory Model for final field initialization and reading
  • Ensures final fields are safely published across threads
  • Can be applied to individual fields or entire types

Reflection Support

Reflective Instantiation

class EnableReflectiveInstantiation extends scala.annotation.StaticAnnotation

Reflection annotation:

  • @EnableReflectiveInstantiation - Enable reflective instantiation for annotated class/trait/object
  • Allows runtime identification through scala.scalanative.reflect.Reflect methods
  • Applied to types that need runtime reflection capabilities

Development Annotations

Development Support

class stub extends scala.annotation.StaticAnnotation

Development annotation:

  • @stub - Mark methods as unimplemented stubs

Usage Examples

Optimization Control

import scala.scalanative.annotation._

class MathUtils {
  // Force inlining for performance-critical methods
  @alwaysinline
  def fastSquare(x: Double): Double = x * x
  
  // Prevent inlining to reduce code size
  @noinline  
  def largeComplexFunction(): Unit = {
    // Large method body...
  }
  
  // Disable all optimizations for debugging
  @nooptimize
  def debugOnlyMethod(): Unit = {
    // Debug-specific logic
  }
  
  // Disable specialization to reduce binary size
  @nospecialize  
  def genericMethod[T](value: T): T = value
}

Memory Alignment

import scala.scalanative.annotation._
import scala.scalanative.unsafe._

// Align struct fields for performance
class AlignedStruct {
  @align(64)  // Cache line alignment
  var criticalData: Long = 0
  
  @align(16)  // SIMD alignment
  var vectorData: Ptr[Float] = null
  
  // Group related fields together (like JVM @Contended)
  @align(8, "counters")
  var counter1: Long = 0
  
  @align(8, "counters") 
  var counter2: Long = 0
}

// Align entire class
@align(32)
class CacheAlignedClass {
  var data: Int = 0
}

External C Interface

import scala.scalanative.annotation._
import scala.scalanative.unsafe._

// External C library declarations
@extern
@link("m")  // Link with math library (-lm)
object LibMath {
  // C function: double sin(double x)
  def sin(x: CDouble): CDouble = extern
  
  // C function: double cos(double x)  
  def cos(x: CDouble): CDouble = extern
  
  // Blocking I/O function
  @blocking
  def sleep(seconds: CUnsignedInt): CUnsignedInt = extern
}

// External C library with custom names
@extern
@link("custom")
object CustomLib {
  // Map Scala name to C symbol name
  @name("c_process_data")
  def processData(data: Ptr[Byte], size: CSize): CInt = extern
  
  // Define preprocessor macro
  @define("BUFFER_SIZE", "1024")
  def getBufferSize(): CSize = extern
}

Exported Functions

import scala.scalanative.annotation._
import scala.scalanative.unsafe._

// Export Scala functions to be callable from C
object ScalaCallbacks {
  // Export with default name (scalanative_callback)
  @exported
  def callback(value: CInt): CInt = {
    value * 2
  }
  
  // Export with custom C symbol name
  @exported("my_custom_callback")
  def customCallback(data: Ptr[Byte], size: CSize): Unit = {
    // Process data...
  }
  
  // Export function pointer type
  @exported("error_handler")
  def errorHandler(code: CInt, message: CString): Unit = {
    val msg = fromCString(message)
    println(s"Error $code: $msg")
  }
}

Link-time Resolution

import scala.scalanative.annotation._
import scala.scalanative.unsafe._

object LinkTimeConfig {
  // Values determined at link time
  @resolvedAtLinktime  
  def isDebugBuild(): Boolean = resolved
  
  @resolvedAtLinktime
  def getTargetPlatform(): CString = resolved
  
  @resolvedAtLinktime
  def getBuildTimestamp(): CLong = resolved
  
  // Use in conditional compilation
  def logDebug(message: String): Unit = {
    if (isDebugBuild()) {
      println(s"DEBUG: $message")
    }
  }
}

Development Stubs

import scala.scalanative.annotation._

trait NetworkInterface {
  def connect(host: String, port: Int): Boolean
  def sendData(data: Array[Byte]): Int
  def disconnect(): Unit
}

class NetworkImplementation extends NetworkInterface {
  def connect(host: String, port: Int): Boolean = {
    // Full implementation
    true
  }
  
  @stub
  def sendData(data: Array[Byte]): Int = {
    // TODO: Implement data sending
    throw new UnsupportedOperationException("sendData not implemented yet")
  }
  
  @stub  
  def disconnect(): Unit = {
    // TODO: Implement disconnection
    throw new UnsupportedOperationException("disconnect not implemented yet")
  }
}

Complex External Library Integration

import scala.scalanative.annotation._
import scala.scalanative.unsafe._

// Complex C++ library integration
@extern
@linkCppRuntime
@link("mylib")
@define("MYLIB_VERSION", "2")
object MyLibrary {
  // C++ function with name mangling
  @name("_Z10processFooPN6MyLib4DataE")
  def processFoo(data: Ptr[Byte]): CInt = extern
  
  // Initialize library (must be called first)
  @name("MyLib_Initialize")
  def initialize(): CBool = extern
  
  // Cleanup (should be called on exit)
  @name("MyLib_Shutdown")  
  def shutdown(): Unit = extern
  
  // Async function that may block
  @blocking
  @name("MyLib_AsyncProcess")
  def asyncProcess(data: Ptr[Byte], callback: CFuncPtr1[CInt, Unit]): Unit = extern
}

// Usage with proper initialization
object MyApp {
  def main(args: Array[String]): Unit = {
    if (MyLibrary.initialize()) {
      try {
        // Use library functions...
        Zone.acquire { implicit z =>
          val data = alloc[Byte](1024)
          val result = MyLibrary.processFoo(data)
          println(s"Processing result: $result")
        }
      } finally {
        MyLibrary.shutdown()
      }
    } else {
      println("Failed to initialize library")
    }
  }
}

Performance-Critical Code

import scala.scalanative.annotation._
import scala.scalanative.unsafe._

class HighPerformanceMatrix {
  @align(64)  // Cache line aligned
  private var data: Ptr[Double] = _
  
  private var rows: Int = _
  private var cols: Int = _
  
  def initialize(r: Int, c: Int): Unit = {
    Zone.acquire { implicit z =>
      rows = r
      cols = c
      data = alloc[Double](rows * cols)
    }
  }
  
  // Critical path - always inline
  @alwaysinline
  def get(row: Int, col: Int): Double = {
    data(row * cols + col)
  }
  
  // Critical path - always inline  
  @alwaysinline
  def set(row: Int, col: Int, value: Double): Unit = {
    data(row * cols + col) = value
  }
  
  // Large method - don't inline to save code space
  @noinline
  def multiply(other: HighPerformanceMatrix): HighPerformanceMatrix = {
    val result = new HighPerformanceMatrix
    result.initialize(rows, other.cols)
    
    // Matrix multiplication implementation...
    for (i <- 0 until rows) {
      for (j <- 0 until other.cols) {
        var sum = 0.0
        for (k <- 0 until cols) {
          sum += get(i, k) * other.get(k, j)
        }
        result.set(i, j, sum)
      }
    }
    
    result
  }
}

Best Practices

  1. Use @alwaysinline sparingly - only for small, performance-critical methods
  2. Apply @align strategically - consider cache lines (64 bytes) and SIMD requirements (16 bytes)
  3. Mark blocking operations - essential for proper threading behavior
  4. Use @extern consistently - group related external functions in objects
  5. Export functions carefully - ensure proper memory management across boundaries
  6. Link libraries explicitly - specify all required libraries with @link
  7. Stub incomplete implementations - use @stub during development for clarity
  8. Test with different optimization levels - ensure annotations work as expected

Install with Tessl CLI

npx tessl i tessl/maven-org-scala-native--nativelib-native0-5-3

docs

annotations.md

arrays-runtime.md

c-interop.md

index.md

memory-management.md

unsigned-types.md

tile.json