or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

context-management.mdindex.mdio-filesystem.mdlanguage-execution.mdmonitoring-management.mdproxy-system.mdsecurity-access.mdvalue-interop.md

value-interop.mddocs/

0

# Value Types and Host-Guest Interoperability

1

2

The Value class is the central abstraction for language-agnostic operations on polyglot values. It provides seamless interoperability between host (Java) and guest languages, enabling type conversion, container operations, and function execution across language boundaries.

3

4

## Value Type System

5

6

The Value class provides comprehensive type checking and conversion capabilities for all supported polyglot value types.

7

8

### Basic Type Checking

9

10

```java { .api }

11

public final class Value extends AbstractValue {

12

// Null and basic type checks

13

public boolean isNull();

14

public boolean isNumber();

15

public boolean isBoolean();

16

public boolean isString();

17

18

// Object type checks

19

public boolean isHostObject();

20

public boolean isProxyObject();

21

public boolean isNativePointer();

22

23

// Temporal type checks

24

public boolean isDate();

25

public boolean isTime();

26

public boolean isTimeZone();

27

public boolean isDuration();

28

public boolean isInstant();

29

30

// Exception checking

31

public boolean isException();

32

}

33

```

34

35

**Type Checking Example:**

36

37

```java

38

Context context = Context.create("js");

39

40

Value stringValue = context.eval("js", "'Hello World'");

41

Value numberValue = context.eval("js", "42.5");

42

Value arrayValue = context.eval("js", "[1, 2, 3]");

43

Value objectValue = context.eval("js", "({name: 'Alice', age: 30})");

44

45

System.out.println(stringValue.isString()); // true

46

System.out.println(numberValue.isNumber()); // true

47

System.out.println(arrayValue.hasArrayElements()); // true

48

System.out.println(objectValue.hasMembers()); // true

49

```

50

51

### Basic Type Conversion

52

53

```java { .api }

54

// Primitive type conversion

55

public boolean asBoolean();

56

public String asString();

57

public int asInt();

58

public long asLong();

59

public float asFloat();

60

public double asDouble();

61

public byte asByte();

62

public short asShort();

63

64

// Temporal type conversion

65

public LocalDate asDate();

66

public LocalTime asTime();

67

public ZoneId asTimeZone();

68

public Duration asDuration();

69

public Instant asInstant();

70

71

// Object type conversion

72

public long asNativePointer();

73

public <T> T asHostObject();

74

public <T extends Proxy> T asProxyObject();

75

```

76

77

**Type Conversion Examples:**

78

79

```java

80

Context context = Context.create("js");

81

82

// JavaScript number to Java types

83

Value jsNumber = context.eval("js", "Math.PI");

84

double pi = jsNumber.asDouble(); // 3.141592653589793

85

int piInt = jsNumber.asInt(); // 3 (truncated)

86

String piStr = jsNumber.asString(); // "3.141592653589793"

87

88

// JavaScript string to Java types

89

Value jsString = context.eval("js", "'42'");

90

int fromString = jsString.asInt(); // 42 (parsed)

91

String original = jsString.asString(); // "42"

92

93

// JavaScript boolean

94

Value jsBool = context.eval("js", "true");

95

boolean bool = jsBool.asBoolean(); // true

96

String boolStr = jsBool.asString(); // "true"

97

```

98

99

### Generic Type Conversion

100

101

```java { .api }

102

// Type-safe conversion with Class

103

public <T> T as(Class<T> targetType);

104

105

// Type-safe conversion with TypeLiteral

106

public <T> T as(TypeLiteral<T> targetType);

107

```

108

109

**Generic Conversion Examples:**

110

111

```java

112

Context context = Context.create("js");

113

114

// JavaScript array to Java List

115

Value jsArray = context.eval("js", "[1, 2, 3, 4, 5]");

116

List<Integer> javaList = jsArray.as(List.class);

117

System.out.println(javaList); // [1, 2, 3, 4, 5]

118

119

// JavaScript object to Java Map

120

Value jsObject = context.eval("js", "({name: 'Alice', age: 30})");

121

Map<String, Object> javaMap = jsObject.as(Map.class);

122

System.out.println(javaMap.get("name")); // "Alice"

123

124

// Custom type conversion with TypeLiteral

125

Value jsListOfMaps = context.eval("js", "[{x: 1}, {x: 2}, {x: 3}]");

126

TypeLiteral<List<Map<String, Integer>>> listType = new TypeLiteral<List<Map<String, Integer>>>() {};

127

List<Map<String, Integer>> typedList = jsListOfMaps.as(listType);

128

```

