or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdarrays-runtime.mdc-interop.mdindex.mdmemory-management.mdunsigned-types.md

annotations.mddocs/

0

# Annotations

1

2

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

3

4

## Optimization Annotations

5

6

### Inlining Control

7

8

```scala { .api }

9

class alwaysinline extends scala.annotation.StaticAnnotation

10

class noinline extends scala.annotation.StaticAnnotation

11

class nooptimize extends scala.annotation.StaticAnnotation

12

class nospecialize extends scala.annotation.StaticAnnotation

13

```

14

15

**Optimization annotations**:

16

- `@alwaysinline` - Force method inlining even in debug mode

17

- `@noinline` - Prevent method from being inlined

18

- `@nooptimize` - Disable all optimizations (implies noinline and nospecialize)

19

- `@nospecialize` - Disable generic specialization for this method

20

21

## Memory Layout and Alignment

22

23

### Alignment Control

24

25

```scala { .api }

26

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

27

```

28

29

**Alignment annotation**:

30

- `@align(size)` - Control memory alignment for fields and structures

31

- `@align(size, group)` - Group-based alignment compatible with JVM `@Contended`

32

33

**Parameters**:

34

- `size: Int` - Alignment size in bytes (must be power of 2)

35

- `group: String` - Optional group name for organizing related fields

36

37

## External Interface Annotations

38

39

### Native Interoperability

40

41

```scala { .api }

42

class extern extends scala.annotation.StaticAnnotation

43

class blocking extends scala.annotation.StaticAnnotation

44

class exported(name: String = "") extends scala.annotation.StaticAnnotation

45

class name(n: String) extends scala.annotation.StaticAnnotation

46

class link(name: String) extends scala.annotation.StaticAnnotation

47

class linkCppRuntime extends scala.annotation.StaticAnnotation

48

class define(name: String, value: String) extends scala.annotation.StaticAnnotation

49

class resolvedAtLinktime extends scala.annotation.StaticAnnotation

50

```

51

52

**External interface annotations**:

53

- `@extern` - Mark objects containing externally-defined members

54

- `@blocking` - Mark methods as potentially blocking (for threading)

55

- `@exported` - Export Scala function to be callable from C

56

- `@name` - Specify external symbol name

57

- `@link` - Link with external library

58

- `@linkCppRuntime` - Link with C++ runtime

59

- `@define` - Set preprocessor define

60

- `@resolvedAtLinktime` - Mark values resolved during linking

61

62

## Memory Model and Threading

63

64

### Memory Consistency

65

66

```scala { .api }

67

class safePublish extends scala.annotation.StaticAnnotation

68

```

69

70

**Memory model annotation**:

71

- `@safePublish` - Follow Java Memory Model for final field initialization and reading

72

- Ensures final fields are safely published across threads

73

- Can be applied to individual fields or entire types

74

75

## Reflection Support

76

77

### Reflective Instantiation

78

79

```scala { .api }

80

class EnableReflectiveInstantiation extends scala.annotation.StaticAnnotation

81

```

82

83

**Reflection annotation**:

84

- `@EnableReflectiveInstantiation` - Enable reflective instantiation for annotated class/trait/object

85

- Allows runtime identification through `scala.scalanative.reflect.Reflect` methods

86

- Applied to types that need runtime reflection capabilities

87

88

## Development Annotations

89

90

### Development Support

91

92

```scala { .api }

93

class stub extends scala.annotation.StaticAnnotation

94

```

95

96

**Development annotation**:

97

- `@stub` - Mark methods as unimplemented stubs

98

99

## Usage Examples

100

101

### Optimization Control

102

103

