src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java

Print this page




 326             if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD && !isOptimisticOrRestOf()) {
 327                 method.loadCompilerConstant(SCOPE);
 328                 // As shared scope vars are only used in non-optimistic compilation, we switch from using TypeBounds to
 329                 // just a single definitive type, resultBounds.widest.
 330                 loadSharedScopeVar(resultBounds.widest, symbol, flags);
 331             } else {
 332                 new LoadFastScopeVar(identNode, resultBounds, flags).emit();
 333             }
 334         } else {
 335             //slow scope load, we have no proto depth
 336             new LoadScopeVar(identNode, resultBounds, flags).emit();
 337         }
 338 
 339         return method;
 340     }
 341 
 342     // Any access to LET and CONST variables before their declaration must throw ReferenceError.
 343     // This is called the temporal dead zone (TDZ). See https://gist.github.com/rwaldron/f0807a758aa03bcdd58a
 344     private void checkTemporalDeadZone(final IdentNode identNode) {
 345         if (identNode.isDead()) {
 346             method.load(identNode.getSymbol().getName());
 347             method.invoke(ScriptRuntime.THROW_REFERENCE_ERROR);






 348         }
 349     }
 350 
 351     private boolean isRestOf() {
 352         return continuationEntryPoints != null;
 353     }
 354 
 355     private boolean isOptimisticOrRestOf() {
 356         return useOptimisticTypes() || isRestOf();
 357     }
 358 
 359     private boolean isCurrentContinuationEntryPoint(final int programPoint) {
 360         return isRestOf() && getCurrentContinuationEntryPoint() == programPoint;
 361     }
 362 
 363     private int[] getContinuationEntryPoints() {
 364         return isRestOf() ? continuationEntryPoints : null;
 365     }
 366 
 367     private int getCurrentContinuationEntryPoint() {


 770                 }.emit(baseAlreadyOnStack ? 2 : 0);
 771                 return false;
 772             }
 773 
 774             @Override
 775             public boolean enterFunctionNode(final FunctionNode functionNode) {
 776                 // function nodes will always leave a constructed function object on stack, no need to load the symbol
 777                 // separately as in enterDefault()
 778                 lc.pop(functionNode);
 779                 functionNode.accept(codegen);
 780                 // NOTE: functionNode.accept() will produce a different FunctionNode that we discard. This incidentally
 781                 // doesn't cause problems as we're never touching FunctionNode again after it's visited here - codegen
 782                 // is the last element in the compilation pipeline, the AST it produces is not used externally. So, we
 783                 // re-push the original functionNode.
 784                 lc.push(functionNode);
 785                 return false;
 786             }
 787 
 788             @Override
 789             public boolean enterASSIGN(final BinaryNode binaryNode) {

 790                 loadASSIGN(binaryNode);
 791                 return false;
 792             }
 793 
 794             @Override
 795             public boolean enterASSIGN_ADD(final BinaryNode binaryNode) {

 796                 loadASSIGN_ADD(binaryNode);
 797                 return false;
 798             }
 799 
 800             @Override
 801             public boolean enterASSIGN_BIT_AND(final BinaryNode binaryNode) {

 802                 loadASSIGN_BIT_AND(binaryNode);
 803                 return false;
 804             }
 805 
 806             @Override
 807             public boolean enterASSIGN_BIT_OR(final BinaryNode binaryNode) {

 808                 loadASSIGN_BIT_OR(binaryNode);
 809                 return false;
 810             }
 811 
 812             @Override
 813             public boolean enterASSIGN_BIT_XOR(final BinaryNode binaryNode) {

 814                 loadASSIGN_BIT_XOR(binaryNode);
 815                 return false;
 816             }
 817 
 818             @Override
 819             public boolean enterASSIGN_DIV(final BinaryNode binaryNode) {

 820                 loadASSIGN_DIV(binaryNode);
 821                 return false;
 822             }
 823 
 824             @Override
 825             public boolean enterASSIGN_MOD(final BinaryNode binaryNode) {

 826                 loadASSIGN_MOD(binaryNode);
 827                 return false;
 828             }
 829 
 830             @Override
 831             public boolean enterASSIGN_MUL(final BinaryNode binaryNode) {

 832                 loadASSIGN_MUL(binaryNode);
 833                 return false;
 834             }
 835 
 836             @Override
 837             public boolean enterASSIGN_SAR(final BinaryNode binaryNode) {

 838                 loadASSIGN_SAR(binaryNode);
 839                 return false;
 840             }
 841 
 842             @Override
 843             public boolean enterASSIGN_SHL(final BinaryNode binaryNode) {

 844                 loadASSIGN_SHL(binaryNode);
 845                 return false;
 846             }
 847 
 848             @Override
 849             public boolean enterASSIGN_SHR(final BinaryNode binaryNode) {

 850                 loadASSIGN_SHR(binaryNode);
 851                 return false;
 852             }
 853 
 854             @Override
 855             public boolean enterASSIGN_SUB(final BinaryNode binaryNode) {

 856                 loadASSIGN_SUB(binaryNode);
 857                 return false;
 858             }
 859 
 860             @Override
 861             public boolean enterCallNode(final CallNode callNode) {
 862                 return loadCallNode(callNode, resultBounds);
 863             }
 864 
 865             @Override
 866             public boolean enterLiteralNode(final LiteralNode<?> literalNode) {
 867                 loadLiteral(literalNode, resultBounds);
 868                 return false;
 869             }
 870 
 871             @Override
 872             public boolean enterTernaryNode(final TernaryNode ternaryNode) {
 873                 loadTernaryNode(ternaryNode, resultBounds);
 874                 return false;
 875             }


