8008239: Unpublicized parts of the code generator package that were only package internal.
Reviewed-by: hannesw, attila
--- a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java Fri Feb 15 09:44:15 2013 +0100
@@ -25,14 +25,14 @@
package jdk.nashorn.internal.codegen;
-import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.EQ;
-import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.GE;
-import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.GT;
-import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.LE;
-import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.LT;
-import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.NE;
+import static jdk.nashorn.internal.codegen.Condition.EQ;
+import static jdk.nashorn.internal.codegen.Condition.GE;
+import static jdk.nashorn.internal.codegen.Condition.GT;
+import static jdk.nashorn.internal.codegen.Condition.LE;
+import static jdk.nashorn.internal.codegen.Condition.LT;
+import static jdk.nashorn.internal.codegen.Condition.NE;
-import jdk.nashorn.internal.codegen.MethodEmitter.Label;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.BinaryNode;
import jdk.nashorn.internal.ir.Node;
--- a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java Fri Feb 15 09:44:15 2013 +0100
@@ -62,6 +62,7 @@
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.util.TraceClassVisitor;
+import jdk.nashorn.internal.codegen.Emitter;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.runtime.Context;
@@ -102,7 +103,6 @@
* detect if this is not true
*
* @see Compiler
- * @see CodeGenerator
*/
public class ClassEmitter implements Emitter {
@@ -156,7 +156,7 @@
* @param superClassName super class name for class
* @param interfaceNames names of interfaces implemented by this class, or null if none
*/
- public ClassEmitter(final Context context, final String className, final String superClassName, final String... interfaceNames) {
+ ClassEmitter(final Context context, final String className, final String superClassName, final String... interfaceNames) {
this(context, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClassName, interfaceNames);
}
@@ -363,7 +363,7 @@
* @param bytecode byte array representing bytecode
* @return disassembly as human readable string
*/
- public static String disassemble(final byte[] bytecode) {
+ static String disassemble(final byte[] bytecode) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (final PrintWriter pw = new PrintWriter(baos)) {
new ClassReader(bytecode).accept(new TraceClassVisitor(pw), 0);
@@ -411,7 +411,7 @@
*
* @return method emitter to use for weaving this method
*/
- public MethodEmitter method(final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
+ MethodEmitter method(final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
return method(DEFAULT_METHOD_FLAGS, methodName, rtype, ptypes); //TODO why public default ?
}
@@ -425,7 +425,7 @@
*
* @return method emitter to use for weaving this method
*/
- public MethodEmitter method(final EnumSet<Flag> methodFlags, final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
+ MethodEmitter method(final EnumSet<Flag> methodFlags, final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
return new MethodEmitter(this, cw.visitMethod(Flag.getValue(methodFlags), methodName, methodDescriptor(rtype, ptypes), null, null));
}
@@ -437,7 +437,7 @@
*
* @return method emitter to use for weaving this method
*/
- public MethodEmitter method(final String methodName, final String descriptor) {
+ MethodEmitter method(final String methodName, final String descriptor) {
return method(DEFAULT_METHOD_FLAGS, methodName, descriptor);
}
@@ -450,7 +450,7 @@
*
* @return method emitter to use for weaving this method
*/
- public MethodEmitter method(final EnumSet<Flag> methodFlags, final String methodName, final String descriptor) {
+ MethodEmitter method(final EnumSet<Flag> methodFlags, final String methodName, final String descriptor) {
return new MethodEmitter(this, cw.visitMethod(Flag.getValue(methodFlags), methodName, descriptor, null, null));
}
@@ -460,7 +460,7 @@
* @param functionNode the function node to generate a method for
* @return method emitter to use for weaving this method
*/
- public MethodEmitter method(final FunctionNode functionNode) {
+ MethodEmitter method(final FunctionNode functionNode) {
final MethodVisitor mv = cw.visitMethod(
ACC_PUBLIC | ACC_STATIC | (functionNode.isVarArg() ? ACC_VARARGS : 0),
functionNode.getName(),
@@ -476,7 +476,7 @@
*
* @return method emitter to use for weaving <clinit>
*/
- public MethodEmitter clinit() {
+ MethodEmitter clinit() {
return method(EnumSet.of(Flag.STATIC), CLINIT.tag(), void.class);
}
@@ -485,7 +485,7 @@
*
* @return method emitter to use for weaving <init>()V
*/
- public MethodEmitter init() {
+ MethodEmitter init() {
return method(INIT.tag(), void.class);
}
@@ -495,7 +495,7 @@
* @param ptypes parameter types for constructor
* @return method emitter to use for weaving <init>()V
*/
- public MethodEmitter init(final Class<?>... ptypes) {
+ MethodEmitter init(final Class<?>... ptypes) {
return method(INIT.tag(), void.class, ptypes);
}
@@ -507,7 +507,7 @@
*
* @return method emitter to use for weaving <init>(...)V
*/
- public MethodEmitter init(final EnumSet<Flag> flags, final Class<?>... ptypes) {
+ MethodEmitter init(final EnumSet<Flag> flags, final Class<?>... ptypes) {
return method(flags, INIT.tag(), void.class, ptypes);
}
@@ -521,7 +521,7 @@
*
* @see ClassEmitter.Flag
*/
- public final void field(final EnumSet<Flag> fieldFlags, final String fieldName, final Class<?> fieldType, final Object value) {
+ final void field(final EnumSet<Flag> fieldFlags, final String fieldName, final Class<?> fieldType, final Object value) {
cw.visitField(Flag.getValue(fieldFlags), fieldName, typeDescriptor(fieldType), null, value).visitEnd();
}
@@ -534,7 +534,7 @@
*
* @see ClassEmitter.Flag
*/
- public final void field(final EnumSet<Flag> fieldFlags, final String fieldName, final Class<?> fieldType) {
+ final void field(final EnumSet<Flag> fieldFlags, final String fieldName, final Class<?> fieldType) {
field(fieldFlags, fieldName, fieldType, null);
}
@@ -544,7 +544,7 @@
* @param fieldName name of field
* @param fieldType type of field
*/
- public final void field(final String fieldName, final Class<?> fieldType) {
+ final void field(final String fieldName, final Class<?> fieldType) {
field(EnumSet.of(Flag.PUBLIC), fieldName, fieldType, null);
}
@@ -554,7 +554,7 @@
*
* @return byte code array for generated class, null if class generation hasn't been ended with {@link ClassEmitter#end()}
*/
- public byte[] toByteArray() {
+ byte[] toByteArray() {
assert classEnded;
if (!classEnded) {
return null;
@@ -572,7 +572,7 @@
* Flags are provided for method handles, protection levels, static/virtual
* fields/methods.
*/
- public static enum Flag {
+ static enum Flag {
/** method handle with static access */
HANDLE_STATIC(H_INVOKESTATIC),
/** method handle with new invoke special access */
@@ -603,7 +603,7 @@
* Get the value of this flag
* @return the int value
*/
- public int getValue() {
+ int getValue() {
return value;
}
@@ -613,7 +613,7 @@
* @param flags enum set of flags
* @return an integer value representing the flags intrinsic values or:ed together
*/
- public static int getValue(final EnumSet<Flag> flags) {
+ static int getValue(final EnumSet<Flag> flags) {
int v = 0;
for (final Flag flag : flags) {
v |= flag.getValue();
@@ -621,5 +621,4 @@
return v;
}
}
-
}
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java Fri Feb 15 09:44:15 2013 +0100
@@ -63,13 +63,7 @@
import java.util.TreeMap;
import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
-import jdk.nashorn.internal.codegen.MethodEmitter.Condition;
-import jdk.nashorn.internal.codegen.MethodEmitter.Label;
import jdk.nashorn.internal.codegen.RuntimeCallSite.SpecializedRuntimeNode;
-import jdk.nashorn.internal.codegen.objects.FieldObjectCreator;
-import jdk.nashorn.internal.codegen.objects.MapCreator;
-import jdk.nashorn.internal.codegen.objects.ObjectCreator;
-import jdk.nashorn.internal.codegen.objects.ObjectMapCreator;
import jdk.nashorn.internal.codegen.types.ArrayType;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.AccessNode;
@@ -118,6 +112,7 @@
import jdk.nashorn.internal.runtime.CodeInstaller;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ECMAException;
+import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.Scope;
import jdk.nashorn.internal.runtime.ScriptFunction;
@@ -147,7 +142,7 @@
* The CodeGenerator visits nodes only once, tags them as resolved and emits
* bytecode for them.
*/
-public final class CodeGenerator extends NodeOperatorVisitor {
+final class CodeGenerator extends NodeOperatorVisitor {
/** Name of the Global object, cannot be referred to as .class, @see CodeGenerator */
private static final String GLOBAL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "Global";
@@ -189,7 +184,7 @@
*
* @return the correct flags for a call site in the current function
*/
- public int getCallSiteFlags() {
+ int getCallSiteFlags() {
return getCurrentFunctionNode().isStrictMode() ? callSiteFlags | CALLSITE_STRICT : callSiteFlags;
}
@@ -302,7 +297,7 @@
*
* @return the method emitter used
*/
- public MethodEmitter load(final Node node) {
+ MethodEmitter load(final Node node) {
return load(node, false);
}
@@ -661,9 +656,8 @@
} else { // get global from scope (which is the self)
globalInstance();
}
-
loadArgs(args, signature, isVarArg, argCount);
- method.invokeStatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature);
+ method.invokestatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature);
assert method.peekType().equals(callee.getReturnType()) : method.peekType() + " != " + callee.getReturnType();
return null;
@@ -1138,7 +1132,7 @@
savedMethod.swap();
savedMethod.loadScope();
savedMethod.swap();
- savedMethod.invokeStatic(className, name, signature);
+ savedMethod.invokestatic(className, name, signature);
}
} finally {
setCurrentCompileUnit(savedCompileUnit);
@@ -1191,13 +1185,13 @@
*
* @param string string to load
*/
- public void loadConstant(final String string) {
+ void loadConstant(final String string) {
final String unitClassName = getCurrentCompileUnit().getUnitClassName();
final ClassEmitter classEmitter = getCurrentCompileUnit().getClassEmitter();
final int index = compiler.getConstantData().add(string);
method.load(index);
- method.invokeStatic(unitClassName, GET_STRING.tag(), methodDescriptor(String.class, int.class));
+ method.invokestatic(unitClassName, GET_STRING.tag(), methodDescriptor(String.class, int.class));
classEmitter.needGetConstantMethod(String.class);
}
@@ -1207,7 +1201,7 @@
*
* @param object object to load
*/
- public void loadConstant(final Object object) {
+ void loadConstant(final Object object) {
final String unitClassName = getCurrentCompileUnit().getUnitClassName();
final ClassEmitter classEmitter = getCurrentCompileUnit().getClassEmitter();
final int index = compiler.getConstantData().add(object);
@@ -1215,12 +1209,12 @@
if (cls == PropertyMap.class) {
method.load(index);
- method.invokeStatic(unitClassName, GET_MAP.tag(), methodDescriptor(PropertyMap.class, int.class));
+ method.invokestatic(unitClassName, GET_MAP.tag(), methodDescriptor(PropertyMap.class, int.class));
classEmitter.needGetConstantMethod(PropertyMap.class);
} else if (cls.isArray()) {
method.load(index);
final String methodName = ClassEmitter.getArrayMethodName(cls);
- method.invokeStatic(unitClassName, methodName, methodDescriptor(cls, int.class));
+ method.invokestatic(unitClassName, methodName, methodDescriptor(cls, int.class));
classEmitter.needGetConstantMethod(cls);
} else {
method.loadConstants(unitClassName).load(index).arrayload();
@@ -1363,7 +1357,12 @@
*/
@Override
protected MapCreator newMapCreator(final Class<?> fieldObjectClass) {
- return new ObjectMapCreator(fieldObjectClass, keys, symbols);
+ return new MapCreator(fieldObjectClass, keys, symbols) {
+ @Override
+ protected int getPropertyFlags(final Symbol symbol, final boolean isVarArg) {
+ return super.getPropertyFlags(symbol, isVarArg) | Property.IS_ALWAYS_OBJECT;
+ }
+ };
}
}.makeObject(method);
@@ -1487,7 +1486,7 @@
method.label(falseLabel);
load(rhs);
- method.invokeStatic(CompilerConstants.className(ScriptRuntime.class), request.toString(), signature);
+ method.invokestatic(CompilerConstants.className(ScriptRuntime.class), request.toString(), signature);
method._goto(endLabel);
method.label(trueLabel);
@@ -1628,7 +1627,7 @@
load(arg).convert(Type.OBJECT); //TODO this should not be necessary below Lower
}
- method.invokeStatic(
+ method.invokestatic(
CompilerConstants.className(ScriptRuntime.class),
runtimeNode.getRequest().toString(),
new FunctionSignature(
@@ -1746,7 +1745,7 @@
labels[i] = new Label("split_state_" + i);
}
- caller.tableSwitch(low, targetCount, breakLabel, labels);
+ caller.tableswitch(low, targetCount, breakLabel, labels);
for (int i = low; i <= targetCount; i++) {
caller.label(labels[i - low]);
if (i == 0) {
@@ -1853,7 +1852,7 @@
table[value - lo] = labels[i];
}
- method.tableSwitch(lo, hi, defaultLabel, table);
+ method.tableswitch(lo, hi, defaultLabel, table);
} else {
final int[] ints = new int[size];
@@ -1861,7 +1860,7 @@
ints[i] = values[i];
}
- method.lookupSwitch(defaultLabel, ints, labels);
+ method.lookupswitch(defaultLabel, ints, labels);
}
} else {
load(expression);
@@ -1869,7 +1868,7 @@
if (expression.getType().isInteger()) {
method.convert(Type.NUMBER).dup();
method.store(tag);
- method.conditionalJump(MethodEmitter.Condition.NE, true, defaultLabel);
+ method.conditionalJump(Condition.NE, true, defaultLabel);
} else {
method.store(tag);
}
@@ -3245,7 +3244,7 @@
new ObjectCreator(this, new ArrayList<String>(), new ArrayList<Symbol>(), false, false) {
@Override
- public void makeObject(final MethodEmitter method) {
+ protected void makeObject(final MethodEmitter method) {
final String className = isLazy ? SCRIPTFUNCTION_TRAMPOLINE_OBJECT : SCRIPTFUNCTION_IMPL_OBJECT;
method._new(className).dup();
@@ -3286,36 +3285,36 @@
* is from the code pipeline is Global
*/
private MethodEmitter globalInstance() {
- return method.invokeStatic(GLOBAL_OBJECT, "instance", "()L" + GLOBAL_OBJECT + ';');
+ return method.invokestatic(GLOBAL_OBJECT, "instance", "()L" + GLOBAL_OBJECT + ';');
}
private MethodEmitter globalObjectPrototype() {
- return method.invokeStatic(GLOBAL_OBJECT, "objectPrototype", methodDescriptor(ScriptObject.class));
+ return method.invokestatic(GLOBAL_OBJECT, "objectPrototype", methodDescriptor(ScriptObject.class));
}
private MethodEmitter globalAllocateArguments() {
- return method.invokeStatic(GLOBAL_OBJECT, "allocateArguments", methodDescriptor(ScriptObject.class, Object[].class, Object.class, int.class));
+ return method.invokestatic(GLOBAL_OBJECT, "allocateArguments", methodDescriptor(ScriptObject.class, Object[].class, Object.class, int.class));
}
private MethodEmitter globalNewRegExp() {
- return method.invokeStatic(GLOBAL_OBJECT, "newRegExp", methodDescriptor(Object.class, String.class, String.class));
+ return method.invokestatic(GLOBAL_OBJECT, "newRegExp", methodDescriptor(Object.class, String.class, String.class));
}
private MethodEmitter globalRegExpCopy() {
- return method.invokeStatic(GLOBAL_OBJECT, "regExpCopy", methodDescriptor(Object.class, Object.class));
+ return method.invokestatic(GLOBAL_OBJECT, "regExpCopy", methodDescriptor(Object.class, Object.class));
}
private MethodEmitter globalAllocateArray(final ArrayType type) {
//make sure the native array is treated as an array type
- return method.invokeStatic(GLOBAL_OBJECT, "allocate", "(" + type.getDescriptor() + ")Ljdk/nashorn/internal/objects/NativeArray;");
+ return method.invokestatic(GLOBAL_OBJECT, "allocate", "(" + type.getDescriptor() + ")Ljdk/nashorn/internal/objects/NativeArray;");
}
private MethodEmitter globalIsEval() {
- return method.invokeStatic(GLOBAL_OBJECT, "isEval", methodDescriptor(boolean.class, Object.class));
+ return method.invokestatic(GLOBAL_OBJECT, "isEval", methodDescriptor(boolean.class, Object.class));
}
private MethodEmitter globalDirectEval() {
- return method.invokeStatic(GLOBAL_OBJECT, "directEval",
+ return method.invokestatic(GLOBAL_OBJECT, "directEval",
methodDescriptor(Object.class, Object.class, Object.class, Object.class, Object.class, Object.class));
}
}
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java Fri Feb 15 09:44:15 2013 +0100
@@ -76,18 +76,7 @@
CONSTANT_FOLDING_PHASE(EnumSet.of(INITIALIZED), CONSTANT_FOLDED) {
@Override
boolean transform(final Compiler compiler, final FunctionNode fn) {
- final Context context = compiler.getContext();
-
- if (context._print_ast) {
- context.getErr().println(new ASTWriter(fn));
- }
-
- if (context._print_parse) {
- context.getErr().println(new PrintVisitor(fn));
- }
-
fn.accept(new FoldConstants());
-
return true;
}
@@ -137,7 +126,7 @@
if (context._print_lower_parse) {
context.getErr().println(new PrintVisitor(fn));
- }
+ }
}
}
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java Fri Feb 15 09:44:15 2013 +0100
@@ -320,7 +320,7 @@
return new Call(null, className, name, desc) {
@Override
public MethodEmitter invoke(final MethodEmitter method) {
- return method.invokeSpecial(className, name, descriptor);
+ return method.invokespecial(className, name, descriptor);
}
};
}
@@ -354,7 +354,7 @@
return new Call(null, className, name, desc) {
@Override
public MethodEmitter invoke(final MethodEmitter method) {
- return method.invokeStatic(className, name, descriptor);
+ return method.invokestatic(className, name, descriptor);
}
};
}
@@ -389,7 +389,7 @@
return new Call(null, className(clazz), name, methodDescriptor(rtype, ptypes)) {
@Override
public MethodEmitter invoke(final MethodEmitter method) {
- return method.invokeVirtual(className, name, descriptor);
+ return method.invokevirtual(className, name, descriptor);
}
};
}
@@ -409,7 +409,7 @@
return new Call(null, className(clazz), name, methodDescriptor(rtype, ptypes)) {
@Override
public MethodEmitter invoke(final MethodEmitter method) {
- return method.invokeInterface(className, name, descriptor);
+ return method.invokeinterface(className, name, descriptor);
}
};
}
@@ -519,7 +519,7 @@
return new Call(MH.findStatic(lookup, clazz, name, MH.type(rtype, ptypes)), className(clazz), name, methodDescriptor(rtype, ptypes)) {
@Override
public MethodEmitter invoke(final MethodEmitter method) {
- return method.invokeStatic(className, name, descriptor);
+ return method.invokestatic(className, name, descriptor);
}
};
}
@@ -553,7 +553,7 @@
return new Call(MH.findVirtual(lookup, clazz, name, MH.type(rtype, ptypes)), className(clazz), name, methodDescriptor(rtype, ptypes)) {
@Override
public MethodEmitter invoke(final MethodEmitter method) {
- return method.invokeVirtual(className, name, descriptor);
+ return method.invokevirtual(className, name, descriptor);
}
};
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Condition.java Fri Feb 15 09:44:15 2013 +0100
@@ -0,0 +1,107 @@
+/*
+ * 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.codegen;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.IFEQ;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFGE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFGT;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFLE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFLT;
+import static jdk.internal.org.objectweb.asm.Opcodes.IFNE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ACMPEQ;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ACMPNE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPEQ;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPGE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPGT;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPLE;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPLT;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPNE;
+import jdk.nashorn.internal.ir.RuntimeNode;
+
+/**
+ * Condition enum used for all kinds of jumps, regardless of type
+ */
+enum Condition {
+ EQ,
+ NE,
+ LE,
+ LT,
+ GE,
+ GT;
+
+ static Condition forRuntimeRequest(final RuntimeNode.Request request) {
+ try {
+ final String reqString = request.toString().replace("_STRICT", "");
+ return Condition.valueOf(reqString);
+ } catch (final IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ static int toUnary(final Condition c) {
+ switch (c) {
+ case EQ:
+ return IFEQ;
+ case NE:
+ return IFNE;
+ case LE:
+ return IFLE;
+ case LT:
+ return IFLT;
+ case GE:
+ return IFGE;
+ case GT:
+ return IFGT;
+ default:
+ assert false;
+ return -1;
+ }
+ }
+
+ static int toBinary(final Condition c) {
+ return toBinary(c, false);
+ }
+
+ static int toBinary(final Condition c, final boolean isObject) {
+ switch (c) {
+ case EQ:
+ return isObject ? IF_ACMPEQ : IF_ICMPEQ;
+ case NE:
+ return isObject ? IF_ACMPNE : IF_ICMPNE;
+ case LE:
+ return IF_ICMPLE;
+ case LT:
+ return IF_ICMPLT;
+ case GE:
+ return IF_ICMPGE;
+ case GT:
+ return IF_ICMPGT;
+ default:
+ assert false;
+ return -1;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java Fri Feb 15 09:44:15 2013 +0100
@@ -0,0 +1,191 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
+import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
+
+import java.util.Iterator;
+import java.util.List;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+
+/**
+ * Analyze an object's characteristics for appropriate code generation. This
+ * is used for functions and for objects. A field object take a set of values which
+ * to assign to the various fields in the object. This is done by the generated code
+ *
+ * @param <T> the value type for the fields being written on object creation, e.g. Node
+ * @see jdk.nashorn.internal.ir.Node
+ */
+public abstract class FieldObjectCreator<T> extends ObjectCreator {
+ /** array of corresponding values to symbols (null for no values) */
+ private final List<T> values;
+
+ /** call site flags to be used for invocations */
+ private final int callSiteFlags;
+
+ /**
+ * Constructor
+ *
+ * @param codegen code generator
+ * @param keys keys for fields in object
+ * @param symbols symbols for fields in object
+ * @param values list of values corresponding to keys
+ */
+ FieldObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<T> values) {
+ this(codegen, keys, symbols, values, false, false);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param codegen code generator
+ * @param keys keys for fields in object
+ * @param symbols symbols for fields in object
+ * @param values values (or null where no value) to be written to the fields
+ * @param isScope is this a scope object
+ * @param hasArguments does the created object have an "arguments" property
+ */
+ FieldObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<T> values, final boolean isScope, final boolean hasArguments) {
+ super(codegen, keys, symbols, isScope, hasArguments);
+ this.values = values;
+ this.callSiteFlags = codegen.getCallSiteFlags();
+ }
+
+ /**
+ * Loads the scope on the stack through the passed method emitter.
+ * @param method the method emitter to use
+ */
+ protected void loadScope(final MethodEmitter method) {
+ method.loadScope();
+ }
+
+ /**
+ * Construct an object.
+ *
+ * @param method the method emitter
+ */
+ @Override
+ protected void makeObject(final MethodEmitter method) {
+ makeMap();
+
+ method._new(getClassName()).dup(); // create instance
+ loadMap(method); //load the map
+
+ if (isScope()) {
+ loadScope(method);
+
+ if (hasArguments()) {
+ method.loadArguments();
+ method.invoke(constructorNoLookup(getClassName(), PropertyMap.class, ScriptObject.class, ARGUMENTS.type()));
+ } else {
+ method.invoke(constructorNoLookup(getClassName(), PropertyMap.class, ScriptObject.class));
+ }
+ } else {
+ method.invoke(constructorNoLookup(getClassName(), PropertyMap.class));
+ }
+
+ // Set values.
+ final Iterator<Symbol> symbolIter = symbols.iterator();
+ final Iterator<String> keyIter = keys.iterator();
+ final Iterator<T> valueIter = values.iterator();
+
+ while (symbolIter.hasNext()) {
+ final Symbol symbol = symbolIter.next();
+ final String key = keyIter.next();
+ final T value = valueIter.next();
+
+ if (symbol != null && value != null) {
+ final int index = ArrayIndex.getArrayIndexNoThrow(key);
+
+ if (index < 0) {
+ putField(method, key, symbol.getFieldIndex(), value);
+ } else {
+ putSlot(method, index, value);
+ }
+ }
+ }
+ }
+
+ /**
+ * Technique for loading an initial value. Defined by anonymous subclasses in code gen.
+ *
+ * @param value Value to load.
+ */
+ protected abstract void loadValue(T value);
+
+ /**
+ * Determine the type of a value. Defined by anonymous subclasses in code gen.
+ *
+ * @param value Value to inspect.
+ *
+ * @return Value type.
+ */
+ protected abstract Type getValueType(T value);
+
+ /**
+ * Store a value in a field of the generated class object.
+ *
+ * @param method Script method.
+ * @param key Property key.
+ * @param fieldIndex Field number.
+ * @param value Value to store.
+ */
+ private void putField(final MethodEmitter method, final String key, final int fieldIndex, final T value) {
+ method.dup();
+
+ loadValue(value);
+
+ final Type valueType = getValueType(value);
+ // for example when we have a with scope
+ if (valueType.isObject() || valueType.isBoolean()) {
+ method.convert(OBJECT);
+ }
+
+ method.convert(OBJECT);
+ method.putField(getClassName(), ObjectClassGenerator.getFieldName(fieldIndex, Type.OBJECT), typeDescriptor(Object.class));
+ }
+
+ /**
+ * Store a value in an indexed slot of a generated class object.
+ *
+ * @param method Script method.
+ * @param index Slot index.
+ * @param value Value to store.
+ */
+ private void putSlot(final MethodEmitter method, final int index, final T value) {
+ method.dup();
+ method.load(index);
+ loadValue(value);
+ method.dynamicSetIndex(callSiteFlags);
+ }
+}
--- a/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java Fri Feb 15 09:44:15 2013 +0100
@@ -202,7 +202,6 @@
return methodType;
}
-
private static Type[] objectArgs(final int nArgs) {
final Type[] array = new Type[nArgs];
for (int i = 0; i < nArgs; i++) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Label.java Fri Feb 15 09:44:15 2013 +0100
@@ -0,0 +1,83 @@
+/*
+ * 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.codegen;
+
+import java.util.ArrayDeque;
+
+import jdk.nashorn.internal.codegen.types.Type;
+
+/**
+ * Abstraction for labels, separating a label from the underlying
+ * byte code emitter. Also augmenting label with e.g. a name
+ * for easier debugging and reading code
+ *
+ * see -Dnashorn.codegen.debug, --log=codegen
+ */
+public class Label extends jdk.internal.org.objectweb.asm.Label {
+ /** Name of this label */
+ private final String name;
+
+ /** Type stack at this label */
+ private ArrayDeque<Type> stack;
+
+ /**
+ * Constructor
+ *
+ * @param name name of this label
+ */
+ public Label(final String name) {
+ super();
+ this.name = name;
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param label a label to clone
+ */
+ public Label(final Label label) {
+ super();
+ this.name = label.name;
+ }
+
+ ArrayDeque<Type> getStack() {
+ return stack;
+ }
+
+ void setStack(final ArrayDeque<Type> stack) {
+ this.stack = stack;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ String s = super.toString();
+ s = s.substring(1, s.length());
+ sb.append(name).append('_').append(Long.toHexString(Long.parseLong(s)));
+
+ return sb.toString();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java Fri Feb 15 09:44:15 2013 +0100
@@ -0,0 +1,122 @@
+/*
+ * 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.codegen;
+
+import java.util.ArrayList;
+import java.util.List;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.runtime.AccessorProperty;
+import jdk.nashorn.internal.runtime.Property;
+import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+
+/**
+ * Class that creates PropertyMap sent to script object constructors.
+ */
+public class MapCreator {
+ /** Object structure for objects associated with this map */
+ private final Class<?> structure;
+
+ /** key set for object map */
+ private final String[] keys;
+
+ /** corresponding symbol set for object map */
+ private final Symbol[] symbols;
+
+ /**
+ * Constructor
+ *
+ * @param structure structure to generate map for (a JO$ subclass)
+ * @param keys list of keys for map
+ * @param symbols list of symbols for map
+ */
+ MapCreator(final Class<?> structure, final List<String> keys, final List<Symbol> symbols) {
+ final int size = keys.size();
+
+ this.structure = structure;
+ this.keys = keys.toArray(new String[size]);
+ this.symbols = symbols.toArray(new Symbol[size]);
+ }
+
+ /**
+ * Constructs a property map based on a set of fields.
+ *
+ * @param hasArguments does the created object have an "arguments" property
+ *
+ * @return New map populated with accessor properties.
+ */
+ PropertyMap makeMap(final boolean hasArguments) {
+ final List<Property> properties = new ArrayList<>();
+
+ assert keys != null;
+
+ for (int i = 0; i < keys.length; i++) {
+ final String key = keys[i];
+ final Symbol symbol = symbols[i];
+
+ if (symbol != null && !ArrayIndex.isIndexKey(key)) {
+ properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), structure, symbol.getFieldIndex()));
+ }
+ }
+
+ return PropertyMap.newMap(structure, properties);
+ }
+
+ /**
+ * Compute property flags given local state of a field. May be overridden and extended,
+ *
+ * @param symbol symbol to check
+ * @param hasArguments does the created object have an "arguments" property
+ *
+ * @return flags to use for fields
+ */
+ protected int getPropertyFlags(final Symbol symbol, final boolean hasArguments) {
+ int flags = 0;
+
+ if (symbol.isParam()) {
+ flags |= Property.IS_ALWAYS_OBJECT | Property.IS_PARAMETER;
+ }
+
+ if (hasArguments) {
+ flags |= Property.IS_ALWAYS_OBJECT | Property.HAS_ARGUMENTS;
+ }
+
+ if (symbol.isScope()) {
+ flags |= Property.NOT_CONFIGURABLE;
+ }
+
+ if (symbol.canBePrimitive()) {
+ flags |= Property.CAN_BE_PRIMITIVE;
+ }
+
+ if (symbol.canBeUndefined()) {
+ flags |= Property.CAN_BE_UNDEFINED;
+ }
+
+ return flags;
+ }
+
+}
--- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java Fri Feb 15 09:44:15 2013 +0100
@@ -43,10 +43,6 @@
import static jdk.internal.org.objectweb.asm.Opcodes.IF_ACMPEQ;
import static jdk.internal.org.objectweb.asm.Opcodes.IF_ACMPNE;
import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPEQ;
-import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPGE;
-import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPGT;
-import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPLE;
-import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPLT;
import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPNE;
import static jdk.internal.org.objectweb.asm.Opcodes.INSTANCEOF;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE;
@@ -114,7 +110,7 @@
private final MethodVisitor method;
/** Current type stack for current evaluation */
- protected ArrayDeque<Type> stack;
+ private ArrayDeque<Type> stack;
/** Parent classEmitter representing the class of this method */
private final ClassEmitter classEmitter;
@@ -287,7 +283,7 @@
*
* @return the type at position "pos" on the stack
*/
- public final Type peekType(final int pos) {
+ final Type peekType(final int pos) {
final Iterator<Type> iter = stack.iterator();
for (int i = 0; i < pos; i++) {
iter.next();
@@ -300,7 +296,7 @@
*
* @return the type at the top of the stack
*/
- public final Type peekType() {
+ final Type peekType() {
return stack.peek();
}
@@ -312,7 +308,7 @@
*
* @return the method emitter
*/
- public MethodEmitter _new(final String classDescriptor) {
+ MethodEmitter _new(final String classDescriptor) {
debug("new", classDescriptor);
method.visitTypeInsn(NEW, classDescriptor);
pushType(Type.OBJECT);
@@ -327,7 +323,7 @@
*
* @return the method emitter
*/
- public MethodEmitter _new(final Class<?> clazz) {
+ MethodEmitter _new(final Class<?> clazz) {
return _new(className(clazz));
}
@@ -338,7 +334,7 @@
*
* @return the method emitter
*/
- public MethodEmitter newInstance(final Class<?> clazz) {
+ MethodEmitter newInstance(final Class<?> clazz) {
return invoke(constructorNoLookup(clazz));
}
@@ -352,7 +348,7 @@
* @return the method emitter, or null if depth is illegal and
* has no instruction equivalent.
*/
- public MethodEmitter dup(final int depth) {
+ MethodEmitter dup(final int depth) {
if (peekType().dup(method, depth) == null) {
return null;
}
@@ -396,7 +392,7 @@
*
* @return the method emitter
*/
- public MethodEmitter dup2() {
+ MethodEmitter dup2() {
debug("dup2");
if (peekType().isCategory2()) {
@@ -417,7 +413,7 @@
*
* @return the method emitter
*/
- public MethodEmitter dup() {
+ MethodEmitter dup() {
return dup(0);
}
@@ -426,7 +422,7 @@
*
* @return the method emitter
*/
- public MethodEmitter pop() {
+ MethodEmitter pop() {
debug("pop", peekType());
popType().pop(method);
return this;
@@ -438,7 +434,7 @@
*
* @return the method emitter
*/
- public MethodEmitter pop2() {
+ MethodEmitter pop2() {
if (peekType().isCategory2()) {
popType();
} else {
@@ -453,7 +449,7 @@
*
* @return the method emitter
*/
- public MethodEmitter swap() {
+ MethodEmitter swap() {
debug("swap");
final Type p0 = popType();
@@ -473,7 +469,7 @@
* @param start start of scope
* @param end end of scope
*/
- public void localVariable(final Symbol symbol, final Label start, final Label end) {
+ void localVariable(final Symbol symbol, final Label start, final Label end) {
if (!symbol.hasSlot()) {
return;
}
@@ -492,7 +488,7 @@
*
* @return the method emitter
*/
- public MethodEmitter newStringBuilder() {
+ MethodEmitter newStringBuilder() {
return invoke(constructorNoLookup(StringBuilder.class)).dup();
}
@@ -503,7 +499,7 @@
*
* @return the method emitter
*/
- public MethodEmitter stringBuilderAppend() {
+ MethodEmitter stringBuilderAppend() {
convert(Type.STRING);
return invoke(virtualCallNoLookup(StringBuilder.class, "append", StringBuilder.class, String.class));
}
@@ -515,7 +511,7 @@
* @param start start
* @param end end
*/
- public void markerVariable(final String name, final Label start, final Label end) {
+ void markerVariable(final String name, final Label start, final Label end) {
method.visitLocalVariable(name, Type.OBJECT.getDescriptor(), null, start, end, 0);
}
@@ -525,7 +521,7 @@
*
* @return the method emitter
*/
- public MethodEmitter and() {
+ MethodEmitter and() {
debug("and");
pushType(get2i().and(method));
return this;
@@ -537,7 +533,7 @@
*
* @return the method emitter
*/
- public MethodEmitter or() {
+ MethodEmitter or() {
debug("or");
pushType(get2i().or(method));
return this;
@@ -549,7 +545,7 @@
*
* @return the method emitter
*/
- public MethodEmitter xor() {
+ MethodEmitter xor() {
debug("xor");
pushType(get2i().xor(method));
return this;
@@ -561,7 +557,7 @@
*
* @return the method emitter
*/
- public MethodEmitter shr() {
+ MethodEmitter shr() {
debug("shr");
popType(Type.INT);
pushType(popInteger().shr(method));
@@ -574,7 +570,7 @@
*
* @return the method emitter
*/
- public MethodEmitter shl() {
+ MethodEmitter shl() {
debug("shl");
popType(Type.INT);
pushType(popInteger().shl(method));
@@ -587,7 +583,7 @@
*
* @return the method emitter
*/
- public MethodEmitter sar() {
+ MethodEmitter sar() {
debug("sar");
popType(Type.INT);
pushType(popInteger().sar(method));
@@ -599,7 +595,7 @@
*
* @return the method emitter
*/
- public MethodEmitter neg() {
+ MethodEmitter neg() {
debug("neg");
pushType(popNumeric().neg(method));
return this;
@@ -611,7 +607,7 @@
*
* @param recovery label pointing to start of catch block
*/
- public void _catch(final Label recovery) {
+ void _catch(final Label recovery) {
stack.clear();
stack.push(Type.OBJECT);
label(recovery);
@@ -625,7 +621,7 @@
* @param recovery start label for catch
* @param typeDescriptor type descriptor for exception
*/
- public void _try(final Label entry, final Label exit, final Label recovery, final String typeDescriptor) {
+ void _try(final Label entry, final Label exit, final Label recovery, final String typeDescriptor) {
method.visitTryCatchBlock(entry, exit, recovery, typeDescriptor);
}
@@ -637,7 +633,7 @@
* @param recovery start label for catch
* @param clazz exception class
*/
- public void _try(final Label entry, final Label exit, final Label recovery, final Class<?> clazz) {
+ void _try(final Label entry, final Label exit, final Label recovery, final Class<?> clazz) {
method.visitTryCatchBlock(entry, exit, recovery, CompilerConstants.className(clazz));
}
@@ -648,7 +644,7 @@
* @param exit end label for try
* @param recovery start label for catch
*/
- public void _try(final Label entry, final Label exit, final Label recovery) {
+ void _try(final Label entry, final Label exit, final Label recovery) {
_try(entry, exit, recovery, (String)null);
}
@@ -658,7 +654,7 @@
* @param unitClassName name of the compile unit from which to load constants
* @return this method emitter
*/
- public MethodEmitter loadConstants(final String unitClassName) {
+ MethodEmitter loadConstants(final String unitClassName) {
getStatic(unitClassName, CONSTANTS.tag(), CONSTANTS.descriptor());
assert peekType().isArray() : peekType();
return this;
@@ -673,7 +669,7 @@
* @param type the type for which to push UNDEFINED
* @return the method emitter
*/
- public MethodEmitter loadUndefined(final Type type) {
+ MethodEmitter loadUndefined(final Type type) {
debug("load undefined " + type);
pushType(type.loadUndefined(method));
return this;
@@ -685,7 +681,7 @@
* @param type the type
* @return the method emitter
*/
- public MethodEmitter loadEmpty(final Type type) {
+ MethodEmitter loadEmpty(final Type type) {
debug("load empty " + type);
pushType(type.loadEmpty(method));
return this;
@@ -696,7 +692,7 @@
*
* @return the method emitter
*/
- public MethodEmitter loadNull() {
+ MethodEmitter loadNull() {
debug("aconst_null");
pushType(Type.OBJECT.ldc(method, null));
return this;
@@ -709,7 +705,7 @@
*
* @return the method emitter
*/
- public MethodEmitter loadType(final String className) {
+ MethodEmitter loadType(final String className) {
debug("load type", className);
method.visitLdcInsn(jdk.internal.org.objectweb.asm.Type.getObjectType(className));
pushType(Type.OBJECT);
@@ -723,7 +719,7 @@
*
* @return the method emitter
*/
- public MethodEmitter load(final boolean b) {
+ MethodEmitter load(final boolean b) {
debug("load boolean", b);
pushType(Type.BOOLEAN.ldc(method, b));
return this;
@@ -736,7 +732,7 @@
*
* @return the method emitter
*/
- public MethodEmitter load(final int i) {
+ MethodEmitter load(final int i) {
debug("load int", i);
pushType(Type.INT.ldc(method, i));
return this;
@@ -749,7 +745,7 @@
*
* @return the method emitter
*/
- public MethodEmitter load(final double d) {
+ MethodEmitter load(final double d) {
debug("load double", d);
pushType(Type.NUMBER.ldc(method, d));
return this;
@@ -762,7 +758,7 @@
*
* @return the method emitter
*/
- public MethodEmitter load(final long l) {
+ MethodEmitter load(final long l) {
debug("load long", l);
pushType(Type.LONG.ldc(method, l));
return this;
@@ -772,7 +768,7 @@
* Fetch the length of an array.
* @return Array length.
*/
- public MethodEmitter arraylength() {
+ MethodEmitter arraylength() {
debug("arraylength");
popType(Type.OBJECT);
pushType(Type.OBJECT_ARRAY.arraylength(method));
@@ -786,7 +782,7 @@
*
* @return the method emitter
*/
- public MethodEmitter load(final String s) {
+ MethodEmitter load(final String s) {
debug("load string", s);
if (s == null) {
@@ -826,7 +822,7 @@
*
* @return the method emitter
*/
- public MethodEmitter load(final Symbol symbol) {
+ MethodEmitter load(final Symbol symbol) {
assert symbol != null;
if (symbol.hasSlot()) {
final int slot = symbol.getSlot();
@@ -837,7 +833,7 @@
assert !symbol.isScope();
assert functionNode.isVarArg() : "Non-vararg functions have slotted parameters";
final int index = symbol.getFieldIndex();
- if(functionNode.needsArguments()) {
+ if (functionNode.needsArguments()) {
// ScriptObject.getArgument(int) on arguments
debug("load symbol", symbol.getName(), " arguments index=", index);
loadArguments();
@@ -864,7 +860,7 @@
*
* @return the method emitter
*/
- public MethodEmitter load(final Type type, final int slot) {
+ MethodEmitter load(final Type type, final int slot) {
debug("explicit load", type, slot);
final Type loadType = type.load(method, slot);
pushType(loadType == Type.OBJECT && isThisSlot(slot) ? Type.THIS : loadType);
@@ -886,7 +882,7 @@
*
* @return the method emitter
*/
- public MethodEmitter loadThis() {
+ MethodEmitter loadThis() {
load(functionNode.getThisNode().getSymbol());
return this;
}
@@ -896,7 +892,7 @@
*
* @return the method emitter
*/
- public MethodEmitter loadScope() {
+ MethodEmitter loadScope() {
if (peekType() == Type.SCOPE) {
dup();
return this;
@@ -910,7 +906,7 @@
*
* @return the method emitter
*/
- public MethodEmitter loadResult() {
+ MethodEmitter loadResult() {
load(functionNode.getResultNode().getSymbol());
return this;
}
@@ -924,11 +920,9 @@
* @param descName descriptor
* @param flags flags that describe this handle, e.g. invokespecial new, or invoke virtual
*
- * @see ClassEmitter.Flag
- *
* @return the method emitter
*/
- public MethodEmitter loadHandle(final String className, final String methodName, final String descName, final EnumSet<Flag> flags) {
+ MethodEmitter loadHandle(final String className, final String methodName, final String descName, final EnumSet<Flag> flags) {
debug("load handle ");
pushType(Type.OBJECT.ldc(method, new Handle(Flag.getValue(flags), className, methodName, descName)));
return this;
@@ -939,7 +933,7 @@
*
* @return the method emitter
*/
- public MethodEmitter loadVarArgs() {
+ MethodEmitter loadVarArgs() {
debug("load var args " + functionNode.getVarArgsNode().getSymbol());
return load(functionNode.getVarArgsNode().getSymbol());
}
@@ -949,7 +943,7 @@
*
* @return the method emitter
*/
- public MethodEmitter loadArguments() {
+ MethodEmitter loadArguments() {
debug("load arguments ", functionNode.getArgumentsNode().getSymbol());
assert functionNode.getArgumentsNode().getSymbol().getSlot() != 0;
return load(functionNode.getArgumentsNode().getSymbol());
@@ -960,7 +954,7 @@
*
* @return the method emitter
*/
- public MethodEmitter loadCallee() {
+ MethodEmitter loadCallee() {
final Symbol calleeSymbol = functionNode.getCalleeNode().getSymbol();
debug("load callee ", calleeSymbol);
assert calleeSymbol.getSlot() == 0 : "callee has wrong slot " + calleeSymbol.getSlot() + " in " + functionNode.getName();
@@ -971,7 +965,7 @@
/**
* Pop the scope from the stack and store it in its predefined slot
*/
- public void storeScope() {
+ void storeScope() {
debug("store scope");
store(functionNode.getScopeNode().getSymbol());
}
@@ -979,7 +973,7 @@
/**
* Pop the return from the stack and store it in its predefined slot
*/
- public void storeResult() {
+ void storeResult() {
debug("store result");
store(functionNode.getResultNode().getSymbol());
}
@@ -987,7 +981,7 @@
/**
* Pop the arguments array from the stack and store it in its predefined slot
*/
- public void storeArguments() {
+ void storeArguments() {
debug("store arguments");
store(functionNode.getArgumentsNode().getSymbol());
}
@@ -996,7 +990,7 @@
* Load an element from an array, determining type automatically
* @return the method emitter
*/
- public MethodEmitter arrayload() {
+ MethodEmitter arrayload() {
debug("Xaload");
popType(Type.INT);
pushType(popArray().aload(method));
@@ -1007,7 +1001,7 @@
* Pop a value, an index and an array from the stack and store
* the value at the given index in the array.
*/
- public void arraystore() {
+ void arraystore() {
debug("Xastore");
final Type value = popType();
final Type index = popType(Type.INT);
@@ -1025,7 +1019,7 @@
*
* @param symbol symbol to store stack to
*/
- public void store(final Symbol symbol) {
+ void store(final Symbol symbol) {
assert symbol != null : "No symbol to store";
if (symbol.hasSlot()) {
final int slot = symbol.getSlot();
@@ -1035,7 +1029,7 @@
assert !symbol.isScope();
assert functionNode.isVarArg() : "Non-vararg functions have slotted parameters";
final int index = symbol.getFieldIndex();
- if(functionNode.needsArguments()) {
+ if (functionNode.needsArguments()) {
debug("store symbol", symbol.getName(), " arguments index=", index);
loadArguments();
load(index);
@@ -1057,7 +1051,7 @@
* @param type the type to pop
* @param slot the slot
*/
- public void store(final Type type, final int slot) {
+ void store(final Type type, final int slot) {
popType(type);
type.store(method, slot);
}
@@ -1068,7 +1062,7 @@
* @param slot the int slot
* @param increment the amount to increment
*/
- public void iinc(final int slot, final int increment) {
+ void iinc(final int slot, final int increment) {
debug("iinc");
method.visitIincInsn(slot, increment);
}
@@ -1094,7 +1088,7 @@
*
* @return the method emitter
*/
- public MethodEmitter _instanceof(final String classDescriptor) {
+ MethodEmitter _instanceof(final String classDescriptor) {
debug("instanceof", classDescriptor);
popType(Type.OBJECT);
method.visitTypeInsn(INSTANCEOF, classDescriptor);
@@ -1111,7 +1105,7 @@
*
* @return the method emitter
*/
- public MethodEmitter _instanceof(final Class<?> clazz) {
+ MethodEmitter _instanceof(final Class<?> clazz) {
return _instanceof(CompilerConstants.className(clazz));
}
@@ -1123,7 +1117,7 @@
*
* @return the method emitter
*/
- public MethodEmitter checkcast(final String classDescriptor) {
+ MethodEmitter checkcast(final String classDescriptor) {
debug("checkcast", classDescriptor);
assert peekType().isObject();
method.visitTypeInsn(CHECKCAST, classDescriptor);
@@ -1138,7 +1132,7 @@
*
* @return the method emitter
*/
- public MethodEmitter checkcast(final Class<?> clazz) {
+ MethodEmitter checkcast(final Class<?> clazz) {
return checkcast(CompilerConstants.className(clazz));
}
@@ -1150,7 +1144,7 @@
*
* @return the method emitter
*/
- public MethodEmitter newarray(final ArrayType arrayType) {
+ MethodEmitter newarray(final ArrayType arrayType) {
debug("newarray ", "arrayType=" + arrayType);
popType(Type.INT); //LENGTH
pushType(arrayType.newarray(method));
@@ -1166,7 +1160,7 @@
*
* @return the method emitter
*/
- public MethodEmitter multinewarray(final ArrayType arrayType, final int dims) {
+ MethodEmitter multinewarray(final ArrayType arrayType, final int dims) {
debug("multianewarray ", arrayType, dims);
for (int i = 0; i < dims; i++) {
popType(Type.INT); //LENGTH
@@ -1200,7 +1194,7 @@
*
* @return the method emitter
*/
- public MethodEmitter invoke(final Call call) {
+ MethodEmitter invoke(final Call call) {
return call.invoke(this);
}
@@ -1229,7 +1223,7 @@
*
* @return the method emitter
*/
- public MethodEmitter invokeSpecial(final String className, final String methodName, final String methodDescriptor) {
+ MethodEmitter invokespecial(final String className, final String methodName, final String methodDescriptor) {
debug("invokespecial", className + "." + methodName + methodDescriptor);
return invoke(INVOKESPECIAL, className, methodName, methodDescriptor, true);
}
@@ -1243,7 +1237,7 @@
*
* @return the method emitter
*/
- public MethodEmitter invokeVirtual(final String className, final String methodName, final String methodDescriptor) {
+ MethodEmitter invokevirtual(final String className, final String methodName, final String methodDescriptor) {
debug("invokevirtual", className + "." + methodName + methodDescriptor + " " + stack);
return invoke(INVOKEVIRTUAL, className, methodName, methodDescriptor, true);
}
@@ -1257,7 +1251,7 @@
*
* @return the method emitter
*/
- public MethodEmitter invokeStatic(final String className, final String methodName, final String methodDescriptor) {
+ MethodEmitter invokestatic(final String className, final String methodName, final String methodDescriptor) {
debug("invokestatic", className + "." + methodName + methodDescriptor);
invoke(INVOKESTATIC, className, methodName, methodDescriptor, false);
return this;
@@ -1274,8 +1268,8 @@
*
* @return the method emitter
*/
- public MethodEmitter invokeStatic(final String className, final String methodName, final String methodDescriptor, final Type returnType) {
- invokeStatic(className, methodName, methodDescriptor);
+ MethodEmitter invokeStatic(final String className, final String methodName, final String methodDescriptor, final Type returnType) {
+ invokestatic(className, methodName, methodDescriptor);
popType();
pushType(returnType);
return this;
@@ -1290,7 +1284,7 @@
*
* @return the method emitter
*/
- public MethodEmitter invokeInterface(final String className, final String methodName, final String methodDescriptor) {
+ MethodEmitter invokeinterface(final String className, final String methodName, final String methodDescriptor) {
debug("invokeinterface", className + "." + methodName + methodDescriptor);
return invoke(INVOKEINTERFACE, className, methodName, methodDescriptor, true);
}
@@ -1302,7 +1296,7 @@
* @param values case values for the table
* @param table default label
*/
- public void lookupSwitch(final Label defaultLabel, final int[] values, final Label[] table) {
+ void lookupswitch(final Label defaultLabel, final int[] values, final Label[] table) {
debug("lookupswitch", peekType());
popType(Type.INT);
method.visitLookupSwitchInsn(defaultLabel, values, table);
@@ -1315,7 +1309,7 @@
* @param defaultLabel default label
* @param table label table
*/
- public void tableSwitch(final int lo, final int hi, final Label defaultLabel, final Label[] table) {
+ void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label[] table) {
debug("tableswitch", peekType());
popType(Type.INT);
method.visitTableSwitchInsn(lo, hi, defaultLabel, table);
@@ -1357,7 +1351,7 @@
*
* @param type the type for the return
*/
- public void _return(final Type type) {
+ void _return(final Type type) {
debug("return", type);
assert stack.size() == 1 : "Only return value on stack allowed at return point - depth=" + stack.size() + " stack = " + stack;
final Type stackType = peekType();
@@ -1371,14 +1365,14 @@
/**
* Perform a return using the stack top value as the guide for the type
*/
- public void _return() {
+ void _return() {
_return(peekType());
}
/**
* Perform a void return.
*/
- public void returnVoid() {
+ void returnVoid() {
debug("return [void]");
assert stack.isEmpty() : stack;
method.visitInsn(RETURN);
@@ -1392,7 +1386,7 @@
*
* @param label destination label
*/
- public void splitAwareGoto(final Label label) {
+ void splitAwareGoto(final Label label) {
if (splitNode != null) {
final int index = splitNode.getExternalTargets().indexOf(label);
@@ -1418,7 +1412,7 @@
*
* @return the method emitter
*/
- public MethodEmitter cmp(final boolean isCmpG) {
+ MethodEmitter cmp(final boolean isCmpG) {
pushType(get2n().cmp(method, isCmpG));
return this;
}
@@ -1443,7 +1437,7 @@
*
* @param label label to true case
*/
- public void if_acmpeq(final Label label) {
+ void if_acmpeq(final Label label) {
debug("if_acmpeq", label);
jump(IF_ACMPEQ, label, 2);
}
@@ -1453,7 +1447,7 @@
*
* @param label label to true case
*/
- public void if_acmpne(final Label label) {
+ void if_acmpne(final Label label) {
debug("if_acmpne", label);
jump(IF_ACMPNE, label, 2);
}
@@ -1463,7 +1457,7 @@
*
* @param label label to true case
*/
- public void ifnull(final Label label) {
+ void ifnull(final Label label) {
debug("ifnull", label);
jump(IFNULL, label, 1);
}
@@ -1473,7 +1467,7 @@
*
* @param label label to true case
*/
- public void ifnonnull(final Label label) {
+ void ifnonnull(final Label label) {
debug("ifnonnull", label);
jump(IFNONNULL, label, 1);
}
@@ -1483,7 +1477,7 @@
*
* @param label label to true case
*/
- public void ifeq(final Label label) {
+ void ifeq(final Label label) {
debug("ifeq ", label);
jump(IFEQ, label, 1);
}
@@ -1493,7 +1487,7 @@
*
* @param label label to true case
*/
- public void if_icmpeq(final Label label) {
+ void if_icmpeq(final Label label) {
debug("if_icmpeq", label);
jump(IF_ICMPEQ, label, 2);
}
@@ -1503,8 +1497,7 @@
*
* @param label label to true case
*/
-
- public void ifne(final Label label) {
+ void ifne(final Label label) {
debug("ifne", label);
jump(IFNE, label, 1);
}
@@ -1514,7 +1507,7 @@
*
* @param label label to true case
*/
- public void if_icmpne(final Label label) {
+ void if_icmpne(final Label label) {
debug("if_icmpne", label);
jump(IF_ICMPNE, label, 2);
}
@@ -1524,7 +1517,7 @@
*
* @param label label to true case
*/
- public void iflt(final Label label) {
+ void iflt(final Label label) {
debug("iflt", label);
jump(IFLT, label, 1);
}
@@ -1534,7 +1527,7 @@
*
* @param label label to true case
*/
- public void ifle(final Label label) {
+ void ifle(final Label label) {
debug("ifle", label);
jump(IFLE, label, 1);
}
@@ -1544,7 +1537,7 @@
*
* @param label label to true case
*/
- public void ifgt(final Label label) {
+ void ifgt(final Label label) {
debug("ifgt", label);
jump(IFGT, label, 1);
}
@@ -1554,7 +1547,7 @@
*
* @param label label to true case
*/
- public void ifge(final Label label) {
+ void ifge(final Label label) {
debug("ifge", label);
jump(IFGE, label, 1);
}
@@ -1564,7 +1557,7 @@
*
* @param label destination label
*/
- public void _goto(final Label label) {
+ void _goto(final Label label) {
debug("goto", label);
jump(GOTO, label, 0);
stack = null;
@@ -1617,7 +1610,7 @@
*
* @param label the label
*/
- public void label(final Label label) {
+ void label(final Label label) {
/*
* If stack == null, this means that we came here not through a fallthrough.
* E.g. a label after an athrow. Then we create a new stack if one doesn't exist
@@ -1643,7 +1636,7 @@
*
* @return the method emitter
*/
- public MethodEmitter convert(final Type to) {
+ MethodEmitter convert(final Type to) {
final Type type = peekType().convert(method, to);
if (type != null) {
if (peekType() != to) {
@@ -1696,7 +1689,7 @@
*
* @return the method emitter
*/
- public MethodEmitter add() {
+ MethodEmitter add() {
debug("add");
pushType(get2().add(method));
return this;
@@ -1707,7 +1700,7 @@
*
* @return the method emitter
*/
- public MethodEmitter sub() {
+ MethodEmitter sub() {
debug("sub");
pushType(get2n().sub(method));
return this;
@@ -1718,7 +1711,7 @@
*
* @return the method emitter
*/
- public MethodEmitter mul() {
+ MethodEmitter mul() {
debug("mul ");
pushType(get2n().mul(method));
return this;
@@ -1729,7 +1722,7 @@
*
* @return the method emitter
*/
- public MethodEmitter div() {
+ MethodEmitter div() {
debug("div");
pushType(get2n().div(method));
return this;
@@ -1740,7 +1733,7 @@
*
* @return the method emitter
*/
- public MethodEmitter rem() {
+ MethodEmitter rem() {
debug("rem");
pushType(get2n().rem(method));
return this;
@@ -1795,7 +1788,7 @@
*
* @return the method emitter
*/
- public MethodEmitter dynamicNew(final int argCount, final int flags) {
+ MethodEmitter dynamicNew(final int argCount, final int flags) {
debug("dynamic_new", "argcount=" + argCount);
final String signature = getDynamicSignature(Type.OBJECT, argCount);
method.visitInvokeDynamicInsn("dyn:new", signature, LINKERBOOTSTRAP, flags);
@@ -1812,7 +1805,7 @@
*
* @return the method emitter
*/
- public MethodEmitter dynamicCall(final Type returnType, final int argCount, final int flags) {
+ MethodEmitter dynamicCall(final Type returnType, final int argCount, final int flags) {
debug("dynamic_call", "args=" + argCount, "returnType=" + returnType);
final String signature = getDynamicSignature(returnType, argCount); // +1 because the function itself is the 1st parameter for dynamic calls (what you call - call target)
debug(" signature", signature);
@@ -1831,7 +1824,7 @@
*
* @return the method emitter
*/
- public MethodEmitter dynamicRuntimeCall(final String name, final Type returnType, final RuntimeNode.Request request) {
+ MethodEmitter dynamicRuntimeCall(final String name, final Type returnType, final RuntimeNode.Request request) {
debug("dynamic_runtime_call", name, "args=" + request.getArity(), "returnType=" + returnType);
final String signature = getDynamicSignature(returnType, request.getArity());
debug(" signature", signature);
@@ -1851,7 +1844,7 @@
*
* @return the method emitter
*/
- public 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) {
debug("dynamic_get", name, valueType);
Type type = valueType;
@@ -1877,7 +1870,7 @@
* @param name name of property
* @param flags call site flags
*/
- public void dynamicSet(final Type valueType, final String name, final int flags) {
+ void dynamicSet(final Type valueType, final String name, final int flags) {
debug("dynamic_set", name, peekType());
Type type = valueType;
@@ -1902,7 +1895,7 @@
*
* @return the method emitter
*/
- public MethodEmitter dynamicGetIndex(final Type result, final int flags, final boolean isMethod) {
+ MethodEmitter dynamicGetIndex(final Type result, final int flags, final boolean isMethod) {
debug("dynamic_get_index", peekType(1) + "[" + peekType() + "]");
Type resultType = result;
@@ -1938,7 +1931,7 @@
*
* @param flags call site flags for setter
*/
- public void dynamicSetIndex(final int flags) {
+ void dynamicSetIndex(final int flags) {
debug("dynamic_set_index", peekType(2) + "[" + peekType(1) + "] =", peekType());
Type value = peekType();
@@ -2015,7 +2008,7 @@
*
* @return the method emitter
*/
- public MethodEmitter getField(final FieldAccess fa) {
+ MethodEmitter getField(final FieldAccess fa) {
return fa.get(this);
}
@@ -2024,7 +2017,7 @@
*
* @param fa the field access
*/
- public void putField(final FieldAccess fa) {
+ void putField(final FieldAccess fa) {
fa.put(this);
}
@@ -2038,7 +2031,7 @@
*
* @return the method emitter
*/
- public MethodEmitter getField(final String className, final String fieldName, final String fieldDescriptor) {
+ MethodEmitter getField(final String className, final String fieldName, final String fieldDescriptor) {
debug("getfield", "receiver=" + peekType(), className + "." + fieldName + fieldDescriptor);
final Type receiver = popType();
assert receiver.isObject();
@@ -2056,7 +2049,7 @@
*
* @return the method emitter
*/
- public MethodEmitter getStatic(final String className, final String fieldName, final String fieldDescriptor) {
+ MethodEmitter getStatic(final String className, final String fieldName, final String fieldDescriptor) {
debug("getstatic", className + "." + fieldName + "." + fieldDescriptor);
method.visitFieldInsn(GETSTATIC, className, fieldName, fieldDescriptor);
pushType(fieldType(fieldDescriptor));
@@ -2070,7 +2063,7 @@
* @param fieldName field name
* @param fieldDescriptor field descriptor
*/
- public void putField(final String className, final String fieldName, final String fieldDescriptor) {
+ void putField(final String className, final String fieldName, final String fieldDescriptor) {
debug("putfield", "receiver=" + peekType(1), "value=" + peekType());
popType(fieldType(fieldDescriptor));
popType(Type.OBJECT);
@@ -2084,7 +2077,7 @@
* @param fieldName field name
* @param fieldDescriptor field descriptor
*/
- public void putStatic(final String className, final String fieldName, final String fieldDescriptor) {
+ void putStatic(final String className, final String fieldName, final String fieldDescriptor) {
debug("putfield", "value=" + peekType());
popType(fieldType(fieldDescriptor));
method.visitFieldInsn(PUTSTATIC, className, fieldName, fieldDescriptor);
@@ -2096,7 +2089,7 @@
* @param line line number
* @param label label
*/
- public void lineNumber(final int line, final Label label) {
+ void lineNumber(final int line, final Label label) {
method.visitLineNumber(line, label);
}
@@ -2112,7 +2105,7 @@
/**
* Emit a System.err.print statement of whatever is on top of the bytecode stack
*/
- public void print() {
+ void print() {
getField(ERR_STREAM);
swap();
convert(Type.OBJECT);
@@ -2122,7 +2115,7 @@
/**
* Emit a System.err.println statement of whatever is on top of the bytecode stack
*/
- public void println() {
+ void println() {
getField(ERR_STREAM);
swap();
convert(Type.OBJECT);
@@ -2133,7 +2126,7 @@
* Emit a System.err.print statement
* @param string string to print
*/
- public void print(final String string) {
+ void print(final String string) {
getField(ERR_STREAM);
load(string);
invoke(PRINT);
@@ -2143,7 +2136,7 @@
* Emit a System.err.println statement
* @param string string to print
*/
- public void println(final String string) {
+ void println(final String string) {
getField(ERR_STREAM);
load(string);
invoke(PRINTLN);
@@ -2152,7 +2145,7 @@
/**
* Print a stacktrace to S
*/
- public void stacktrace() {
+ void stacktrace() {
_new(Throwable.class);
dup();
invoke(constructorNoLookup(Throwable.class));
@@ -2254,130 +2247,11 @@
}
}
-
- /**
- * Abstraction for labels, separating a label from the underlying
- * byte code emitter. Also augmenting label with e.g. a name
- * for easier debugging and reading code
- *
- * see -Dnashorn.codegen.debug, --log=codegen
- */
- public static class Label extends jdk.internal.org.objectweb.asm.Label {
- /** Name of this label */
- private final String name;
-
- /** Type stack at this label */
- private ArrayDeque<Type> stack;
-
- /**
- * Constructor
- *
- * @param name name of this label
- */
- public Label(final String name) {
- super();
- this.name = name;
- }
-
- /**
- * Copy constructor
- *
- * @param label a label to clone
- */
- public Label(final Label label) {
- super();
- name = label.name;
- }
-
- ArrayDeque<Type> getStack() {
- return stack;
- }
-
- void setStack(final ArrayDeque<Type> stack) {
- this.stack = stack;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- String s = super.toString();
- s = s.substring(1, s.length());
- sb.append(name).append('_').append(Long.toHexString(Long.parseLong(s)));
-
- return sb.toString();
- }
- }
-
- /**
- * Condition enum used for all kinds of jumps, regardless of type
- */
- static enum Condition {
- EQ,
- NE,
- LE,
- LT,
- GE,
- GT;
-
- public static Condition forRuntimeRequest(final RuntimeNode.Request request) {
- try {
- final String reqString = request.toString().replace("_STRICT", "");
- return Condition.valueOf(reqString);
- } catch (final IllegalArgumentException e) {
- return null;
- }
- }
-
- public static int toUnary(final Condition c) {
- switch (c) {
- case EQ:
- return IFEQ;
- case NE:
- return IFNE;
- case LE:
- return IFLE;
- case LT:
- return IFLT;
- case GE:
- return IFGE;
- case GT:
- return IFGT;
- default:
- assert false;
- return -1;
- }
- }
-
- public static int toBinary(final Condition c) {
- return toBinary(c, false);
- }
-
- public static int toBinary(final Condition c, final boolean isObject) {
- switch (c) {
- case EQ:
- return isObject ? IF_ACMPEQ : IF_ICMPEQ;
- case NE:
- return isObject ? IF_ACMPNE : IF_ICMPNE;
- case LE:
- return IF_ICMPLE;
- case LT:
- return IF_ICMPLT;
- case GE:
- return IF_ICMPGE;
- case GT:
- return IF_ICMPGT;
- default:
- assert false;
- return -1;
- }
- }
- }
-
/**
* Set the current function node being emitted
* @param functionNode the function node
*/
- public void setFunctionNode(final FunctionNode functionNode) {
+ void setFunctionNode(final FunctionNode functionNode) {
this.functionNode = functionNode;
}
@@ -2387,7 +2261,7 @@
*
* @return split node
*/
- public SplitNode getSplitNode() {
+ SplitNode getSplitNode() {
return splitNode;
}
@@ -2395,7 +2269,7 @@
* Set the split node for this method emitter
* @param splitNode split node
*/
- public void setSplitNode(final SplitNode splitNode) {
+ void setSplitNode(final SplitNode splitNode) {
this.splitNode = splitNode;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Fri Feb 15 09:44:15 2013 +0100
@@ -0,0 +1,760 @@
+/*
+ * 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.codegen;
+
+import static jdk.nashorn.internal.codegen.Compiler.SCRIPTS_PACKAGE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.ALLOCATE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.INIT_ARGUMENTS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.INIT_SCOPE;
+import static jdk.nashorn.internal.codegen.CompilerConstants.JAVA_THIS;
+import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_PREFIX;
+import static jdk.nashorn.internal.codegen.CompilerConstants.MAP;
+import static jdk.nashorn.internal.codegen.CompilerConstants.className;
+import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
+import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.runtime.AccessorProperty;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.FunctionScope;
+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.options.Options;
+
+/**
+ * Generates the ScriptObject subclass structure with fields for a user objects.
+ */
+public final class ObjectClassGenerator {
+
+ /**
+ * Marker for scope parameters.
+ */
+ static final String SCOPE_MARKER = "P";
+
+ /**
+ * Debug field logger
+ * Should we print debugging information for fields when they are generated and getters/setters are called?
+ */
+ public static final DebugLogger LOG = new DebugLogger("fields", "nashorn.fields.debug");
+
+ /**
+ * is field debugging enabled. Several modules in codegen and properties use this, hence
+ * public access.
+ */
+ public static final boolean DEBUG_FIELDS = LOG.isEnabled();
+
+ /**
+ * Should the runtime only use java.lang.Object slots for fields? If this is false, the representation
+ * will be a primitive 64-bit long value used for all primitives and a java.lang.Object for references.
+ * This introduces a larger number of method handles in the system, as we need to have different getters
+ * and setters for the different fields. Currently this introduces significant overhead in Hotspot.
+ *
+ * This is engineered to plug into the TaggedArray implementation, when it's done.
+ */
+ public static final boolean OBJECT_FIELDS_ONLY = !Options.getBooleanProperty("nashorn.fields.dual");
+
+ /** The field types in the system */
+ private static final List<Type> FIELD_TYPES = new LinkedList<>();
+
+ /** What type is the primitive type in dual representation */
+ public static final Type PRIMITIVE_TYPE = Type.LONG;
+
+ /**
+ * The list of field types that we support - one type creates one field. This is currently either
+ * LONG + OBJECT or just OBJECT for classic mode.
+ */
+ static {
+ if (!OBJECT_FIELDS_ONLY) {
+ System.err.println("WARNING!!! Running with primitive fields - there is untested functionality!");
+ FIELD_TYPES.add(PRIMITIVE_TYPE);
+ }
+ FIELD_TYPES.add(Type.OBJECT);
+ }
+
+ /** The context */
+ private final Context context;
+
+ /**
+ * The list of available accessor types in width order. This order is used for type guesses narrow->wide
+ * in the dual--fields world
+ */
+ public static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
+ Arrays.asList(
+ Type.INT,
+ Type.LONG,
+ Type.NUMBER,
+ Type.OBJECT));
+
+ //these are hard coded for speed and so that we can switch on them
+ private static final int TYPE_INT_INDEX = 0; //getAccessorTypeIndex(int.class);
+ private static final int TYPE_LONG_INDEX = 1; //getAccessorTypeIndex(long.class);
+ private static final int TYPE_DOUBLE_INDEX = 2; //getAccessorTypeIndex(double.class);
+ private static final int TYPE_OBJECT_INDEX = 3; //getAccessorTypeIndex(Object.class);
+
+ /**
+ * Constructor
+ *
+ * @param context a context
+ */
+ public ObjectClassGenerator(final Context context) {
+ this.context = context;
+ assert context != null;
+ }
+
+ /**
+ * Given a type of an accessor, return its index in [0..getNumberOfAccessorTypes())
+ *
+ * @param type the type
+ *
+ * @return the accessor index, or -1 if no accessor of this type exists
+ */
+ public static int getAccessorTypeIndex(final Type type) {
+ return getAccessorTypeIndex(type.getTypeClass());
+ }
+
+ /**
+ * Given a class of an accessor, return its index in [0..getNumberOfAccessorTypes())
+ *
+ * Note that this is hardcoded with respect to the dynamic contents of the accessor
+ * types array for speed. Hotspot got stuck with this as 5% of the runtime in
+ * a benchmark when it looped over values and increased an index counter. :-(
+ *
+ * @param type the type
+ *
+ * @return the accessor index, or -1 if no accessor of this type exists
+ */
+ public static int getAccessorTypeIndex(final Class<?> type) {
+ if (type == int.class) {
+ return 0;
+ } else if (type == long.class) {
+ return 1;
+ } else if (type == double.class) {
+ return 2;
+ } else if (!type.isPrimitive()) {
+ return 3;
+ }
+ return -1;
+ }
+
+ /**
+ * Return the number of accessor types available.
+ *
+ * @return number of accessor types in system
+ */
+ public static int getNumberOfAccessorTypes() {
+ return ACCESSOR_TYPES.size();
+ }
+
+ /**
+ * Return the accessor type based on its index in [0..getNumberOfAccessorTypes())
+ * Indexes are ordered narrower->wider / optimistic->pessimistic. Invalidations always
+ * go to a type of higher index
+ *
+ * @param index accessor type index
+ *
+ * @return a type corresponding to the index.
+ */
+
+ public static Type getAccessorType(final int index) {
+ return ACCESSOR_TYPES.get(index);
+ }
+
+ /**
+ * Returns the class name for JavaScript objects with fieldCount fields.
+ *
+ * @param fieldCount Number of fields to allocate.
+ *
+ * @return The class name.
+ */
+ public static String getClassName(final int fieldCount) {
+ return fieldCount != 0 ? SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.tag() + fieldCount :
+ SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.tag();
+ }
+
+ /**
+ * Returns the class name for JavaScript scope with fieldCount fields and
+ * paramCount parameters.
+ *
+ * @param fieldCount Number of fields to allocate.
+ * @param paramCount Number of parameters to allocate
+ *
+ * @return The class name.
+ */
+ public static String getClassName(final int fieldCount, final int paramCount) {
+ return SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.tag() + fieldCount + SCOPE_MARKER + paramCount;
+ }
+
+ /**
+ * Returns the name of a field based on number and type.
+ *
+ * @param fieldIndex Ordinal of field.
+ * @param type Type of field.
+ *
+ * @return The field name.
+ */
+ public static String getFieldName(final int fieldIndex, final Type type) {
+ return type.getDescriptor().substring(0, 1) + fieldIndex;
+ }
+
+ /**
+ * In the world of Object fields, we also have no undefined SwitchPoint, to reduce as much potential
+ * MethodHandle overhead as possible. In that case, we explicitly need to assign undefined to fields
+ * when we initialize them.
+ *
+ * @param init constructor to generate code in
+ * @param className name of class
+ * @param fieldNames fields to initialize to undefined, where applicable
+ */
+ private static void initializeToUndefined(final MethodEmitter init, final String className, final List<String> fieldNames) {
+ if (fieldNames.isEmpty()) {
+ return;
+ }
+
+ // always initialize fields to undefined, even with --dual-fields. Then it's ok to
+ // remember things like "widest set type" in properties, and if it's object, don't
+ // add any special "return undefined" getters, saving an invalidation
+ init.load(Type.OBJECT, JAVA_THIS.slot());
+ init.loadUndefined(Type.OBJECT);
+
+ final Iterator<String> iter = fieldNames.iterator();
+ while (iter.hasNext()) {
+ final String fieldName = iter.next();
+ if (iter.hasNext()) {
+ init.dup2();
+ }
+ init.putField(className, fieldName, Type.OBJECT.getDescriptor());
+ }
+ }
+
+ /**
+ * Generate the byte codes for a JavaScript object class or scope.
+ * Class name is a function of number of fields and number of param
+ * fields
+ *
+ * @param descriptor Descriptor pulled from class name.
+ *
+ * @return Byte codes for generated class.
+ */
+ public byte[] generate(final String descriptor) {
+ final String[] counts = descriptor.split(SCOPE_MARKER);
+ final int fieldCount = Integer.valueOf(counts[0]);
+
+ if (counts.length == 1) {
+ return generate(fieldCount);
+ }
+
+ final int paramCount = Integer.valueOf(counts[1]);
+
+ return generate(fieldCount, paramCount);
+ }
+
+ /**
+ * Generate the byte codes for a JavaScript object class with fieldCount fields.
+ *
+ * @param fieldCount Number of fields in the JavaScript object.
+ *
+ * @return Byte codes for generated class.
+ */
+ public byte[] generate(final int fieldCount) {
+ final String className = getClassName(fieldCount);
+ final String superName = className(ScriptObject.class);
+ final ClassEmitter classEmitter = newClassEmitter(className, superName);
+ final List<String> initFields = addFields(classEmitter, fieldCount);
+
+ final MethodEmitter init = newInitMethod(classEmitter);
+ initializeToUndefined(init, className, initFields);
+ init.returnVoid();
+ init.end();
+
+ newEmptyInit(classEmitter, className);
+ newAllocate(classEmitter, className);
+
+ return toByteArray(classEmitter);
+ }
+
+ /**
+ * Generate the byte codes for a JavaScript scope class with fieldCount fields
+ * and paramCount parameters.
+ *
+ * @param fieldCount Number of fields in the JavaScript scope.
+ * @param paramCount Number of parameters in the JavaScript scope
+ * .
+ * @return Byte codes for generated class.
+ */
+ public byte[] generate(final int fieldCount, final int paramCount) {
+ final String className = getClassName(fieldCount, paramCount);
+ final String superName = className(FunctionScope.class);
+ final ClassEmitter classEmitter = newClassEmitter(className, superName);
+ final List<String> initFields = addFields(classEmitter, fieldCount);
+
+ final MethodEmitter init = newInitScopeMethod(classEmitter);
+ initializeToUndefined(init, className, initFields);
+ init.returnVoid();
+ init.end();
+
+ final MethodEmitter initWithArguments = newInitScopeWithArgumentsMethod(classEmitter);
+ initializeToUndefined(initWithArguments, className, initFields);
+ initWithArguments.returnVoid();
+ initWithArguments.end();
+
+ return toByteArray(classEmitter);
+ }
+
+ /**
+ * Generates the needed fields.
+ *
+ * @param classEmitter Open class emitter.
+ * @param fieldCount Number of fields.
+ *
+ * @return List fields that need to be initialized.
+ */
+ private static List<String> addFields(final ClassEmitter classEmitter, final int fieldCount) {
+ final List<String> initFields = new LinkedList<>();
+
+ for (int i = 0; i < fieldCount; i++) {
+ for (final Type type : FIELD_TYPES) {
+ final String fieldName = getFieldName(i, type);
+ classEmitter.field(fieldName, type.getTypeClass());
+
+ if (type == Type.OBJECT) {
+ initFields.add(fieldName);
+ }
+ }
+ }
+
+ return initFields;
+ }
+
+ /**
+ * Allocate and initialize a new class emitter.
+ *
+ * @param className Name of JavaScript class.
+ *
+ * @return Open class emitter.
+ */
+ private ClassEmitter newClassEmitter(final String className, final String superName) {
+ final ClassEmitter classEmitter = new ClassEmitter(context, className, superName);
+ classEmitter.begin();
+
+ return classEmitter;
+ }
+
+ /**
+ * Allocate and initialize a new <init> method.
+ *
+ * @param classEmitter Open class emitter.
+ *
+ * @return Open method emitter.
+ */
+ private static MethodEmitter newInitMethod(final ClassEmitter classEmitter) {
+ final MethodEmitter init = classEmitter.init(PropertyMap.class);
+ init.begin();
+ init.load(Type.OBJECT, JAVA_THIS.slot());
+ init.load(Type.OBJECT, MAP.slot());
+ init.invoke(constructorNoLookup(ScriptObject.class, PropertyMap.class));
+
+ return init;
+ }
+
+ /**
+ * Allocate and initialize a new <init> method for scopes.
+ * @param classEmitter Open class emitter.
+ * @return Open method emitter.
+ */
+ private static MethodEmitter newInitScopeMethod(final ClassEmitter classEmitter) {
+ final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class);
+ init.begin();
+ init.load(Type.OBJECT, JAVA_THIS.slot());
+ init.load(Type.OBJECT, MAP.slot());
+ init.load(Type.OBJECT, INIT_SCOPE.slot());
+ init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class));
+
+ return init;
+ }
+
+ /**
+ * Allocate and initialize a new <init> method for scopes with arguments.
+ * @param classEmitter Open class emitter.
+ * @return Open method emitter.
+ */
+ private static MethodEmitter newInitScopeWithArgumentsMethod(final ClassEmitter classEmitter) {
+ final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class, Object.class);
+ init.begin();
+ init.load(Type.OBJECT, JAVA_THIS.slot());
+ init.load(Type.OBJECT, MAP.slot());
+ init.load(Type.OBJECT, INIT_SCOPE.slot());
+ init.load(Type.OBJECT, INIT_ARGUMENTS.slot());
+ init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class, Object.class));
+
+ return init;
+ }
+
+ /**
+ * Add an empty <init> method to the JavaScript class.
+ *
+ * @param classEmitter Open class emitter.
+ * @param className Name of JavaScript class.
+ */
+ private static void newEmptyInit(final ClassEmitter classEmitter, final String className) {
+ final MethodEmitter emptyInit = classEmitter.init();
+ emptyInit.begin();
+ emptyInit.load(Type.OBJECT, JAVA_THIS.slot());
+ emptyInit.loadNull();
+ emptyInit.invoke(constructorNoLookup(className, PropertyMap.class));
+ emptyInit.returnVoid();
+ emptyInit.end();
+ }
+
+ /**
+ * Add an empty <init> method to the JavaScript class.
+ *
+ * @param classEmitter Open class emitter.
+ * @param className Name of JavaScript class.
+ */
+ private static void newAllocate(final ClassEmitter classEmitter, final String className) {
+ final MethodEmitter allocate = classEmitter.method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), ALLOCATE.tag(), ScriptObject.class, PropertyMap.class);
+ allocate.begin();
+ allocate._new(className);
+ allocate.dup();
+ allocate.load(Type.typeFor(PropertyMap.class), 0);
+ allocate.invoke(constructorNoLookup(className, PropertyMap.class));
+ allocate._return();
+ allocate.end();
+ }
+
+ /**
+ * Collects the byte codes for a generated JavaScript class.
+ *
+ * @param classEmitter Open class emitter.
+ * @return Byte codes for the class.
+ */
+ private byte[] toByteArray(final ClassEmitter classEmitter) {
+ classEmitter.end();
+
+ final byte[] code = classEmitter.toByteArray();
+
+ if (context != null && context._print_code) {
+ Context.getCurrentErr().println(ClassEmitter.disassemble(code));
+ }
+
+ if (context != null && context._verify_code) {
+ context.verify(code);
+ }
+
+ return code;
+ }
+
+ /** Double to long bits, used with --dual-fields for primitive double values */
+ private static final MethodHandle PACK_DOUBLE =
+ MH.explicitCastArguments(MH.findStatic(MethodHandles.publicLookup(), Double.class, "doubleToRawLongBits", MH.type(long.class, double.class)), MH.type(long.class, double.class));
+
+ /** double bits to long, used with --dual-fields for primitive double values */
+ private static MethodHandle UNPACK_DOUBLE =
+ MH.findStatic(MethodHandles.publicLookup(), Double.class, "longBitsToDouble", MH.type(double.class, long.class));
+
+ /** object conversion quickies with JS semantics - used for return value and parameter filter */
+ private static MethodHandle[] CONVERT_OBJECT = {
+ JSType.TO_INT32.methodHandle(),
+ JSType.TO_UINT32.methodHandle(),
+ JSType.TO_NUMBER.methodHandle(),
+ null
+ };
+
+ /**
+ * Given a primitiveGetter (optional for non dual fields) and an objectSetter that retrieve
+ * the primitive and object version of a field respectively, return one with the correct
+ * method type and the correct filters. For example, if the value is stored as a double
+ * and we want an Object getter, in the dual fields world we'd pick the primitiveGetter,
+ * which reads a long, use longBitsToDouble on the result to unpack it, and then change the
+ * return type to Object, boxing it. In the objects only world there are only object fields,
+ * primtives are boxed when asked for them and we don't need to bother with primitive encoding
+ * (or even undefined, which if forType==null) representation, so we just return whatever is
+ * in the object field. The object field is always initiated to Undefined, so here, where we have
+ * the representation for Undefined in all our bits, this is not a problem.
+ * <p>
+ * Representing undefined in a primitive is hard, for an int there aren't enough bits, for a long
+ * we could limit the width of a representation, and for a double (as long as it is stored as long,
+ * as all NaNs will turn into QNaN on ia32, which is one bit pattern, we should use a special NaN).
+ * Naturally we could have special undefined values for all types which mean "go look in a wider field",
+ * but the guards needed on every getter took too much time.
+ * <p>
+ * To see how this is used, look for example in {@link AccessorProperty#getGetter}
+ * <p>
+ * @param forType representation of the underlying type in the field, null if undefined
+ * @param type type to retrieve it as
+ * @param primitiveGetter getter to read the primitive version of this field (null if Objects Only)
+ * @param objectGetter getter to read the object version of this field
+ *
+ * @return getter for the given representation that returns the given type
+ */
+ public static MethodHandle createGetter(final Class<?> forType, final Class<?> type, final MethodHandle primitiveGetter, final MethodHandle objectGetter) {
+ final int fti = forType == null ? -1 : getAccessorTypeIndex(forType);
+ final int ti = getAccessorTypeIndex(type);
+
+ if (fti == TYPE_OBJECT_INDEX || OBJECT_FIELDS_ONLY) {
+ if (ti == TYPE_OBJECT_INDEX) {
+ return objectGetter;
+ }
+
+ return MH.filterReturnValue(objectGetter, CONVERT_OBJECT[ti]);
+ }
+
+ assert !OBJECT_FIELDS_ONLY;
+ if (forType == null) {
+ return GET_UNDEFINED[ti];
+ }
+
+ final MethodType pmt = primitiveGetter.type();
+
+ switch (fti) {
+ case TYPE_INT_INDEX:
+ case TYPE_LONG_INDEX:
+ switch (ti) {
+ case TYPE_INT_INDEX:
+ //get int while an int, truncating cast of long value
+ return MH.explicitCastArguments(primitiveGetter, pmt.changeReturnType(int.class));
+ case TYPE_LONG_INDEX:
+ return primitiveGetter;
+ default:
+ return MH.asType(primitiveGetter, pmt.changeReturnType(type));
+ }
+ case TYPE_DOUBLE_INDEX:
+ final MethodHandle getPrimitiveAsDouble = MH.filterReturnValue(primitiveGetter, UNPACK_DOUBLE);
+ switch (ti) {
+ case TYPE_INT_INDEX:
+ case TYPE_LONG_INDEX:
+ return MH.explicitCastArguments(getPrimitiveAsDouble, pmt.changeReturnType(type));
+ case TYPE_DOUBLE_INDEX:
+ return getPrimitiveAsDouble;
+ default:
+ return MH.asType(getPrimitiveAsDouble, pmt.changeReturnType(Object.class));
+ }
+ default:
+ assert false;
+ return null;
+ }
+ }
+
+ private static final MethodHandle IS_TYPE_GUARD = findOwnMH("isType", boolean.class, Class.class, Object.class);
+
+ @SuppressWarnings("unused")
+ private static boolean isType(final Class<?> boxedForType, final Object x) {
+ return x.getClass() == boxedForType;
+ }
+
+ private static Class<? extends Number> getBoxedType(final Class<?> forType) {
+ if (forType == int.class) {
+ return Integer.class;
+ }
+
+ if (forType == long.class) {
+ return Long.class;
+ }
+
+ if (forType == double.class) {
+ return Double.class;
+ }
+
+ assert false;
+ return null;
+ }
+
+ /**
+ * If we are setting boxed types (because the compiler couldn't determine which they were) to
+ * a primitive field, we can reuse the primitive field getter, as long as we are setting an element
+ * of the same boxed type as the primitive type representation
+ *
+ * @param forType the current type
+ * @param primitiveSetter primitive setter for the current type with an element of the current type
+ * @param objectSetter the object setter
+ *
+ * @return method handle that checks if the element to be set is of the currenttype, even though it's boxed
+ * and instead of using the generic object setter, that would blow up the type and invalidate the map,
+ * unbox it and call the primitive setter instead
+ */
+ public static MethodHandle createGuardBoxedPrimitiveSetter(final Class<?> forType, final MethodHandle primitiveSetter, final MethodHandle objectSetter) {
+ final Class<? extends Number> boxedForType = getBoxedType(forType);
+ //object setter that checks for primitive if current type is primitive
+
+ return MH.guardWithTest(
+ MH.insertArguments(
+ MH.dropArguments(
+ IS_TYPE_GUARD,
+ 1,
+ Object.class),
+ 0,
+ boxedForType),
+ MH.asType(
+ primitiveSetter,
+ objectSetter.type()),
+ objectSetter);
+ }
+
+ /**
+ * This is similar to the {@link ObjectClassGenerator#createGetter} function. Performs
+ * the necessary operations to massage a setter operand of type {@code type} to
+ * fit into the primitive field (if primitive and dual fields is enabled) or into
+ * the object field (box if primitive and dual fields is disabled)
+ *
+ * @param forType representation of the underlying object
+ * @param type representation of field to write, and setter signature
+ * @param primitiveSetter setter that writes to the primitive field (null if Objects Only)
+ * @param objectSetter setter that writes to the object field
+ *
+ * @return the setter for the given representation that takes a {@code type}
+ */
+ public static MethodHandle createSetter(final Class<?> forType, final Class<?> type, final MethodHandle primitiveSetter, final MethodHandle objectSetter) {
+ assert forType != null;
+
+ final int fti = getAccessorTypeIndex(forType);
+ final int ti = getAccessorTypeIndex(type);
+
+ if (fti == TYPE_OBJECT_INDEX || OBJECT_FIELDS_ONLY) {
+ if (ti == TYPE_OBJECT_INDEX) {
+ return objectSetter;
+ }
+
+ return MH.asType(objectSetter, objectSetter.type().changeParameterType(1, type));
+ }
+
+ assert !OBJECT_FIELDS_ONLY;
+
+ final MethodType pmt = primitiveSetter.type();
+
+ switch (fti) {
+ case TYPE_INT_INDEX:
+ case TYPE_LONG_INDEX:
+ switch (ti) {
+ case TYPE_INT_INDEX:
+ return MH.asType(primitiveSetter, pmt.changeParameterType(1, int.class));
+ case TYPE_LONG_INDEX:
+ return primitiveSetter;
+ case TYPE_DOUBLE_INDEX:
+ return MH.filterArguments(primitiveSetter, 1, PACK_DOUBLE);
+ default:
+ return objectSetter;
+ }
+ case TYPE_DOUBLE_INDEX:
+ if (ti == TYPE_OBJECT_INDEX) {
+ return objectSetter;
+ }
+ return MH.asType(MH.filterArguments(primitiveSetter, 1, PACK_DOUBLE), pmt.changeParameterType(1, type));
+ default:
+ assert false;
+ return null;
+ }
+ }
+
+ //
+ // Provide generic getters and setters for undefined types. If a type is undefined, all
+ // and marshals the set to the correct setter depending on the type of the value being set.
+ // Note that there are no actual undefined versions of int, long and double in JavaScript,
+ // but executing toInt32, toLong and toNumber always returns a working result, 0, 0L or NaN
+ //
+
+ /** The value of Undefined cast to an int32 */
+ public static final int UNDEFINED_INT = 0;
+ /** The value of Undefined cast to a long */
+ public static final long UNDEFINED_LONG = 0L;
+ /** The value of Undefined cast to a double */
+ public static final double UNDEFINED_DOUBLE = Double.NaN;
+
+ /**
+ * Compute type name for correct undefined getter
+ * @param type the type
+ * @return name of getter
+ */
+ private static String typeName(final Type type) {
+ String name = type.getTypeClass().getName();
+ final int dot = name.lastIndexOf('.');
+ if (dot != -1) {
+ name = name.substring(dot + 1);
+ }
+ return Character.toUpperCase(name.charAt(0)) + name.substring(1);
+ }
+
+ /**
+ * Handles for undefined getters of the different types
+ */
+ private static final MethodHandle[] GET_UNDEFINED = new MethodHandle[ObjectClassGenerator.getNumberOfAccessorTypes()];
+
+ /**
+ * Used to wrap getters for undefined values, where this matters. Currently only in dual fields.
+ * If an object starts out as undefined it needs special getters until it has been assigned
+ * something the first time
+ *
+ * @param returnType type to cast the undefined to
+ *
+ * @return undefined as returnType
+ */
+ public static MethodHandle getUndefined(final Class<?> returnType) {
+ return GET_UNDEFINED[ObjectClassGenerator.getAccessorTypeIndex(returnType)];
+ }
+
+ static {
+ int pos = 0;
+ for (final Type type : ACCESSOR_TYPES) {
+ GET_UNDEFINED[pos++] = findOwnMH("getUndefined" + typeName(type), type.getTypeClass(), Object.class);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private static int getUndefinedInt(final Object obj) {
+ return UNDEFINED_INT;
+ }
+
+ @SuppressWarnings("unused")
+ private static long getUndefinedLong(final Object obj) {
+ return UNDEFINED_LONG;
+ }
+
+ @SuppressWarnings("unused")
+ private static double getUndefinedDouble(final Object obj) {
+ return UNDEFINED_DOUBLE;
+ }
+
+ @SuppressWarnings("unused")
+ private static Object getUndefinedObject(final Object obj) {
+ return ScriptRuntime.UNDEFINED;
+ }
+
+ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+ return MH.findStatic(MethodHandles.lookup(), ObjectClassGenerator.class, name, MH.type(rtype, types));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java Fri Feb 15 09:44:15 2013 +0100
@@ -0,0 +1,172 @@
+/*
+ * 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.codegen;
+
+import java.util.List;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.PropertyMap;
+
+/**
+ * Base class for object creation code generation.
+ */
+public abstract class ObjectCreator {
+
+ /** Compile unit for this ObjectCreator, see CompileUnit */
+ protected final CompileUnit compileUnit;
+
+ /** List of keys to initiate in this ObjectCreator */
+ protected final List<String> keys;
+
+ /** List of symbols to initiate in this ObjectCreator */
+ protected final List<Symbol> symbols;
+
+ /** Code generator */
+ protected final CodeGenerator codegen;
+
+ private final boolean isScope;
+ private final boolean hasArguments;
+ private int fieldCount;
+ private int paramCount;
+ private String fieldObjectClassName;
+ private Class<?> fieldObjectClass;
+ private PropertyMap propertyMap;
+
+ /**
+ * Constructor
+ *
+ * @param codegen the code generator
+ * @param keys the keys
+ * @param symbols the symbols corresponding to keys, same index
+ * @param isScope is this object scope
+ * @param hasArguments does the created object have an "arguments" property
+ */
+ protected ObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final boolean isScope, final boolean hasArguments) {
+ this.codegen = codegen;
+ this.compileUnit = codegen.getCurrentCompileUnit();
+ this.keys = keys;
+ this.symbols = symbols;
+ this.isScope = isScope;
+ this.hasArguments = hasArguments;
+
+ countFields();
+ findClass();
+ }
+
+ /**
+ * Tally the number of fields and parameters.
+ */
+ private void countFields() {
+ for (final Symbol symbol : this.symbols) {
+ if (symbol != null) {
+ if (hasArguments() && symbol.isParam()) {
+ symbol.setFieldIndex(paramCount++);
+ } else {
+ symbol.setFieldIndex(fieldCount++);
+ }
+ }
+ }
+ }
+
+ /**
+ * Locate (or indirectly create) the object container class.
+ */
+ private void findClass() {
+ fieldObjectClassName = isScope() ?
+ ObjectClassGenerator.getClassName(fieldCount, paramCount) :
+ ObjectClassGenerator.getClassName(fieldCount);
+
+ try {
+ this.fieldObjectClass = Context.forStructureClass(Compiler.binaryName(fieldObjectClassName));
+ } catch (final ClassNotFoundException e) {
+ throw new AssertionError("Nashorn has encountered an internal error. Structure can not be created.");
+ }
+ }
+
+ /**
+ * Generate code for making the object.
+ * @param method Script method.
+ */
+ protected abstract void makeObject(final MethodEmitter method);
+
+ /**
+ * Create a new MapCreator
+ * @param clazz type of MapCreator
+ * @return map creator instantiated by type
+ */
+ protected MapCreator newMapCreator(final Class<?> clazz) {
+ return new MapCreator(clazz, keys, symbols);
+ }
+
+ /**
+ * Construct the property map appropriate for the object.
+ * @return the newly created property map
+ */
+ protected PropertyMap makeMap() {
+ if (keys.isEmpty()) { //empty map
+ propertyMap = PropertyMap.newMap(fieldObjectClass);
+ } else {
+ propertyMap = newMapCreator(fieldObjectClass).makeMap(hasArguments());
+ }
+ return propertyMap;
+ }
+
+ /**
+ * Emit the correct map for the object.
+ * @param method method emitter
+ * @return the method emitter
+ */
+ protected MethodEmitter loadMap(final MethodEmitter method) {
+ codegen.loadConstant(propertyMap);
+ return method;
+ }
+
+ /**
+ * Get the class name for the object class,
+ * e.g. {@code com.nashorn.oracle.scripts.JO$2P0}
+ *
+ * @return script class name
+ */
+ String getClassName() {
+ return fieldObjectClassName;
+ }
+
+ /**
+ * Is this a scope object
+ * @return true if scope
+ */
+ protected boolean isScope() {
+ return isScope;
+ }
+
+ /**
+ * Does the created object have an "arguments" property
+ * @return true if has an "arguments" property
+ */
+ protected boolean hasArguments() {
+ return hasArguments;
+ }
+}
--- a/nashorn/src/jdk/nashorn/internal/codegen/SharedScopeCall.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/SharedScopeCall.java Fri Feb 15 09:44:15 2013 +0100
@@ -48,7 +48,7 @@
* <p>Scope calls must not be shared between normal callsites and callsites contained in a <tt>with</tt>
* statement as this condition is not handled by current guards and will cause a runtime error.</p>
*/
-public class SharedScopeCall {
+class SharedScopeCall {
/** Threshold for using shared scope calls with fast scope access. */
public static final int FAST_SCOPE_CALL_THRESHOLD = 4;
@@ -118,7 +118,7 @@
* @param method the method emitter
*/
public void generateInvoke(final MethodEmitter method) {
- method.invokeStatic(compileUnit.getUnitClassName(), methodName, getStaticSignature());
+ method.invokestatic(compileUnit.getUnitClassName(), methodName, getStaticSignature());
}
/**
@@ -138,8 +138,8 @@
// Load correct scope by calling getProto() on the scope argument as often as specified
// by the second argument.
- final MethodEmitter.Label parentLoopStart = new MethodEmitter.Label("parent_loop_start");
- final MethodEmitter.Label parentLoopDone = new MethodEmitter.Label("parent_loop_done");
+ final Label parentLoopStart = new Label("parent_loop_start");
+ final Label parentLoopDone = new Label("parent_loop_done");
method.load(Type.OBJECT, 0);
method.label(parentLoopStart);
method.load(Type.INT, 1);
--- a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java Fri Feb 15 09:44:15 2013 +0100
@@ -396,7 +396,7 @@
* @param targetNode the jump target node.
* @param targetLabel the jump target label.
*/
- private void searchJumpTarget(final Node targetNode, final MethodEmitter.Label targetLabel) {
+ private void searchJumpTarget(final Node targetNode, final Label targetLabel) {
final SplitNode targetSplit = targetNodes.get(targetNode);
// Note that targetSplit may be null, indicating that targetNode is in top level method.
@@ -406,7 +406,7 @@
if (split == targetSplit) {
break;
}
- final List<MethodEmitter.Label> externalTargets = split.getExternalTargets();
+ final List<Label> externalTargets = split.getExternalTargets();
if (!externalTargets.contains(targetLabel)) {
split.addExternalTarget(targetLabel);
}
--- a/nashorn/src/jdk/nashorn/internal/codegen/objects/FieldObjectCreator.java Fri Feb 15 09:18:05 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-/*
- * 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.codegen.objects;
-
-import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS;
-import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
-import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
-import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
-
-import java.util.Iterator;
-import java.util.List;
-import jdk.nashorn.internal.codegen.CodeGenerator;
-import jdk.nashorn.internal.codegen.MethodEmitter;
-import jdk.nashorn.internal.codegen.types.Type;
-import jdk.nashorn.internal.ir.Symbol;
-import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
-
-/**
- * Analyze an object's characteristics for appropriate code generation. This
- * is used for functions and for objects. A field object take a set of values which
- * to assign to the various fields in the object. This is done by the generated code
- *
- * @param <T> the value type for the fields being written on object creation, e.g. Node
- * @see jdk.nashorn.internal.ir.Node
- */
-public abstract class FieldObjectCreator<T> extends ObjectCreator {
- /** array of corresponding values to symbols (null for no values) */
- private final List<T> values;
-
- /** call site flags to be used for invocations */
- private final int callSiteFlags;
-
- /**
- * Constructor
- *
- * @param codegen code generator
- * @param keys keys for fields in object
- * @param symbols symbols for fields in object
- * @param values list of values corresponding to keys
- */
- public FieldObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<T> values) {
- this(codegen, keys, symbols, values, false, false);
- }
-
- /**
- * Constructor
- *
- * @param codegen code generator
- * @param keys keys for fields in object
- * @param symbols symbols for fields in object
- * @param values values (or null where no value) to be written to the fields
- * @param isScope is this a scope object
- * @param hasArguments does the created object have an "arguments" property
- */
- public FieldObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final List<T> values, final boolean isScope, final boolean hasArguments) {
- super(codegen, keys, symbols, isScope, hasArguments);
- this.values = values;
- this.callSiteFlags = codegen.getCallSiteFlags();
- }
-
- /**
- * Loads the scope on the stack through the passed method emitter.
- * @param method the method emitter to use
- */
- protected void loadScope(final MethodEmitter method) {
- method.loadScope();
- }
-
- /**
- * Construct an object.
- *
- * @param method the method emitter
- */
- @Override
- public void makeObject(final MethodEmitter method) {
- makeMap();
-
- method._new(getClassName()).dup(); // create instance
- loadMap(method); //load the map
-
- if (isScope()) {
- loadScope(method);
-
- if (hasArguments()) {
- method.loadArguments();
- method.invoke(constructorNoLookup(getClassName(), PropertyMap.class, ScriptObject.class, ARGUMENTS.type()));
- } else {
- method.invoke(constructorNoLookup(getClassName(), PropertyMap.class, ScriptObject.class));
- }
- } else {
- method.invoke(constructorNoLookup(getClassName(), PropertyMap.class));
- }
-
- // Set values.
- final Iterator<Symbol> symbolIter = symbols.iterator();
- final Iterator<String> keyIter = keys.iterator();
- final Iterator<T> valueIter = values.iterator();
-
- while (symbolIter.hasNext()) {
- final Symbol symbol = symbolIter.next();
- final String key = keyIter.next();
- final T value = valueIter.next();
-
- if (symbol != null && value != null) {
- final int index = ArrayIndex.getArrayIndexNoThrow(key);
-
- if (index < 0) {
- putField(method, key, symbol.getFieldIndex(), value);
- } else {
- putSlot(method, index, value);
- }
- }
- }
- }
-
- /**
- * Technique for loading an initial value. Defined by anonymous subclasses in code gen.
- *
- * @param value Value to load.
- */
- protected abstract void loadValue(T value);
-
- /**
- * Determine the type of a value. Defined by anonymous subclasses in code gen.
- *
- * @param value Value to inspect.
- *
- * @return Value type.
- */
- protected abstract Type getValueType(T value);
-
- /**
- * Store a value in a field of the generated class object.
- *
- * @param method Script method.
- * @param key Property key.
- * @param fieldIndex Field number.
- * @param value Value to store.
- */
- private void putField(final MethodEmitter method, final String key, final int fieldIndex, final T value) {
- method.dup();
-
- loadValue(value);
-
- final Type valueType = getValueType(value);
- // for example when we have a with scope
- if (valueType.isObject() || valueType.isBoolean()) {
- method.convert(OBJECT);
- }
-
- method.convert(OBJECT);
- method.putField(getClassName(), ObjectClassGenerator.getFieldName(fieldIndex, Type.OBJECT), typeDescriptor(Object.class));
- }
-
- /**
- * Store a value in an indexed slot of a generated class object.
- *
- * @param method Script method.
- * @param index Slot index.
- * @param value Value to store.
- */
- private void putSlot(final MethodEmitter method, final int index, final T value) {
- method.dup();
- method.load(index);
- loadValue(value);
- method.dynamicSetIndex(callSiteFlags);
- }
-
-}
--- a/nashorn/src/jdk/nashorn/internal/codegen/objects/MapCreator.java Fri Feb 15 09:18:05 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * 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.codegen.objects;
-
-import java.util.ArrayList;
-import java.util.List;
-import jdk.nashorn.internal.ir.Symbol;
-import jdk.nashorn.internal.runtime.AccessorProperty;
-import jdk.nashorn.internal.runtime.Property;
-import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
-
-/**
- * Class that creates PropertyMap sent to script object constructors.
- */
-public class MapCreator {
- /** Object structure for objects associated with this map */
- private final Class<?> structure;
-
- /** key set for object map */
- private final String[] keys;
-
- /** corresponding symbol set for object map */
- private final Symbol[] symbols;
-
- /**
- * Constructor
- *
- * @param structure structure to generate map for (a JO$ subclass)
- * @param keys list of keys for map
- * @param symbols list of symbols for map
- */
- public MapCreator(final Class<?> structure, final List<String> keys, final List<Symbol> symbols) {
- final int size = keys.size();
-
- this.structure = structure;
- this.keys = keys.toArray(new String[size]);
- this.symbols = symbols.toArray(new Symbol[size]);
- }
-
- /**
- * Constructs a property map based on a set of fields.
- *
- * @param hasArguments does the created object have an "arguments" property
- *
- * @return New map populated with accessor properties.
- */
- public PropertyMap makeMap(final boolean hasArguments) {
- final List<Property> properties = new ArrayList<>();
-
- assert keys != null;
-
- for (int i = 0; i < keys.length; i++) {
- final String key = keys[i];
- final Symbol symbol = symbols[i];
-
- if (symbol != null && !ArrayIndex.isIndexKey(key)) {
- properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), structure, symbol.getFieldIndex()));
- }
- }
-
- return PropertyMap.newMap(structure, properties);
- }
-
- /**
- * Compute property flags given local state of a field. Maybe be overridden and extended,
- * as is the case in {@link ObjectMapCreator}
- *
- * @param symbol symbol to check
- * @param hasArguments does the created object have an "arguments" property
- *
- * @return flags to use for fields
- */
- protected int getPropertyFlags(final Symbol symbol, final boolean hasArguments) {
- int flags = 0;
-
- if (symbol.isParam()) {
- flags |= Property.IS_ALWAYS_OBJECT | Property.IS_PARAMETER;
- }
-
- if (hasArguments) {
- flags |= Property.IS_ALWAYS_OBJECT | Property.HAS_ARGUMENTS;
- }
-
- if (symbol.isScope()) {
- flags |= Property.NOT_CONFIGURABLE;
- }
-
- if (symbol.canBePrimitive()) {
- flags |= Property.CAN_BE_PRIMITIVE;
- }
-
- if (symbol.canBeUndefined()) {
- flags |= Property.CAN_BE_UNDEFINED;
- }
-
- return flags;
- }
-
-}
--- a/nashorn/src/jdk/nashorn/internal/codegen/objects/ObjectClassGenerator.java Fri Feb 15 09:18:05 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,762 +0,0 @@
-/*
- * 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.codegen.objects;
-
-import static jdk.nashorn.internal.codegen.Compiler.SCRIPTS_PACKAGE;
-import static jdk.nashorn.internal.codegen.CompilerConstants.ALLOCATE;
-import static jdk.nashorn.internal.codegen.CompilerConstants.INIT_ARGUMENTS;
-import static jdk.nashorn.internal.codegen.CompilerConstants.INIT_SCOPE;
-import static jdk.nashorn.internal.codegen.CompilerConstants.JAVA_THIS;
-import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_PREFIX;
-import static jdk.nashorn.internal.codegen.CompilerConstants.MAP;
-import static jdk.nashorn.internal.codegen.CompilerConstants.className;
-import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
-import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import jdk.nashorn.internal.codegen.ClassEmitter;
-import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
-import jdk.nashorn.internal.codegen.MethodEmitter;
-import jdk.nashorn.internal.codegen.types.Type;
-import jdk.nashorn.internal.runtime.AccessorProperty;
-import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.DebugLogger;
-import jdk.nashorn.internal.runtime.FunctionScope;
-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.options.Options;
-
-/**
- * Generates the ScriptObject subclass structure with fields for a user objects.
- */
-public final class ObjectClassGenerator {
-
- /**
- * Marker for scope parameters.
- */
- public static final String SCOPE_MARKER = "P";
-
- /**
- * Debug field logger
- * Should we print debugging information for fields when they are generated and getters/setters are called?
- */
- public static final DebugLogger LOG = new DebugLogger("fields", "nashorn.fields.debug");
-
- /**
- * is field debugging enabled. Several modules in codegen and properties use this, hence
- * public access.
- */
- public static final boolean DEBUG_FIELDS = LOG.isEnabled();
-
- /**
- * Should the runtime only use java.lang.Object slots for fields? If this is false, the representation
- * will be a primitive 64-bit long value used for all primitives and a java.lang.Object for references.
- * This introduces a larger number of method handles in the system, as we need to have different getters
- * and setters for the different fields. Currently this introduces significant overhead in Hotspot.
- *
- * This is engineered to plug into the TaggedArray implementation, when it's done.
- */
- public static final boolean OBJECT_FIELDS_ONLY = !Options.getBooleanProperty("nashorn.fields.dual");
-
- /** The field types in the system */
- private static final List<Type> FIELD_TYPES = new LinkedList<>();
-
- /** What type is the primitive type in dual representation */
- public static final Type PRIMITIVE_TYPE = Type.LONG;
-
- /**
- * The list of field types that we support - one type creates one field. This is currently either
- * LONG + OBJECT or just OBJECT for classic mode.
- */
- static {
- if (!OBJECT_FIELDS_ONLY) {
- System.err.println("WARNING!!! Running with primitive fields - there is untested functionality!");
- FIELD_TYPES.add(PRIMITIVE_TYPE);
- }
- FIELD_TYPES.add(Type.OBJECT);
- }
-
- /** The context */
- private final Context context;
-
- /**
- * The list of available accessor types in width order. This order is used for type guesses narrow->wide
- * in the dual--fields world
- */
- public static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
- Arrays.asList(
- Type.INT,
- Type.LONG,
- Type.NUMBER,
- Type.OBJECT));
-
- //these are hard coded for speed and so that we can switch on them
- private static final int TYPE_INT_INDEX = 0; //getAccessorTypeIndex(int.class);
- private static final int TYPE_LONG_INDEX = 1; //getAccessorTypeIndex(long.class);
- private static final int TYPE_DOUBLE_INDEX = 2; //getAccessorTypeIndex(double.class);
- private static final int TYPE_OBJECT_INDEX = 3; //getAccessorTypeIndex(Object.class);
-
- /**
- * Constructor
- *
- * @param context a context
- */
- public ObjectClassGenerator(final Context context) {
- this.context = context;
- assert context != null;
- }
-
- /**
- * Given a type of an accessor, return its index in [0..getNumberOfAccessorTypes())
- *
- * @param type the type
- *
- * @return the accessor index, or -1 if no accessor of this type exists
- */
- public static int getAccessorTypeIndex(final Type type) {
- return getAccessorTypeIndex(type.getTypeClass());
- }
-
- /**
- * Given a class of an accessor, return its index in [0..getNumberOfAccessorTypes())
- *
- * Note that this is hardcoded with respect to the dynamic contents of the accessor
- * types array for speed. Hotspot got stuck with this as 5% of the runtime in
- * a benchmark when it looped over values and increased an index counter. :-(
- *
- * @param type the type
- *
- * @return the accessor index, or -1 if no accessor of this type exists
- */
- public static int getAccessorTypeIndex(final Class<?> type) {
- if (type == int.class) {
- return 0;
- } else if (type == long.class) {
- return 1;
- } else if (type == double.class) {
- return 2;
- } else if (!type.isPrimitive()) {
- return 3;
- }
- return -1;
- }
-
- /**
- * Return the number of accessor types available.
- *
- * @return number of accessor types in system
- */
- public static int getNumberOfAccessorTypes() {
- return ACCESSOR_TYPES.size();
- }
-
- /**
- * Return the accessor type based on its index in [0..getNumberOfAccessorTypes())
- * Indexes are ordered narrower->wider / optimistic->pessimistic. Invalidations always
- * go to a type of higher index
- *
- * @param index accessor type index
- *
- * @return a type corresponding to the index.
- */
-
- public static Type getAccessorType(final int index) {
- return ACCESSOR_TYPES.get(index);
- }
-
- /**
- * Returns the class name for JavaScript objects with fieldCount fields.
- *
- * @param fieldCount Number of fields to allocate.
- *
- * @return The class name.
- */
- public static String getClassName(final int fieldCount) {
- return fieldCount != 0 ? SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.tag() + fieldCount :
- SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.tag();
- }
-
- /**
- * Returns the class name for JavaScript scope with fieldCount fields and
- * paramCount parameters.
- *
- * @param fieldCount Number of fields to allocate.
- * @param paramCount Number of parameters to allocate
- *
- * @return The class name.
- */
- public static String getClassName(final int fieldCount, final int paramCount) {
- return SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.tag() + fieldCount + SCOPE_MARKER + paramCount;
- }
-
- /**
- * Returns the name of a field based on number and type.
- *
- * @param fieldIndex Ordinal of field.
- * @param type Type of field.
- *
- * @return The field name.
- */
- public static String getFieldName(final int fieldIndex, final Type type) {
- return type.getDescriptor().substring(0, 1) + fieldIndex;
- }
-
- /**
- * In the world of Object fields, we also have no undefined SwitchPoint, to reduce as much potential
- * MethodHandle overhead as possible. In that case, we explicitly need to assign undefined to fields
- * when we initialize them.
- *
- * @param init constructor to generate code in
- * @param className name of class
- * @param fieldNames fields to initialize to undefined, where applicable
- */
- private static void initializeToUndefined(final MethodEmitter init, final String className, final List<String> fieldNames) {
- if (fieldNames.isEmpty()) {
- return;
- }
-
- // always initialize fields to undefined, even with --dual-fields. Then it's ok to
- // remember things like "widest set type" in properties, and if it's object, don't
- // add any special "return undefined" getters, saving an invalidation
- init.load(Type.OBJECT, JAVA_THIS.slot());
- init.loadUndefined(Type.OBJECT);
-
- final Iterator<String> iter = fieldNames.iterator();
- while (iter.hasNext()) {
- final String fieldName = iter.next();
- if (iter.hasNext()) {
- init.dup2();
- }
- init.putField(className, fieldName, Type.OBJECT.getDescriptor());
- }
- }
-
- /**
- * Generate the byte codes for a JavaScript object class or scope.
- * Class name is a function of number of fields and number of param
- * fields
- *
- * @param descriptor Descriptor pulled from class name.
- *
- * @return Byte codes for generated class.
- */
- public byte[] generate(final String descriptor) {
- final String[] counts = descriptor.split(SCOPE_MARKER);
- final int fieldCount = Integer.valueOf(counts[0]);
-
- if (counts.length == 1) {
- return generate(fieldCount);
- }
-
- final int paramCount = Integer.valueOf(counts[1]);
-
- return generate(fieldCount, paramCount);
- }
-
- /**
- * Generate the byte codes for a JavaScript object class with fieldCount fields.
- *
- * @param fieldCount Number of fields in the JavaScript object.
- *
- * @return Byte codes for generated class.
- */
- public byte[] generate(final int fieldCount) {
- final String className = getClassName(fieldCount);
- final String superName = className(ScriptObject.class);
- final ClassEmitter classEmitter = newClassEmitter(className, superName);
- final List<String> initFields = addFields(classEmitter, fieldCount);
-
- final MethodEmitter init = newInitMethod(classEmitter);
- initializeToUndefined(init, className, initFields);
- init.returnVoid();
- init.end();
-
- newEmptyInit(classEmitter, className);
- newAllocate(classEmitter, className);
-
- return toByteArray(classEmitter);
- }
-
- /**
- * Generate the byte codes for a JavaScript scope class with fieldCount fields
- * and paramCount parameters.
- *
- * @param fieldCount Number of fields in the JavaScript scope.
- * @param paramCount Number of parameters in the JavaScript scope
- * .
- * @return Byte codes for generated class.
- */
- public byte[] generate(final int fieldCount, final int paramCount) {
- final String className = getClassName(fieldCount, paramCount);
- final String superName = className(FunctionScope.class);
- final ClassEmitter classEmitter = newClassEmitter(className, superName);
- final List<String> initFields = addFields(classEmitter, fieldCount);
-
- final MethodEmitter init = newInitScopeMethod(classEmitter);
- initializeToUndefined(init, className, initFields);
- init.returnVoid();
- init.end();
-
- final MethodEmitter initWithArguments = newInitScopeWithArgumentsMethod(classEmitter);
- initializeToUndefined(initWithArguments, className, initFields);
- initWithArguments.returnVoid();
- initWithArguments.end();
-
- return toByteArray(classEmitter);
- }
-
- /**
- * Generates the needed fields.
- *
- * @param classEmitter Open class emitter.
- * @param fieldCount Number of fields.
- *
- * @return List fields that need to be initialized.
- */
- private static List<String> addFields(final ClassEmitter classEmitter, final int fieldCount) {
- final List<String> initFields = new LinkedList<>();
-
- for (int i = 0; i < fieldCount; i++) {
- for (final Type type : FIELD_TYPES) {
- final String fieldName = getFieldName(i, type);
- classEmitter.field(fieldName, type.getTypeClass());
-
- if (type == Type.OBJECT) {
- initFields.add(fieldName);
- }
- }
- }
-
- return initFields;
- }
-
- /**
- * Allocate and initialize a new class emitter.
- *
- * @param className Name of JavaScript class.
- *
- * @return Open class emitter.
- */
- private ClassEmitter newClassEmitter(final String className, final String superName) {
- final ClassEmitter classEmitter = new ClassEmitter(context, className, superName);
- classEmitter.begin();
-
- return classEmitter;
- }
-
- /**
- * Allocate and initialize a new <init> method.
- *
- * @param classEmitter Open class emitter.
- *
- * @return Open method emitter.
- */
- private static MethodEmitter newInitMethod(final ClassEmitter classEmitter) {
- final MethodEmitter init = classEmitter.init(PropertyMap.class);
- init.begin();
- init.load(Type.OBJECT, JAVA_THIS.slot());
- init.load(Type.OBJECT, MAP.slot());
- init.invoke(constructorNoLookup(ScriptObject.class, PropertyMap.class));
-
- return init;
- }
-
- /**
- * Allocate and initialize a new <init> method for scopes.
- * @param classEmitter Open class emitter.
- * @return Open method emitter.
- */
- private static MethodEmitter newInitScopeMethod(final ClassEmitter classEmitter) {
- final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class);
- init.begin();
- init.load(Type.OBJECT, JAVA_THIS.slot());
- init.load(Type.OBJECT, MAP.slot());
- init.load(Type.OBJECT, INIT_SCOPE.slot());
- init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class));
-
- return init;
- }
-
- /**
- * Allocate and initialize a new <init> method for scopes with arguments.
- * @param classEmitter Open class emitter.
- * @return Open method emitter.
- */
- private static MethodEmitter newInitScopeWithArgumentsMethod(final ClassEmitter classEmitter) {
- final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class, Object.class);
- init.begin();
- init.load(Type.OBJECT, JAVA_THIS.slot());
- init.load(Type.OBJECT, MAP.slot());
- init.load(Type.OBJECT, INIT_SCOPE.slot());
- init.load(Type.OBJECT, INIT_ARGUMENTS.slot());
- init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class, Object.class));
-
- return init;
- }
-
- /**
- * Add an empty <init> method to the JavaScript class.
- *
- * @param classEmitter Open class emitter.
- * @param className Name of JavaScript class.
- */
- private static void newEmptyInit(final ClassEmitter classEmitter, final String className) {
- final MethodEmitter emptyInit = classEmitter.init();
- emptyInit.begin();
- emptyInit.load(Type.OBJECT, JAVA_THIS.slot());
- emptyInit.loadNull();
- emptyInit.invoke(constructorNoLookup(className, PropertyMap.class));
- emptyInit.returnVoid();
- emptyInit.end();
- }
-
- /**
- * Add an empty <init> method to the JavaScript class.
- *
- * @param classEmitter Open class emitter.
- * @param className Name of JavaScript class.
- */
- private static void newAllocate(final ClassEmitter classEmitter, final String className) {
- final MethodEmitter allocate = classEmitter.method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), ALLOCATE.tag(), ScriptObject.class, PropertyMap.class);
- allocate.begin();
- allocate._new(className);
- allocate.dup();
- allocate.load(Type.typeFor(PropertyMap.class), 0);
- allocate.invoke(constructorNoLookup(className, PropertyMap.class));
- allocate._return();
- allocate.end();
- }
-
- /**
- * Collects the byte codes for a generated JavaScript class.
- *
- * @param classEmitter Open class emitter.
- * @return Byte codes for the class.
- */
- private byte[] toByteArray(final ClassEmitter classEmitter) {
- classEmitter.end();
-
- final byte[] code = classEmitter.toByteArray();
-
- if (context != null && context._print_code) {
- Context.getCurrentErr().println(ClassEmitter.disassemble(code));
- }
-
- if (context != null && context._verify_code) {
- context.verify(code);
- }
-
- return code;
- }
-
- /** Double to long bits, used with --dual-fields for primitive double values */
- private static final MethodHandle PACK_DOUBLE =
- MH.explicitCastArguments(MH.findStatic(MethodHandles.publicLookup(), Double.class, "doubleToRawLongBits", MH.type(long.class, double.class)), MH.type(long.class, double.class));
-
- /** double bits to long, used with --dual-fields for primitive double values */
- private static MethodHandle UNPACK_DOUBLE =
- MH.findStatic(MethodHandles.publicLookup(), Double.class, "longBitsToDouble", MH.type(double.class, long.class));
-
- /** object conversion quickies with JS semantics - used for return value and parameter filter */
- private static MethodHandle[] CONVERT_OBJECT = {
- JSType.TO_INT32.methodHandle(),
- JSType.TO_UINT32.methodHandle(),
- JSType.TO_NUMBER.methodHandle(),
- null
- };
-
- /**
- * Given a primitiveGetter (optional for non dual fields) and an objectSetter that retrieve
- * the primitive and object version of a field respectively, return one with the correct
- * method type and the correct filters. For example, if the value is stored as a double
- * and we want an Object getter, in the dual fields world we'd pick the primitiveGetter,
- * which reads a long, use longBitsToDouble on the result to unpack it, and then change the
- * return type to Object, boxing it. In the objects only world there are only object fields,
- * primtives are boxed when asked for them and we don't need to bother with primitive encoding
- * (or even undefined, which if forType==null) representation, so we just return whatever is
- * in the object field. The object field is always initiated to Undefined, so here, where we have
- * the representation for Undefined in all our bits, this is not a problem.
- * <p>
- * Representing undefined in a primitive is hard, for an int there aren't enough bits, for a long
- * we could limit the width of a representation, and for a double (as long as it is stored as long,
- * as all NaNs will turn into QNaN on ia32, which is one bit pattern, we should use a special NaN).
- * Naturally we could have special undefined values for all types which mean "go look in a wider field",
- * but the guards needed on every getter took too much time.
- * <p>
- * To see how this is used, look for example in {@link AccessorProperty#getGetter}
- * <p>
- * @param forType representation of the underlying type in the field, null if undefined
- * @param type type to retrieve it as
- * @param primitiveGetter getter to read the primitive version of this field (null if Objects Only)
- * @param objectGetter getter to read the object version of this field
- *
- * @return getter for the given representation that returns the given type
- */
- public static MethodHandle createGetter(final Class<?> forType, final Class<?> type, final MethodHandle primitiveGetter, final MethodHandle objectGetter) {
- final int fti = forType == null ? -1 : getAccessorTypeIndex(forType);
- final int ti = getAccessorTypeIndex(type);
-
- if (fti == TYPE_OBJECT_INDEX || OBJECT_FIELDS_ONLY) {
- if (ti == TYPE_OBJECT_INDEX) {
- return objectGetter;
- }
-
- return MH.filterReturnValue(objectGetter, CONVERT_OBJECT[ti]);
- }
-
- assert !OBJECT_FIELDS_ONLY;
- if (forType == null) {
- return GET_UNDEFINED[ti];
- }
-
- final MethodType pmt = primitiveGetter.type();
-
- switch (fti) {
- case TYPE_INT_INDEX:
- case TYPE_LONG_INDEX:
- switch (ti) {
- case TYPE_INT_INDEX:
- //get int while an int, truncating cast of long value
- return MH.explicitCastArguments(primitiveGetter, pmt.changeReturnType(int.class));
- case TYPE_LONG_INDEX:
- return primitiveGetter;
- default:
- return MH.asType(primitiveGetter, pmt.changeReturnType(type));
- }
- case TYPE_DOUBLE_INDEX:
- final MethodHandle getPrimitiveAsDouble = MH.filterReturnValue(primitiveGetter, UNPACK_DOUBLE);
- switch (ti) {
- case TYPE_INT_INDEX:
- case TYPE_LONG_INDEX:
- return MH.explicitCastArguments(getPrimitiveAsDouble, pmt.changeReturnType(type));
- case TYPE_DOUBLE_INDEX:
- return getPrimitiveAsDouble;
- default:
- return MH.asType(getPrimitiveAsDouble, pmt.changeReturnType(Object.class));
- }
- default:
- assert false;
- return null;
- }
- }
-
- private static final MethodHandle IS_TYPE_GUARD = findOwnMH("isType", boolean.class, Class.class, Object.class);
-
- @SuppressWarnings("unused")
- private static boolean isType(final Class<?> boxedForType, final Object x) {
- return x.getClass() == boxedForType;
- }
-
- private static Class<? extends Number> getBoxedType(final Class<?> forType) {
- if (forType == int.class) {
- return Integer.class;
- }
-
- if (forType == long.class) {
- return Long.class;
- }
-
- if (forType == double.class) {
- return Double.class;
- }
-
- assert false;
- return null;
- }
-
- /**
- * If we are setting boxed types (because the compiler couldn't determine which they were) to
- * a primitive field, we can reuse the primitive field getter, as long as we are setting an element
- * of the same boxed type as the primitive type representation
- *
- * @param forType the current type
- * @param primitiveSetter primitive setter for the current type with an element of the current type
- * @param objectSetter the object setter
- *
- * @return method handle that checks if the element to be set is of the currenttype, even though it's boxed
- * and instead of using the generic object setter, that would blow up the type and invalidate the map,
- * unbox it and call the primitive setter instead
- */
- public static MethodHandle createGuardBoxedPrimitiveSetter(final Class<?> forType, final MethodHandle primitiveSetter, final MethodHandle objectSetter) {
- final Class<? extends Number> boxedForType = getBoxedType(forType);
- //object setter that checks for primitive if current type is primitive
-
- return MH.guardWithTest(
- MH.insertArguments(
- MH.dropArguments(
- IS_TYPE_GUARD,
- 1,
- Object.class),
- 0,
- boxedForType),
- MH.asType(
- primitiveSetter,
- objectSetter.type()),
- objectSetter);
- }
-
- /**
- * This is similar to the {@link ObjectClassGenerator#createGetter} function. Performs
- * the necessary operations to massage a setter operand of type {@code type} to
- * fit into the primitive field (if primitive and dual fields is enabled) or into
- * the object field (box if primitive and dual fields is disabled)
- *
- * @param forType representation of the underlying object
- * @param type representation of field to write, and setter signature
- * @param primitiveSetter setter that writes to the primitive field (null if Objects Only)
- * @param objectSetter setter that writes to the object field
- *
- * @return the setter for the given representation that takes a {@code type}
- */
- public static MethodHandle createSetter(final Class<?> forType, final Class<?> type, final MethodHandle primitiveSetter, final MethodHandle objectSetter) {
- assert forType != null;
-
- final int fti = getAccessorTypeIndex(forType);
- final int ti = getAccessorTypeIndex(type);
-
- if (fti == TYPE_OBJECT_INDEX || OBJECT_FIELDS_ONLY) {
- if (ti == TYPE_OBJECT_INDEX) {
- return objectSetter;
- }
-
- return MH.asType(objectSetter, objectSetter.type().changeParameterType(1, type));
- }
-
- assert !OBJECT_FIELDS_ONLY;
-
- final MethodType pmt = primitiveSetter.type();
-
- switch (fti) {
- case TYPE_INT_INDEX:
- case TYPE_LONG_INDEX:
- switch (ti) {
- case TYPE_INT_INDEX:
- return MH.asType(primitiveSetter, pmt.changeParameterType(1, int.class));
- case TYPE_LONG_INDEX:
- return primitiveSetter;
- case TYPE_DOUBLE_INDEX:
- return MH.filterArguments(primitiveSetter, 1, PACK_DOUBLE);
- default:
- return objectSetter;
- }
- case TYPE_DOUBLE_INDEX:
- if (ti == TYPE_OBJECT_INDEX) {
- return objectSetter;
- }
- return MH.asType(MH.filterArguments(primitiveSetter, 1, PACK_DOUBLE), pmt.changeParameterType(1, type));
- default:
- assert false;
- return null;
- }
- }
-
- //
- // Provide generic getters and setters for undefined types. If a type is undefined, all
- // and marshals the set to the correct setter depending on the type of the value being set.
- // Note that there are no actual undefined versions of int, long and double in JavaScript,
- // but executing toInt32, toLong and toNumber always returns a working result, 0, 0L or NaN
- //
-
- /** The value of Undefined cast to an int32 */
- public static final int UNDEFINED_INT = 0;
- /** The value of Undefined cast to a long */
- public static final long UNDEFINED_LONG = 0L;
- /** The value of Undefined cast to a double */
- public static final double UNDEFINED_DOUBLE = Double.NaN;
-
- /**
- * Compute type name for correct undefined getter
- * @param type the type
- * @return name of getter
- */
- private static String typeName(final Type type) {
- String name = type.getTypeClass().getName();
- final int dot = name.lastIndexOf('.');
- if (dot != -1) {
- name = name.substring(dot + 1);
- }
- return Character.toUpperCase(name.charAt(0)) + name.substring(1);
- }
-
- /**
- * Handles for undefined getters of the different types
- */
- private static final MethodHandle[] GET_UNDEFINED = new MethodHandle[ObjectClassGenerator.getNumberOfAccessorTypes()];
-
- /**
- * Used to wrap getters for undefined values, where this matters. Currently only in dual fields.
- * If an object starts out as undefined it needs special getters until it has been assigned
- * something the first time
- *
- * @param returnType type to cast the undefined to
- *
- * @return undefined as returnType
- */
- public static MethodHandle getUndefined(final Class<?> returnType) {
- return GET_UNDEFINED[ObjectClassGenerator.getAccessorTypeIndex(returnType)];
- }
-
- static {
- int pos = 0;
- for (final Type type : ACCESSOR_TYPES) {
- GET_UNDEFINED[pos++] = findOwnMH("getUndefined" + typeName(type), type.getTypeClass(), Object.class);
- }
- }
-
- @SuppressWarnings("unused")
- private static int getUndefinedInt(final Object obj) {
- return UNDEFINED_INT;
- }
-
- @SuppressWarnings("unused")
- private static long getUndefinedLong(final Object obj) {
- return UNDEFINED_LONG;
- }
-
- @SuppressWarnings("unused")
- private static double getUndefinedDouble(final Object obj) {
- return UNDEFINED_DOUBLE;
- }
-
- @SuppressWarnings("unused")
- private static Object getUndefinedObject(final Object obj) {
- return ScriptRuntime.UNDEFINED;
- }
-
- private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
- return MH.findStatic(MethodHandles.lookup(), ObjectClassGenerator.class, name, MH.type(rtype, types));
- }
-}
--- a/nashorn/src/jdk/nashorn/internal/codegen/objects/ObjectCreator.java Fri Feb 15 09:18:05 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-/*
- * 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.codegen.objects;
-
-import java.util.List;
-import jdk.nashorn.internal.codegen.CodeGenerator;
-import jdk.nashorn.internal.codegen.CompileUnit;
-import jdk.nashorn.internal.codegen.Compiler;
-import jdk.nashorn.internal.codegen.MethodEmitter;
-import jdk.nashorn.internal.ir.Symbol;
-import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.PropertyMap;
-
-/**
- * Base class for object creation code generation.
- */
-public abstract class ObjectCreator {
-
- /** Compile unit for this ObjectCreator, see CompileUnit */
- protected final CompileUnit compileUnit;
-
- /** List of keys to initiate in this ObjectCreator */
- protected final List<String> keys;
-
- /** List of symbols to initiate in this ObjectCreator */
- protected final List<Symbol> symbols;
-
- /** Code generator */
- protected final CodeGenerator codegen;
-
- private final boolean isScope;
- private final boolean hasArguments;
- private int fieldCount;
- private int paramCount;
- private String fieldObjectClassName;
- private Class<?> fieldObjectClass;
- private PropertyMap propertyMap;
-
- /**
- * Constructor
- *
- * @param codegen the code generator
- * @param keys the keys
- * @param symbols the symbols corresponding to keys, same index
- * @param isScope is this object scope
- * @param hasArguments does the created object have an "arguments" property
- */
- protected ObjectCreator(final CodeGenerator codegen, final List<String> keys, final List<Symbol> symbols, final boolean isScope, final boolean hasArguments) {
- this.codegen = codegen;
- this.compileUnit = codegen.getCurrentCompileUnit();
- this.keys = keys;
- this.symbols = symbols;
- this.isScope = isScope;
- this.hasArguments = hasArguments;
-
- countFields();
- findClass();
- }
-
- /**
- * Tally the number of fields and parameters.
- */
- private void countFields() {
- for (final Symbol symbol : this.symbols) {
- if (symbol != null) {
- if (hasArguments() && symbol.isParam()) {
- symbol.setFieldIndex(paramCount++);
- } else {
- symbol.setFieldIndex(fieldCount++);
- }
- }
- }
- }
-
- /**
- * Locate (or indirectly create) the object container class.
- */
- private void findClass() {
- fieldObjectClassName = isScope() ?
- ObjectClassGenerator.getClassName(fieldCount, paramCount) :
- ObjectClassGenerator.getClassName(fieldCount);
-
- try {
- this.fieldObjectClass = Context.forStructureClass(Compiler.binaryName(fieldObjectClassName));
- } catch (final ClassNotFoundException e) {
- throw new AssertionError("Nashorn has encountered an internal error. Structure can not be created.");
- }
- }
-
- /**
- * Generate code for making the object.
- * @param method Script method.
- */
- public abstract void makeObject(final MethodEmitter method);
-
- /**
- * Create a new MapCreator
- * @param clazz type of MapCreator
- * @return map creator instantiated by type
- */
- protected MapCreator newMapCreator(final Class<?> clazz) {
- return new MapCreator(clazz, keys, symbols);
- }
-
- /**
- * Construct the property map appropriate for the object.
- * @return the newly created property map
- */
- protected PropertyMap makeMap() {
- if (keys.isEmpty()) { //empty map
- propertyMap = PropertyMap.newMap(fieldObjectClass);
- } else {
- propertyMap = newMapCreator(fieldObjectClass).makeMap(hasArguments());
- }
- return propertyMap;
- }
-
- /**
- * Emit the correct map for the object.
- * @param method method emitter
- * @return the method emitter
- */
- protected MethodEmitter loadMap(final MethodEmitter method) {
- codegen.loadConstant(propertyMap);
- return method;
- }
-
- /**
- * Get the class name for the object class,
- * e.g. {@code com.nashorn.oracle.scripts.JO$2P0}
- *
- * @return script class name
- */
- public String getClassName() {
- return fieldObjectClassName;
- }
-
- /**
- * Is this a scope object
- * @return true if scope
- */
- protected boolean isScope() {
- return isScope;
- }
-
- /**
- * Does the created object have an "arguments" property
- * @return true if has an "arguments" property
- */
- protected boolean hasArguments() {
- return hasArguments;
- }
-}
--- a/nashorn/src/jdk/nashorn/internal/codegen/objects/ObjectMapCreator.java Fri Feb 15 09:18:05 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * 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.codegen.objects;
-
-import java.util.List;
-import jdk.nashorn.internal.ir.Symbol;
-import jdk.nashorn.internal.runtime.Property;
-
-/**
- * This map creator is used to guarantee that all properties start out as
- * object types. Only semantically significant in the -Dnashorn.fields.dual=true world,
- * where we want to avoid invalidation upon initialization e.g. for var x = {a:"str"};
- */
-
-public class ObjectMapCreator extends MapCreator {
- /**
- * Constructor
- *
- * @param structure structure for object class
- * @param keys keys in object
- * @param symbols symbols in object corresponding to keys
- */
- public ObjectMapCreator(final Class<?> structure, final List<String> keys, final List<Symbol> symbols) {
- super(structure, keys, symbols);
- }
-
- @Override
- protected int getPropertyFlags(final Symbol symbol, final boolean isVarArg) {
- return super.getPropertyFlags(symbol, isVarArg) | Property.IS_ALWAYS_OBJECT;
- }
-}
--- a/nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java Fri Feb 15 09:44:15 2013 +0100
@@ -59,7 +59,7 @@
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.nashorn.internal.codegen.CompilerConstants;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.runtime.JSType;
/**
--- a/nashorn/src/jdk/nashorn/internal/codegen/types/IntType.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/IntType.java Fri Feb 15 09:44:15 2013 +0100
@@ -55,7 +55,7 @@
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.nashorn.internal.codegen.CompilerConstants;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
/**
* Type class: INT
--- a/nashorn/src/jdk/nashorn/internal/codegen/types/LongType.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/LongType.java Fri Feb 15 09:44:15 2013 +0100
@@ -49,7 +49,7 @@
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.nashorn.internal.codegen.CompilerConstants;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
/**
* Type class: LONG
--- a/nashorn/src/jdk/nashorn/internal/codegen/types/NumberType.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/NumberType.java Fri Feb 15 09:44:15 2013 +0100
@@ -42,7 +42,7 @@
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.nashorn.internal.codegen.CompilerConstants;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.runtime.JSType;
class NumberType extends NumericType {
--- a/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -25,9 +25,9 @@
package jdk.nashorn.internal.ir;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.DEBUG_FIELDS;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Source;
--- a/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -60,7 +60,7 @@
*/
protected BaseNode(final BaseNode baseNode, final CopyState cs) {
super(baseNode);
- base = cs.existingOrCopy(baseNode.getBase());
+ this.base = cs.existingOrCopy(baseNode.getBase());
setStart(base.getStart());
}
--- a/nashorn/src/jdk/nashorn/internal/ir/Block.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/Block.java Fri Feb 15 09:44:15 2013 +0100
@@ -40,7 +40,7 @@
import java.util.HashMap;
import java.util.List;
import jdk.nashorn.internal.codegen.Frame;
-import jdk.nashorn.internal.codegen.MethodEmitter.Label;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.ir.annotations.Ignore;
import jdk.nashorn.internal.ir.annotations.ParentNode;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
@@ -94,7 +94,6 @@
this.function = function;
this.statements = new ArrayList<>();
this.symbols = new HashMap<>();
- this.frame = null;
this.entryLabel = new Label("block_entry");
this.breakLabel = new Label("block_break");
}
@@ -108,16 +107,16 @@
protected Block(final Block block, final CopyState cs) {
super(block);
- parent = block.parent;
- function = block.function;
- statements = new ArrayList<>();
+ this.parent = block.parent;
+ this.function = block.function;
+ this.statements = new ArrayList<>();
for (final Node statement : block.getStatements()) {
statements.add(cs.existingOrCopy(statement));
}
- symbols = new HashMap<>();
- frame = block.frame == null ? null : block.frame.copy();
- entryLabel = new Label(block.entryLabel);
- breakLabel = new Label(block.breakLabel);
+ this.symbols = new HashMap<>();
+ this.frame = block.frame == null ? null : block.frame.copy();
+ this.entryLabel = new Label(block.entryLabel);
+ this.breakLabel = new Label(block.breakLabel);
assert block.symbols.isEmpty() : "must not clone with symbols";
}
--- a/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -25,7 +25,7 @@
package jdk.nashorn.internal.ir;
-import jdk.nashorn.internal.codegen.MethodEmitter;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Source;
@@ -75,7 +75,7 @@
* Return the target label of this break node.
* @return the target label.
*/
- public MethodEmitter.Label getTargetLabel() {
+ public Label getTargetLabel() {
if (targetNode instanceof BreakableNode) {
return ((BreakableNode)targetNode).getBreakLabel();
} else if (targetNode instanceof Block) {
--- a/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -25,7 +25,7 @@
package jdk.nashorn.internal.ir;
-import jdk.nashorn.internal.codegen.MethodEmitter;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.runtime.Source;
/**
@@ -35,7 +35,7 @@
public abstract class BreakableNode extends Node {
/** break label. */
- protected MethodEmitter.Label breakLabel;
+ protected Label breakLabel;
/**
* Constructor
@@ -61,7 +61,7 @@
* Return the break label, i.e. the location to go to on break.
* @return the break label
*/
- public MethodEmitter.Label getBreakLabel() {
+ public Label getBreakLabel() {
return breakLabel;
}
--- a/nashorn/src/jdk/nashorn/internal/ir/CallNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/CallNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -164,10 +164,10 @@
newArgs.add(cs.existingOrCopy(arg));
}
- function = cs.existingOrCopy(callNode.function); //TODO existing or same?
- args = newArgs;
- isNew = callNode.isNew;
- inWithBlock = callNode.inWithBlock;
+ this.function = cs.existingOrCopy(callNode.function); //TODO existing or same?
+ this.args = newArgs;
+ this.isNew = callNode.isNew;
+ this.inWithBlock = callNode.inWithBlock;
}
--- a/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/CaseNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -25,7 +25,7 @@
package jdk.nashorn.internal.ir;
-import jdk.nashorn.internal.codegen.MethodEmitter.Label;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Source;
--- a/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -67,10 +67,10 @@
private CatchNode(final CatchNode catchNode, final CopyState cs) {
super(catchNode);
- exception = (IdentNode)cs.existingOrCopy(catchNode.exception);
- exceptionCondition = cs.existingOrCopy(catchNode.exceptionCondition);
- body = (Block)cs.existingOrCopy(catchNode.body);
- isSyntheticRethrow = catchNode.isSyntheticRethrow;
+ this.exception = (IdentNode)cs.existingOrCopy(catchNode.exception);
+ this.exceptionCondition = cs.existingOrCopy(catchNode.exceptionCondition);
+ this.body = (Block)cs.existingOrCopy(catchNode.body);
+ this.isSyntheticRethrow = catchNode.isSyntheticRethrow;
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -25,7 +25,7 @@
package jdk.nashorn.internal.ir;
-import jdk.nashorn.internal.codegen.MethodEmitter;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Source;
@@ -72,7 +72,7 @@
* Return the target label of this continue node.
* @return the target label.
*/
- public MethodEmitter.Label getTargetLabel() {
+ public Label getTargetLabel() {
assert targetNode instanceof WhileNode : "continue target must be a while node";
return ((WhileNode)targetNode).getContinueLabel();
}
--- a/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/IdentNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -28,9 +28,9 @@
import static jdk.nashorn.internal.codegen.CompilerConstants.__DIR__;
import static jdk.nashorn.internal.codegen.CompilerConstants.__FILE__;
import static jdk.nashorn.internal.codegen.CompilerConstants.__LINE__;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.DEBUG_FIELDS;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Source;
--- a/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/IndexNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -25,9 +25,9 @@
package jdk.nashorn.internal.ir;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.DEBUG_FIELDS;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Source;
--- a/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/LabelNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -68,10 +68,10 @@
private LabelNode(final LabelNode labelNode, final CopyState cs) {
super(labelNode);
- label = (IdentNode)cs.existingOrCopy(labelNode.label);
- body = (Block)cs.existingOrCopy(labelNode.body);
- breakNode = cs.existingOrSame(labelNode.breakNode);
- continueNode = cs.existingOrSame(labelNode.continueNode);
+ this.label = (IdentNode)cs.existingOrCopy(labelNode.label);
+ this.body = (Block)cs.existingOrCopy(labelNode.body);
+ this.breakNode = cs.existingOrSame(labelNode.breakNode);
+ this.continueNode = cs.existingOrSame(labelNode.continueNode);
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -53,7 +53,7 @@
private LineNumberNode(final LineNumberNode lineNumberNode) {
super(lineNumberNode);
- lineNumber = lineNumberNode.getLineNumber();
+ this.lineNumber = lineNumberNode.getLineNumber();
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -68,8 +68,8 @@
newElements.add(cs.existingOrCopy(element));
}
- context = (Block)cs.existingOrCopy(objectNode.context);
- elements = newElements;
+ this.context = (Block)cs.existingOrCopy(objectNode.context);
+ this.elements = newElements;
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -65,8 +65,8 @@
private ReturnNode(final ReturnNode returnNode, final CopyState cs) {
super(returnNode);
- expression = cs.existingOrCopy(returnNode.expression);
- tryChain = (TryNode)cs.existingOrSame(returnNode.tryChain);
+ this.expression = cs.existingOrCopy(returnNode.expression);
+ this.tryChain = (TryNode)cs.existingOrSame(returnNode.tryChain);
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/SplitNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -29,6 +29,7 @@
import java.util.Collections;
import java.util.List;
import jdk.nashorn.internal.codegen.CompileUnit;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.codegen.MethodEmitter;
import jdk.nashorn.internal.ir.annotations.Ignore;
import jdk.nashorn.internal.ir.annotations.Reference;
@@ -57,7 +58,7 @@
/** A list of target labels in parent methods this split node may encounter. */
@Ignore
- private final List<MethodEmitter.Label> externalTargets;
+ private final List<Label> externalTargets;
/** True if this split node or any of its children contain a return statement. */
private boolean hasReturn;
@@ -85,10 +86,10 @@
private SplitNode(final SplitNode splitNode, final CopyState cs) {
super(splitNode);
- name = splitNode.name;
- functionNode = (FunctionNode)cs.existingOrSame(splitNode.functionNode);
- body = cs.existingOrCopy(splitNode.body);
- externalTargets = new ArrayList<>();
+ this.name = splitNode.name;
+ this.functionNode = (FunctionNode)cs.existingOrSame(splitNode.functionNode);
+ this.body = cs.existingOrCopy(splitNode.body);
+ this.externalTargets = new ArrayList<>();
}
@Override
@@ -196,7 +197,7 @@
* Get the external targets for this SplitNode
* @return list of external targets
*/
- public List<MethodEmitter.Label> getExternalTargets() {
+ public List<Label> getExternalTargets() {
return Collections.unmodifiableList(externalTargets);
}
@@ -204,7 +205,7 @@
* Add an external target for this SplitNode
* @param targetLabel target label
*/
- public void addExternalTarget(final MethodEmitter.Label targetLabel) {
+ public void addExternalTarget(final Label targetLabel) {
externalTargets.add(targetLabel);
}
--- a/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -28,7 +28,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import jdk.nashorn.internal.codegen.MethodEmitter.Label;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.ir.annotations.Ignore;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Source;
@@ -59,12 +59,7 @@
*/
public SwitchNode(final Source source, final long token, final int finish) {
super(source, token, finish);
-
- expression = null;
- tag = null;
- cases = null;
- defaultCase = null;
- breakLabel = new Label("switch_break");
+ this.breakLabel = new Label("switch_break");
}
private SwitchNode(final SwitchNode switchNode, final CopyState cs) {
@@ -76,11 +71,11 @@
newCases.add((CaseNode)cs.existingOrCopy(caseNode));
}
- expression = cs.existingOrCopy(switchNode.getExpression());
- tag = switchNode.getTag();
- cases = newCases;
- defaultCase = (CaseNode)cs.existingOrCopy(switchNode.getDefaultCase());
- breakLabel = new Label(switchNode.getBreakLabel());
+ this.expression = cs.existingOrCopy(switchNode.getExpression());
+ this.tag = switchNode.getTag();
+ this.cases = newCases;
+ this.defaultCase = (CaseNode)cs.existingOrCopy(switchNode.getDefaultCase());
+ this.breakLabel = new Label(switchNode.getBreakLabel());
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -60,8 +60,8 @@
private ThrowNode(final ThrowNode throwNode, final CopyState cs) {
super(throwNode);
- expression = cs.existingOrCopy(throwNode.expression);
- tryChain = (TryNode)cs.existingOrSame(throwNode.tryChain);
+ this.expression = cs.existingOrCopy(throwNode.expression);
+ this.tryChain = (TryNode)cs.existingOrSame(throwNode.tryChain);
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/ir/TryNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/TryNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -28,7 +28,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import jdk.nashorn.internal.codegen.MethodEmitter.Label;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.ir.annotations.Ignore;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Source;
--- a/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -67,7 +67,7 @@
protected UnaryNode(final UnaryNode unaryNode, final CopyState cs) {
super(unaryNode);
- rhs = cs.existingOrCopy(unaryNode.rhs);
+ this.rhs = cs.existingOrCopy(unaryNode.rhs);
}
/**
--- a/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/WhileNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -25,7 +25,7 @@
package jdk.nashorn.internal.ir;
-import jdk.nashorn.internal.codegen.MethodEmitter.Label;
+import jdk.nashorn.internal.codegen.Label;
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
import jdk.nashorn.internal.runtime.Source;
@@ -53,10 +53,8 @@
public WhileNode(final Source source, final long token, final int finish) {
super(source, token, finish);
- test = null;
- body = null;
- breakLabel = new Label("while_break");
- continueLabel = new Label("while_continue");
+ this.breakLabel = new Label("while_break");
+ this.continueLabel = new Label("while_continue");
}
/**
@@ -68,10 +66,10 @@
protected WhileNode(final WhileNode whileNode, final CopyState cs) {
super(whileNode);
- test = cs.existingOrCopy(whileNode.test);
- body = (Block)cs.existingOrCopy(whileNode.body);
- breakLabel = new Label(whileNode.breakLabel);
- continueLabel = new Label(whileNode.continueLabel);
+ this.test = cs.existingOrCopy(whileNode.test);
+ this.body = (Block)cs.existingOrCopy(whileNode.body);
+ this.breakLabel = new Label(whileNode.breakLabel);
+ this.continueLabel = new Label(whileNode.continueLabel);
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/ir/WithNode.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/ir/WithNode.java Fri Feb 15 09:44:15 2013 +0100
@@ -57,8 +57,8 @@
private WithNode(final WithNode withNode, final CopyState cs) {
super(withNode);
- expression = cs.existingOrCopy(withNode.expression);
- body = (Block)cs.existingOrCopy(withNode.body);
+ this.expression = cs.existingOrCopy(withNode.expression);
+ this.body = (Block)cs.existingOrCopy(withNode.body);
}
@Override
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java Fri Feb 15 09:44:15 2013 +0100
@@ -203,8 +203,7 @@
}
/**
- * External constructor used in generated code created by {@link jdk.nashorn.internal.codegen.CodeGenerator}, which
- * explain the {@code public} access.
+ * External constructor used in generated code, which explains the public access
*
* @param regexp regexp
* @param flags flags
--- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java Fri Feb 15 09:44:15 2013 +0100
@@ -94,7 +94,6 @@
/**
* Constructor called by (compiler) generated code for {@link ScriptObject}s.
- * Code is generated by {@link jdk.nashorn.internal.codegen.CodeGenerator#newFunctionObject}
*
* @param data static function data
* @param methodHandle handle for invocation
--- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java Fri Feb 15 09:44:15 2013 +0100
@@ -25,24 +25,24 @@
package jdk.nashorn.internal.runtime;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.ACCESSOR_TYPES;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.DEBUG_FIELDS;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.LOG;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.PRIMITIVE_TYPE;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.createGetter;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.createGuardBoxedPrimitiveSetter;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.createSetter;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.getAccessorType;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.getAccessorTypeIndex;
-import static jdk.nashorn.internal.codegen.objects.ObjectClassGenerator.getNumberOfAccessorTypes;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.ACCESSOR_TYPES;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.LOG;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.PRIMITIVE_TYPE;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createGetter;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createGuardBoxedPrimitiveSetter;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createSetter;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getAccessorType;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getAccessorTypeIndex;
+import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getNumberOfAccessorTypes;
import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
import static jdk.nashorn.internal.runtime.linker.MethodHandleFactory.stripName;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.runtime.linker.Lookup;
import jdk.nashorn.internal.runtime.linker.MethodHandleFactory;
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java Fri Feb 15 09:44:15 2013 +0100
@@ -51,8 +51,9 @@
import jdk.nashorn.internal.codegen.ClassEmitter;
import jdk.nashorn.internal.codegen.Compiler;
import jdk.nashorn.internal.codegen.Namespace;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.debug.ASTWriter;
import jdk.nashorn.internal.ir.debug.PrintVisitor;
import jdk.nashorn.internal.parser.Parser;
import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
@@ -917,7 +918,11 @@
return null;
}
- if (_print_lower_parse) {
+ if (_print_ast) {
+ getErr().println(new ASTWriter(functionNode));
+ }
+
+ if (_print_parse) {
getErr().println(new PrintVisitor(functionNode));
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java Fri Feb 15 09:44:15 2013 +0100
@@ -46,7 +46,6 @@
public final class ECMAException extends NashornException {
/**
* Method handle pointing to the constructor {@link ECMAException#ECMAException(Object, String, int, int)},
- * used from {@link jdk.nashorn.internal.codegen.CodeGenerator}
*/
public static final Call THROW_INIT = constructorNoLookup(ECMAException.class, Object.class, String.class, int.class, int.class);
--- a/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java Fri Feb 15 09:44:15 2013 +0100
@@ -28,7 +28,7 @@
import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
import java.lang.invoke.MethodHandle;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
/**
* This class represents the result from a find property search.
--- a/nashorn/src/jdk/nashorn/internal/runtime/Property.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java Fri Feb 15 09:44:15 2013 +0100
@@ -31,7 +31,7 @@
import java.lang.invoke.MethodHandle;
import java.util.Objects;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.codegen.types.Type;
/**
--- a/nashorn/src/jdk/nashorn/internal/runtime/Scope.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Scope.java Fri Feb 15 09:44:15 2013 +0100
@@ -27,7 +27,6 @@
import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
-import jdk.nashorn.internal.codegen.CodeGenerator;
import jdk.nashorn.internal.codegen.CompilerConstants;
/**
@@ -35,10 +34,10 @@
*/
public interface Scope {
- /** Method handle that points to {@link Scope#getSplitState}. Used by {@link CodeGenerator} */
+ /** Method handle that points to {@link Scope#getSplitState}. */
public static final CompilerConstants.Call GET_SPLIT_STATE = interfaceCallNoLookup(Scope.class, "getSplitState", int.class);
- /** Method handle that points to {@link Scope#setSplitState(int)}. Used by {@link CodeGenerator} */
+ /** Method handle that points to {@link Scope#setSplitState(int)}. */
public static final CompilerConstants.Call SET_SPLIT_STATE = interfaceCallNoLookup(Scope.class, "setSplitState", void.class, int.class);
/**
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Feb 15 09:44:15 2013 +0100
@@ -60,7 +60,7 @@
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.objects.AccessorPropertyDescriptor;
import jdk.nashorn.internal.objects.DataPropertyDescriptor;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
@@ -144,13 +144,13 @@
/** Method handle for setting a function argument at a given index. Used from MapCreator */
public static final Call SET_ARGUMENT = virtualCall(ScriptObject.class, "setArgument", void.class, int.class, Object.class);
- /** Method handle for getting the proto of a ScriptObject - used by {@link jdk.nashorn.internal.codegen.CodeGenerator} */
+ /** Method handle for getting the proto of a ScriptObject */
public static final Call GET_PROTO = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class);
- /** Method handle for setting the proto of a ScriptObject - used by {@link jdk.nashorn.internal.codegen.CodeGenerator} */
+ /** Method handle for setting the proto of a ScriptObject */
public static final Call SET_PROTO = virtualCallNoLookup(ScriptObject.class, "setProto", void.class, ScriptObject.class);
- /** Method handle for setting the user accessors of a ScriptObject - used by {@link jdk.nashorn.internal.codegen.CodeGenerator} */
+ /** Method handle for setting the user accessors of a ScriptObject */
public static final Call SET_USER_ACCESSORS = virtualCall(ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
/** Method handle for getter for {@link UserAccessorProperty}, given a slot */
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Fri Feb 15 09:44:15 2013 +0100
@@ -71,27 +71,25 @@
/** Method handle to generic === operator, operating on objects */
public static final Call EQ_STRICT = staticCallNoLookup(ScriptRuntime.class, "EQ_STRICT", boolean.class, Object.class, Object.class);
- /** Method handle used to enter a {@code with} scope at runtime. Used from {@link jdk.nashorn.internal.codegen.CodeGenerator} */
+ /** Method handle used to enter a {@code with} scope at runtime. */
public static final Call OPEN_WITH = staticCallNoLookup(ScriptRuntime.class, "openWith", ScriptObject.class, ScriptObject.class, Object.class);
- /** Method handle used to exit a {@code with} scope at runtime. Used from {@link jdk.nashorn.internal.codegen.CodeGenerator} */
+ /** Method handle used to exit a {@code with} scope at runtime. */
public static final Call CLOSE_WITH = staticCallNoLookup(ScriptRuntime.class, "closeWith", ScriptObject.class, ScriptObject.class);
/**
* Method used to place a scope's variable into the Global scope, which has to be done for the
- * properties declared at outermost script level. Used from {@link jdk.nashorn.internal.codegen.CodeGenerator}
+ * properties declared at outermost script level.
*/
public static final Call MERGE_SCOPE = staticCallNoLookup(ScriptRuntime.class, "mergeScope", ScriptObject.class, ScriptObject.class);
/**
* Return an appropriate iterator for the elements in a for-in construct
- * Used from {@link jdk.nashorn.internal.codegen.CodeGenerator}
*/
public static final Call TO_PROPERTY_ITERATOR = staticCallNoLookup(ScriptRuntime.class, "toPropertyIterator", Iterator.class, Object.class);
/**
* Return an appropriate iterator for the elements in a for-each construct
- * Used from {@link jdk.nashorn.internal.codegen.CodeGenerator}
*/
public static final Call TO_VALUE_ITERATOR = staticCallNoLookup(ScriptRuntime.class, "toValueIterator", Iterator.class, Object.class);
--- a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Fri Feb 15 09:44:15 2013 +0100
@@ -31,7 +31,7 @@
import java.lang.invoke.MethodHandle;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.runtime.linker.Lookup;
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
import jdk.nashorn.internal.runtime.linker.NashornGuards;
--- a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java Fri Feb 15 09:18:05 2013 +0100
+++ b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java Fri Feb 15 09:44:15 2013 +0100
@@ -38,7 +38,7 @@
import java.security.CodeSource;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import jdk.nashorn.internal.codegen.objects.ObjectClassGenerator;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
/**
* Responsible for on the fly construction of structure classes as well