oracle/graal · error · IllegalArgumentException

Expected an EspressoExternalObjectConstant for dest, got

Error message

Expected an EspressoExternalObjectConstant for dest, got 

What it means

The destination side of copyArray must equally be an EspressoExternalObjectConstant wrapping a guest array, because System.arraycopy executes inside the guest Espresso VM and can only store into guest memory. A dest constant from a foreign backend is rejected with IllegalArgumentException('Expected an EspressoExternalObjectConstant for dest, ...') before any copy is attempted, so no partial write can occur.

Source

Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccess.java:609

    public JavaConstant clonePrimitiveArray(JavaConstant primitiveArray) {
        if (!(primitiveArray instanceof EspressoExternalObjectConstant objectConstant)) {
            throw new IllegalArgumentException("Expected an EspressoExternalObjectConstant, got " + safeGetClass(primitiveArray));
        }
        EspressoResolvedObjectType arrayType = objectConstant.getType();
        if (!(arrayType.isArray() && arrayType.getComponentType().isPrimitive())) {
            throw new IllegalArgumentException("Expected a primitive array constant, got " + arrayType);
        }
        Value copy = invokeJVMCIHelper("clonePrimitiveArray", objectConstant.getValue());
        return new EspressoExternalObjectConstant(this, copy);
    }

    @Override
    public void copyArray(JavaConstant src, int srcPos, JavaConstant dest, int destPos, int length) {
        if (!(src instanceof EspressoExternalObjectConstant srcArray)) {
            throw new IllegalArgumentException("Expected an EspressoExternalObjectConstant for src, got " + safeGetClass(src));
        }
        if (!(dest instanceof EspressoExternalObjectConstant destArray)) {
            throw new IllegalArgumentException("Expected an EspressoExternalObjectConstant for dest, got " + safeGetClass(dest));
        }
        if (!srcArray.getType().isArray()) {
            throw new IllegalArgumentException("Expected an array constant for src, got " + srcArray.getType());
        }
        if (!destArray.getType().isArray()) {
            throw new IllegalArgumentException("Expected an array constant for dest, got " + destArray.getType());
        }
        try {
            invoke(java_lang_System_arraycopy, null, srcArray, JavaConstant.forInt(srcPos), destArray, JavaConstant.forInt(destPos), JavaConstant.forInt(length));
        } catch (InvocationException e) {
            if (e.getCause() instanceof PolyglotException polyglotException) {
                throw throwHostException(polyglotException);
            }
            throw e;
        }
    }

    @Override

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Allocate the destination through this Espresso provider (createPrimitiveArray / asArrayConstant) before copyArray.
  2. Guard dest instanceof EspressoExternalObjectConstant; otherwise copy into the host array with System.arraycopy after unwrapping the source values.
  3. Keep allocation and copy on the same side of the host/guest boundary.

Example fix

// before
JavaConstant dest = JavaConstant.forObject(new byte[n]);
vmAccess.copyArray(src, 0, dest, 0, n);

// after
JavaConstant dest = vmAccess.createPrimitiveArray(JavaKind.Byte, n);
vmAccess.copyArray(src, 0, dest, 0, n);
Defensive patterns

Strategy: validation

Validate before calling

if (!(dest instanceof EspressoExternalObjectConstant)) {
    dest = vmAccess.createPrimitiveArray(kind, length); // guest-allocated destination
}

Type guard

static boolean isEspressoConstant(JavaConstant c) {
    return c instanceof EspressoExternalObjectConstant;
}

Try / catch

catch (IllegalArgumentException e) with 'for dest' -> allocate dest via createPrimitiveArray/asArrayConstant and retry the copy.

Prevention

When it happens

Trigger: Copying guest data into a destination allocated by the host provider (JavaConstant.forObject(hostArray)) or by another Espresso context.

Common situations: Result buffers pre-allocated on the host and passed into guest copy routines; mixed provider usage in buffer management code.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/31cf3e7af5d67ae4. Report an issue: GitHub.