1045             @Override
1046             public boolean enterObjectNode(final ObjectNode objectNode) {
1047                 loadObjectNode(objectNode);
1048                 return false;
1049             }
1050 
1051             @Override
1052             public boolean enterRuntimeNode(final RuntimeNode runtimeNode) {
1053                 loadRuntimeNode(runtimeNode);
1054                 return false;
1055             }
1056 
1057             @Override
1058             public boolean enterNEW(final UnaryNode unaryNode) {
1059                 loadNEW(unaryNode);
1060                 return false;
1061             }
1062 
1063             @Override
1064             public boolean enterDECINC(final UnaryNode unaryNode) {

1065                 loadDECINC(unaryNode);
1066                 return false;
1067             }
1068 
1069             @Override
1070             public boolean enterJoinPredecessorExpression(final JoinPredecessorExpression joinExpr) {
1071                 loadExpression(joinExpr.getExpression(), resultBounds);
1072                 return false;
1073             }
1074 
1075             @Override
1076             public boolean enterGetSplitState(final GetSplitState getSplitState) {
1077                 method.loadScope();
1078                 method.invoke(Scope.GET_SPLIT_STATE);
1079                 return false;
1080             }
1081 
1082             @Override
1083             public boolean enterDefault(final Node otherNode) {
1084                 // Must have handled all expressions that can legally be encountered.




 326             if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD && !isOptimisticOrRestOf()) {
 327                 method.loadCompilerConstant(SCOPE);
 328                 // As shared scope vars are only used in non-optimistic compilation, we switch from using TypeBounds to
 329                 // just a single definitive type, resultBounds.widest.
 330                 loadSharedScopeVar(resultBounds.widest, symbol, flags);
 331             } else {
 332                 new LoadFastScopeVar(identNode, resultBounds, flags).emit();
 333             }
 334         } else {
 335             //slow scope load, we have no proto depth
 336             new LoadScopeVar(identNode, resultBounds, flags).emit();
 337         }
 338 
 339         return method;
 340     }
 341 
 342     // Any access to LET and CONST variables before their declaration must throw ReferenceError.
 343     // This is called the temporal dead zone (TDZ). See https://gist.github.com/rwaldron/f0807a758aa03bcdd58a
 344     private void checkTemporalDeadZone(final IdentNode identNode) {
 345         if (identNode.isDead()) {
 346             method.load(identNode.getSymbol().getName()).invoke(ScriptRuntime.THROW_REFERENCE_ERROR);
 347         }
 348     }
 349 
 350     // Runtime check for assignment to ES6 const
 351     private void checkAssignTarget(final Expression expression) {
 352         if (expression instanceof IdentNode && ((IdentNode)expression).getSymbol().isConst()) {
 353             method.load(((IdentNode)expression).getSymbol().getName()).invoke(ScriptRuntime.THROW_CONST_TYPE_ERROR);
 354         }
 355     }
 356 
 357     private boolean isRestOf() {
 358         return continuationEntryPoints != null;
 359     }
 360 
 361     private boolean isOptimisticOrRestOf() {
 362         return useOptimisticTypes() || isRestOf();
 363     }
 364 
 365     private boolean isCurrentContinuationEntryPoint(final int programPoint) {
 366         return isRestOf() && getCurrentContinuationEntryPoint() == programPoint;
 367     }
 368 
 369     private int[] getContinuationEntryPoints() {
 370         return isRestOf() ? continuationEntryPoints : null;
 371     }
 372 
 373     private int getCurrentContinuationEntryPoint() {


 776                 }.emit(baseAlreadyOnStack ? 2 : 0);
 777                 return false;
 778             }
 779 
 780             @Override
 781             public boolean enterFunctionNode(final FunctionNode functionNode) {
 782                 // function nodes will always leave a constructed function object on stack, no need to load the symbol
 783                 // separately as in enterDefault()
 784                 lc.pop(functionNode);
 785                 functionNode.accept(codegen);
 786                 // NOTE: functionNode.accept() will produce a different FunctionNode that we discard. This incidentally
 787                 // doesn't cause problems as we're never touching FunctionNode again after it's visited here - codegen
 788                 // is the last element in the compilation pipeline, the AST it produces is not used externally. So, we
 789                 // re-push the original functionNode.
 790                 lc.push(functionNode);
 791                 return false;
 792             }
 793 
 794             @Override
 795             public boolean enterASSIGN(final BinaryNode binaryNode) {
 796                 checkAssignTarget(binaryNode.lhs());
 797                 loadASSIGN(binaryNode);
 798                 return false;
 799             }
 800 
 801             @Override
 802             public boolean enterASSIGN_ADD(final BinaryNode binaryNode) {
 803                 checkAssignTarget(binaryNode.lhs());
 804                 loadASSIGN_ADD(binaryNode);
 805                 return false;
 806             }
 807 
 808             @Override
 809             public boolean enterASSIGN_BIT_AND(final BinaryNode binaryNode) {
 810                 checkAssignTarget(binaryNode.lhs());
 811                 loadASSIGN_BIT_AND(binaryNode);
 812                 return false;
 813             }
 814 
 815             @Override
 816             public boolean enterASSIGN_BIT_OR(final BinaryNode binaryNode) {
 817                 checkAssignTarget(binaryNode.lhs());
 818                 loadASSIGN_BIT_OR(binaryNode);
 819                 return false;
 820             }
 821 
 822             @Override
 823             public boolean enterASSIGN_BIT_XOR(final BinaryNode binaryNode) {
 824                 checkAssignTarget(binaryNode.lhs());
 825                 loadASSIGN_BIT_XOR(binaryNode);
 826                 return false;
 827             }
 828 
 829             @Override
 830             public boolean enterASSIGN_DIV(final BinaryNode binaryNode) {
 831                 checkAssignTarget(binaryNode.lhs());
 832                 loadASSIGN_DIV(binaryNode);
 833                 return false;
 834             }
 835 
 836             @Override
 837             public boolean enterASSIGN_MOD(final BinaryNode binaryNode) {
 838                 checkAssignTarget(binaryNode.lhs());
 839                 loadASSIGN_MOD(binaryNode);
 840                 return false;
 841             }
 842 
 843             @Override
 844             public boolean enterASSIGN_MUL(final BinaryNode binaryNode) {
 845                 checkAssignTarget(binaryNode.lhs());
 846                 loadASSIGN_MUL(binaryNode);
 847                 return false;
 848             }
 849 
 850             @Override
 851             public boolean enterASSIGN_SAR(final BinaryNode binaryNode) {
 852                 checkAssignTarget(binaryNode.lhs());
 853                 loadASSIGN_SAR(binaryNode);
 854                 return false;
 855             }
 856 
 857             @Override
 858             public boolean enterASSIGN_SHL(final BinaryNode binaryNode) {
 859                 checkAssignTarget(binaryNode.lhs());
 860                 loadASSIGN_SHL(binaryNode);
 861                 return false;
 862             }
 863 
 864             @Override
 865             public boolean enterASSIGN_SHR(final BinaryNode binaryNode) {
 866                 checkAssignTarget(binaryNode.lhs());
 867                 loadASSIGN_SHR(binaryNode);
 868                 return false;
 869             }
 870 
 871             @Override
 872             public boolean enterASSIGN_SUB(final BinaryNode binaryNode) {
 873                 checkAssignTarget(binaryNode.lhs());
 874                 loadASSIGN_SUB(binaryNode);
 875                 return false;
 876             }
 877 
 878             @Override
 879             public boolean enterCallNode(final CallNode callNode) {
 880                 return loadCallNode(callNode, resultBounds);
 881             }
 882 
 883             @Override
 884             public boolean enterLiteralNode(final LiteralNode<?> literalNode) {
 885                 loadLiteral(literalNode, resultBounds);
 886                 return false;
 887             }
 888 
 889             @Override
 890             public boolean enterTernaryNode(final TernaryNode ternaryNode) {
 891                 loadTernaryNode(ternaryNode, resultBounds);
 892                 return false;
 893             }


