package com.oracle.truffle.llvm.runtime.interop.export;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateUncached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.llvm.runtime.interop.access.LLVMInteropType;
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMNode;
import com.oracle.truffle.llvm.runtime.pointer.LLVMPointer;
@GenerateUncached
public abstract class LLVMForeignGetMemberPointerNode extends LLVMNode {
public abstract LLVMPointer execute(LLVMInteropType type, LLVMPointer pointer, String ident) throws UnsupportedMessageException, UnknownIdentifierException;
@Specialization(guards = {"cachedMember != null", "cachedMember.struct == struct", "cachedIdent.equals(ident)"})
LLVMPointer doCached(@SuppressWarnings("unused") LLVMInteropType.Struct struct, LLVMPointer pointer, @SuppressWarnings("unused") String ident,
@Cached("ident") @SuppressWarnings("unused") String cachedIdent,
@Cached("struct.findMember(cachedIdent)") LLVMInteropType.StructMember cachedMember) {
return pointer.increment(cachedMember.startOffset).export(cachedMember.type);
}
@Specialization(replaces = "doCached")
static LLVMPointer doGeneric(LLVMInteropType.Struct struct, LLVMPointer pointer, String ident,
@Cached BranchProfile exception) throws UnknownIdentifierException {
LLVMInteropType.StructMember member = struct.findMember(ident);
if (member == null) {
exception.enter();
throw UnknownIdentifierException.create(ident);
}
return pointer.increment(member.startOffset).export(member.type);
}
@Fallback
static LLVMPointer doError(LLVMInteropType type, LLVMPointer object, String ident) throws UnsupportedMessageException {
throw UnsupportedMessageException.create();
}
}