129

130

## Container Operations

131

132

The Value class provides unified access to container-like objects including arrays, objects with members, and hash maps.

133

134

### Array Operations

135

136

```java { .api }

137

// Array type checking and access

138

public boolean hasArrayElements();

139

public long getArraySize();

140

public Value getArrayElement(long index);

141

public void setArrayElement(long index, Object value);

142

public boolean removeArrayElement(long index);

143

```

144

145

**Array Manipulation Examples:**

146

147

```java

148

Context context = Context.create("js");

149

150

// Create and access JavaScript array

151

Value jsArray = context.eval("js", "['hello', 'world', 42, true]");

152

153

System.out.println(jsArray.hasArrayElements()); // true

154

System.out.println(jsArray.getArraySize()); // 4

155

156

// Access elements

157

System.out.println(jsArray.getArrayElement(0).asString()); // "hello"

158

System.out.println(jsArray.getArrayElement(2).asInt()); // 42

159

160

// Modify array

161

jsArray.setArrayElement(1, "polyglot");

162

jsArray.setArrayElement(4, "new element"); // Extends array

163

164

// Remove elements

165

jsArray.removeArrayElement(3); // Remove boolean true

166

System.out.println(jsArray.getArraySize()); // 4

167

```

168

169

### Member Operations

170

171

```java { .api }

172

// Object member operations

173

public boolean hasMembers();

174

public Set<String> getMemberKeys();

175

public boolean hasMember(String identifier);

176

public Value getMember(String identifier);

177

public void putMember(String identifier, Object value);

178

public boolean removeMember(String identifier);

179

```

180

181

**Member Access Examples:**

182

183

```java

184

Context context = Context.create("js");

185

186

// Create JavaScript object

187

Value jsObject = context.eval("js", """

188

({

189

name: 'Alice',

190

age: 30,

191

greet: function() { return 'Hello, ' + this.name; },

192

address: {

193

city: 'San Francisco',

194

country: 'USA'

195

}

196

})

197

""");

198

199

System.out.println(jsObject.hasMembers()); // true

200

201

// Get all member keys

202

Set<String> keys = jsObject.getMemberKeys();

203

System.out.println(keys); // [name, age, greet, address]

204

205

// Access members

206

System.out.println(jsObject.getMember("name").asString()); // "Alice"

207

System.out.println(jsObject.getMember("age").asInt()); // 30

208

209

// Access nested members

210

Value address = jsObject.getMember("address");

211

System.out.println(address.getMember("city").asString()); // "San Francisco"

212

213

// Modify members

214

jsObject.putMember("age", 31);

215

jsObject.putMember("email", "alice@example.com");

216

217

// Remove members

218

jsObject.removeMember("address");

219

System.out.println(jsObject.hasMember("address")); // false

220

```

221

222

### Hash/Map Operations

223

224

```java { .api }

225

// Hash map operations (for languages that support map-like objects)

226

public boolean hasHashEntries();

227

public long getHashSize();

228

public boolean hasHashEntry(Object key);

229

public Value getHashValue(Object key);

230

public Value getHashValueOrDefault(Object key, Object defaultValue);

231

public void putHashEntry(Object key, Object value);

232

public boolean removeHashEntry(Object key);

233

public Value getHashEntriesIterator();

234

public Value getHashKeysIterator();

235

public Value getHashValuesIterator();

236

```

237

238

**Hash Operations Examples:**

239

240

```java

241

Context context = Context.create("js");

242

243

// Create a Map-like structure

244

Value jsMap = context.eval("js", "new Map([['key1', 'value1'], ['key2', 42]])");

245

246

if (jsMap.hasHashEntries()) {

247

System.out.println(jsMap.getHashSize()); // 2

248

249

// Access values

250

System.out.println(jsMap.getHashValue("key1").asString()); // "value1"

251

System.out.println(jsMap.getHashValue("key2").asInt()); // 42

252

253

// Add/modify entries

254

jsMap.putHashEntry("key3", "new value");

255

jsMap.putHashEntry("key1", "updated value");

256

257

// Iterate over entries

258

Value entriesIterator = jsMap.getHashEntriesIterator();

259

while (entriesIterator.hasIteratorNextElement()) {

260

Value entry = entriesIterator.getIteratorNextElement();

261

Value key = entry.getArrayElement(0);

262

Value value = entry.getArrayElement(1);

263

System.out.printf("%s -> %s%n", key.asString(), value.toString());

264

}

265

}

266

```

267

268

### Iterator Operations

269

270

```java { .api }

271

// Iterator support

272

public boolean hasIterator();

273

public Value getIterator();

274

public boolean isIterator();

275

public boolean hasIteratorNextElement();

276

public Value getIteratorNextElement();

277

```

278

279

**Iterator Examples:**

280

281

```java

282

Context context = Context.create("js");

283

284

// JavaScript iterable

285

Value jsIterable = context.eval("js", "[10, 20, 30, 40, 50]");

286

287

if (jsIterable.hasIterator()) {

288

Value iterator = jsIterable.getIterator();

289

290

while (iterator.hasIteratorNextElement()) {

291

Value element = iterator.getIteratorNextElement();

292

System.out.println(element.asInt());

293

}

294

}

295

296

// Custom iterator from JavaScript generator

297

Value jsGenerator = context.eval("js", """

298

(function* fibonacci() {

299

let a = 0, b = 1;

300

while (a < 100) {

301

yield a;

302

[a, b] = [b, a + b];

303

}

304

})()

305

""");

306

307

while (jsGenerator.hasIteratorNextElement()) {

308

Value fib = jsGenerator.getIteratorNextElement();

309

System.out.println(fib.asInt()); // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89

310

}

311

```

312

313

## Function Execution

314

315

The Value class supports executing functions and constructors from guest languages with type-safe parameter passing.

316

317

### Function Execution

318

319

```java { .api }

320

// Function execution

321

public boolean canExecute();

322

public Value execute(Object... arguments);

323

public void executeVoid(Object... arguments);

324

325

// Constructor invocation

326

public boolean canInstantiate();

327

public Value newInstance(Object... arguments);

328

329

// Member method invocation

330

public boolean canInvokeMember(String identifier);

331

public Value invokeMember(String identifier, Object... arguments);

332

```

333

334

**Function Execution Examples:**

335

336

```java

337

Context context = Context.create("js");

338

339

// Define JavaScript function

340

Value jsFunction = context.eval("js", """

341

function calculate(operation, a, b) {

342

switch(operation) {

343

case 'add': return a + b;

344

case 'multiply': return a * b;

345

case 'power': return Math.pow(a, b);

346

default: return null;

347

}

348

}

349

calculate;

350

""");

351

352

if (jsFunction.canExecute()) {

353

Value result1 = jsFunction.execute("add", 5, 3);

354

Value result2 = jsFunction.execute("multiply", 4, 7);

355

Value result3 = jsFunction.execute("power", 2, 8);

356

357

System.out.println(result1.asInt()); // 8

358

System.out.println(result2.asInt()); // 28

359

System.out.println(result3.asInt()); // 256

360

}

361

362

// Constructor invocation

363

Value jsClass = context.eval("js", """

364

class Person {

365

constructor(name, age) {

366

this.name = name;

367

this.age = age;

368

}

369

370

greet() {

371

return `Hello, I'm ${this.name} and I'm ${this.age} years old.`;

372

}

373

}

374

Person;

375

""");

376

377

if (jsClass.canInstantiate()) {

378

Value person = jsClass.newInstance("Alice", 30);

379

Value greeting = person.invokeMember("greet");

380

System.out.println(greeting.asString()); // "Hello, I'm Alice and I'm 30 years old."

381

}

382

```

383

384

### Method Invocation

385

386

```java

387

Context context = Context.create("js");

388

389

// JavaScript object with methods

390

Value jsObject = context.eval("js", """

391

({

392

data: [1, 2, 3, 4, 5],

393

394

sum: function() {

395

return this.data.reduce((a, b) => a + b, 0);

396

},

397

398

filter: function(predicate) {

399

return this.data.filter(predicate);

400

},

401

402

map: function(transform) {

403

return this.data.map(transform);

404

}

405

})

406

""");

407

408

// Invoke methods

409

Value sum = jsObject.invokeMember("sum");

410

System.out.println(sum.asInt()); // 15

411

412

// Pass function as argument

413

Value squares = jsObject.invokeMember("map", context.eval("js", "x => x * x"));

414

System.out.println(squares.as(List.class)); // [1, 4, 9, 16, 25]

415

416

// Chain method calls

417

Value evenNumbers = jsObject.invokeMember("filter", context.eval("js", "x => x % 2 === 0"));

418

System.out.println(evenNumbers.as(List.class)); // [2, 4]

419

```

420

421

## Buffer Operations

422

423

For languages that support binary data, the Value class provides low-level buffer operations.

424

425

### Buffer Access

426

427

```java { .api }

428

// Buffer operations

429

public boolean hasBufferElements();

430

public boolean isBufferWritable();

431

public long getBufferSize();

432

433

// Byte operations

434

public byte readBufferByte(long byteOffset);

435

public void writeBufferByte(long byteOffset, byte value);

436

437

// Multi-byte operations with endianness

438

public short readBufferShort(ByteOrder order, long byteOffset);

439

public void writeBufferShort(ByteOrder order, long byteOffset, short value);

440

public int readBufferInt(ByteOrder order, long byteOffset);

441

public void writeBufferInt(ByteOrder order, long byteOffset, int value);

442

public long readBufferLong(ByteOrder order, long byteOffset);

443

public void writeBufferLong(ByteOrder order, long byteOffset, long value);

444

public float readBufferFloat(ByteOrder order, long byteOffset);

445

public void writeBufferFloat(ByteOrder order, long byteOffset, float value);

446

public double readBufferDouble(ByteOrder order, long byteOffset);

447

public void writeBufferDouble(ByteOrder order, long byteOffset, double value);

448

```

449

450

**Buffer Operations Example:**

451

452

```java

453

Context context = Context.create("js");

454

455

// Create JavaScript ArrayBuffer

456

Value jsBuffer = context.eval("js", "new ArrayBuffer(32)");

457

458

if (jsBuffer.hasBufferElements()) {

459

System.out.println("Buffer size: " + jsBuffer.getBufferSize()); // 32

460

System.out.println("Writable: " + jsBuffer.isBufferWritable()); // true

461

462

// Write various data types

463

jsBuffer.writeBufferInt(ByteOrder.BIG_ENDIAN, 0, 0x12345678);

464

jsBuffer.writeBufferFloat(ByteOrder.LITTLE_ENDIAN, 4, 3.14159f);

465

jsBuffer.writeBufferDouble(ByteOrder.BIG_ENDIAN, 8, Math.E);

466

467

// Read back the data

468

int intValue = jsBuffer.readBufferInt(ByteOrder.BIG_ENDIAN, 0);

469

float floatValue = jsBuffer.readBufferFloat(ByteOrder.LITTLE_ENDIAN, 4);

470

double doubleValue = jsBuffer.readBufferDouble(ByteOrder.BIG_ENDIAN, 8);

471

472

System.out.printf("Int: 0x%08X%n", intValue); // 0x12345678

473

System.out.printf("Float: %f%n", floatValue); // 3.141590

474

System.out.printf("Double: %f%n", doubleValue); // 2.718282

475

}

476

```

477

478

## Meta-Object Operations

479

480

The Value class provides access to meta-information about objects and their types.

481

482

### Meta-Object Protocol

483

484

```java { .api }

485

// Meta-object operations

486

public Value getMetaObject();

487

public boolean isMetaObject();

488

public String getMetaQualifiedName();

489

public String getMetaSimpleName();

490

public boolean isMetaInstance(Object instance);

491

public boolean hasMetaParents();

492

public Value getMetaParents();

493

```

494

495

**Meta-Object Examples:**

496

497

```java

498

Context context = Context.create("js");

499

500

// Create JavaScript object and get its meta-object

501

Value jsObject = context.eval("js", "new Date()");

502

Value metaObject = jsObject.getMetaObject();

503

504

if (metaObject.isMetaObject()) {

505

System.out.println("Type name: " + metaObject.getMetaSimpleName()); // "Date"

506

System.out.println("Qualified name: " + metaObject.getMetaQualifiedName()); // "Date"

507

508

// Check if another object is instance of this type

509

Value anotherDate = context.eval("js", "new Date(2023, 0, 1)");

510

boolean isInstance = metaObject.isMetaInstance(anotherDate);

511

System.out.println("Is instance: " + isInstance); // true

512

513

// Check parents/prototypes

514

if (metaObject.hasMetaParents()) {

515

Value parents = metaObject.getMetaParents();

516

System.out.println("Has parent types: " + parents.getArraySize());

517

}

518

}

519

```

520

521

## Host-Guest Integration

522

523

### Converting Java Objects to Values

524

525

