/*
 * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.nashorn.internal.objects;

import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.lookup.Lookup;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
import jdk.nashorn.internal.runtime.FindProperty;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
import jdk.nashorn.internal.scripts.JO;

/**
 * This class is the implementation of the Nashorn-specific global object named {@code JSAdapter}. It can be thought of
 * as the {@link java.lang.reflect.Proxy} equivalent for JavaScript. A {@code NativeJSAdapter} calls specially named
 * JavaScript methods on an adaptee object when property access/update/call/new/delete is attempted on it. Example:
 *<pre>
 *    var y = {
 *                __get__     : function (name) { ... }
 *                __has__     : function (name) { ... }
 *                __put__     : function (name, value) {...}
 *                __call__    : function (name, arg1, arg2) {...}
 *                __new__     : function (arg1, arg2) {...}
 *                __delete__  : function (name) { ... }
 *                __getKeys__ : function () { ... }
 *            };
 *
 *    var x = new JSAdapter(y);
 *
 *    x.i;                        // calls y.__get__
 *    x.foo();                    // calls y.__call__
 *    new x();                    // calls y.__new__
 *    i in x;                     // calls y.__has__
 *    x.p = 10;                   // calls y.__put__
 *    delete x.p;                 // calls y.__delete__
 *    for (i in x) { print(i); }  // calls y.__getKeys__
 * </pre>
 * <p>
 * The {@code __getKeys__} and {@code __getIds__} properties are mapped to the same operation. Concrete
 * {@code JSAdapter} implementations are expected to use only one of these. As {@code __getIds__} exists for
 * compatibility reasons only, use of {@code __getKeys__} is recommended.
 * </p>
 * <p>
 * The JavaScript caller of an adapter object is oblivious of the property access/mutation/deletion's being adapted.
 * </p>
 * <p>
 * The {@code JSAdapter} constructor can optionally receive an "overrides" object. The properties of overrides object
 * are copied to the {@code JSAdapter} instance. In case user-accessed properties are among these, the adaptee's methods
 * like {@code __get__}, {@code __put__} etc. are not called for them. This can be used to make certain "preferred"
 * properties that can be accessed in the usual/faster way avoiding the proxy mechanism. Example:
 * </p>
 * <pre>
 *     var x = new JSAdapter({ foo: 444, bar: 6546 }) {
 *          __get__: function(name) { return name; }
 *      };
 *
 *     x.foo;           // 444 directly retrieved without __get__ call
 *     x.bar = 'hello'; // "bar" directly set without __put__ call
 *     x.prop           // calls __get__("prop") as 'prop' is not overridden
 * </pre>
 * It is possible to pass a specific prototype for the {@code JSAdapter} instance by passing three arguments to the
 * {@code JSAdapter} constructor. The exact signature of the {@code JSAdapter} constructor is as follows:
 * <pre>
 *     JSAdapter([proto], [overrides], adaptee);
 * </pre>
 * Both the {@code proto} and {@code overrides} arguments are optional - but {@code adaptee} is not. When {@code proto}
 * is not passed, {@code JSAdapter.prototype} is used.
 */
@ScriptClass("JSAdapter")
public final class NativeJSAdapter extends ScriptObject {
    /** object get operation */
    public static final String __get__       = "__get__";
    /** object out operation */
    public static final String __put__       = "__put__";
    /** object call operation */
    public static final String __call__      = "__call__";
    /** object new operation */
    public static final String __new__       = "__new__";
    /** object getIds operation (provided for compatibility reasons; use of getKeys is preferred) */
    public static final String __getIds__    = "__getIds__";
    /** object getKeys operation */
    public static final String __getKeys__   = "__getKeys__";
    /** object getValues operation */
    public static final String __getValues__ = "__getValues__";
    /** object has operation */
    public static final String __has__       = "__has__";
    /** object delete operation */
    public static final String __delete__    = "__delete__";

    // the new extensibility, sealing and freezing operations

