or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced.mdcore-api.mddata-types.mddsl.mdindex.mdinstrumentation.mdinterop.md

interop.mddocs/

0

# Cross-Language Interoperability

1

2

Truffle's interoperability system enables seamless integration between different languages through a standardized message-based protocol. It provides polyglot object access, cross-language method calls, and unified data type handling across the Truffle ecosystem.

3

4

## Capabilities

5

6

### Interop Library System

7

8

Core library providing standardized messages for cross-language object interaction.

9

10

```java { .api }

11

/**

12

* Main library for polyglot interoperability operations

13

*/

14

public abstract class InteropLibrary extends Library {

15

16

/**

17

* Get uncached interop library instance

18

* @return Uncached InteropLibrary

19

*/

20

public static InteropLibrary getUncached();

21

22

/**

23

* Get interop library for specific receiver

24

* @param receiver Object to get library for

25

* @return InteropLibrary instance

26

*/

27

public static InteropLibrary getUncached(Object receiver);

28

29

// ===== Array Operations =====

30

31

/**

32

* Check if object has array elements

33

* @param receiver Object to check

34

* @return true if has array elements

35

*/

36

public abstract boolean hasArrayElements(Object receiver);

37

38

/**

39

* Get array size

40

* @param receiver Array object

41

* @return Array size

42

* @throws UnsupportedMessageException if not an array

43

*/

44

public abstract long getArraySize(Object receiver) throws UnsupportedMessageException;

45

46

/**

47

* Check if array index is readable

48

* @param receiver Array object

49

* @param index Array index

50

* @return true if readable

51

*/

52

public abstract boolean isArrayElementReadable(Object receiver, long index);

53

54

/**

55

* Check if array index is writable

56

* @param receiver Array object

57

* @param index Array index

58

* @return true if writable

59

*/

60

public abstract boolean isArrayElementWritable(Object receiver, long index);

61

62

/**

63

* Check if array index is insertable

64

* @param receiver Array object

65

* @param index Array index

66

* @return true if insertable

67

*/

68

public abstract boolean isArrayElementInsertable(Object receiver, long index);

69

70

/**

71

* Check if array index is removable

72

* @param receiver Array object

73

* @param index Array index

74

* @return true if removable

75

*/

76

public abstract boolean isArrayElementRemovable(Object receiver, long index);

77

78

/**

79

* Read array element

80

* @param receiver Array object

81

* @param index Array index

82

* @return Element value

83

* @throws UnsupportedMessageException if not supported

84

* @throws InvalidArrayIndexException if invalid index

85

*/

86

public abstract Object readArrayElement(Object receiver, long index)

87

throws UnsupportedMessageException, InvalidArrayIndexException;

88

89

/**

90

* Write array element

91

* @param receiver Array object

92

* @param index Array index

93

* @param value New value

94

* @throws UnsupportedMessageException if not supported

95

* @throws UnsupportedTypeException if incompatible type

96

* @throws InvalidArrayIndexException if invalid index

97

*/

98

public abstract void writeArrayElement(Object receiver, long index, Object value)

99

throws UnsupportedMessageException, UnsupportedTypeException, InvalidArrayIndexException;

100

101

/**

102

* Remove array element

103

* @param receiver Array object

104

* @param index Array index

105

* @throws UnsupportedMessageException if not supported

106

* @throws InvalidArrayIndexException if invalid index

107

*/

108

public abstract void removeArrayElement(Object receiver, long index)

109

throws UnsupportedMessageException, InvalidArrayIndexException;

110

111

// ===== Object Member Operations =====

112

113

/**

114

* Check if object has members

115

* @param receiver Object to check

116

* @return true if has members

117

*/

118

public abstract boolean hasMembers(Object receiver);

119

120

/**

121

* Get object members

122

* @param receiver Object to inspect

123

* @param includeInternal Whether to include internal members

124

* @return Object with member names

125

* @throws UnsupportedMessageException if not supported

126

*/

127

public abstract Object getMembers(Object receiver, boolean includeInternal)

128

throws UnsupportedMessageException;

129

130

/**

131

* Check if member is readable

132

* @param receiver Object to check

133

* @param member Member name

134

* @return true if readable

135

*/

136

public abstract boolean isMemberReadable(Object receiver, String member);

137

138

/**

139

* Check if member is writable

140

* @param receiver Object to check

141

* @param member Member name

142

* @return true if writable

143

*/

144

public abstract boolean isMemberWritable(Object receiver, String member);

145

146

/**

147

* Check if member is insertable

148

* @param receiver Object to check

149

* @param member Member name

150

* @return true if insertable

151

*/

152

public abstract boolean isMemberInsertable(Object receiver, String member);

153

154

/**

155

* Check if member is removable

156

* @param receiver Object to check

157

* @param member Member name

158

* @return true if removable

159

*/

160

public abstract boolean isMemberRemovable(Object receiver, String member);

161

162

/**

163

* Check if member is invocable

164

* @param receiver Object to check

165

* @param member Member name

166

* @return true if invocable

167

*/

168

public abstract boolean isMemberInvocable(Object receiver, String member);

169

170

/**

171

* Read object member

172

* @param receiver Object to read from

173

* @param member Member name

174

* @return Member value

175

* @throws UnsupportedMessageException if not supported

176

* @throws UnknownIdentifierException if member not found

177

*/

178

public abstract Object readMember(Object receiver, String member)

179

throws UnsupportedMessageException, UnknownIdentifierException;

180

181

/**

182

* Write object member

183

* @param receiver Object to write to

184

* @param member Member name

185

* @param value New value

186

* @throws UnsupportedMessageException if not supported

187

* @throws UnknownIdentifierException if member not found

188

* @throws UnsupportedTypeException if incompatible type

189

*/

190

public abstract void writeMember(Object receiver, String member, Object value)

191

throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException;

192

193

/**

194

* Remove object member

195

* @param receiver Object to modify

196

* @param member Member name

197

* @throws UnsupportedMessageException if not supported

198

* @throws UnknownIdentifierException if member not found

199

*/

200

public abstract void removeMember(Object receiver, String member)

201

throws UnsupportedMessageException, UnknownIdentifierException;

202

203

/**

204

* Invoke object member

205

* @param receiver Object containing member

206

* @param member Member name

207

* @param arguments Invocation arguments

208

* @return Invocation result

209

* @throws UnsupportedMessageException if not supported

210

* @throws UnknownIdentifierException if member not found

211

* @throws ArityException if wrong number of arguments

212

* @throws UnsupportedTypeException if incompatible argument types

213

*/

214

public abstract Object invokeMember(Object receiver, String member, Object... arguments)

215

throws UnsupportedMessageException, UnknownIdentifierException, ArityException, UnsupportedTypeException;

216

217

// ===== Executable Operations =====

218

219

/**

220

* Check if object is executable

221

* @param receiver Object to check

222

* @return true if executable

223

*/

224

public abstract boolean isExecutable(Object receiver);

225

226

/**

227

* Execute object

228

* @param receiver Executable object

229

* @param arguments Execution arguments

230

* @return Execution result

231

* @throws UnsupportedMessageException if not executable

232

* @throws ArityException if wrong number of arguments

233

* @throws UnsupportedTypeException if incompatible argument types

234

*/

235

public abstract Object execute(Object receiver, Object... arguments)

236

throws UnsupportedMessageException, ArityException, UnsupportedTypeException;

237

238

// ===== Instantiation Operations =====

239

240

/**

241

* Check if object is instantiable

242

* @param receiver Object to check

243

* @return true if instantiable

244

*/

245

public abstract boolean isInstantiable(Object receiver);

246

247

/**

248

* Instantiate object

249

* @param receiver Constructor object

250

* @param arguments Constructor arguments

251

* @return New instance

252

* @throws UnsupportedMessageException if not instantiable

253

* @throws ArityException if wrong number of arguments

254

* @throws UnsupportedTypeException if incompatible argument types

255

*/

256

public abstract Object instantiate(Object receiver, Object... arguments)

257

throws UnsupportedMessageException, ArityException, UnsupportedTypeException;

258

259

// ===== Pointer Operations =====

260

261

/**

262

* Check if object is a pointer

263

* @param receiver Object to check

264

* @return true if pointer

265

*/

266

public abstract boolean isPointer(Object receiver);

267

268

/**

269

* Get pointer address

270

* @param receiver Pointer object

271

* @return Pointer address

272

* @throws UnsupportedMessageException if not a pointer

273

*/

274

public abstract long asPointer(Object receiver)

275

throws UnsupportedMessageException;

276

277

/**

278

* Convert to native pointer

279

* @param receiver Object to convert

280

* @return Native pointer

281

* @throws UnsupportedMessageException if not convertible

282

*/

283

public abstract void toNative(Object receiver)

284

throws UnsupportedMessageException;

285

286

// ===== Type Checking Operations =====

287

288

/**

289

* Check if object is null

290

* @param receiver Object to check

291

* @return true if null

292

*/

293

public abstract boolean isNull(Object receiver);

294

295

/**

296

* Check if object is boolean

297

* @param receiver Object to check

298

* @return true if boolean

299

*/

300

public abstract boolean isBoolean(Object receiver);

301

302

/**

303

* Convert to boolean

304

* @param receiver Object to convert

305

* @return boolean value

306

* @throws UnsupportedMessageException if not convertible

307

*/

308

public abstract boolean asBoolean(Object receiver)

309

throws UnsupportedMessageException;

310

311

/**

312

* Check if object is string

313

* @param receiver Object to check

314

* @return true if string

315

*/

316

public abstract boolean isString(Object receiver);

317

318

/**

319

* Convert to string

320

* @param receiver Object to convert

321

* @return String value

322

* @throws UnsupportedMessageException if not convertible

323

*/

324

public abstract String asString(Object receiver)

325

throws UnsupportedMessageException;

326

327

/**

328

* Check if object is number

329

* @param receiver Object to check

330

* @return true if number

331

*/

332

public abstract boolean isNumber(Object receiver);

333

334

/**

335

* Check if number fits in int

336

* @param receiver Number object

337

* @return true if fits in int

338

*/

339

public abstract boolean fitsInInt(Object receiver);

340

341

/**

342

* Convert to int

343

* @param receiver Number object

344

* @return int value

345

* @throws UnsupportedMessageException if not convertible

346

*/

347

public abstract int asInt(Object receiver)

348

throws UnsupportedMessageException;

349

350

/**

351

* Check if number fits in long

352

* @param receiver Number object

353

* @return true if fits in long

354

*/

355

public abstract boolean fitsInLong(Object receiver);

356

357

/**

358

* Convert to long

359

* @param receiver Number object

360

* @return long value

361

* @throws UnsupportedMessageException if not convertible

362

*/

363

public abstract long asLong(Object receiver)

364

throws UnsupportedMessageException;

365

366

/**

367

* Check if number fits in double

368

* @param receiver Number object

369

* @return true if fits in double

370

*/

371

public abstract boolean fitsInDouble(Object receiver);

372

373

/**

374

* Convert to double

375

* @param receiver Number object

376

* @return double value

377

* @throws UnsupportedMessageException if not convertible

378

*/

379

public abstract double asDouble(Object receiver)

380

throws UnsupportedMessageException;

381

}

382

```

