All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.oracle.graal.python.nodes.PGuards Maven / Gradle / Ivy

There is a newer version: 24.1.1
Show newest version
/*
 * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * The Universal Permissive License (UPL), Version 1.0
 *
 * Subject to the condition set forth below, permission is hereby granted to any
 * person obtaining a copy of this software, associated documentation and/or
 * data (collectively the "Software"), free of charge and under any and all
 * copyright rights in the Software, and any and all patent rights owned or
 * freely licensable by each licensor hereunder covering either (i) the
 * unmodified Software as contributed to or provided by such licensor, or (ii)
 * the Larger Works (as defined below), to deal in both
 *
 * (a) the Software, and
 *
 * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
 * one is included with the Software each a "Larger Work" to which the Software
 * is contributed by such licensors),
 *
 * without restriction, including without limitation the rights to copy, create
 * derivative works of, display, perform, and distribute the Software and make,
 * use, sell, offer for sale, import, export, have made, and have sold the
 * Software and the Larger Work(s), and to sublicense the foregoing rights on
 * either these or other terms.
 *
 * This license is subject to the following condition:
 *
 * The above copyright notice and either this complete permission notice or at a
 * minimum a reference to the UPL must be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.oracle.graal.python.nodes;

import static com.oracle.graal.python.nodes.truffle.TruffleStringMigrationHelpers.isJavaString;
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;

import com.oracle.graal.python.builtins.PythonBuiltinClassType;
import com.oracle.graal.python.builtins.modules.ctypes.CDataObject;
import com.oracle.graal.python.builtins.modules.ctypes.PyCArgObject;
import com.oracle.graal.python.builtins.modules.ctypes.StgDictObject;
import com.oracle.graal.python.builtins.objects.PNone;
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
import com.oracle.graal.python.builtins.objects.array.PArray;
import com.oracle.graal.python.builtins.objects.bytes.PByteArray;
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
import com.oracle.graal.python.builtins.objects.bytes.PBytesLike;
import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass;
import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject;
import com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapper;
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyHandle;
import com.oracle.graal.python.builtins.objects.cext.hpy.PythonHPyObject;
import com.oracle.graal.python.builtins.objects.code.PCode;
import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage;
import com.oracle.graal.python.builtins.objects.common.EmptyStorage;
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
import com.oracle.graal.python.builtins.objects.common.PHashingCollection;
import com.oracle.graal.python.builtins.objects.complex.PComplex;
import com.oracle.graal.python.builtins.objects.dict.PDict;
import com.oracle.graal.python.builtins.objects.dict.PDictView;
import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis;
import com.oracle.graal.python.builtins.objects.exception.PBaseException;
import com.oracle.graal.python.builtins.objects.floats.PFloat;
import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor;
import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.BinaryBuiltinDescriptor;
import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.TernaryBuiltinDescriptor;
import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.UnaryBuiltinDescriptor;
import com.oracle.graal.python.builtins.objects.function.PArguments;
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
import com.oracle.graal.python.builtins.objects.function.PFunction;
import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorDeleteMarker;
import com.oracle.graal.python.builtins.objects.ints.PInt;
import com.oracle.graal.python.builtins.objects.iterator.PSequenceIterator;
import com.oracle.graal.python.builtins.objects.list.PList;
import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView;
import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
import com.oracle.graal.python.builtins.objects.method.PMethod;
import com.oracle.graal.python.builtins.objects.mmap.PMMap;
import com.oracle.graal.python.builtins.objects.module.PythonModule;
import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
import com.oracle.graal.python.builtins.objects.object.PythonObject;
import com.oracle.graal.python.builtins.objects.range.PRange;
import com.oracle.graal.python.builtins.objects.set.PBaseSet;
import com.oracle.graal.python.builtins.objects.set.PFrozenSet;
import com.oracle.graal.python.builtins.objects.set.PSet;
import com.oracle.graal.python.builtins.objects.slice.PSlice;
import com.oracle.graal.python.builtins.objects.str.PString;
import com.oracle.graal.python.builtins.objects.traceback.PTraceback;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
import com.oracle.graal.python.builtins.objects.type.PythonClass;
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
import com.oracle.graal.python.lib.PyIndexCheckNode;
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
import com.oracle.graal.python.nodes.object.GetClassNode;
import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
import com.oracle.graal.python.runtime.sequence.PSequence;
import com.oracle.graal.python.runtime.sequence.storage.BasicSequenceStorage;
import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage;
import com.oracle.graal.python.runtime.sequence.storage.DoubleSequenceStorage;
import com.oracle.graal.python.runtime.sequence.storage.EmptySequenceStorage;
import com.oracle.graal.python.runtime.sequence.storage.IntSequenceStorage;
import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage;
import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage;
import com.oracle.graal.python.util.OverflowException;
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
import com.oracle.truffle.api.dsl.Idempotent;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
import com.oracle.truffle.api.strings.TruffleString;
import com.oracle.truffle.api.strings.TruffleString.CodeRange;

public abstract class PGuards {
    /**
     * Specialization guards.
     */

    public static boolean stringEquals(String expected, String other, ConditionProfile profile) {
        if (profile.profile(expected == other)) {
            return true;
        }
        return expected.equals(other);
    }

    public static boolean stringEquals(String expected, String other, Node inliningTarget, InlinedConditionProfile profile) {
        if (profile.profile(inliningTarget, expected == other)) {
            return true;
        }
        return expected.equals(other);
    }

    public static boolean stringEquals(TruffleString expected, TruffleString other, TruffleString.EqualNode equalNode, ConditionProfile profile) {
        if (profile.profile(expected == other)) {
            return true;
        }
        return equalNode.execute(expected, other, TS_ENCODING);
    }

    public static boolean stringEquals(TruffleString expected, TruffleString other, TruffleString.EqualNode equalNode, Node inliningTarget, InlinedConditionProfile profile) {
        if (profile.profile(inliningTarget, expected == other)) {
            return true;
        }
        return equalNode.execute(expected, other, TS_ENCODING);
    }

    public static boolean stringEquals(TruffleString key, TruffleString cachedKey, TruffleString.EqualNode equalNode) {
        return equalNode.execute(cachedKey, key, TS_ENCODING);
    }

    public static boolean isSameObject(Object left, Object right) {
        return left == right;
    }

    public static boolean isEmpty(Object[] array) {
        return array.length == 0;
    }

    public static boolean isNone(Object value) {
        return value == PNone.NONE;
    }

    public static boolean isNoValue(Object object) {
        return object == PNone.NO_VALUE;
    }

    public static boolean isEllipsis(Object object) {
        return object == PEllipsis.INSTANCE;
    }

    public static boolean isMemoryView(Object object) {
        return object instanceof PMemoryView;
    }

    public static boolean isMMap(Object object) {
        return object instanceof PMMap;
    }

    public static boolean isDeleteMarker(Object object) {
        return object == DescriptorDeleteMarker.INSTANCE;
    }

    public static boolean isDict(Object object) {
        return object instanceof PDict;
    }

    public static boolean isCode(Object object) {
        return object instanceof PCode;
    }

    public static boolean isStgDict(Object dict) {
        return dict instanceof StgDictObject;
    }

    @Idempotent
    public static boolean isFunction(Object value) {
        return value instanceof PBuiltinFunction || value instanceof PFunction;
    }

    @Idempotent
    public static boolean isPBuiltinFunction(Object value) {
        return value instanceof PBuiltinFunction;
    }

    @Idempotent
    public static boolean isPFunction(Object value) {
        return value instanceof PFunction;
    }

    public static boolean isCallable(Object value) {
        return value instanceof PBuiltinFunction || value instanceof PFunction || value instanceof PBuiltinMethod || value instanceof PMethod;
    }

    /**
     * Use instead of {@link #isCallable(Object)} for objects coming from
     * {@link com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode}. Note that such
     * objects can be then forwarded only to call nodes that support them.
     */
    public static boolean isCallableOrDescriptor(Object value) {
        return isCallable(value) || BuiltinMethodDescriptor.isInstance(value);
    }

    public static boolean isBuiltinDescriptor(Object value) {
        return BuiltinMethodDescriptor.isInstance(value);
    }

    public static boolean isClass(Node inliningTarget, Object obj, TypeNodes.IsTypeNode isTypeNode) {
        return isTypeNode.execute(inliningTarget, obj);
    }

    public static boolean isClassUncached(Object obj) {
        return TypeNodes.IsTypeNode.executeUncached(obj);
    }

    public static boolean isEmptyStorage(PSequence sequence) {
        return sequence.getSequenceStorage() instanceof EmptySequenceStorage;
    }

    public static boolean isBasicStorage(PSequence sequence) {
        return sequence.getSequenceStorage() instanceof BasicSequenceStorage;
    }

    public static boolean isIntStorage(PSequence sequence) {
        return sequence.getSequenceStorage() instanceof IntSequenceStorage;
    }

    public static boolean isByteStorage(PSequence array) {
        return array.getSequenceStorage() instanceof ByteSequenceStorage;
    }

    public static boolean areBothIntStorage(PSequence first, PSequence second) {
        return first.getSequenceStorage() instanceof IntSequenceStorage && second.getSequenceStorage() instanceof IntSequenceStorage;
    }

    public static boolean areBothByteStorage(PSequence first, PSequence second) {
        return first.getSequenceStorage() instanceof ByteSequenceStorage && second.getSequenceStorage() instanceof ByteSequenceStorage;
    }

    public static boolean isLongStorage(PSequence sequence) {
        return sequence.getSequenceStorage() instanceof LongSequenceStorage;
    }

    public static boolean areBothLongStorage(PList first, PList second) {
        return first.getSequenceStorage() instanceof LongSequenceStorage && second.getSequenceStorage() instanceof LongSequenceStorage;
    }

    public static boolean isDoubleStorage(PSequence sequence) {
        return sequence.getSequenceStorage() instanceof DoubleSequenceStorage;
    }

    public static boolean areBothDoubleStorage(PList first, PList second) {
        return first.getSequenceStorage() instanceof DoubleSequenceStorage && second.getSequenceStorage() instanceof DoubleSequenceStorage;
    }

    public static boolean isObjectStorage(PSequence list) {
        return list.getSequenceStorage() instanceof ObjectSequenceStorage;
    }

    public static boolean areBothObjectStorage(PList first, PList second) {
        return first.getSequenceStorage() instanceof ObjectSequenceStorage && second.getSequenceStorage() instanceof ObjectSequenceStorage;
    }

    public static boolean isList(Object o) {
        return o instanceof PList;
    }

    public static boolean isEconomicMapOrEmpty(HashingStorage self) {
        return self instanceof EconomicMapStorage || self instanceof EmptyStorage;
    }

    public static boolean isObjectStorageIterator(PSequenceIterator iterator) {
        if (!iterator.isPSequence()) {
            return false;
        }

        PSequence sequence = iterator.getPSequence();

        if (sequence instanceof PList) {
            PList list = (PList) sequence;
            return list.getSequenceStorage() instanceof ObjectSequenceStorage;
        }

        return false;
    }

    public static boolean isPythonObject(Object obj) {
        return obj instanceof PythonObject;
    }

    public static boolean isPythonModule(Object obj) {
        return obj instanceof PythonModule;
    }

    /**
     * Argument guards.
     */
    public static boolean emptyArguments(VirtualFrame frame) {
        return PArguments.getUserArgumentLength(frame) == 0;
    }

    public static boolean argGiven(Object object) {
        return object == PNone.NO_VALUE;
    }

    public static boolean emptyArguments(PNone none) {
        return none == PNone.NO_VALUE;
    }

    public static boolean isIndexPositive(int idx) {
        return idx >= 0;
    }

    public static boolean isIndexNegative(int idx) {
        return idx < 0;
    }

    public static boolean isIndexPositive(long idx) {
        return idx >= 0;
    }

    public static boolean isIndexNegative(long idx) {
        return idx < 0;
    }

    public static boolean isPythonUserClass(Object klass) {
        return klass instanceof PythonClass || PythonNativeClass.isInstance(klass);
    }

    public static boolean isPythonBuiltinClassType(Object klass) {
        return klass instanceof PythonBuiltinClassType;
    }

    public static boolean isPythonBuiltinClass(Object klass) {
        return klass instanceof PythonBuiltinClass;
    }

    public static boolean isNativeObject(Object object) {
        return PythonNativeObject.isInstance(object);
    }

    public static boolean isManagedClass(Object klass) {
        return PythonManagedClass.isInstance(klass);
    }

    public static boolean isNativeClass(Object klass) {
        return PythonNativeClass.isInstance(klass);
    }

    public static boolean isPythonClass(Object klass) {
        return PythonAbstractClass.isInstance(klass) || klass instanceof PythonBuiltinClassType;
    }

    public static boolean isPRange(Object obj) {
        return obj instanceof PRange;
    }

    public static boolean isString(Object obj) {
        return isJavaString(obj) || obj instanceof TruffleString || obj instanceof PString;
    }

    public static boolean isTruffleString(Object obj) {
        return obj instanceof TruffleString;
    }

    public static boolean isBuiltinString(Node inliningTarget, Object obj, IsBuiltinObjectProfile profile) {
        return isJavaString(obj) || obj instanceof TruffleString || profile.profileObject(inliningTarget, obj, PythonBuiltinClassType.PString);
    }

    public static boolean isBuiltinFunction(Object obj) {
        return obj instanceof PBuiltinFunction;
    }

    public static boolean isMethod(Object value) {
        return value instanceof PMethod || value instanceof PBuiltinMethod;
    }

    public static boolean isPMethod(Object value) {
        return value instanceof PMethod;
    }

    public static boolean isBuiltinMethod(Object obj) {
        return obj instanceof PBuiltinMethod;
    }

    public static boolean isBuiltinObject(Object obj) {
        return obj instanceof PythonBuiltinObject;
    }

    public static boolean isAnyPythonObject(Object obj) {
        return obj instanceof PythonAbstractObject;
    }

    public static boolean canBeInteger(Object idx) {
        return isBoolean(idx) || isInteger(idx) || isPInt(idx);
    }

    public static boolean isNumber(Object num) {
        return isPFloat(num) || isDouble(num) || canBeInteger(num);
    }

    public static boolean isPInt(Object obj) {
        return obj instanceof PInt;
    }

    public static boolean isBuiltinPInt(PInt obj) {
        /*
         * int's __class__ cannot be reassigned and other objects cannot have their class assigned
         * to builtin int, so it is enough to look at the initial class. PInt constructor ensures
         * that it cannot be PythonBuiltinClass.
         */
        return obj.getInitialPythonClass() == PythonBuiltinClassType.PInt;
    }

    public static boolean isPString(Object obj) {
        return obj instanceof PString;
    }

    public static boolean isPFloat(Object obj) {
        return obj instanceof PFloat;
    }

    public static boolean isPNone(Object obj) {
        return obj instanceof PNone;
    }

    public static boolean isPComplex(Object obj) {
        return obj instanceof PComplex;
    }

    public static boolean isPTuple(Object obj) {
        return obj instanceof PTuple;
    }

    public static boolean isPSequence(Object obj) {
        return obj instanceof PSequence;
    }

    public static boolean isPCode(Object obj) {
        return obj instanceof PCode;
    }

    public static boolean isPBaseException(Object obj) {
        return obj instanceof PBaseException;
    }

    public static boolean isPTraceback(Object obj) {
        return obj instanceof PTraceback;
    }

    public static boolean isInt(Object obj) {
        return obj instanceof Integer;
    }

    public static boolean isLong(Object obj) {
        return obj instanceof Long;
    }

    public static boolean isInteger(Object obj) {
        return obj instanceof Long || obj instanceof Integer;
    }

    public static boolean isDouble(Object obj) {
        return obj instanceof Double;
    }

    public static boolean isBoolean(Object obj) {
        return obj instanceof Boolean;
    }

    public static boolean isBytes(Object obj) {
        return obj instanceof PBytesLike;
    }

    public static boolean isPBytes(Object obj) {
        return obj instanceof PBytes;
    }

    public static boolean isPByteArray(Object obj) {
        return obj instanceof PByteArray;
    }

    public static boolean isArray(Object obj) {
        return obj instanceof PArray;
    }

    public static boolean isAnySet(Object obj) {
        return obj instanceof PBaseSet;
    }

    public static boolean isDictView(Object obj) {
        return obj instanceof PDictView;
    }

    public static boolean isDictKeysView(Object obj) {
        return obj instanceof PDictView.PDictKeysView;
    }

    public static boolean isDictItemsView(Object obj) {
        return obj instanceof PDictView.PDictItemsView;
    }

    public static boolean isPHashingCollection(Object o) {
        return o instanceof PHashingCollection;
    }

    public static boolean isPSet(Object o) {
        return o instanceof PSet;
    }

    public static boolean isPFrozenSet(Object o) {
        return o instanceof PFrozenSet;
    }

    public static boolean canDoSetBinOp(Object o) {
        return isAnySet(o) || isDictView(o);
    }

    public static boolean isPSlice(Object obj) {
        return obj instanceof PSlice;
    }

    public static boolean isPyCArg(Object obj) {
        return obj instanceof PyCArgObject;
    }

    public static boolean isCDataObject(Object obj) {
        return obj instanceof CDataObject;
    }

    public static boolean isHPyHandle(Object obj) {
        return obj instanceof GraalHPyHandle;
    }

    public static boolean isHPyObject(Object obj) {
        return obj instanceof PythonHPyObject;
    }

    public static boolean expectBoolean(Object result) throws UnexpectedResultException {
        if (result instanceof Boolean) {
            return (Boolean) result;
        }
        throw new UnexpectedResultException(result);
    }

    public static int expectInteger(Object result) throws UnexpectedResultException {
        if (result instanceof Integer) {
            return (Integer) result;
        }
        throw new UnexpectedResultException(result);
    }

    public static int expectInt(Object result) throws UnexpectedResultException, OverflowException {
        if (result instanceof Integer) {
            return (Integer) result;
        }
        if (result instanceof Long) {
            return PInt.intValueExact((Long) result);
        }
        throw new UnexpectedResultException(result);
    }

    public static long expectLong(Object result) throws UnexpectedResultException {
        if (result instanceof Long) {
            return (Long) result;
        }
        throw new UnexpectedResultException(result);
    }

    public static double expectDouble(Object result) throws UnexpectedResultException {
        if (result instanceof Double) {
            return (Double) result;
        }
        throw new UnexpectedResultException(result);
    }

    /**
     * Tests if the class of a Python object is a builtin class, i.e., any magic methods cannot be
     * overridden.
     */
    public static boolean cannotBeOverridden(Object clazz) {
        return clazz instanceof PythonBuiltinClassType || clazz instanceof PythonBuiltinClass;
    }

    @InliningCutoff
    public static boolean cannotBeOverridden(Object object, Node inliningTarget, GetClassNode getClassNode) {
        Object clazz = getClassNode.execute(inliningTarget, object);
        return clazz instanceof PythonBuiltinClassType || clazz instanceof PythonBuiltinClass;
    }

    @InliningCutoff
    public static boolean cannotBeOverridden(PythonObject object, Node inliningTarget, GetPythonObjectClassNode getClassNode) {
        Object clazz = getClassNode.execute(inliningTarget, object);
        return clazz instanceof PythonBuiltinClassType || clazz instanceof PythonBuiltinClass;
    }

    /**
     * Tests if the class of this Python object is a builtin class. This method is supposed to be
     * used for builtin types that do not support __class__ assignment at all, so we can safely read
     * the initialPythonClass field and assume that is the current class as well.
     */
    public static boolean cannotBeOverriddenForImmutableType(PythonObject object) {
        Object clazz = object.getInitialPythonClass();
        return clazz instanceof PythonBuiltinClassType || clazz instanceof PythonBuiltinClass;
    }

    public static boolean isBuiltinDict(PDict dict) {
        /*
         * dict's __class__ cannot be reassigned and other objects cannot have their class assigned
         * to builtin dict, so it is enough to look at the initial class. PDict constructor ensures
         * that it cannot be PythonBuiltinClass.
         */
        return dict.getInitialPythonClass() == PythonBuiltinClassType.PDict;
    }

    public static boolean isKindOfBuiltinClass(Object clazz) {
        return clazz instanceof PythonBuiltinClassType || clazz instanceof PythonBuiltinClass;
    }

    public static boolean isUnaryBuiltinDescriptor(Object value) {
        return value instanceof UnaryBuiltinDescriptor;
    }

    public static boolean isBinaryBuiltinDescriptor(Object value) {
        return value instanceof BinaryBuiltinDescriptor;
    }

    public static boolean isTernaryBuiltinDescriptor(Object value) {
        return value instanceof TernaryBuiltinDescriptor;
    }

    public static boolean isMinusOne(long l) {
        return l == -1;
    }

    public static boolean isAscii(TruffleString str, TruffleString.GetCodeRangeNode getCodeRangeNode) {
        return getCodeRangeNode.execute(str, TS_ENCODING) == CodeRange.ASCII;
    }

    @InliningCutoff
    public static boolean isIndexOrSlice(Node inliningTarget, PyIndexCheckNode indexCheckNode, Object key) {
        return indexCheckNode.execute(inliningTarget, key) || isPSlice(key);
    }

    @InliningCutoff
    public static boolean isNativeWrapper(PythonAbstractObject object) {
        PythonNativeWrapper wrapper = object.getNativeWrapper();
        return wrapper != null && wrapper.isNative();
    }

    public static boolean isNullOrZero(Object value, InteropLibrary lib) {
        if (value instanceof Long) {
            return ((long) value) == 0;
        } else {
            return lib.isNull(value);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy