0
# Runtime Support
1
2
Low-level runtime support classes and utilities that provide the foundation for Scala.js execution, handling JavaScript-specific concerns while maintaining Scala semantics.
3
4
## Capabilities
5
6
### Runtime Environment
7
8
Core runtime environment support for Scala.js execution context and JavaScript interoperability.
9
10
```scala { .api }
11
/**
12
* Runtime environment utilities and system integration
13
*/
14
object ScalaRunTime {
15
/** Array utilities for runtime support */
16
def array_apply(xs: AnyRef, idx: Int): Any
17
def array_update(xs: AnyRef, idx: Int, value: Any): Unit
18
def array_length(xs: AnyRef): Int
19
20
/** String representation utilities */
21
def stringOf(x: Any): String
22
def replStringOf(x: Any, maxElements: Int): String
23
24
/** Hash code computation */
25
def hash(x: Any): Int
26
27
/** Tuple utilities */
28
def tuple2ToList[A, B](t: (A, B)): List[Any] = List(t._1, t._2)
29
def tuple3ToList[A, B, C](t: (A, B, C)): List[Any] = List(t._1, t._2, t._3)
30
def tuple4ToList[A, B, C, D](t: (A, B, C, D)): List[Any] = List(t._1, t._2, t._3, t._4)
31
def tuple5ToList[A, B, C, D, E](t: (A, B, C, D, E)): List[Any] = List(t._1, t._2, t._3, t._4, t._5)
32
def tuple6ToList[A, B, C, D, E, F](t: (A, B, C, D, E, F)): List[Any] = List(t._1, t._2, t._3, t._4, t._5, t._6)
33
def tuple7ToList[A, B, C, D, E, F, G](t: (A, B, C, D, E, F, G)): List[Any] = List(t._1, t._2, t._3, t._4, t._5, t._6, t._7)
34
def tuple8ToList[A, B, C, D, E, F, G, H](t: (A, B, C, D, E, F, G, H)): List[Any] = List(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8)
35
def tuple9ToList[A, B, C, D, E, F, G, H, I](t: (A, B, C, D, E, F, G, H, I)): List[Any] = List(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9)
36
def tuple10ToList[A, B, C, D, E, F, G, H, I, J](t: (A, B, C, D, E, F, G, H, I, J)): List[Any] = List(t._1, t._2, t._3, t._4, t._5, t._6, t._7, t._8, t._9, t._10)
37
// Additional tuple methods up to tuple22ToList available for higher arities
38
39
/** Type testing utilities */
40
def isArray(x: Any): Boolean
41
def isArray(x: Any, atLevel: Int): Boolean
42
}
43
44
/**
45
* Boxed primitive value utilities
46
*/
47
object BoxesRunTime {
48
/** Boxing operations for primitive types */
49
def boxToBoolean(b: Boolean): java.lang.Boolean
50
def boxToCharacter(c: Char): java.lang.Character
51
def boxToByte(b: Byte): java.lang.Byte
52
def boxToShort(s: Short): java.lang.Short
53
def boxToInteger(i: Int): java.lang.Integer
54
def boxToLong(l: Long): java.lang.Long
55
def boxToFloat(f: Float): java.lang.Float
56
def boxToDouble(d: Double): java.lang.Double
57
58
/** Unboxing operations */
59
def unboxToBoolean(o: Any): Boolean
60
def unboxToChar(o: Any): Char
61
def unboxToByte(o: Any): Byte
62
def unboxToShort(o: Any): Short
63
def unboxToInt(o: Any): Int
64
def unboxToLong(o: Any): Long
65
def unboxToFloat(o: Any): Float
66
def unboxToDouble(o: Any): Double
67
68
/** Equality operations that handle boxing */
69
def equals(x: Any, y: Any): Boolean
70
def equals2(x: Any, y: Any): Boolean
71
}
72
```
73
74
### Scala.js Specific Runtime
75
76
JavaScript-specific runtime utilities for compilation and execution support.
77
78
```scala { .api }
79
/**
80
* Scala.js runtime utilities for JavaScript integration
81
*/
82
object js {
83
/** Global JavaScript environment access */
84
val global: js.Dynamic = js.Dynamic.global
85
86
/** Undefined value representation */
87
val undefined: js.UndefOr[Nothing] = js.native
88
89
/** Type testing utilities */
90
def typeOf(x: Any): String = js.native
91
def isUndefined(x: Any): Boolean = x.asInstanceOf[js.UndefOr[Any]].isEmpty
92
93
/** Dynamic property access */
94
def selectDynamic(receiver: js.Dynamic, name: String): js.Dynamic = js.native
95
def applyDynamic(receiver: js.Dynamic, name: String)(args: Any*): js.Dynamic = js.native
96
97
/** JavaScript object creation */
98
def obj(fields: (String, Any)*): js.Dynamic = js.native
99
def array(elements: Any*): js.Array[Any] = js.native
100
101
/** Function utilities */
102
def functionNToType[F](f: js.Function): F = js.native
103
def typeToFunctionN[F](f: F): js.Function = js.native
104
105
/** Promise integration */
106
def fromPromise[T](promise: js.Promise[T]): Future[T] = js.native
107
def toPromise[T](future: Future[T]): js.Promise[T] = js.native
108
109
/**
110
* Dynamic type for JavaScript interoperability
111
*/
112
trait Dynamic extends Any {
113
/** Dynamic method calls */
114
def applyDynamic(name: String)(args: Any*): js.Dynamic = js.native
115
def applyDynamicNamed(name: String)(args: (String, Any)*): js.Dynamic = js.native
116
117
/** Dynamic property access */
118
def selectDynamic(name: String): js.Dynamic = js.native
119
def updateDynamic(name: String)(value: Any): Unit = js.native
120
121
/** Array-like access */
122
def apply(index: Any): js.Dynamic = js.native
123
def update(index: Any, value: Any): Unit = js.native
124
}
125
126
/**
127
* JavaScript Array type
128
*/
129
@js.native
130
trait Array[+A] extends js.Object {
131
val length: Int = js.native
132
133
def apply(index: Int): A = js.native
134
def update[A1 >: A](index: Int, value: A1): Unit = js.native
135
136
def push[A1 >: A](items: A1*): Int = js.native
137
def pop(): js.UndefOr[A] = js.native
138
def shift(): js.UndefOr[A] = js.native
139
def unshift[A1 >: A](items: A1*): Int = js.native
140
141
def slice(start: Int = 0, end: Int = Int.MaxValue): js.Array[A] = js.native
142
def splice(start: Int, deleteCount: Int, items: A*): js.Array[A] = js.native
143
144
def indexOf[A1 >: A](searchElement: A1, fromIndex: Int = 0): Int = js.native
145
def lastIndexOf[A1 >: A](searchElement: A1, fromIndex: Int = Int.MaxValue): Int = js.native
146
147
def join(separator: String = ","): String = js.native
148
def reverse(): js.Array[A] = js.native
149
def sort(compareFn: js.Function2[A, A, Int] = js.native): js.Array[A] = js.native
150
}
151
}
152
```
153
154
### Reflection Support
155
156
Limited reflection capabilities compatible with JavaScript compilation and runtime constraints.
157
158
```scala { .api }
159
/**
160
* Scala.js compatible reflection utilities
161
* Provides basic type information without full JVM reflection
162
*/
163
object reflect {
164
/**
165
* Class tag for preserving type information at runtime
166
*/
167
trait ClassTag[T] {
168
/** Runtime class representation */
169
def runtimeClass: Class[_]
170
171
/** Create new array of this type */
172
def newArray(len: Int): Array[T]
173
174
/** Wrap array as this type */
175
def wrap: ClassTag[Array[T]]
176
177
/** String representation of type */
178
override def toString: String = s"ClassTag(${runtimeClass.getName})"
179
}
180
181
object ClassTag {
182
/** Create ClassTag for given type */
183
def apply[T](implicit ct: ClassTag[T]): ClassTag[T] = ct
184
185
/** Predefined ClassTags for common types */
186
val Unit: ClassTag[Unit] = ClassTag[Unit]
187
val Boolean: ClassTag[Boolean] = ClassTag[Boolean]
188
val Byte: ClassTag[Byte] = ClassTag[Byte]
189
val Short: ClassTag[Short] = ClassTag[Short]
190
val Char: ClassTag[Char] = ClassTag[Char]
191
val Int: ClassTag[Int] = ClassTag[Int]
192
val Long: ClassTag[Long] = ClassTag[Long]
193
val Float: ClassTag[Float] = ClassTag[Float]
194
val Double: ClassTag[Double] = ClassTag[Double]
195
val AnyVal: ClassTag[AnyVal] = ClassTag[AnyVal]
196
val AnyRef: ClassTag[AnyRef] = ClassTag[AnyRef]
197
val Any: ClassTag[Any] = ClassTag[Any]
198
val Nothing: ClassTag[Nothing] = ClassTag[Nothing]
199
val Null: ClassTag[Null] = ClassTag[Null]
200
}
201
202
/**
203
* Basic class representation for Scala.js
204
*/
205
abstract class Class[T] {
206
/** Simple class name */
207
def getSimpleName: String
208
209
/** Full class name */
210
def getName: String
211
212
/** Test if instance of this class */
213
def isInstance(obj: Any): Boolean
214
215
/** String representation */
216
override def toString: String = s"class $getName"
217
}
218
219
/**
220
* Manifest for preserving generic type information
221
* Limited implementation for JavaScript compatibility
222
*/
223
trait Manifest[T] extends ClassTag[T] {
224
/** Type arguments (limited support) */
225
def typeArguments: List[Manifest[_]]
226
227
/** Array manifest */
228
def arrayManifest: Manifest[Array[T]]
229
}
230
231
object Manifest {
232
/** Create manifest for type */
233
def apply[T](implicit m: Manifest[T]): Manifest[T] = m
234
235
/** Predefined manifests */
236
val Unit: Manifest[Unit] = Manifest[Unit]
237
val Boolean: Manifest[Boolean] = Manifest[Boolean]
238
val Byte: Manifest[Byte] = Manifest[Byte]
239
val Short: Manifest[Short] = Manifest[Short]
240
val Char: Manifest[Char] = Manifest[Char]
241
val Int: Manifest[Int] = Manifest[Int]
242
val Long: Manifest[Long] = Manifest[Long]
243
val Float: Manifest[Float] = Manifest[Float]
244
val Double: Manifest[Double] = Manifest[Double]
245
val AnyVal: Manifest[AnyVal] = Manifest[AnyVal]
246
val AnyRef: Manifest[AnyRef] = Manifest[AnyRef]
247
val Any: Manifest[Any] = Manifest[Any]
248
val Nothing: Manifest[Nothing] = Manifest[Nothing]
249
val Null: Manifest[Null] = Manifest[Null]
250
}
251
}
252
```
253
254
**Usage Examples:**
255
256
```scala
257
import scala.scalajs.js
258
import scala.reflect.ClassTag
259
260
// JavaScript interoperability
261
val jsObject = js.Dynamic.literal(
262
name = "John",
263
age = 30,
264
active = true
265
)
266
267
println(jsObject.name.asInstanceOf[String]) // "John"
268
println(jsObject.age.asInstanceOf[Int]) // 30
269
270
// Dynamic property access
271
jsObject.updateDynamic("email")("john@example.com")
272
val email = jsObject.selectDynamic("email").asInstanceOf[String]
273
println(s"Email: $email")
274
275
// JavaScript Array usage
276
val jsArray = js.Array(1, 2, 3, 4, 5)
277
jsArray.push(6)
278
val popped = jsArray.pop()
279
println(s"Array: ${jsArray.toList}, Popped: $popped")
280
281
// Type checking and conversion
282
def processValue(value: Any): String = {
283
js.typeOf(value) match {
284
case "string" => s"String: $value"
285
case "number" => s"Number: $value"
286
case "boolean" => s"Boolean: $value"
287
case "undefined" => "Undefined value"
288
case _ => s"Object: $value"
289
}
290
}
291
292
println(processValue("hello")) // "String: hello"
293
println(processValue(42)) // "Number: 42"
294
println(processValue(js.undefined)) // "Undefined value"
295
296
// ClassTag usage for generic arrays
297
def createArray[T: ClassTag](size: Int, default: T): Array[T] = {
298
val ct = implicitly[ClassTag[T]]
299
val array = ct.newArray(size)
300
for (i <- array.indices) {
301
array(i) = default
302
}
303
array
304
}
305
306
val intArray = createArray(5, 0)
307
val stringArray = createArray(3, "default")
308
println(s"Int array: ${intArray.toList}")
309
println(s"String array: ${stringArray.toList}")
310
311
// Runtime type information
312
def getTypeInfo[T: ClassTag](value: T): String = {
313
val ct = implicitly[ClassTag[T]]
314
s"Value: $value, Type: ${ct.runtimeClass.getSimpleName}"
315
}
316
317
println(getTypeInfo(42))
318
println(getTypeInfo("hello"))
319
println(getTypeInfo(List(1, 2, 3)))
320
321
// Boxing/unboxing utilities (typically handled automatically)
322
import scala.runtime.BoxesRunTime
323
324
val boxedInt = BoxesRunTime.boxToInteger(42)
325
val unboxedInt = BoxesRunTime.unboxToInt(boxedInt)
326
println(s"Boxed: $boxedInt, Unboxed: $unboxedInt")
327
328
// Safe equality with boxing consideration
329
val result1 = BoxesRunTime.equals(42, 42.0) // false (different types)
330
val result2 = BoxesRunTime.equals(42, 42) // true (same type and value)
331
println(s"42 == 42.0: $result1")
332
println(s"42 == 42: $result2")
333
334
// Global JavaScript environment access
335
val navigator = js.Dynamic.global.navigator
336
if (!js.isUndefined(navigator)) {
337
val userAgent = navigator.userAgent.asInstanceOf[String]
338
println(s"User Agent: $userAgent")
339
} else {
340
println("Running in Node.js environment")
341
}
342
343
// Creating JavaScript objects
344
val config = js.obj(
345
"timeout" -> 5000,
346
"retries" -> 3,
347
"debug" -> true
348
)
349
350
// JavaScript function creation and invocation
351
val jsFunc: js.Function1[Int, Int] = (x: Int) => x * 2
352
val result = jsFunc(21)
353
println(s"JavaScript function result: $result")
354
355
// Working with JavaScript Promises (if available)
356
val jsPromise = js.Promise.resolve("Hello from Promise")
357
val scalaFuture = js.fromPromise(jsPromise)
358
359
scalaFuture.foreach { value =>
360
println(s"Promise result: $value")
361
}
362
363
// Array-like operations with js.Array
364
val fruits = js.Array("apple", "banana", "cherry")
365
fruits.push("date")
366
val sorted = fruits.sort()
367
val joined = fruits.join(" | ")
368
println(s"Fruits: $joined")
369
370
// Runtime class information
371
def analyzeObject(obj: Any): Unit = {
372
val clazz = obj.getClass
373
println(s"Object: $obj")
374
println(s"Class: ${clazz.getName}")
375
println(s"Simple name: ${clazz.getSimpleName}")
376
println(s"Is String: ${clazz.isInstance("test")}")
377
println()
378
}
379
380
analyzeObject(42)
381
analyzeObject("hello")
382
analyzeObject(List(1, 2, 3))
383
```