383

384

### Interoperable Object Interface

385

386

Base interface for objects that participate in cross-language interoperability.

387

388

```java { .api }

389

/**

390

* Marker interface for objects that can be used across language boundaries

391

*/

392

public interface TruffleObject {

393

// Marker interface - no methods

394

}

395

```

396

397

### Library Export System

398

399

Annotations for exporting interop capabilities to other languages.

400

401

```java { .api }

402

/**

403

* Exports library implementation for a class

404

*/

405

@Retention(RetentionPolicy.CLASS)

406

@Target(ElementType.TYPE)

407

@Repeatable(ExportLibrary.List.class)

408

public @interface ExportLibrary {

409

410

/**

411

* Library class to export

412

* @return Library class

413

*/

414

Class<? extends Library> value();

415

416

/**

417

* Receiver type for library

418

* @return Receiver class

419

*/

420

Class<?> receiverType() default Object.class;

421

422

/**

423

* Priority for library resolution

424

* @return Priority value

425

*/

426

int priority() default 0;

427

428

/**

429

* Container for multiple ExportLibrary annotations

430

*/

431

@Retention(RetentionPolicy.CLASS)

432

@Target(ElementType.TYPE)

433

@interface List {

434

ExportLibrary[] value();

435

}

436

}

437

438

/**

439

* Exports message implementation

440

*/

441

@Retention(RetentionPolicy.CLASS)

442

@Target(ElementType.METHOD)

443

public @interface ExportMessage {

444

445

/**

446

* Message name (defaults to method name)

447

* @return Message name

448

*/

449

String name() default "";

450

451

/**

452

* Library class containing message

453

* @return Library class

454

*/

455

Class<? extends Library> library() default Library.class;

456

}

457

```

