package com.oracle.truffle.llvm.runtime.interop.convert;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.llvm.runtime.except.LLVMPolyglotException;
import com.oracle.truffle.llvm.runtime.library.internal.LLVMAsForeignLibrary;
import com.oracle.truffle.llvm.runtime.pointer.LLVMPointer;
public abstract class ToI64 extends ForeignToLLVM {
@Specialization
protected long fromInt(int value) {
return value;
}
@Specialization
protected long fromChar(char value) {
return value;
}
@Specialization
protected long fromShort(short value) {
return value;
}
@Specialization
protected long fromLong(long value) {
return value;
}
@Specialization
protected long fromByte(byte value) {
return value;
}
@Specialization
protected long fromFloat(float value) {
return (long) value;
}
@Specialization
protected long fromDouble(double value) {
return (long) value;
}
@Specialization
protected long fromBoolean(boolean value) {
return value ? 1 : 0;
}
@Specialization
protected long fromString(String value) {
return getSingleStringCharacter(value);
}
@Specialization
protected LLVMPointer fromPointer(LLVMPointer value) {
return value;
}
@Specialization(limit = "5", guards = {"foreigns.isForeign(obj)", "interop.isNumber(foreigns.asForeign(obj))"})
protected long fromForeign(Object obj,
@CachedLibrary("obj") LLVMAsForeignLibrary foreigns,
@CachedLibrary(limit = "3") InteropLibrary interop,
@Cached BranchProfile exception) {
try {
return interop.asLong(foreigns.asForeign(obj));
} catch (UnsupportedMessageException ex) {
exception.enter();
throw new LLVMPolyglotException(this, "Polyglot number can't be converted to long.");
}
}
@Specialization(limit = "5", guards = {"foreigns.isForeign(obj)", "!interop.isNumber(obj)"})
protected Object fromForeignPointer(Object obj,
@CachedLibrary("obj") @SuppressWarnings("unused") InteropLibrary interop,
@Cached ToPointer toPointer,
@SuppressWarnings("unused") @CachedLibrary(limit = "3") LLVMAsForeignLibrary foreigns) {
return toPointer.executeWithTarget(obj);
}
@TruffleBoundary
static long slowPathPrimitiveConvert(ForeignToLLVM thiz, Object value) throws UnsupportedTypeException {
if (value instanceof Number) {
return ((Number) value).longValue();
} else if (value instanceof Boolean) {
return ((boolean) value ? 1 : 0);
} else if (value instanceof Character) {
return (char) value;
} else if (value instanceof String) {
return thiz.getSingleStringCharacter((String) value);
} else {
try {
return InteropLibrary.getFactory().getUncached().asLong(value);
} catch (UnsupportedMessageException ex) {
throw UnsupportedTypeException.create(new Object[]{value});
}
}
}
}