```java

526

Context context = Context.newBuilder("js")

527

.allowHostAccess(HostAccess.EXPLICIT)

528

.build();

529

530

// Java class with exported members

531

public class Calculator {

532

@HostAccess.Export

533

public double add(double a, double b) {

534

return a + b;

535

}

536

537

@HostAccess.Export

538

public double multiply(double a, double b) {

539

return a * b;

540

}

541

}

542

543

// Convert to Value and use in JavaScript

544

Value calculatorValue = context.asValue(new Calculator());

545

Value jsBindings = context.getBindings("js");

546

jsBindings.putMember("calc", calculatorValue);

547

548

Value result = context.eval("js", "calc.add(calc.multiply(3, 4), 5)");

549

System.out.println(result.asDouble()); // 17.0

550

```

551

552

### Guest Objects in Java

553

554

```java

555

Context context = Context.create("js");

556

557

// Create JavaScript object with rich behavior

558

Value jsLibrary = context.eval("js", """

559

({

560

version: '1.0.0',

561

562

users: new Map(),

563

564

addUser: function(id, name, email) {

565

this.users.set(id, {name: name, email: email, created: new Date()});

566

return this.users.get(id);

567

},

568

569

getUser: function(id) {

570

return this.users.get(id);

571

},

572

573

getAllUsers: function() {

574

return Array.from(this.users.values());

575

}

576

})

577

""");

578

579

// Use JavaScript object in Java

580

Value newUser = jsLibrary.invokeMember("addUser", 1, "Alice", "alice@example.com");

581

System.out.println("Created user: " + newUser.getMember("name").asString());

582

583

Value user = jsLibrary.invokeMember("getUser", 1);

584

System.out.println("Retrieved user: " + user.getMember("email").asString());

585

586

Value allUsers = jsLibrary.invokeMember("getAllUsers");

587

System.out.println("Total users: " + allUsers.getArraySize());

588

```

589

590

## Exception Handling

591

592

### Exception Operations

593

594

```java { .api }

595

// Exception handling

596

public boolean isException();

597

public RuntimeException throwException();

598

```

599

600

**Exception Handling Example:**

601

602

```java

603

Context context = Context.create("js");

604

605

try {

606

Value jsError = context.eval("js", """

607

(function() {

608

throw new Error('Something went wrong in JavaScript');

609

})()

610

""");

611

612

if (jsError.isException()) {

613

jsError.throwException(); // Throws PolyglotException

614

}

615

} catch (PolyglotException e) {

616

System.out.println("Caught polyglot exception: " + e.getMessage());

617

if (e.isGuestException()) {

618

Value guestError = e.getGuestObject();

619

System.out.println("Guest error message: " + guestError.getMember("message").asString());

620

}

621

}

622

```

623

624

## Utility Operations

625

626

### Context and Source Information

627

628

```java { .api }

629

// Utility methods

630

public Context getContext();

631

public SourceSection getSourceLocation();

632

public void pin();

633

public static Value asValue(Object o);

634

```

635

636

**Utility Examples:**

637

638

```java

639

Context context = Context.create("js");

640

641

Value jsValue = context.eval("js", "Math.PI");

642

643

// Get associated context

644

Context valueContext = jsValue.getContext();

645

System.out.println("Same context: " + (context == valueContext)); // true

646

647

// Pin value to prevent garbage collection

648

jsValue.pin();

649

650

// Static conversion method

651

Value staticValue = Value.asValue("Hello from static method");

652

```

653

654

## Performance Considerations

655

656

### Value Caching and Reuse

657

658

```java

659

Context context = Context.create("js");

660

661

// Cache frequently accessed values

662

Value jsArrayPrototype = context.eval("js", "Array.prototype");

663

Value pushMethod = jsArrayPrototype.getMember("push");

664

665

// Reuse cached values

666

Value myArray = context.eval("js", "[]");

667

pushMethod.execute(myArray, 1, 2, 3); // Efficient method call

668

```

669

670

### Batch Operations

671

672

```java

673

Context context = Context.create("js");

674

Value jsArray = context.eval("js", "[]");

675

676

// Batch array modifications

677

for (int i = 0; i < 1000; i++) {

678

jsArray.setArrayElement(i, i * i);

679

}

680

681

// More efficient: use JavaScript for bulk operations

682

context.getBindings("js").putMember("data", IntStream.range(0, 1000).toArray());

683

Value processedArray = context.eval("js", "data.map(x => x * x)");

684

```