458

459

**Usage Example:**

460

461

```java

462

@ExportLibrary(InteropLibrary.class)

463

public class MyInteropObject implements TruffleObject {

464

465

private final Map<String, Object> members = new HashMap<>();

466

467

@ExportMessage

468

boolean hasMembers() {

469

return true;

470

}

471

472

@ExportMessage

473

Object getMembers(boolean includeInternal) {

474

return new MemberKeys(members.keySet());

475

}

476

477

@ExportMessage

478

boolean isMemberReadable(String member) {

479

return members.containsKey(member);

480

}

481

482

@ExportMessage

483

Object readMember(String member) throws UnknownIdentifierException {

484

Object value = members.get(member);

485

if (value == null) {

486

throw UnknownIdentifierException.create(member);

487

}

488

return value;

489

}

490

491

@ExportMessage

492

boolean isMemberWritable(String member) {

493

return true;

494

}

495

496

@ExportMessage

497

void writeMember(String member, Object value) {

498

members.put(member, value);

499

}

500

}

501

```

502

503

### Node Library System

504

505

Library for operations on AST nodes in interop contexts.

506

507

```java { .api }

508

/**

509

* Library for interop operations on nodes

510

*/

511

public abstract class NodeLibrary extends Library {

512

513

/**

514

* Get uncached node library

515

* @return Uncached NodeLibrary

516

*/

517

public static NodeLibrary getUncached();

518

519

/**

520

* Check if receiver accepts language and frame

521

* @param receiver Node to check

522

* @param frame Execution frame

523

* @param language Target language

524

* @return true if accepts

525

*/

526

public boolean accepts(Object receiver, VirtualFrame frame, Class<? extends TruffleLanguage<?>> language) {

527

return false;

528

}

529

530

/**

531

* Get view of node for specific language

532

* @param receiver Node to get view for

533

* @param frame Execution frame

534

* @param language Target language

535

* @return Language-specific view

536

* @throws UnsupportedMessageException if not supported

537

*/

538

public Object getView(Object receiver, VirtualFrame frame, Class<? extends TruffleLanguage<?>> language)

539

throws UnsupportedMessageException {

540

throw UnsupportedMessageException.create();

541

}

542

}

543

```

