nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java
changeset 32781 d8f34ffbbc7a
parent 30390 357f9a3f9394
child 34732 6605efbe8447
equal deleted inserted replaced
32712:f61a63b7d1e5 32781:d8f34ffbbc7a
    32 import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getFieldName;
    32 import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getFieldName;
    33 import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getPaddedFieldCount;
    33 import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getPaddedFieldCount;
    34 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
    34 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
    35 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
    35 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
    36 
    36 
    37 import java.util.Iterator;
       
    38 import java.util.List;
    37 import java.util.List;
    39 import jdk.nashorn.internal.codegen.types.Type;
    38 import jdk.nashorn.internal.codegen.types.Type;
    40 import jdk.nashorn.internal.ir.Symbol;
    39 import jdk.nashorn.internal.ir.Symbol;
    41 import jdk.nashorn.internal.runtime.Context;
    40 import jdk.nashorn.internal.runtime.Context;
    42 import jdk.nashorn.internal.runtime.JSType;
    41 import jdk.nashorn.internal.runtime.JSType;
    89         this.evalCode = codegen.isEvalCode();
    88         this.evalCode = codegen.isEvalCode();
    90         countFields();
    89         countFields();
    91         findClass();
    90         findClass();
    92     }
    91     }
    93 
    92 
    94     /**
    93     @Override
    95      * Construct an object.
    94     public void createObject(final MethodEmitter method) {
    96      *
       
    97      * @param method the method emitter
       
    98      */
       
    99     @Override
       
   100     protected void makeObject(final MethodEmitter method) {
       
   101         makeMap();
    95         makeMap();
   102         final String className = getClassName();
    96         final String className = getClassName();
   103         try {
    97         // NOTE: we must load the actual structure class here, because the API operates with Nashorn Type objects,
   104             // NOTE: we must load the actual structure class here, because the API operates with Nashorn Type objects,
    98         // and Type objects need a loaded class, for better or worse. We also have to be specific and use the type
   105             // and Type objects need a loaded class, for better or worse. We also have to be specific and use the type
    99         // of the actual structure class, we can't generalize it to e.g. Type.typeFor(ScriptObject.class) as the
   106             // of the actual structure class, we can't generalize it to e.g. Type.typeFor(ScriptObject.class) as the
   100         // exact type information is needed for generating continuations in rest-of methods. If we didn't do this,
   107             // exact type information is needed for generating continuations in rest-of methods. If we didn't do this,
   101         // object initializers like { x: arr[i] } would fail during deoptimizing compilation on arr[i], as the
   108             // object initializers like { x: arr[i] } would fail during deoptimizing compilation on arr[i], as the
   102         // values restored from the RewriteException would be cast to "ScriptObject" instead of to e.g. "JO4", and
   109             // values restored from the RewriteException would be cast to "ScriptObject" instead of to e.g. "JO4", and
   103         // subsequently the "PUTFIELD J04.L0" instruction in the continuation code would fail bytecode verification.
   110             // subsequently the "PUTFIELD J04.L0" instruction in the continuation code would fail bytecode verification.
   104         assert fieldObjectClass != null;
   111             method._new(Context.forStructureClass(className.replace('/', '.'))).dup();
   105         method._new(fieldObjectClass).dup();
   112         } catch (final ClassNotFoundException e) {
   106 
   113             throw new AssertionError(e);
       
   114         }
       
   115         loadMap(method); //load the map
   107         loadMap(method); //load the map
   116 
   108 
   117         if (isScope()) {
   109         if (isScope()) {
   118             loadScope(method);
   110             loadScope(method);
   119 
   111 
   124                 method.invoke(constructorNoLookup(className, PropertyMap.class, ScriptObject.class));
   116                 method.invoke(constructorNoLookup(className, PropertyMap.class, ScriptObject.class));
   125             }
   117             }
   126         } else {
   118         } else {
   127             method.invoke(constructorNoLookup(className, PropertyMap.class));
   119             method.invoke(constructorNoLookup(className, PropertyMap.class));
   128         }
   120         }
   129 
   121     }
   130         helpOptimisticRecognizeDuplicateIdentity(method);
   122 
   131 
   123     @Override
       
   124     public void populateRange(final MethodEmitter method, final Type objectType, final int objectSlot, final int start, final int end) {
       
   125         method.load(objectType, objectSlot);
   132         // Set values.
   126         // Set values.
   133         final Iterator<MapTuple<T>> iter = tuples.iterator();
   127         for (int i = start; i < end; i++) {
   134 
   128             final MapTuple<T> tuple = tuples.get(i);
   135         while (iter.hasNext()) {
       
   136             final MapTuple<T> tuple = iter.next();
       
   137             //we only load when we have both symbols and values (which can be == the symbol)
   129             //we only load when we have both symbols and values (which can be == the symbol)
   138             //if we didn't load, we need an array property
   130             //if we didn't load, we need an array property
   139             if (tuple.symbol != null && tuple.value != null) {
   131             if (tuple.symbol != null && tuple.value != null) {
   140                 final int index = getArrayIndex(tuple.key);
   132                 final int index = getArrayIndex(tuple.key);
   141                 method.dup();
   133                 method.dup();
   210         } catch (final ClassNotFoundException e) {
   202         } catch (final ClassNotFoundException e) {
   211             throw new AssertionError("Nashorn has encountered an internal error.  Structure can not be created.");
   203             throw new AssertionError("Nashorn has encountered an internal error.  Structure can not be created.");
   212         }
   204         }
   213     }
   205     }
   214 
   206 
       
   207     @Override
       
   208     protected Class<? extends ScriptObject> getAllocatorClass() {
       
   209         return fieldObjectClass;
       
   210     }
       
   211 
   215     /**
   212     /**
   216      * Get the class name for the object class,
   213      * Get the class name for the object class,
   217      * e.g. {@code com.nashorn.oracle.scripts.JO2P0}
   214      * e.g. {@code com.nashorn.oracle.scripts.JO2P0}
   218      *
   215      *
   219      * @return script class name
   216      * @return script class name