1063             @Override
1064             public boolean enterObjectNode(final ObjectNode objectNode) {
1065                 loadObjectNode(objectNode);
1066                 return false;
1067             }
1068 
1069             @Override
1070             public boolean enterRuntimeNode(final RuntimeNode runtimeNode) {
1071                 loadRuntimeNode(runtimeNode);
1072                 return false;
1073             }
1074 
1075             @Override
1076             public boolean enterNEW(final UnaryNode unaryNode) {
1077                 loadNEW(unaryNode);
1078                 return false;
1079             }
1080 
1081             @Override
1082             public boolean enterDECINC(final UnaryNode unaryNode) {
1083                 checkAssignTarget(unaryNode.getExpression());
1084                 loadDECINC(unaryNode);
1085                 return false;
1086             }
1087 
1088             @Override
1089             public boolean enterJoinPredecessorExpression(final JoinPredecessorExpression joinExpr) {
1090                 loadExpression(joinExpr.getExpression(), resultBounds);
1091                 return false;
1092             }
1093 
1094             @Override
1095             public boolean enterGetSplitState(final GetSplitState getSplitState) {
1096                 method.loadScope();
1097                 method.invoke(Scope.GET_SPLIT_STATE);
1098                 return false;
1099             }
1100 
1101             @Override
1102             public boolean enterDefault(final Node otherNode) {
1103                 // Must have handled all expressions that can legally be encountered.