544

545

### Exception Types

546

547

Comprehensive exception hierarchy for interop error handling.

548

549

```java { .api }

550

/**

551

* Base class for all interop exceptions

552

*/

553

public abstract class InteropException extends AbstractTruffleException {

554

555

/**

556

* Protected constructor

557

* @param message Exception message

558

*/

559

protected InteropException(String message) {

560

super(message);

561

}

562

563

/**

564

* Protected constructor

565

* @param message Exception message

566

* @param cause Exception cause

567

*/

568

protected InteropException(String message, Throwable cause) {

569

super(message, cause);

570

}

571

}

572

573

/**

574

* Exception for unsupported interop messages

575

*/

576

public final class UnsupportedMessageException extends InteropException {

577

578

/**

579

* Create exception

580

* @return New exception instance

581

*/

582

public static UnsupportedMessageException create() {

583

return new UnsupportedMessageException();

584

}

585

586

private UnsupportedMessageException() {

587

super("Message not supported");

588

}

589

}

590

591

/**

592

* Exception for incorrect number of arguments

593

*/

594

public final class ArityException extends InteropException {

595

596

/**

597

* Create exception

598

* @param expectedArity Expected number of arguments

599

* @param actualArity Actual number of arguments

600

* @return New exception instance

601

*/

602

public static ArityException create(int expectedArity, int actualArity) {

603

return new ArityException(expectedArity, actualArity);

604

}

605

606

private final int expectedArity;

607

private final int actualArity;

608

609

private ArityException(int expectedArity, int actualArity) {

610

super("Expected " + expectedArity + " arguments but got " + actualArity);

611

this.expectedArity = expectedArity;

612

this.actualArity = actualArity;

613

}

614

615

/**

616

* Get expected arity

617

* @return Expected number of arguments

618

*/

619

public int getExpectedArity() {

620

return expectedArity;

621

}

622

623

/**

624

* Get actual arity

625

* @return Actual number of arguments

626

*/

627

public int getActualArity() {

628

return actualArity;

629

}

630

}

631

632

/**

633

* Exception for unsupported type conversions

634

*/

635

public final class UnsupportedTypeException extends InteropException {

636

637

/**

638

* Create exception

639

* @param suppliedValues Values that caused the error

640

* @return New exception instance

641

*/

642

public static UnsupportedTypeException create(Object[] suppliedValues) {

643

return new UnsupportedTypeException(suppliedValues);

644

}

645

646

/**

647

* Create exception with message

648

* @param suppliedValues Values that caused the error

649

* @param message Error message

650

* @return New exception instance

651

*/

652

public static UnsupportedTypeException create(Object[] suppliedValues, String message) {

653

return new UnsupportedTypeException(suppliedValues, message);

654

}

655

656

private final Object[] suppliedValues;

657

658

private UnsupportedTypeException(Object[] suppliedValues) {

659

super("Unsupported type");

660

this.suppliedValues = suppliedValues;

661

}

662

663

private UnsupportedTypeException(Object[] suppliedValues, String message) {

664

super(message);

665

this.suppliedValues = suppliedValues;

666

}

667

668

/**

669

* Get supplied values

670

* @return Array of supplied values

671

*/

672

public Object[] getSuppliedValues() {

673

return suppliedValues;

674

}

675

}

676

677

/**

678

* Exception for unknown identifiers/members

679

*/

680

public final class UnknownIdentifierException extends InteropException {

681

682

/**

683

* Create exception

684

* @param unknownIdentifier Unknown identifier

685

* @return New exception instance

686

*/

687

public static UnknownIdentifierException create(String unknownIdentifier) {

688

return new UnknownIdentifierException(unknownIdentifier);

689

}

690

691

private final String unknownIdentifier;

692

693

private UnknownIdentifierException(String unknownIdentifier) {

694

super("Unknown identifier: " + unknownIdentifier);

695

this.unknownIdentifier = unknownIdentifier;

696

}

697

698

/**

699

* Get unknown identifier

700

* @return Unknown identifier string

701

*/

702

public String getUnknownIdentifier() {

703

return unknownIdentifier;

704

}

705

}

706

707

/**

708

* Exception for invalid array indices

709

*/

710

public final class InvalidArrayIndexException extends InteropException {

711

712

/**

713

* Create exception

714

* @param invalidIndex Invalid index value

715

* @return New exception instance

716

*/

717

public static InvalidArrayIndexException create(long invalidIndex) {

718

return new InvalidArrayIndexException(invalidIndex);

719

}

720

721

private final long invalidIndex;

722

723

private InvalidArrayIndexException(long invalidIndex) {

724

super("Invalid array index: " + invalidIndex);

725

this.invalidIndex = invalidIndex;

726

}

727

728

/**

729

* Get invalid index

730

* @return Invalid index value

731

*/

732

public long getInvalidIndex() {

733

return invalidIndex;

734

}

735

}

736

737

/**

738

* Exception for iterator exhaustion

739

*/

740

public final class StopIterationException extends InteropException {

741

742

/**

743

* Create exception

744

* @return New exception instance

745

*/

746

public static StopIterationException create() {

747

return new StopIterationException();

748

}

749

750

private StopIterationException() {

751

super("Iterator exhausted");

752

}

753

}

754

```