```scala

104

import scala.scalanative.annotation._

105

106

class MathUtils {

107

// Force inlining for performance-critical methods

108

@alwaysinline

109

def fastSquare(x: Double): Double = x * x

110

111

// Prevent inlining to reduce code size

112

@noinline

113

def largeComplexFunction(): Unit = {

114

// Large method body...

115

}

116

117

// Disable all optimizations for debugging

118

@nooptimize

119

def debugOnlyMethod(): Unit = {

120

// Debug-specific logic

121

}

122

123

// Disable specialization to reduce binary size

124

@nospecialize

125

def genericMethod[T](value: T): T = value

126

}

127

```

128

129

### Memory Alignment

130

131

```scala

132

import scala.scalanative.annotation._

133

import scala.scalanative.unsafe._

134

135

// Align struct fields for performance

136

class AlignedStruct {

137

@align(64) // Cache line alignment

138

var criticalData: Long = 0

139

140

@align(16) // SIMD alignment

141

var vectorData: Ptr[Float] = null

142

143

// Group related fields together (like JVM @Contended)

144

@align(8, "counters")

145

var counter1: Long = 0

146

147

@align(8, "counters")

148

var counter2: Long = 0

149

}

150

151

// Align entire class

152

@align(32)

153

class CacheAlignedClass {

154

var data: Int = 0

155

}

156

```

157

158

### External C Interface

159

160

```scala

161

import scala.scalanative.annotation._

162

import scala.scalanative.unsafe._

163

164

// External C library declarations

165

@extern

166

@link("m") // Link with math library (-lm)

167

object LibMath {

168

// C function: double sin(double x)

169

def sin(x: CDouble): CDouble = extern

170

171

// C function: double cos(double x)

172

def cos(x: CDouble): CDouble = extern

173

174

// Blocking I/O function

175

@blocking

176

def sleep(seconds: CUnsignedInt): CUnsignedInt = extern

177

}

178

179

// External C library with custom names

180

@extern

181

@link("custom")

182

object CustomLib {

183

// Map Scala name to C symbol name

184

@name("c_process_data")

185

def processData(data: Ptr[Byte], size: CSize): CInt = extern

186

187

// Define preprocessor macro

188

@define("BUFFER_SIZE", "1024")

189

def getBufferSize(): CSize = extern

190

}

191

```

192

193

### Exported Functions

194

195

```scala

196

import scala.scalanative.annotation._

197

import scala.scalanative.unsafe._

198

199

// Export Scala functions to be callable from C

200

object ScalaCallbacks {

201

// Export with default name (scalanative_callback)

202

@exported

203

def callback(value: CInt): CInt = {

204

value * 2

205

}

206

207

// Export with custom C symbol name

208

@exported("my_custom_callback")

209

def customCallback(data: Ptr[Byte], size: CSize): Unit = {

210

// Process data...

211

}

212

213

// Export function pointer type

214

@exported("error_handler")

215

def errorHandler(code: CInt, message: CString): Unit = {

216

val msg = fromCString(message)

217

println(s"Error $code: $msg")

218

}

219

}

220

```

221

222

### Link-time Resolution

223

224

```scala

225

import scala.scalanative.annotation._

226

import scala.scalanative.unsafe._

227

228

object LinkTimeConfig {

229

// Values determined at link time

230

@resolvedAtLinktime

231

def isDebugBuild(): Boolean = resolved

232

233

@resolvedAtLinktime

234

def getTargetPlatform(): CString = resolved

235

236

@resolvedAtLinktime

237

def getBuildTimestamp(): CLong = resolved

238

239

// Use in conditional compilation

240

def logDebug(message: String): Unit = {

241

if (isDebugBuild()) {

242

println(s"DEBUG: $message")

243

}

244

}

245

}

246

```

247

248

### Development Stubs

249

250

```scala

251

import scala.scalanative.annotation._

252

253

trait NetworkInterface {

254

def connect(host: String, port: Int): Boolean

255

def sendData(data: Array[Byte]): Int

256

def disconnect(): Unit

257

}

258

259

class NetworkImplementation extends NetworkInterface {

260

def connect(host: String, port: Int): Boolean = {

261

// Full implementation

262

true

263

}

264

265

@stub

266

def sendData(data: Array[Byte]): Int = {

267

// TODO: Implement data sending

268

throw new UnsupportedOperationException("sendData not implemented yet")

269

}

270

271

@stub

272

def disconnect(): Unit = {

273

// TODO: Implement disconnection

274

throw new UnsupportedOperationException("disconnect not implemented yet")

275

}

276

}

277

```

278

279

### Complex External Library Integration

280

281

```scala

282

import scala.scalanative.annotation._

283

import scala.scalanative.unsafe._

284

285

// Complex C++ library integration

286

@extern

287

@linkCppRuntime

288

@link("mylib")

289

@define("MYLIB_VERSION", "2")

290

object MyLibrary {

291

// C++ function with name mangling

292

@name("_Z10processFooPN6MyLib4DataE")

293

def processFoo(data: Ptr[Byte]): CInt = extern

294

295

// Initialize library (must be called first)

296

@name("MyLib_Initialize")

297

def initialize(): CBool = extern

298

299

// Cleanup (should be called on exit)

300

@name("MyLib_Shutdown")

301

def shutdown(): Unit = extern

302

303

// Async function that may block

304

@blocking

305

@name("MyLib_AsyncProcess")

306

def asyncProcess(data: Ptr[Byte], callback: CFuncPtr1[CInt, Unit]): Unit = extern

307

}

308

309

// Usage with proper initialization

310

object MyApp {

311

def main(args: Array[String]): Unit = {

312

if (MyLibrary.initialize()) {

313

try {

314

// Use library functions...

315

Zone.acquire { implicit z =>

316

val data = alloc[Byte](1024)

317

val result = MyLibrary.processFoo(data)

318

println(s"Processing result: $result")

319

}

320

} finally {

321

MyLibrary.shutdown()

322

}

323

} else {

324

println("Failed to initialize library")

325

}

326

}

327

}

328

```

329

330

### Performance-Critical Code

331

332

```scala

333

import scala.scalanative.annotation._

334

import scala.scalanative.unsafe._

335

336

class HighPerformanceMatrix {

337

@align(64) // Cache line aligned

338

private var data: Ptr[Double] = _

339

340

private var rows: Int = _

341

private var cols: Int = _

342

343

def initialize(r: Int, c: Int): Unit = {

344

Zone.acquire { implicit z =>

345

rows = r

346

cols = c

347

data = alloc[Double](rows * cols)

348

}

349

}

350

351

// Critical path - always inline

352

@alwaysinline

353

def get(row: Int, col: Int): Double = {

354

data(row * cols + col)

355

}

356

357

// Critical path - always inline

358

@alwaysinline

359

def set(row: Int, col: Int, value: Double): Unit = {

360

data(row * cols + col) = value

361

}

362

363

// Large method - don't inline to save code space

364

@noinline

365

def multiply(other: HighPerformanceMatrix): HighPerformanceMatrix = {

366

val result = new HighPerformanceMatrix

367

result.initialize(rows, other.cols)

368

369

// Matrix multiplication implementation...

370

for (i <- 0 until rows) {

371

for (j <- 0 until other.cols) {

372

var sum = 0.0

373

for (k <- 0 until cols) {

374

sum += get(i, k) * other.get(k, j)

375

}

376

result.set(i, j, sum)

377

}

378

}

379

380

result

381

}

382

}

383

```

384

385

## Best Practices

386

387

1. **Use @alwaysinline sparingly** - only for small, performance-critical methods

388

2. **Apply @align strategically** - consider cache lines (64 bytes) and SIMD requirements (16 bytes)

389

3. **Mark blocking operations** - essential for proper threading behavior

390

4. **Use @extern consistently** - group related external functions in objects

391

5. **Export functions carefully** - ensure proper memory management across boundaries

392

6. **Link libraries explicitly** - specify all required libraries with @link

393

7. **Stub incomplete implementations** - use @stub during development for clarity

394

8. **Test with different optimization levels** - ensure annotations work as expected