    /** prevent extensions operation */
    public static final String __preventExtensions__ = "__preventExtensions__";
    /** isExtensible extensions operation */
    public static final String __isExtensible__      = "__isExtensible__";
    /** seal operation */
    public static final String __seal__              = "__seal__";
    /** isSealed extensions operation */
    public static final String __isSealed__          = "__isSealed__";
    /** freeze operation */
    public static final String __freeze__            = "__freeze__";
    /** isFrozen extensions operation */
    public static final String __isFrozen__          = "__isFrozen__";

    private final ScriptObject adaptee;
    private final boolean overrides;

    private static final MethodHandle IS_JSADAPTER = findOwnMH("isJSAdapter", boolean.class, Object.class, Object.class, MethodHandle.class, Object.class, ScriptFunction.class);

    // initialized by nasgen
    private static PropertyMap $nasgenmap$;

    NativeJSAdapter(final Object overrides, final ScriptObject adaptee, final ScriptObject proto, final PropertyMap map) {
        super(proto, map);
        this.adaptee = wrapAdaptee(adaptee);
        if (overrides instanceof ScriptObject) {
            this.overrides = true;
            final ScriptObject sobj = (ScriptObject)overrides;
            this.addBoundProperties(sobj);
        } else {
            this.overrides = false;
        }
    }

    private static ScriptObject wrapAdaptee(final ScriptObject adaptee) {
        return new JO(adaptee);
    }

    @Override
    public String getClassName() {
        return "JSAdapter";
    }

    @Override
    public int getInt(final Object key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
    }

    @Override
    public int getInt(final double key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
    }

    @Override
    public int getInt(final long key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
    }

    @Override
    public int getInt(final int key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
    }

    @Override
    public long getLong(final Object key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
    }

    @Override
    public long getLong(final double key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
    }

    @Override
    public long getLong(final long key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
    }

    @Override
    public long getLong(final int key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
    }

    @Override
    public double getDouble(final Object key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
    }

    @Override
    public double getDouble(final double key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
    }

    @Override
    public double getDouble(final long key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
    }

    @Override
    public double getDouble(final int key, final int programPoint) {
        return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
    }

    @Override
    public Object get(final Object key) {
        return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
    }

    @Override
    public Object get(final double key) {
        return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
    }

    @Override
    public Object get(final long key) {
        return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
    }

    @Override
    public Object get(final int key) {
        return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
    }