755

756

### Exception Type Classification

757

758

Enumeration for categorizing interop exceptions.

759

760

```java { .api }

761

/**

762

* Categories of interop exceptions

763

*/

764

public enum ExceptionType {

765

766

/**

767

* Runtime error in guest language

768

*/

769

RUNTIME_ERROR,

770

771

/**

772

* Parsing error in guest language

773

*/

774

PARSE_ERROR,

775

776

/**

777

* Exit request from guest language

778

*/

779

EXIT,

780

781

/**

782

* Interrupt signal

783

*/

784

INTERRUPT

785

}

786

```

787

788

### Iterator Support

789

790

Classes for cross-language iteration support.

791

792

```java { .api }

793

/**

794

* Iterator for arrays in interop contexts

795

*/

796

public final class ArrayIterator implements TruffleObject {

797

798

/**

799

* Create array iterator

800

* @param array Array to iterate

801

* @return ArrayIterator instance

802

*/

803

public static ArrayIterator create(Object array) {

804

return new ArrayIterator(array);

805

}

806

807

private ArrayIterator(Object array) {

808

// Implementation details

809

}

810

}

811

812

/**

813

* Iterator for hash-like objects in interop contexts

814

*/

815

public final class HashIterator implements TruffleObject {

816

817

/**

818

* Create hash iterator

819

* @param hash Hash object to iterate

820

* @return HashIterator instance

821

*/

822

public static HashIterator create(Object hash) {

823

return new HashIterator(hash);

824

}

825

826

private HashIterator(Object hash) {

827

// Implementation details

828

}

829

}

830

```

