nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java
changeset 28320 bbf9cfde97f6
parent 27977 42799be30dcd
child 28690 78317797ab62
equal deleted inserted replaced
28319:95bed8b1847f 28320:bbf9cfde97f6
    36 import static jdk.nashorn.internal.codegen.CompilerConstants.REGEX_PREFIX;
    36 import static jdk.nashorn.internal.codegen.CompilerConstants.REGEX_PREFIX;
    37 import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
    37 import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
    38 import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX;
    38 import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX;
    39 import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
    39 import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
    40 import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
    40 import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
    41 import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
       
    42 import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
    41 import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
    43 import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
    42 import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
    44 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
    43 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
    45 import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
    44 import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
    46 import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
    45 import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
   184 
   183 
   185     private static final Type SCOPE_TYPE = Type.typeFor(ScriptObject.class);
   184     private static final Type SCOPE_TYPE = Type.typeFor(ScriptObject.class);
   186 
   185 
   187     private static final String GLOBAL_OBJECT = Type.getInternalName(Global.class);
   186     private static final String GLOBAL_OBJECT = Type.getInternalName(Global.class);
   188 
   187 
   189     private static final String SCRIPTFUNCTION_IMPL_NAME = Type.getInternalName(ScriptFunctionImpl.class);
       
   190     private static final Type   SCRIPTFUNCTION_IMPL_TYPE   = Type.typeFor(ScriptFunction.class);
       
   191 
       
   192     private static final Call CREATE_REWRITE_EXCEPTION = CompilerConstants.staticCallNoLookup(RewriteException.class,
   188     private static final Call CREATE_REWRITE_EXCEPTION = CompilerConstants.staticCallNoLookup(RewriteException.class,
   193             "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class);
   189             "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class);
   194     private static final Call CREATE_REWRITE_EXCEPTION_REST_OF = CompilerConstants.staticCallNoLookup(RewriteException.class,
   190     private static final Call CREATE_REWRITE_EXCEPTION_REST_OF = CompilerConstants.staticCallNoLookup(RewriteException.class,
   195             "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class, int[].class);
   191             "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class, int[].class);
   196 
   192 
   198             "ensureInt", int.class, Object.class, int.class);
   194             "ensureInt", int.class, Object.class, int.class);
   199     private static final Call ENSURE_LONG = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
   195     private static final Call ENSURE_LONG = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
   200             "ensureLong", long.class, Object.class, int.class);
   196             "ensureLong", long.class, Object.class, int.class);
   201     private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
   197     private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
   202             "ensureNumber", double.class, Object.class, int.class);
   198             "ensureNumber", double.class, Object.class, int.class);
       
   199 
       
   200     private static final Call CREATE_FUNCTION_OBJECT = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
       
   201             "create", ScriptFunction.class, Object[].class, int.class, ScriptObject.class);
       
   202     private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunctionImpl.class,
       
   203             "create", ScriptFunction.class, Object[].class, int.class);
   203 
   204 
   204     private static final Class<?> ITERATOR_CLASS = Iterator.class;
   205     private static final Class<?> ITERATOR_CLASS = Iterator.class;
   205     static {
   206     static {
   206         assert ITERATOR_CLASS == CompilerConstants.ITERATOR_PREFIX.type();
   207         assert ITERATOR_CLASS == CompilerConstants.ITERATOR_PREFIX.type();
   207     }
   208     }
  2240             methodEmitter.invokestatic(unitClassName, methodName, methodDescriptor(cls, int.class));
  2241             methodEmitter.invokestatic(unitClassName, methodName, methodDescriptor(cls, int.class));
  2241             classEmitter.needGetConstantMethod(cls);
  2242             classEmitter.needGetConstantMethod(cls);
  2242         } else {
  2243         } else {
  2243             methodEmitter.loadConstants().load(index).arrayload();
  2244             methodEmitter.loadConstants().load(index).arrayload();
  2244             if (object instanceof ArrayData) {
  2245             if (object instanceof ArrayData) {
  2245                 // avoid cast to non-public ArrayData subclass
       
  2246                 methodEmitter.checkcast(ArrayData.class);
  2246                 methodEmitter.checkcast(ArrayData.class);
  2247                 methodEmitter.invoke(virtualCallNoLookup(ArrayData.class, "copy", ArrayData.class));
  2247                 methodEmitter.invoke(virtualCallNoLookup(ArrayData.class, "copy", ArrayData.class));
  2248             } else if (cls != Object.class) {
  2248             } else if (cls != Object.class) {
  2249                 methodEmitter.checkcast(cls);
  2249                 methodEmitter.checkcast(cls);
  2250             }
  2250             }
  2251         }
  2251         }
       
  2252     }
       
  2253 
       
  2254     private void loadConstantsAndIndex(final Object object, final MethodEmitter methodEmitter) {
       
  2255         methodEmitter.loadConstants().load(compiler.getConstantData().add(object));
  2252     }
  2256     }
  2253 
  2257 
  2254     // literal values
  2258     // literal values
  2255     private void loadLiteral(final LiteralNode<?> node, final TypeBounds resultBounds) {
  2259     private void loadLiteral(final LiteralNode<?> node, final TypeBounds resultBounds) {
  2256         final Object value = node.getValue();
  2260         final Object value = node.getValue();
  4321         assert lc.peek() == functionNode;
  4325         assert lc.peek() == functionNode;
  4322 
  4326 
  4323         final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(functionNode.getId());
  4327         final RecompilableScriptFunctionData data = compiler.getScriptFunctionData(functionNode.getId());
  4324 
  4328 
  4325         if (functionNode.isProgram() && !compiler.isOnDemandCompilation()) {
  4329         if (functionNode.isProgram() && !compiler.isOnDemandCompilation()) {
  4326             final CompileUnit fnUnit = functionNode.getCompileUnit();
  4330             final MethodEmitter createFunction = functionNode.getCompileUnit().getClassEmitter().method(
  4327             final MethodEmitter createFunction = fnUnit.getClassEmitter().method(
       
  4328                     EnumSet.of(Flag.PUBLIC, Flag.STATIC), CREATE_PROGRAM_FUNCTION.symbolName(),
  4331                     EnumSet.of(Flag.PUBLIC, Flag.STATIC), CREATE_PROGRAM_FUNCTION.symbolName(),
  4329                     ScriptFunction.class, ScriptObject.class);
  4332                     ScriptFunction.class, ScriptObject.class);
  4330             createFunction.begin();
  4333             createFunction.begin();
  4331             createFunction._new(SCRIPTFUNCTION_IMPL_NAME, SCRIPTFUNCTION_IMPL_TYPE).dup();
  4334             loadConstantsAndIndex(data, createFunction);
  4332             loadConstant(data, fnUnit, createFunction);
       
  4333             createFunction.load(SCOPE_TYPE, 0);
  4335             createFunction.load(SCOPE_TYPE, 0);
  4334             createFunction.invoke(constructorNoLookup(SCRIPTFUNCTION_IMPL_NAME, RecompilableScriptFunctionData.class, ScriptObject.class));
  4336             createFunction.invoke(CREATE_FUNCTION_OBJECT);
  4335             createFunction._return();
  4337             createFunction._return();
  4336             createFunction.end();
  4338             createFunction.end();
  4337         }
  4339         }
  4338 
  4340 
  4339         if (addInitializer && !compiler.isOnDemandCompilation()) {
  4341         if (addInitializer && !compiler.isOnDemandCompilation()) {
  4344         // generated in its outer context that'd need it as a callee).
  4346         // generated in its outer context that'd need it as a callee).
  4345         if (lc.getOutermostFunction() == functionNode) {
  4347         if (lc.getOutermostFunction() == functionNode) {
  4346             return;
  4348             return;
  4347         }
  4349         }
  4348 
  4350 
  4349         method._new(SCRIPTFUNCTION_IMPL_NAME, SCRIPTFUNCTION_IMPL_TYPE).dup();
  4351         loadConstantsAndIndex(data, method);
  4350         loadConstant(data);
       
  4351 
  4352 
  4352         if (functionNode.needsParentScope()) {
  4353         if (functionNode.needsParentScope()) {
  4353             method.loadCompilerConstant(SCOPE);
  4354             method.loadCompilerConstant(SCOPE);
       
  4355             method.invoke(CREATE_FUNCTION_OBJECT);
  4354         } else {
  4356         } else {
  4355             method.loadNull();
  4357             method.invoke(CREATE_FUNCTION_OBJECT_NO_SCOPE);
  4356         }
  4358         }
  4357         method.invoke(constructorNoLookup(SCRIPTFUNCTION_IMPL_NAME, RecompilableScriptFunctionData.class, ScriptObject.class));
       
  4358     }
  4359     }
  4359 
  4360 
  4360     // calls on Global class.
  4361     // calls on Global class.
  4361     private MethodEmitter globalInstance() {
  4362     private MethodEmitter globalInstance() {
  4362         return method.invokestatic(GLOBAL_OBJECT, "instance", "()L" + GLOBAL_OBJECT + ';');
  4363         return method.invokestatic(GLOBAL_OBJECT, "instance", "()L" + GLOBAL_OBJECT + ';');