    @Override
    public void set(final Object key, final int value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final Object key, final long value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final Object key, final double value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final Object key, final Object value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final double key, final int value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final double key, final long value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final double key, final double value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final double key, final Object value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final long key, final int value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final long key, final long value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final long key, final double value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final long key, final Object value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final int key, final int value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final int key, final long value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final int key, final double value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public void set(final int key, final Object value, final int flags) {
        if (overrides && super.hasOwnProperty(key)) {
            super.set(key, value, flags);
        } else {
            callAdaptee(__put__, key, value, flags);
        }
    }

    @Override
    public boolean has(final Object key) {
        if (overrides && super.hasOwnProperty(key)) {
            return true;
        }

        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
    }

    @Override
    public boolean has(final int key) {
        if (overrides && super.hasOwnProperty(key)) {
            return true;
        }

        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
    }

    @Override
    public boolean has(final long key) {
        if (overrides && super.hasOwnProperty(key)) {
            return true;
        }

        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
    }

    @Override
    public boolean has(final double key) {
        if (overrides && super.hasOwnProperty(key)) {
            return true;
        }

        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
    }

    @Override
    public boolean delete(final int key, final boolean strict) {
        if (overrides && super.hasOwnProperty(key)) {
            return super.delete(key, strict);
        }

        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
    }

    @Override
    public boolean delete(final long key, final boolean strict) {
        if (overrides && super.hasOwnProperty(key)) {
            return super.delete(key, strict);
        }

        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
    }

    @Override
    public boolean delete(final double key, final boolean strict) {
        if (overrides && super.hasOwnProperty(key)) {
            return super.delete(key, strict);
        }

        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
    }

    @Override
    public boolean delete(final Object key, final boolean strict) {
        if (overrides && super.hasOwnProperty(key)) {
            return super.delete(key, strict);
        }

        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
    }

    @Override
    public Iterator<String> propertyIterator() {
        // Try __getIds__ first, if not found then try __getKeys__
        // In jdk6, we had added "__getIds__" so this is just for compatibility.
        Object func = adaptee.get(__getIds__);
        if (!(func instanceof ScriptFunction)) {
            func = adaptee.get(__getKeys__);
        }

        Object obj;
        if (func instanceof ScriptFunction) {
            obj = ScriptRuntime.apply((ScriptFunction)func, adaptee);
        } else {
            obj = new NativeArray(0);
        }

        final List<String> array = new ArrayList<>();
        for (final Iterator<Object> iter = ArrayLikeIterator.arrayLikeIterator(obj); iter.hasNext(); ) {
            array.add((String)iter.next());
        }

        return array.iterator();
    }


    @Override
    public Iterator<Object> valueIterator() {
        final Object obj = callAdaptee(new NativeArray(0), __getValues__);
        return ArrayLikeIterator.arrayLikeIterator(obj);
    }

    @Override
    public ScriptObject preventExtensions() {
        callAdaptee(__preventExtensions__);
        return this;
    }

    @Override
    public boolean isExtensible() {
        return JSType.toBoolean(callAdaptee(Boolean.TRUE, __isExtensible__));
    }

    @Override
    public ScriptObject seal() {
        callAdaptee(__seal__);
        return this;
    }

    @Override
    public boolean isSealed() {
        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __isSealed__));
    }

    @Override
    public ScriptObject freeze() {
        callAdaptee(__freeze__);
        return this;
    }

    @Override
    public boolean isFrozen() {
        return JSType.toBoolean(callAdaptee(Boolean.FALSE, __isFrozen__));
    }

    /**
     * Constructor
     *
     * @param isNew is this NativeJSAdapter instantiated with the new operator
     * @param self  self reference
     * @param args  arguments ([adaptee], [overrides, adaptee] or [proto, overrides, adaptee]
     * @return new NativeJSAdapter
     */
    @Constructor
    public static NativeJSAdapter construct(final boolean isNew, final Object self, final Object... args) {
        Object proto     = UNDEFINED;
        Object overrides = UNDEFINED;
        Object adaptee;

        if (args == null || args.length == 0) {
            throw typeError("not.an.object", "null");
        }

        switch (args.length) {
        case 1:
            adaptee = args[0];
            break;

        case 2:
            overrides = args[0];
            adaptee   = args[1];
            break;

        default:
            //fallthru
        case 3:
            proto = args[0];
            overrides = args[1];
            adaptee = args[2];
            break;
        }

        if (!(adaptee instanceof ScriptObject)) {
            throw typeError("not.an.object", ScriptRuntime.safeToString(adaptee));
        }

        final Global global = Global.instance();
        if (proto != null && !(proto instanceof ScriptObject)) {
            proto = global.getJSAdapterPrototype();
        }

        return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, $nasgenmap$);
    }

    @Override
    protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc, final LinkRequest request) {
        return findHook(desc, __new__, false);
    }

    @Override
    protected GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final LinkRequest request) {
        if (overrides && super.hasOwnProperty(desc.getNameToken(2))) {
            try {
                final GuardedInvocation inv = super.findCallMethodMethod(desc, request);
                if (inv != null) {
                    return inv;
                }
            } catch (final Exception e) {
                //ignored
            }
        }

        return findHook(desc, __call__);
    }

    @Override
    protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operation) {
        final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
        if (overrides && super.hasOwnProperty(name)) {
            try {
                final GuardedInvocation inv = super.findGetMethod(desc, request, operation);
                if (inv != null) {
                    return inv;
                }
            } catch (final Exception e) {
                //ignored
            }
        }

        switch(operation) {
        case "getProp":
        case "getElem":
            return findHook(desc, __get__);
        case "getMethod":
            final FindProperty find = adaptee.findProperty(__call__, true);
            if (find != null) {
                final Object value = find.getObjectValue();
                if (value instanceof ScriptFunction) {
                    final ScriptFunction func = (ScriptFunction)value;
                    // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
                    // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
                    return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
                            func.createBound(this, new Object[] { name })), 0, Object.class),
                            testJSAdapter(adaptee, null, null, null),
                            adaptee.getProtoSwitchPoints(__call__, find.getOwner()), null);
                }
            }
            throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
        default:
            break;
        }

        throw new AssertionError("should not reach here");
    }

    @Override
    protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
        if (overrides && super.hasOwnProperty(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND))) {
            try {
                final GuardedInvocation inv = super.findSetMethod(desc, request);
                if (inv != null) {
                    return inv;
                }
            } catch (final Exception e) {
                //ignored
            }
        }

        return findHook(desc, __put__);
    }

    // -- Internals only below this point
    private Object callAdaptee(final String name, final Object... args) {
        return callAdaptee(UNDEFINED, name, args);
    }

    private double callAdapteeDouble(final int programPoint, final String name, final Object... args) {
        return JSType.toNumberMaybeOptimistic(callAdaptee(name, args), programPoint);
    }

    private long callAdapteeLong(final int programPoint, final String name, final Object... args) {
        return JSType.toLongMaybeOptimistic(callAdaptee(name, args), programPoint);
    }

    private int callAdapteeInt(final int programPoint, final String name, final Object... args) {
        return JSType.toInt32MaybeOptimistic(callAdaptee(name, args), programPoint);
    }

    private Object callAdaptee(final Object retValue, final String name, final Object... args) {
        final Object func = adaptee.get(name);
        if (func instanceof ScriptFunction) {
            return ScriptRuntime.apply((ScriptFunction)func, adaptee, args);
        }
        return retValue;
    }

    private GuardedInvocation findHook(final CallSiteDescriptor desc, final String hook) {
        return findHook(desc, hook, true);
    }

    private GuardedInvocation findHook(final CallSiteDescriptor desc, final String hook, final boolean useName) {
        final FindProperty findData = adaptee.findProperty(hook, true);
        final MethodType type = desc.getMethodType();
        if (findData != null) {
            final String name = desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null;
            final Object value = findData.getObjectValue();
            if (value instanceof ScriptFunction) {
                final ScriptFunction func = (ScriptFunction)value;

                final MethodHandle methodHandle = getCallMethodHandle(findData, type,
                    useName ? name : null);
                if (methodHandle != null) {
                    return new GuardedInvocation(
                            methodHandle,
                            testJSAdapter(adaptee, findData.getGetter(Object.class, INVALID_PROGRAM_POINT, null), findData.getOwner(), func),
                            adaptee.getProtoSwitchPoints(hook, findData.getOwner()), null);
                }
             }
        }

        switch (hook) {
        case __call__:
            throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this));
        default:
            final MethodHandle methodHandle = hook.equals(__put__) ?
            MH.asType(Lookup.EMPTY_SETTER, type) :
            Lookup.emptyGetter(type.returnType());
            return new GuardedInvocation(methodHandle, testJSAdapter(adaptee, null, null, null), adaptee.getProtoSwitchPoints(hook, null), null);
        }
    }

    private static MethodHandle testJSAdapter(final Object adaptee, final MethodHandle getter, final Object where, final ScriptFunction func) {
        return MH.insertArguments(IS_JSADAPTER, 1, adaptee, getter, where, func);
    }

    @SuppressWarnings("unused")
    private static boolean isJSAdapter(final Object self, final Object adaptee, final MethodHandle getter, final Object where, final ScriptFunction func) {
        final boolean res = self instanceof NativeJSAdapter && ((NativeJSAdapter)self).getAdaptee() == adaptee;
        if (res && getter != null) {
            try {
                return getter.invokeExact(where) == func;
            } catch (final RuntimeException | Error e) {
                throw e;
            } catch (final Throwable t) {
                throw new RuntimeException(t);
            }
        }

        return res;
    }

    /**
     * Get the adaptee
     * @return adaptee ScriptObject
     */
    public ScriptObject getAdaptee() {
        return adaptee;
    }

    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
        return MH.findStatic(MethodHandles.lookup(), NativeJSAdapter.class, name, MH.type(rtype, types));
    }
}
