oracle/graal · error · GraalError

Cannot bind label to negative position

Error message

Cannot bind label to negative position %d

What it means

Thrown by readPrimitiveArrayUnaligned when the array constant is not an EspressoExternalObjectConstant. The unaligned read decodes bytes directly from the guest array via interop buffer access (readBufferByte/Short/Int/Long/...), which requires an espresso object constant holding the polyglot Value.

Solutions

  1. Only pass espresso object constants obtained from the same vm access instance
  2. Guard with instanceof and route non-espresso constants to the host unaligned read implementation

Example fix

// before
JavaConstant v = vmAccess.readPrimitiveArrayUnaligned(anyConst, kind, offset);

// after
JavaConstant v = anyConst instanceof EspressoExternalObjectConstant
        ? vmAccess.readPrimitiveArrayUnaligned(anyConst, kind, offset)
        : hostBackend.readUnaligned(anyConst, kind, offset);
Defensive patterns

Strategy: type-guard

Type guard

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

Prevention

When it happens

Trigger: Passing a host constant, primitive constant, or foreign-backend constant as the array argument.

Common situations: Constants crossing backend boundaries (host JVMCI -> espresso access); mocks; stale constants from a previous guest context.

Related errors


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

Appendix: source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/Label.java:78

    public Label() {
        blockId = -1;
    }

    public Label(int id) {
        blockId = id;
    }

    public int getBlockId() {
        return blockId;
    }

    /**
     * Binds the label to {@code pos} and patches all instructions added by
     * {@link #addPatchAt(int, Assembler)}.
     */
    protected void bind(int pos, Assembler<?> asm) {
        if (pos < 0) {
            throw new GraalError("Cannot bind label to negative position %d", pos);
        }
        this.position = pos;
        if (patchPositions != null) {
            for (int i = 0; i < patchPositions.size(); ++i) {
                asm.patchJumpTarget(patchPositions.get(i), position);
            }
            patchPositions = null;
        }
    }

    public boolean isBound() {
        return position >= 0;
    }

    public void addPatchAt(int branchLocation, Assembler<?> asm) {
        assert !isBound() : "Label is already bound " + this + " " + branchLocation + " at position " + position;
        if (patchPositions == null) {
            patchPositions = new ArrayList<>(2);

View on GitHub (pinned to a66e9ccd1d)