or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compilation-optimization.mdframes.mdindex.mdinteroperability.mdlanguage-spi.mdmonitoring-profiling.mdnodes.mdruntime-management.mdservice-provider-framework.md

nodes.mddocs/

0

# Node Framework

1

2

Abstract Syntax Tree (AST) node framework providing the foundation for building executable language interpreters with support for optimization, specialization, and compilation.

3

4

## Capabilities

5

6

### Node

7

8

Base class for all AST nodes in Truffle, providing core functionality for tree structure, source attribution, and optimization support.

9

10

```java { .api }

11

/**

12

* Base class for all nodes in a Truffle AST

13

* Provides tree structure, source information, and optimization hooks

14

*/

15

public abstract class Node implements NodeInterface, Cloneable {

16

/** Returns the parent node or null for root */

17

public final Node getParent();

18

19

/** Returns all child nodes */

20

public final Iterable<Node> getChildren();

21

22

/** Replaces this node with another node */

23

public final <T extends Node> T replace(T newNode);

24

25

/** Replaces this node with another node and reason */

26

public final <T extends Node> T replace(T newNode, CharSequence reason);

27

28

/** Checks if this node can be replaced */

29

public boolean isReplaceable();

30

31

/** Returns a deep copy of this node */

32

public Node deepCopy();

33

34

/** Returns a copy of this node */

35

public Node copy();

36

37

/** Accepts a node visitor */

38

public void accept(NodeVisitor visitor);

39

40

/** Returns the source section for this node */

41

public SourceSection getSourceSection();

42

43

/** Checks if source section is available */

44

public final boolean hasSourceSection();

45

46

/** Returns a string representation of the source location */

47

public final String getSourceLocation();

48

49

/** Returns the root node of this AST */

50

public final RootNode getRootNode();

51

52

/** Returns the language info for this node's language */

53

public final LanguageInfo getLanguage();

54

55

/** Notifies that this node was adopted into an AST */

56

protected void onReplace(Node newNode, CharSequence reason) {

57

// Default implementation does nothing

58

}

59

60

/**

61

* Returns a cost estimate for this node

62

* Used by the runtime for compilation heuristics

63

*/

64

public NodeCost getCost() {

65

return NodeCost.MONOMORPHIC;

66

}

67

68

/**

69

* Returns debug information about this node

70

*/

71

protected Object getDebugProperties() {

72

return null;

73

}

74

}

75

```

76

77

### RootNode

78

79

Special node representing the root of an executable AST, serving as the entry point for method execution.

80

81

```java { .api }

82

/**

83

* Root node of a Truffle AST representing an executable unit

84

* Entry point for method/function execution

85

*/

86

public abstract class RootNode extends Node {

87

/**

88

* Executes this root node with the given frame

89

* @param frame Execution frame containing arguments and local variables

90

* @return Execution result

91

*/

92

public abstract Object execute(VirtualFrame frame);

93

94

/** Returns the language info for this root node */

95

public final LanguageInfo getLanguageInfo();

96

97

/** Returns the call target for this root node */

98

public final CallTarget getCallTarget();

99

100

/** Returns the frame descriptor for this root node */

101

public final FrameDescriptor getFrameDescriptor();

102

103

/**

104

* Returns the name of this executable unit

105

* Used for debugging and profiling

106

*/

107

public String getName() {

108

return "Unnamed";

109

}

110

111

/**

112

* Returns a qualified name including module/class information

113

*/

114

public String getQualifiedName() {

115

return getName();

116

}

117

118

/**

119

* Checks if this root node represents internal code

120

* Internal code is excluded from stack traces by default

121

*/

122

public boolean isInternal() {

123

return false;

124

}

125

126

/**

127

* Checks if this root node can be cloned for splitting

128

*/

129

public boolean isCloningAllowed() {

130

return true;

131

}

132

133

/**

134

* Creates a split version of this root node

135

*/

136

public RootNode split() {

137

return cloneUninitializedRootNode();

138

}

139

140

/**

141

* Checks if this root node represents a tail call position

142

*/

143

public boolean isTail() {

144

return true;

145

}

146

147

/**

148

* Returns debug information for this root node

149

*/

150

protected Object getDebugInfo() {

151

return null;

152

}

153

}

154

```

155

156

**Usage Examples:**

157

158