831

832

## Types

833

834

### Library System Types

835

836

```java { .api }

837

/**

838

* Base class for all Truffle libraries

839

*/

840

public abstract class Library extends Node {

841

842

/**

843

* Check if library accepts receiver

844

* @param receiver Object to check

845

* @return true if accepts

846

*/

847

public boolean accepts(Object receiver) {

848

return true;

849

}

850

}

851

852

/**

853

* Factory for library instances

854

*/

855

public abstract class LibraryFactory<T extends Library> {

856

857

/**

858

* Get uncached library instance

859

* @return Uncached library

860

*/

861

public abstract T getUncached();

862

863

/**

864

* Get uncached library for specific receiver

865

* @param receiver Target receiver

866

* @return Uncached library

867

*/

868

public abstract T getUncached(Object receiver);

869

870

/**

871

* Create cached library

872

* @param receiver Target receiver

873

* @return Cached library

874

*/

875

public abstract T create(Object receiver);

876

}

877

878

/**

879

* Message representation for library operations

880

*/

881

public abstract class Message {

882

883

/**

884

* Get message name

885

* @return Message name

886

*/

887

public abstract String getSimpleName();

888

889

/**

890

* Get qualified message name

891

* @return Qualified name

892

*/

893

public abstract String getQualifiedName();

894

}

895

```