0
# Core Language Implementation API
1
2
The core Truffle API provides essential abstractions for implementing dynamic languages on the JVM. This includes language registration, context management, AST node hierarchies, execution frames, and source code representation.
3
4
## Capabilities
5
6
### Language Registration and Management
7
8
The foundation for implementing a Truffle-based dynamic language through the `TruffleLanguage` abstract class and related infrastructure.
9
10
```java { .api }
11
/**
12
* Base class for implementing Truffle languages. Must be annotated with @Registration.
13
*/
14
public abstract class TruffleLanguage<C> {
15
16
/**
17
* Create a new context for this language
18
* @param env The language environment
19
* @return New context instance
20
*/
21
protected abstract C createContext(Env env);
22
23
/**
24
* Parse source code and return executable call target
25
* @param request Parsing request with source and context
26
* @return CallTarget for execution
27
*/
28
protected abstract CallTarget parse(ParsingRequest request) throws Exception;
29
30
/**
31
* Get language context for current thread
32
* @return Current context instance
33
*/
34
protected final C getCurrentContext();
35
36
/**
37
* Get language environment
38
* @return Current environment
39
*/
40
protected final Env getCurrentEnv();
41
42
/**
43
* Check if context pre-initialization is supported
44
* @return true if pre-initialization supported
45
*/
46
protected boolean areOptionsCompatible(OptionValues firstOptions, OptionValues newOptions);
47
48
/**
49
* Language registration annotation
50
*/
51
@Retention(RetentionPolicy.RUNTIME)
52
@Target(ElementType.TYPE)
53
public @interface Registration {
54
String id();
55
String name();
56
String version() default "";
57
String[] mimeType() default {};
58
boolean interactive() default true;
59
boolean internal() default false;
60
}
61
62
/**
63
* Language environment providing access to system services
64
*/
65
public static final class Env {
66
67
/**
68
* Get file system access for internal files
69
* @param path File path
70
* @return TruffleFile instance
71
*/
72
public TruffleFile getInternalTruffleFile(String path);
73
74
/**
75
* Get public file system access
76
* @param path File path
77
* @return TruffleFile instance
78
*/
79
public TruffleFile getPublicTruffleFile(String path);
80
81
/**
82
* Get logger for this language
83
* @param loggerName Logger name
84
* @return TruffleLogger instance
85
*/
86
public TruffleLogger getLogger(String loggerName);
87
88
/**
89
* Register service for other languages/instruments
90
* @param service Service object
91
*/
92
public void registerService(Object service);
93
94
/**
95
* Get option values for this language
96
* @return OptionValues instance
97
*/
98
public OptionValues getOptions();
99
100
/**
101
* Check if context pre-initialization active
102
* @return true if pre-initializing
103
*/
104
public boolean isPreInitialization();
105
}
106
107
/**
108
* Parsing request containing source and context information
109
*/
110
public static final class ParsingRequest {
111
112
/**
113
* Get source to parse
114
* @return Source instance
115
*/
116
public Source getSource();
117
118
/**
119
* Get argument names for top-level function
120
* @return Array of argument names
121
*/
122
public String[] getArgumentNames();
123
}
124
}
125
```
126
127
**Usage Example:**
128
129
```java
130
@TruffleLanguage.Registration(id = "mylang", name = "MyLanguage", version = "1.0")
131
public final class MyLanguage extends TruffleLanguage<MyContext> {
132
133
@Override
134
protected MyContext createContext(Env env) {
135
return new MyContext(env);
136
}
137
138
@Override
139
protected CallTarget parse(ParsingRequest request) throws Exception {
140
Source source = request.getSource();
141
// Parse source and build AST
142
MyRootNode rootNode = MyParser.parse(source, this);
143
return rootNode.getCallTarget();
144
}
145
}
146
```
147
148
### AST Node Hierarchy
149
150
Core node classes for building abstract syntax trees that represent executable code.
151
152
```java { .api }
153
/**
154
* Base class for all AST nodes in Truffle
155
*/
156
public abstract class Node implements NodeInterface, Cloneable {
157
158
/**
159
* Replace this node with a new node in the AST
160
* @param newNode Replacement node
161
* @return The new node
162
*/
163
public final <T extends Node> T replace(T newNode);
164
165
/**
166
* Insert new child nodes into this node
167
* @param newChildren New child nodes
168
* @return Array of inserted nodes
169
*/
170
public final <T extends Node> T[] insert(T[] newChildren);
171
172
/**
173
* Get execution cost hint for this node
174
* @return NodeCost enum value
175
*/
176
public final NodeCost getCost();
177
178
/**
179
* Get source section for this node
180
* @return SourceSection or null
181
*/
182
public final SourceSection getSourceSection();
183
184
/**
185
* Set source section for this node
186
* @param sourceSection Source section
187
*/
188
public final void setSourceSection(SourceSection sourceSection);
189
190
/**
191
* Get root node containing this node
192
* @return RootNode ancestor
193
*/
194
public final RootNode getRootNode();
195
196
/**
197
* Called when node is inserted into AST
198
* @param newChild Child node being inserted
199
*/
200
protected final void notifyInserted(Node newChild);
201
202
/**
203
* Accept node visitor
204
* @param visitor NodeVisitor instance
205
*/
206
public final void accept(NodeVisitor visitor);
207
208
/**
209
* Get description for debugging
210
* @return String description
211
*/
212
public String getDescription();
213
}
214
215
/**
216
* Root node of an executable AST
217
*/
218
public abstract class RootNode extends Node {
219
220
/**
221
* Create root node for language
222
* @param language TruffleLanguage instance
223
*/
224
protected RootNode(TruffleLanguage<?> language);
225
226
/**
227
* Create root node with frame descriptor
228
* @param language TruffleLanguage instance
229
* @param frameDescriptor Frame descriptor
230
*/
231
protected RootNode(TruffleLanguage<?> language, FrameDescriptor frameDescriptor);
232
233
/**
234
* Execute this root node
235
* @param frame Execution frame
236
* @return Execution result
237
*/
238
public abstract Object execute(VirtualFrame frame);
239
240
/**
241
* Get call target for this root node
242
* @return CallTarget instance
243
*/
244
public final CallTarget getCallTarget();
245
246
/**
247
* Get name of this root node
248
* @return Name string
249
*/
250
public String getName();
251
252
/**
253
* Get frame descriptor
254
* @return FrameDescriptor instance
255
*/
256
public final FrameDescriptor getFrameDescriptor();
257
258
/**
259
* Check if this root node can be cloned
260
* @return true if clonable
261
*/
262
public boolean isCloningAllowed();
263
264
/**
265
* Create split version of this root node
266
* @return Split RootNode
267
*/
268
protected RootNode cloneUninitialized();
269
}
270
271
/**
272
* Node for executing other executable nodes
273
*/
274
public abstract class ExecutableNode extends Node {
275
276
/**
277
* Execute this node
278
* @param frame Execution frame
279
* @return Execution result
280
*/
281
public abstract Object execute(VirtualFrame frame);
282
}
283
284
/**
285
* Node for direct method calls with caching
286
*/
287
public abstract class DirectCallNode extends Node {
288
289
/**
290
* Create direct call node
291
* @param callTarget Target to call
292
* @return DirectCallNode instance
293
*/
294
public static DirectCallNode create(CallTarget callTarget);
295
296
/**
297
* Call target with arguments
298
* @param arguments Call arguments
299
* @return Call result
300
*/
301
public abstract Object call(Object[] arguments);
302
303
/**
304
* Get call target
305
* @return CallTarget instance
306
*/
307
public abstract CallTarget getCallTarget();
308
309
/**
310
* Check if call site is inlinable
311
* @return true if inlinable
312
*/
313
public abstract boolean isInlinable();
314
315
/**
316
* Check if call can be inlined
317
* @return true if can inline
318
*/
319
public abstract boolean isCallTargetCloningAllowed();
320
}
321
322
/**
323
* Node for indirect method calls
324
*/
325
public abstract class IndirectCallNode extends Node {
326
327
/**
328
* Create indirect call node
329
* @return IndirectCallNode instance
330
*/
331
public static IndirectCallNode create();
332
333
/**
334
* Call target with arguments
335
* @param callTarget Target to call
336
* @param arguments Call arguments
337
* @return Call result
338
*/
339
public abstract Object call(CallTarget callTarget, Object[] arguments);
340
}
341
```
342
343
### Execution Frames
344
345
Frame system for managing local variables and execution state during AST execution.
346
347
```java { .api }
348
/**
349
* Base interface for execution frames
350
*/
351
public interface Frame {
352
353
/**
354
* Get frame descriptor
355
* @return FrameDescriptor instance
356
*/
357
FrameDescriptor getFrameDescriptor();
358
359
/**
360
* Get call arguments
361
* @return Arguments array
362
*/
363
Object[] getArguments();
364
}
365
366
/**
367
* Virtual frame for efficient execution
368
*/
369
public interface VirtualFrame extends Frame {
370
371
/**
372
* Get object value from frame slot
373
* @param slot Frame slot index
374
* @return Object value
375
* @throws FrameSlotTypeException if wrong type
376
*/
377
Object getObject(int slot) throws FrameSlotTypeException;
378
379
/**
380
* Set object value in frame slot
381
* @param slot Frame slot index
382
* @param value Object value
383
*/
384
void setObject(int slot, Object value);
385
386
/**
387
* Get byte value from frame slot
388
* @param slot Frame slot index
389
* @return byte value
390
* @throws FrameSlotTypeException if wrong type
391
*/
392
byte getByte(int slot) throws FrameSlotTypeException;
393
394
/**
395
* Set byte value in frame slot
396
* @param slot Frame slot index
397
* @param value byte value
398
*/
399
void setByte(int slot, byte value);
400
401
/**
402
* Get boolean value from frame slot
403
* @param slot Frame slot index
404
* @return boolean value
405
* @throws FrameSlotTypeException if wrong type
406
*/
407
boolean getBoolean(int slot) throws FrameSlotTypeException;
408
409
/**
410
* Set boolean value in frame slot
411
* @param slot Frame slot index
412
* @param value boolean value
413
*/
414
void setBoolean(int slot, boolean value);
415
416
/**
417
* Get int value from frame slot
418
* @param slot Frame slot index
419
* @return int value
420
* @throws FrameSlotTypeException if wrong type
421
*/
422
int getInt(int slot) throws FrameSlotTypeException;
423
424
/**
425
* Set int value in frame slot
426
* @param slot Frame slot index
427
* @param value int value
428
*/
429
void setInt(int slot, int value);
430
431
/**
432
* Get long value from frame slot
433
* @param slot Frame slot index
434
* @return long value
435
* @throws FrameSlotTypeException if wrong type
436
*/
437
long getLong(int slot) throws FrameSlotTypeException;
438
439
/**
440
* Set long value in frame slot
441
* @param slot Frame slot index
442
* @param value long value
443
*/
444
void setLong(int slot, long value);
445
446
/**
447
* Get float value from frame slot
448
* @param slot Frame slot index
449
* @return float value
450
* @throws FrameSlotTypeException if wrong type
451
*/
452
float getFloat(int slot) throws FrameSlotTypeException;
453
454
/**
455
* Set float value in frame slot
456
* @param slot Frame slot index
457
* @param value float value
458
*/
459
void setFloat(int slot, float value);
460
461
/**
462
* Get double value from frame slot
463
* @param slot Frame slot index
464
* @return double value
465
* @throws FrameSlotTypeException if wrong type
466
*/
467
double getDouble(int slot) throws FrameSlotTypeException;
468
469
/**
470
* Set double value in frame slot
471
* @param slot Frame slot index
472
* @param value double value
473
*/
474
void setDouble(int slot, double value);
475
476
/**
477
* Materialize this virtual frame
478
* @return MaterializedFrame instance
479
*/
480
MaterializedFrame materialize();
481
}
482
483
/**
484
* Materialized frame for persistent access
485
*/
486
public interface MaterializedFrame extends Frame {
487
488
/**
489
* Get object value from frame slot
490
* @param slot Frame slot index
491
* @return Object value
492
*/
493
Object getObject(int slot);
494
495
/**
496
* Set object value in frame slot
497
* @param slot Frame slot index
498
* @param value Object value
499
*/
500
void setObject(int slot, Object value);
501
}
502
503
/**
504
* Descriptor defining frame layout
505
*/
506
public final class FrameDescriptor implements Cloneable {
507
508
/**
509
* Create new frame descriptor
510
* @return FrameDescriptor instance
511
*/
512
public static FrameDescriptor create();
513
514
/**
515
* Create frame descriptor with default value
516
* @param defaultValue Default slot value
517
* @return FrameDescriptor instance
518
*/
519
public static FrameDescriptor create(Object defaultValue);
520
521
/**
522
* Add new frame slot
523
* @param identifier Slot identifier
524
* @return FrameSlot instance
525
*/
526
public FrameSlot addFrameSlot(Object identifier);
527
528
/**
529
* Add frame slot with type hint
530
* @param identifier Slot identifier
531
* @param kind Type hint
532
* @return FrameSlot instance
533
*/
534
public FrameSlot addFrameSlot(Object identifier, FrameSlotKind kind);
535
536
/**
537
* Find existing frame slot
538
* @param identifier Slot identifier
539
* @return FrameSlot or null
540
*/
541
public FrameSlot findFrameSlot(Object identifier);
542
543
/**
544
* Get all frame slots
545
* @return List of FrameSlot instances
546
*/
547
public List<? extends FrameSlot> getSlots();
548
549
/**
550
* Get frame size
551
* @return Number of slots
552
*/
553
public int getSize();
554
}
555
556
/**
557
* Frame slot for variable storage
558
*/
559
public final class FrameSlot implements Cloneable {
560
561
/**
562
* Get slot identifier
563
* @return Identifier object
564
*/
565
public Object getIdentifier();
566
567
/**
568
* Get slot type hint
569
* @return FrameSlotKind enum
570
*/
571
public FrameSlotKind getKind();
572
573
/**
574
* Set slot type hint
575
* @param kind New type hint
576
*/
577
public void setKind(FrameSlotKind kind);
578
579
/**
580
* Get slot index
581
* @return Slot index
582
*/
583
public int getIndex();
584
}
585
586
/**
587
* Type hints for frame slots
588
*/
589
public enum FrameSlotKind {
590
Object, Long, Int, Double, Float, Boolean, Byte, Illegal
591
}
592
593
/**
594
* Exception for frame slot type mismatches
595
*/
596
public final class FrameSlotTypeException extends SlowPathException {
597
public static FrameSlotTypeException create();
598
}
599
```
600
601
### Source Code Representation
602
603
Classes for representing source code, source locations, and managing source metadata.
604
605
```java { .api }
606
/**
607
* Represents source code for parsing and execution
608
*/
609
public final class Source {
610
611
/**
612
* Create source builder
613
* @param language Language identifier
614
* @param characters Source text
615
* @param name Source name
616
* @return Builder instance
617
*/
618
public static Builder newBuilder(String language, CharSequence characters, String name);
619
620
/**
621
* Create source from file
622
* @param language Language identifier
623
* @param file TruffleFile instance
624
* @return Builder instance
625
*/
626
public static Builder newBuilder(String language, TruffleFile file);
627
628
/**
629
* Get source characters
630
* @return Source text
631
*/
632
public CharSequence getCharacters();
633
634
/**
635
* Get source name
636
* @return Source name
637
*/
638
public String getName();
639
640
/**
641
* Get source language
642
* @return Language identifier
643
*/
644
public String getLanguage();
645
646
/**
647
* Get source path
648
* @return Path string or null
649
*/
650
public String getPath();
651
652
/**
653
* Get source URI
654
* @return URI or null
655
*/
656
public URI getURI();
657
658
/**
659
* Check if source is interactive
660
* @return true if interactive
661
*/
662
public boolean isInteractive();
663
664
/**
665
* Check if source is internal
666
* @return true if internal
667
*/
668
public boolean isInternal();
669
670
/**
671
* Get MIME type
672
* @return MIME type string
673
*/
674
public String getMimeType();
675
676
/**
677
* Get character count
678
* @return Number of characters
679
*/
680
public int getLength();
681
682
/**
683
* Get line count
684
* @return Number of lines
685
*/
686
public int getLineCount();
687
688
/**
689
* Create source section
690
* @param startIndex Start character index
691
* @param length Character length
692
* @return SourceSection instance
693
*/
694
public SourceSection createSection(int startIndex, int length);
695
696
/**
697
* Create unavailable source section
698
* @return SourceSection instance
699
*/
700
public SourceSection createUnavailableSection();
701
702
/**
703
* Source builder class
704
*/
705
public static final class Builder {
706
707
/**
708
* Set source name
709
* @param name Source name
710
* @return Builder instance
711
*/
712
public Builder name(String name);
713
714
/**
715
* Set MIME type
716
* @param mimeType MIME type
717
* @return Builder instance
718
*/
719
public Builder mimeType(String mimeType);
720
721
/**
722
* Mark as interactive source
723
* @return Builder instance
724
*/
725
public Builder interactive();
726
727
/**
728
* Mark as internal source
729
* @return Builder instance
730
*/
731
public Builder internal();
732
733
/**
734
* Set encoding
735
* @param encoding Character encoding
736
* @return Builder instance
737
*/
738
public Builder encoding(Charset encoding);
739
740
/**
741
* Set URI
742
* @param uri Source URI
743
* @return Builder instance
744
*/
745
public Builder uri(URI uri);
746
747
/**
748
* Build source
749
* @return Source instance
750
*/
751
public Source build() throws IOException;
752
}
753
}
754
755
/**
756
* Represents a section of source code
757
*/
758
public final class SourceSection {
759
760
/**
761
* Check if source section is available
762
* @return true if available
763
*/
764
public boolean isAvailable();
765
766
/**
767
* Get containing source
768
* @return Source instance
769
*/
770
public Source getSource();
771
772
/**
773
* Get start line number (1-based)
774
* @return Start line
775
*/
776
public int getStartLine();
777
778
/**
779
* Get start column number (1-based)
780
* @return Start column
781
*/
782
public int getStartColumn();
783
784
/**
785
* Get end line number (1-based)
786
* @return End line
787
*/
788
public int getEndLine();
789
790
/**
791
* Get end column number (1-based)
792
* @return End column
793
*/
794
public int getEndColumn();
795
796
/**
797
* Get character index (0-based)
798
* @return Start character index
799
*/
800
public int getCharIndex();
801
802
/**
803
* Get character length
804
* @return Number of characters
805
*/
806
public int getCharLength();
807
808
/**
809
* Get end character index (0-based)
810
* @return End character index
811
*/
812
public int getCharEndIndex();
813
814
/**
815
* Get source characters for this section
816
* @return Character sequence
817
*/
818
public CharSequence getCharacters();
819
}
820
```
821
822
## Types
823
824
### Core Execution Types
825
826
```java { .api }
827
/**
828
* Executable call target
829
*/
830
public interface CallTarget {
831
832
/**
833
* Call with arguments
834
* @param arguments Call arguments
835
* @return Execution result
836
*/
837
Object call(Object... arguments);
838
}
839
840
/**
841
* Root call target for RootNode execution
842
*/
843
public interface RootCallTarget extends CallTarget {
844
845
/**
846
* Get root node
847
* @return RootNode instance
848
*/
849
RootNode getRootNode();
850
}
851
852
/**
853
* Node execution cost hint
854
*/
855
public enum NodeCost {
856
NONE, MONOMORPHIC, POLYMORPHIC, MEGAMORPHIC, UNINITIALIZED
857
}
858
859
/**
860
* Node visitor interface
861
*/
862
public interface NodeVisitor {
863
864
/**
865
* Visit node
866
* @param node Node to visit
867
* @return true to continue visiting
868
*/
869
boolean visit(Node node);
870
}
871
```