```java

159

import com.oracle.truffle.api.frame.VirtualFrame;

160

import com.oracle.truffle.api.nodes.RootNode;

161

162

public class MyLanguageFunctionRootNode extends RootNode {

163

@Child private MyLanguageStatementNode bodyNode;

164

private final String functionName;

165

166

public MyLanguageFunctionRootNode(LanguageInfo language, FrameDescriptor frameDescriptor,

167

MyLanguageStatementNode bodyNode, String functionName) {

168

super(language, frameDescriptor);

169

this.bodyNode = bodyNode;

170

this.functionName = functionName;

171

}

172

173

@Override

174

public Object execute(VirtualFrame frame) {

175

try {

176

return bodyNode.execute(frame);

177

} catch (MyLanguageReturnException returnEx) {

178

return returnEx.getReturnValue();

179

}

180

}

181

182

@Override

183

public String getName() {

184

return functionName;

185

}

186

187

@Override

188

public boolean isInternal() {

189

return functionName.startsWith("__");

190

}

191

}

192

```

193

194

### DirectCallNode

195

196

Optimized node for calling a known call target directly.

197

198

```java { .api }

199

/**

200

* Optimized call node for direct calls to a known call target

201

* Provides better performance than indirect calls when target is known

202

*/

203

public abstract class DirectCallNode extends Node {

204

/** Creates a direct call node for the given call target */

205

public static DirectCallNode create(CallTarget callTarget);

206

207

/** Calls the target with the given arguments */

208

public abstract Object call(Object... arguments);

209

210

/** Returns the call target */

211

public abstract CallTarget getCallTarget();

212

213

/**

214

* Checks if this call can be inlined

215

* Inlining provides better optimization opportunities

216

*/

217

public abstract boolean isInlinable();

218

219

/**

220

* Checks if calls should be inlined

221

* Returns true if inlining is beneficial

222

*/

223

public abstract boolean isInliningForced();

224

225

/**

226

* Forces or prevents inlining of this call

227

*/

228

public abstract void forceInlining();

229

230

/**

231

* Returns the current call target, accounting for splitting

232

*/

233

public abstract CallTarget getCurrentCallTarget();

234

235

/**

236

* Returns the original call target before any splitting

237

*/

238

public abstract CallTarget getClonedCallTarget();

239

}

240

```

241

242

### IndirectCallNode

243

244

Node for calling targets that are not known at compile time.

245

246

```java { .api }

247

/**

248

* Call node for indirect calls where target is determined at runtime

249

* Less optimized than direct calls but supports dynamic dispatch

250

*/

251

public abstract class IndirectCallNode extends Node {

252

/** Creates an indirect call node */

253

public static IndirectCallNode create();

254

255

/** Calls the given call target with arguments */

256

public abstract Object call(CallTarget callTarget, Object... arguments);

257

}

258

```

259

260

### Node Annotations and Metadata

261

262

Annotations for configuring node behavior and specialization.

263

264

```java { .api }

265

/**

266

* Marks a field as a child node

267

* Child nodes are automatically adopted and included in tree operations

268

*/

269

@Target(ElementType.FIELD)

270

@Retention(RetentionPolicy.RUNTIME)

271

public @interface Child {

272

}

273

274

/**

275

* Marks a field as containing child nodes

276

* Used for arrays or collections of child nodes

277

*/

278

@Target(ElementType.FIELD)

279

@Retention(RetentionPolicy.RUNTIME)

280

public @interface Children {

281

}

282

283

/**

284

* Node cost enumeration for optimization heuristics

285

*/

286

public enum NodeCost {

287

/** Uninitialized node - has not executed yet */

288

UNINITIALIZED,

289

290

/** Monomorphic node - handles one type efficiently */

291

MONOMORPHIC,

292

293

/** Polymorphic node - handles multiple types with some overhead */

294

POLYMORPHIC,

295

296

/** Megamorphic node - handles many types with significant overhead */

297

MEGAMORPHIC,

298

299

/** Invalid node - should be replaced */

300

INVALID

301

}

302

```

303

304

### Node Visitors and Introspection

305

306

Utilities for traversing and analyzing node trees.

307

308

```java { .api }

309

/**

310

* Visitor interface for traversing node trees

311

*/

312

public interface NodeVisitor {

313

/**

314

* Visits a node

315

* @param node The node being visited

316

* @return true to continue visiting children, false to skip

317

*/

318

boolean visit(Node node);

319

}

320

321

/**

322

* Utility class for node tree operations

323

*/

324

public final class NodeUtil {

325

/** Finds all nodes of a specific type in the tree */

326

public static <T> List<T> findAllNodeInstances(Node root, Class<T> clazz);

327

328

/** Finds the first node of a specific type */

329

public static <T> T findFirstNodeInstance(Node root, Class<T> clazz);

330

331

/** Counts nodes in the tree */

332

public static int countNodes(Node root);

333

334

/** Creates a tree representation string */

335

public static String printTreeToString(Node root);

336

337

/** Dumps the tree structure to output */

338

public static void printTree(Node root);

339

340

/** Verifies tree structure integrity */

341

public static boolean verify(Node root);

342

343

/** Returns all parent nodes up to root */

344

public static List<Node> collectParents(Node node);

345

}

346

```

