src/jdk/nashorn/api/scripting/ScriptUtils.java

Thu, 24 May 2018 16:39:31 +0800

author
aoqi
date
Thu, 24 May 2018 16:39:31 +0800
changeset 1959
61ffdd1b89f2
parent 1742
fe6ef89d9c04
parent 1490
d85f981c8cf8
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package jdk.nashorn.api.scripting;
    28 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    30 import java.lang.invoke.MethodHandle;
    31 import jdk.internal.dynalink.beans.StaticClass;
    32 import jdk.internal.dynalink.linker.LinkerServices;
    33 import jdk.nashorn.internal.runtime.Context;
    34 import jdk.nashorn.internal.runtime.ScriptFunction;
    35 import jdk.nashorn.internal.runtime.ScriptObject;
    36 import jdk.nashorn.internal.runtime.ScriptRuntime;
    37 import jdk.nashorn.internal.runtime.linker.Bootstrap;
    39 /**
    40  * Utilities that are to be called from script code.
    41  *
    42  * @since 1.8u40
    43  */
    44 @jdk.Exported
    45 public final class ScriptUtils {
    46     private ScriptUtils() {}
    48     /**
    49      * Returns AST as JSON compatible string. This is used to
    50      * implement "parse" function in resources/parse.js script.
    51      *
    52      * @param code code to be parsed
    53      * @param name name of the code source (used for location)
    54      * @param includeLoc tells whether to include location information for nodes or not
    55      * @return JSON string representation of AST of the supplied code
    56      */
    57     public static String parse(final String code, final String name, final boolean includeLoc) {
    58         return ScriptRuntime.parse(code, name, includeLoc);
    59     }
    61     /**
    62      * Method which converts javascript types to java types for the
    63      * String.format method (jrunscript function sprintf).
    64      *
    65      * @param format a format string
    66      * @param args arguments referenced by the format specifiers in format
    67      * @return a formatted string
    68      */
    69     public static String format(final String format, final Object[] args) {
    70         return Formatter.format(format, args);
    71     }
    73     /**
    74      * Create a wrapper function that calls {@code func} synchronized on {@code sync} or, if that is undefined,
    75      * {@code self}. Used to implement "sync" function in resources/mozilla_compat.js.
    76      *
    77      * @param func the function to wrap
    78      * @param sync the object to synchronize on
    79      * @return a synchronizing wrapper function
    80      * @throws IllegalArgumentException if func does not represent a script function
    81      */
    82     public static Object makeSynchronizedFunction(final Object func, final Object sync) {
    83         final Object unwrapped = unwrap(func);
    84         if (unwrapped instanceof ScriptFunction) {
    85             return ((ScriptFunction)unwrapped).createSynchronized(unwrap(sync));
    86         }
    88         throw new IllegalArgumentException();
    89     }
    91     /**
    92      * Make a script object mirror on given object if needed.
    93      *
    94      * @param obj object to be wrapped
    95      * @return wrapped object
    96      * @throws IllegalArgumentException if obj cannot be wrapped
    97      */
    98     public static ScriptObjectMirror wrap(final Object obj) {
    99         if (obj instanceof ScriptObjectMirror) {
   100             return (ScriptObjectMirror)obj;
   101         }
   103         if (obj instanceof ScriptObject) {
   104             final ScriptObject sobj = (ScriptObject)obj;
   105             return (ScriptObjectMirror) ScriptObjectMirror.wrap(sobj, Context.getGlobal());
   106         }
   108         throw new IllegalArgumentException();
   109     }
   111     /**
   112      * Unwrap a script object mirror if needed.
   113      *
   114      * @param obj object to be unwrapped
   115      * @return unwrapped object
   116      */
   117     public static Object unwrap(final Object obj) {
   118         if (obj instanceof ScriptObjectMirror) {
   119             return ScriptObjectMirror.unwrap(obj, Context.getGlobal());
   120         }
   122         return obj;
   123     }
   125     /**
   126      * Wrap an array of object to script object mirrors if needed.
   127      *
   128      * @param args array to be unwrapped
   129      * @return wrapped array
   130      */
   131     public static Object[] wrapArray(final Object[] args) {
   132         if (args == null || args.length == 0) {
   133             return args;
   134         }
   136         return ScriptObjectMirror.wrapArray(args, Context.getGlobal());
   137     }
   139     /**
   140      * Unwrap an array of script object mirrors if needed.
   141      *
   142      * @param args array to be unwrapped
   143      * @return unwrapped array
   144      */
   145     public static Object[] unwrapArray(final Object[] args) {
   146         if (args == null || args.length == 0) {
   147             return args;
   148         }
   150         return ScriptObjectMirror.unwrapArray(args, Context.getGlobal());
   151     }
   153     /**
   154      * Convert the given object to the given type.
   155      *
   156      * @param obj object to be converted
   157      * @param type destination type to convert to. type is either a Class
   158      * or nashorn representation of a Java type returned by Java.type() call in script.
   159      * @return converted object
   160      */
   161     public static Object convert(final Object obj, final Object type) {
   162         if (obj == null) {
   163             return null;
   164         }
   166         final Class<?> clazz;
   167         if (type instanceof Class) {
   168             clazz = (Class<?>)type;
   169         } else if (type instanceof StaticClass) {
   170             clazz = ((StaticClass)type).getRepresentedClass();
   171         } else {
   172             throw new IllegalArgumentException("type expected");
   173         }
   175         final LinkerServices linker = Bootstrap.getLinkerServices();
   176         final Object objToConvert = unwrap(obj);
   177         final MethodHandle converter = linker.getTypeConverter(objToConvert.getClass(),  clazz);
   178         if (converter == null) {
   179             // no supported conversion!
   180             throw new UnsupportedOperationException("conversion not supported");
   181         }
   183         try {
   184             return converter.invoke(objToConvert);
   185         } catch (final RuntimeException | Error e) {
   186             throw e;
   187         } catch (final Throwable t) {
   188             throw new RuntimeException(t);
   189         }
   190     }
   191 }

mercurial