/*
* Copyright (c) 2017, Oracle and/or its affiliates.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.oracle.truffle.llvm.parser.metadata;
import com.oracle.truffle.llvm.parser.model.symbols.constants.NullConstant;
import com.oracle.truffle.llvm.parser.model.symbols.constants.integer.BigIntegerConstant;
import com.oracle.truffle.llvm.parser.model.symbols.constants.integer.IntegerConstant;
import com.oracle.truffle.llvm.runtime.types.Type;
import com.oracle.truffle.llvm.runtime.types.VoidType;
import com.oracle.truffle.llvm.runtime.types.symbols.Symbol;
public final class ParseUtil {
static boolean asInt1(MDTypedValue t) {
return asInt64(t) != 0;
}
public static int asInt32(MDTypedValue t) {
return (int) asInt64(t);
}
public static long asInt64(MDTypedValue t) {
if (t instanceof MDSymbolReference) {
final Symbol s = ((MDSymbolReference) t).get();
if (s instanceof IntegerConstant) {
return ((IntegerConstant) s).getValue();
} else if (s instanceof BigIntegerConstant) {
return ((BigIntegerConstant) s).getValue().longValue();
} else if (s instanceof NullConstant) {
return 0L;
}
}
throw new AssertionError("Cannot retrieve int value from this: " + t);
}
static long asInt64IfPresent(MDTypedValue[] values, int index) {
return index < values.length ? asInt64(values[index]) : 0;
}
static MDReference getReferenceIfPresent(MDTypedValue[] values, int index) {
return index < values.length ? getReference(values[index]) : MDReference.VOID;
}
public static MDReference getReference(MDTypedValue t) {
if (t instanceof MDReference) {
return (MDReference) t;
} else if (t.getType() == VoidType.INSTANCE) {
return MDReference.VOID;
} else if (t instanceof MDSymbolReference) {
final Symbol s = ((MDSymbolReference) t).get();
if (s != null && s instanceof NullConstant) {
return MDReference.VOID;
}
}
throw new IllegalArgumentException("Not a Metadata Reference: " + t);
}
static MDSymbolReference getSymbolReference(MDTypedValue arg) {
if (arg instanceof MDSymbolReference) {
return (MDSymbolReference) arg;
} else {
return MDSymbolReference.VOID;
}
}
public static boolean isInt(MDTypedValue val) {
final Type t = val.getType();
if (!Type.isIntegerType(t) || !(val instanceof MDSymbolReference)) {
return false;
}
final Symbol s = ((MDSymbolReference) val).get();
return s instanceof IntegerConstant || s instanceof BigIntegerConstant;
}
private static final long BYTE_MASK = 0xFF;
static String longArrayToString(int startIndex, long[] chars) {
// We use a byte array, so "new String(...)" is able to handle Unicode Characters correctly
final byte[] bytes = new byte[chars.length - startIndex];
for (int from = startIndex, to = 0; to < bytes.length; from++, to++) {
bytes[to] = (byte) (chars[from] & BYTE_MASK);
}
return new String(bytes);
}
static long unrotateSign(long u) {
return (u & 1) == 1 ? ~(u >> 1) : u >> 1;
}
}