< prev index next >

src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java

Print this page




  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  */
  25 
  26 package jdk.nashorn.internal.runtime.linker;
  27 
  28 import java.lang.invoke.MethodHandles;
  29 import java.lang.invoke.MethodHandles.Lookup;
  30 import java.lang.invoke.MethodType;
  31 import java.util.concurrent.ConcurrentHashMap;
  32 import java.util.concurrent.ConcurrentMap;
  33 import jdk.internal.dynalink.CallSiteDescriptor;
  34 import jdk.internal.dynalink.support.AbstractCallSiteDescriptor;
  35 import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
  36 import jdk.nashorn.internal.ir.debug.NashornTextifier;

  37 
  38 /**
  39  * Nashorn-specific implementation of Dynalink's {@link CallSiteDescriptor}. The reason we have our own subclass is that
  40  * we can have a more compact representation, as we know that we're always only using {@code "dyn:*"} operations; also
  41  * we're storing flags in an additional primitive field.
  42  */
  43 public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor {
  44     /** Flags that the call site references a scope variable (it's an identifier reference or a var declaration, not a
  45      * property access expression. */
  46     public static final int CALLSITE_SCOPE         = 1 << 0;
  47     /** Flags that the call site is in code that uses ECMAScript strict mode. */
  48     public static final int CALLSITE_STRICT        = 1 << 1;
  49     /** Flags that a property getter or setter call site references a scope variable that is located at a known distance
  50      * in the scope chain. Such getters and setters can often be linked more optimally using these assumptions. */
  51     public static final int CALLSITE_FAST_SCOPE    = 1 << 2;
  52     /** Flags that a callsite type is optimistic, i.e. we might get back a wider return value than encoded in the
  53      * descriptor, and in that case we have to throw an UnwarrantedOptimismException */
  54     public static final int CALLSITE_OPTIMISTIC    = 1 << 3;
  55     /** Is this really an apply that we try to call as a call? */
  56     public static final int CALLSITE_APPLY_TO_CALL = 1 << 4;


 228      * single property namespace for all these, therefore it is largely irrelevant what the composite operation is
 229      * structured like; if the first operation can't be satisfied, neither can the others. The first operation is
 230      * however sometimes used to slightly alter the semantics; for example, a distinction between {@code "getProp"} and
 231      * {@code "getMethod"} being the first operation can translate into whether {@code "__noSuchProperty__"} or
 232      * {@code "__noSuchMethod__"} will be executed in case the property is not found.
 233      * @return the first operator in this call site descriptor's name.
 234      */
 235     public String getFirstOperator() {
 236         final int delim = operator.indexOf(CallSiteDescriptor.OPERATOR_DELIMITER);
 237         return delim == -1 ? operator : operator.substring(0, delim);
 238     }
 239 
 240     /**
 241      * Returns the named operand in this descriptor's name. Equivalent to
 242      * {@code getNameToken(CallSiteDescriptor.NAME_OPERAND)}. E.g. for operation {@code "dyn:getProp:color"}, returns
 243      * {@code "color"}. For call sites without named operands (e.g. {@code "dyn:new"}) returns null.
 244      * @return the named operand in this descriptor's name.
 245      */
 246     public String getOperand() {
 247         return operand;
















































 248     }
 249 
 250     /**
 251      * Returns the Nashorn-specific flags for this call site descriptor.
 252      * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
 253      * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
 254      * generated outside of Nashorn.
 255      * @return the Nashorn-specific flags for the call site, or 0 if the passed descriptor is not a Nashorn call site
 256      * descriptor.
 257      */
 258     public static int getFlags(final CallSiteDescriptor desc) {
 259         return desc instanceof NashornCallSiteDescriptor ? ((NashornCallSiteDescriptor)desc).flags : 0;
 260     }
 261 
 262     /**
 263      * Returns true if this descriptor has the specified flag set, see {@code CALLSITE_*} constants in this class.
 264      * @param flag the tested flag
 265      * @return true if the flag is set, false otherwise
 266      */
 267     private boolean isFlag(final int flag) {




  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  */
  25 
  26 package jdk.nashorn.internal.runtime.linker;
  27 
  28 import java.lang.invoke.MethodHandles;
  29 import java.lang.invoke.MethodHandles.Lookup;
  30 import java.lang.invoke.MethodType;
  31 import java.util.concurrent.ConcurrentHashMap;
  32 import java.util.concurrent.ConcurrentMap;
  33 import jdk.internal.dynalink.CallSiteDescriptor;
  34 import jdk.internal.dynalink.support.AbstractCallSiteDescriptor;
  35 import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
  36 import jdk.nashorn.internal.ir.debug.NashornTextifier;
  37 import jdk.nashorn.internal.runtime.ScriptRuntime;
  38 
  39 /**
  40  * Nashorn-specific implementation of Dynalink's {@link CallSiteDescriptor}. The reason we have our own subclass is that
  41  * we can have a more compact representation, as we know that we're always only using {@code "dyn:*"} operations; also
  42  * we're storing flags in an additional primitive field.
  43  */
  44 public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor {
  45     /** Flags that the call site references a scope variable (it's an identifier reference or a var declaration, not a
  46      * property access expression. */
  47     public static final int CALLSITE_SCOPE         = 1 << 0;
  48     /** Flags that the call site is in code that uses ECMAScript strict mode. */
  49     public static final int CALLSITE_STRICT        = 1 << 1;
  50     /** Flags that a property getter or setter call site references a scope variable that is located at a known distance
  51      * in the scope chain. Such getters and setters can often be linked more optimally using these assumptions. */
  52     public static final int CALLSITE_FAST_SCOPE    = 1 << 2;
  53     /** Flags that a callsite type is optimistic, i.e. we might get back a wider return value than encoded in the
  54      * descriptor, and in that case we have to throw an UnwarrantedOptimismException */
  55     public static final int CALLSITE_OPTIMISTIC    = 1 << 3;
  56     /** Is this really an apply that we try to call as a call? */
  57     public static final int CALLSITE_APPLY_TO_CALL = 1 << 4;


 229      * single property namespace for all these, therefore it is largely irrelevant what the composite operation is
 230      * structured like; if the first operation can't be satisfied, neither can the others. The first operation is
 231      * however sometimes used to slightly alter the semantics; for example, a distinction between {@code "getProp"} and
 232      * {@code "getMethod"} being the first operation can translate into whether {@code "__noSuchProperty__"} or
 233      * {@code "__noSuchMethod__"} will be executed in case the property is not found.
 234      * @return the first operator in this call site descriptor's name.
 235      */
 236     public String getFirstOperator() {
 237         final int delim = operator.indexOf(CallSiteDescriptor.OPERATOR_DELIMITER);
 238         return delim == -1 ? operator : operator.substring(0, delim);
 239     }
 240 
 241     /**
 242      * Returns the named operand in this descriptor's name. Equivalent to
 243      * {@code getNameToken(CallSiteDescriptor.NAME_OPERAND)}. E.g. for operation {@code "dyn:getProp:color"}, returns
 244      * {@code "color"}. For call sites without named operands (e.g. {@code "dyn:new"}) returns null.
 245      * @return the named operand in this descriptor's name.
 246      */
 247     public String getOperand() {
 248         return operand;
 249     }
 250 
 251     /**
 252      * If this is a dyn:call or dyn:new, this returns function description from callsite.
 253      * Caller has to make sure this is a dyn:call or dyn:new call site.
 254      *
 255      * @return function description if available (or null)
 256      */
 257     public String getFunctionDescription() {
 258         assert getFirstOperator().equals("call") || getFirstOperator().equals("new");
 259         return getNameTokenCount() > 2? getNameToken(2) : null;
 260     }
 261 
 262     /**
 263      * If this is a dyn:call or dyn:new, this returns function description from callsite.
 264      * Caller has to make sure this is a dyn:call or dyn:new call site.
 265      *
 266      * @param desc call site descriptor
 267      * @return function description if available (or null)
 268      */
 269     public static String getFunctionDescription(final CallSiteDescriptor desc) {
 270         return desc instanceof NashornCallSiteDescriptor ?
 271                 ((NashornCallSiteDescriptor)desc).getFunctionDescription() : null;
 272     }
 273 
 274 
 275     /**
 276      * Returns the error message to be used when dyn:call or dyn:new is used on a non-function.
 277      *
 278      * @param obj object on which dyn:call or dyn:new is used
 279      * @return error message
 280      */
 281     public String getFunctionErrorMessage(final Object obj) {
 282         final String funcDesc = getFunctionDescription();
 283         return funcDesc != null? funcDesc : ScriptRuntime.safeToString(obj);
 284     }
 285 
 286     /**
 287      * Returns the error message to be used when dyn:call or dyn:new is used on a non-function.
 288      *
 289      * @param desc call site descriptor
 290      * @param obj object on which dyn:call or dyn:new is used
 291      * @return error message
 292      */
 293     public static String getFunctionErrorMessage(final CallSiteDescriptor desc, final Object obj) {
 294         return desc instanceof NashornCallSiteDescriptor ?
 295                 ((NashornCallSiteDescriptor)desc).getFunctionErrorMessage(obj) :
 296                 ScriptRuntime.safeToString(obj);
 297     }
 298 
 299     /**
 300      * Returns the Nashorn-specific flags for this call site descriptor.
 301      * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
 302      * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
 303      * generated outside of Nashorn.
 304      * @return the Nashorn-specific flags for the call site, or 0 if the passed descriptor is not a Nashorn call site
 305      * descriptor.
 306      */
 307     public static int getFlags(final CallSiteDescriptor desc) {
 308         return desc instanceof NashornCallSiteDescriptor ? ((NashornCallSiteDescriptor)desc).flags : 0;
 309     }
 310 
 311     /**
 312      * Returns true if this descriptor has the specified flag set, see {@code CALLSITE_*} constants in this class.
 313      * @param flag the tested flag
 314      * @return true if the flag is set, false otherwise
 315      */
 316     private boolean isFlag(final int flag) {


< prev index next >