347

348

### Loop Nodes

349

350

Specialized nodes for optimized loop execution.

351

352

```java { .api }

353

/**

354

* Interface for optimized loop execution

355

*/

356

public interface LoopNode extends Node.Child {

357

/** Executes the loop */

358

void execute(VirtualFrame frame);

359

360

/** Returns the repeating node executed in the loop */

361

RepeatingNode getRepeatingNode();

362

}

363

364

/**

365

* Interface for nodes that repeat in a loop

366

*/

367

public interface RepeatingNode extends Node.Child {

368

/**

369

* Executes one iteration of the loop

370

* @param frame Current execution frame

371

* @return true to continue looping, false to exit

372

*/

373

boolean executeRepeating(VirtualFrame frame);

374

}

375

376

/**

377

* Factory for creating loop nodes

378

*/

379

public final class Truffle {

380

/** Creates an optimized loop node */

381

public static LoopNode createLoopNode(RepeatingNode repeatingNode);

382

}

383

```

384

385

**Usage Examples:**

386

387

```java

388

// Creating a specialized node with child nodes

389

public abstract class MyLanguageBinaryOpNode extends MyLanguageExpressionNode {

390

@Child private MyLanguageExpressionNode leftNode;

391

@Child private MyLanguageExpressionNode rightNode;

392

393

public MyLanguageBinaryOpNode(MyLanguageExpressionNode left, MyLanguageExpressionNode right) {

394

this.leftNode = left;

395

this.rightNode = right;

396

}

397

398

@Override

399

public final Object execute(VirtualFrame frame) {

400

Object leftValue = leftNode.execute(frame);

401

Object rightValue = rightNode.execute(frame);

402

return execute(leftValue, rightValue);

403

}

404

405

protected abstract Object execute(Object left, Object right);

406

}

407

408

// Using loop nodes for optimized iteration

409

public class MyLanguageWhileNode extends MyLanguageStatementNode {

410

@Child private MyLanguageExpressionNode conditionNode;

411

@Child private LoopNode loopNode;

412

413

public MyLanguageWhileNode(MyLanguageExpressionNode condition, MyLanguageStatementNode body) {

414

this.conditionNode = condition;

415

this.loopNode = Truffle.createLoopNode(new MyLanguageWhileRepeatingNode(condition, body));

416

}

417

418

@Override

419

public Object execute(VirtualFrame frame) {

420

loopNode.execute(frame);

421

return MyLanguageNull.INSTANCE;

422

}

423

424

private static class MyLanguageWhileRepeatingNode extends Node implements RepeatingNode {

425

@Child private MyLanguageExpressionNode conditionNode;

426

@Child private MyLanguageStatementNode bodyNode;

427

428

@Override

429

public boolean executeRepeating(VirtualFrame frame) {

430

if (!isTruthy(conditionNode.execute(frame))) {

431

return false; // Exit loop

432

}

433

434

try {

435

bodyNode.execute(frame);

436

return true; // Continue loop

437

} catch (MyLanguageBreakException e) {

438

return false; // Break statement

439

}

440

}

441

}

442

}

443

```

444

445

## Common Types

446

447

```java { .api }

448

public interface NodeInterface {

449

/** Base interface implemented by all nodes */

450

}

451

452

public final class SourceSection {

453

/** Returns the source object */

454

public Source getSource();

455

456

/** Checks if this section is available */

457

public boolean isAvailable();

458

459

/** Returns the start line (1-based) */

460

public int getStartLine();

461

462

/** Returns the start column (1-based) */

463

public int getStartColumn();

464

465

/** Returns the end line (1-based) */

466

public int getEndLine();

467

468

/** Returns the end column (1-based) */

469

public int getEndColumn();

470

471

/** Returns the character index (0-based) */

472

public int getCharIndex();

473

474

/** Returns the character length */

475

public int getCharLength();

476

477

/** Returns the characters in this section */

478

public CharSequence getCharacters();

479

}

480

481

public abstract class CallTarget {

482

/** Calls this target with the given arguments */

483

public abstract Object call(Object... arguments);

484

}

485

```