/* * Copyright (c) 2010, 2013, 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 java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import jdk.dynalink.linker.GuardedInvocation; import jdk.dynalink.linker.LinkRequest; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.linker.PrimitiveLookup; /** * ECMA 15.6 Boolean Objects. */ @ScriptClass("Boolean") public final class NativeBoolean extends ScriptObject { private final boolean value; /** Method handle to create an object wrapper for a primitive boolean. */ static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeBoolean.class, Object.class)); /** Method handle to retrieve the Boolean prototype object. */ private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class)); // initialized by nasgen private static PropertyMap $nasgenmap$; private NativeBoolean(final boolean value, final ScriptObject proto, final PropertyMap map) { super(proto, map); this.value = value; } NativeBoolean(final boolean flag, final Global global) { this(flag, global.getBooleanPrototype(), $nasgenmap$); } NativeBoolean(final boolean flag) { this(flag, Global.instance()); } @Override public String safeToString() { return "[Boolean " + toString() + "]"; } @Override public String toString() { return Boolean.toString(getValue()); } /** * Get the value for this NativeBoolean * @return true or false */ public boolean getValue() { return booleanValue(); } /** * Get the value for this NativeBoolean * @return true or false */ public boolean booleanValue() { return value; } @Override public String getClassName() { return "Boolean"; } /** * ECMA 15.6.4.2 Boolean.prototype.toString ( ) * * @param self self reference * @return string representation of this boolean */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static String toString(final Object self) { return getBoolean(self).toString(); } /** * ECMA 15.6.4.3 Boolean.prototype.valueOf ( ) * * @param self self reference * @return value of this boolean */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static boolean valueOf(final Object self) { return getBoolean(self); } /** * ECMA 15.6.2.1 new Boolean (value) * * @param newObj is the new operator used to instantiate this NativeBoolean * @param self self reference * @param value value of boolean * @return the new NativeBoolean */ @Constructor(arity = 1) public static Object constructor(final boolean newObj, final Object self, final Object value) { final boolean flag = JSType.toBoolean(value); if (newObj) { return new NativeBoolean(flag); } return flag; } private static Boolean getBoolean(final Object self) { if (self instanceof Boolean) { return ((Boolean)self); } else if (self instanceof NativeBoolean) { return ((NativeBoolean)self).getValue(); } else if (self != null && self == Global.instance().getBooleanPrototype()) { return false; } else { throw typeError("not.a.boolean", ScriptRuntime.safeToString(self)); } } /** * Lookup the appropriate method for an invoke dynamic call. * * @param request The link request * @param receiver The receiver for the call * @return Link to be invoked at call site. */ public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) { return PrimitiveLookup.lookupPrimitive(request, Boolean.class, new NativeBoolean((Boolean)receiver), WRAPFILTER, PROTOFILTER); } /** * Wrap a native boolean in a NativeBoolean object. * * @param receiver Native boolean. * @return Wrapped object. */ @SuppressWarnings("unused") private static NativeBoolean wrapFilter(final Object receiver) { return new NativeBoolean((Boolean)receiver); } @SuppressWarnings("unused") private static Object protoFilter(final Object object) { return Global.instance().getBooleanPrototype(); } private static MethodHandle findOwnMH(final String name, final MethodType type) { return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, name, type); } }