src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java
Print this page
@@ -2211,14 +2211,14 @@
*
* @param valueType type of the value to set
* @param name name of property
* @param flags call site flags
* @param isMethod should it prefer retrieving methods
- *
+ * @param isIndex is this an index operation?
* @return the method emitter
*/
- MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod) {
+ MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod, final boolean isIndex) {
if (name.length() > LARGE_STRING_THRESHOLD) { // use getIndex for extremely long names
return load(name).dynamicGetIndex(valueType, flags, isMethod);
}
debug("dynamic_get", name, valueType, getProgramPoint(flags));
@@ -2227,12 +2227,12 @@
if (type.isObject() || type.isBoolean()) {
type = Type.OBJECT; //promote e.g strings to object generic setter
}
popType(Type.SCOPE);
- method.visitInvokeDynamicInsn((isMethod ? "dyn:getMethod|getProp|getElem:" : "dyn:getProp|getElem|getMethod:") +
- NameCodec.encode(name), Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags);
+ method.visitInvokeDynamicInsn(dynGetOperation(isMethod, isIndex) + ':' + NameCodec.encode(name),
+ Type.getMethodDescriptor(type, Type.OBJECT), LINKERBOOTSTRAP, flags);
pushType(type);
convert(valueType); //most probably a nop
return this;
@@ -2241,12 +2241,13 @@
/**
* Generate dynamic setter. Pop receiver and property from stack.
*
* @param name name of property
* @param flags call site flags
+ * @param isIndex is this an index operation?
*/
- void dynamicSet(final String name, final int flags) {
+ void dynamicSet(final String name, final int flags, final boolean isIndex) {
if (name.length() > LARGE_STRING_THRESHOLD) { // use setIndex for extremely long names
load(name).swap().dynamicSetIndex(flags);
return;
}
@@ -2259,11 +2260,12 @@
convert(Type.OBJECT); //TODO bad- until we specialize boolean setters,
}
popType(type);
popType(Type.SCOPE);
- method.visitInvokeDynamicInsn("dyn:setProp|setElem:" + NameCodec.encode(name), methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags);
+ method.visitInvokeDynamicInsn(dynSetOperation(isIndex) + ':' + NameCodec.encode(name),
+ methodDescriptor(void.class, Object.class, type.getTypeClass()), LINKERBOOTSTRAP, flags);
}
/**
* Dynamic getter for indexed structures. Pop index and receiver from stack,
* generate appropriate signatures based on types
@@ -2292,11 +2294,11 @@
popType(Type.OBJECT);
final String signature = Type.getMethodDescriptor(resultType, Type.OBJECT /*e.g STRING->OBJECT*/, index);
- method.visitInvokeDynamicInsn(isMethod ? "dyn:getMethod|getElem|getProp" : "dyn:getElem|getProp|getMethod", signature, LINKERBOOTSTRAP, flags);
+ method.visitInvokeDynamicInsn(dynGetOperation(isMethod, true), signature, LINKERBOOTSTRAP, flags);
pushType(resultType);
if (result.isBoolean()) {
convert(Type.BOOLEAN);
}
@@ -2506,10 +2508,22 @@
}
next = next.getNext();
}
}
+ private static String dynGetOperation(final boolean isMethod, final boolean isIndex) {
+ if (isMethod) {
+ return isIndex ? "dyn:getMethod|getElem|getProp" : "dyn:getMethod|getProp|getElem";
+ } else {
+ return isIndex ? "dyn:getElem|getProp|getMethod" : "dyn:getProp|getElem|getMethod";
+ }
+ }
+
+ private static String dynSetOperation(final boolean isIndex) {
+ return isIndex ? "dyn:setElem|setProp" : "dyn:setProp|setElem";
+ }
+
private Type emitLocalVariableConversion(final LocalVariableConversion conversion, final boolean onlySymbolLiveValue) {
final Type from = conversion.getFrom();
final Type to = conversion.getTo();
final Symbol symbol = conversion.getSymbol();
assert symbol.isBytecodeLocal();