Changeset 192937 in webkit for trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
- Timestamp:
- Dec 1, 2015, 7:16:28 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r192935 r192937 35 35 #include "JIT.h" 36 36 #include "JSFunction.h" 37 #include "JSGeneratorFunction.h" 37 38 #include "JSGlobalObject.h" 38 39 #include "JSONObject.h" … … 146 147 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 147 148 { 148 if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived )149 if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived || generator.generatorThisMode() == GeneratorThisMode::Empty) 149 150 generator.emitTDZCheck(generator.thisRegister()); 150 151 … … 171 172 } 172 173 173 static RegisterID* emit SuperBaseForCallee(BytecodeGenerator& generator)174 static RegisterID* emitHomeObjectForCallee(BytecodeGenerator& generator) 174 175 { 175 176 RegisterID callee; 176 177 callee.setIndex(JSStack::Callee); 177 178 RefPtr<RegisterID> homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName); 178 return generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName); 179 } 180 181 static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator) 182 { 183 RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator); 179 184 return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto); 180 185 } … … 2585 2590 2586 2591 RefPtr<RegisterID> returnRegister = m_value ? generator.emitNodeInTailPosition(dst, m_value) : generator.emitLoad(dst, jsUndefined()); 2592 2587 2593 generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, divotStart(), divotEnd()); 2588 2594 if (generator.isInFinallyBlock()) { … … 2967 2973 generator.emitProfileControlFlow(startStartOffset()); 2968 2974 generator.emitDebugHook(DidEnterCallFrame, startLine(), startStartOffset(), startLineStartOffset()); 2969 emitStatementsBytecode(generator, generator.ignoredResult()); 2970 2971 StatementNode* singleStatement = this->singleStatement(); 2972 ReturnNode* returnNode = 0; 2973 2974 // Check for a return statement at the end of a function composed of a single block. 2975 if (singleStatement && singleStatement->isBlock()) { 2976 StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement(); 2977 if (lastStatementInBlock && lastStatementInBlock->isReturnNode()) 2978 returnNode = static_cast<ReturnNode*>(lastStatementInBlock); 2979 } 2980 2981 // If there is no return we must automatically insert one. 2982 if (!returnNode) { 2983 RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined()); 2984 generator.emitProfileType(r0, ProfileTypeBytecodeFunctionReturnStatement); // Do not emit expression info for this profile because it's not in the user's source code. 2975 2976 switch (generator.parseMode()) { 2977 case SourceParseMode::GeneratorWrapperFunctionMode: { 2978 StatementNode* singleStatement = this->singleStatement(); 2979 ASSERT(singleStatement->isExprStatement()); 2980 ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(singleStatement); 2981 ExpressionNode* expr = exprStatement->expr(); 2982 ASSERT(expr->isFuncExprNode()); 2983 FuncExprNode* funcExpr = static_cast<FuncExprNode*>(expr); 2984 2985 RefPtr<RegisterID> next = generator.newTemporary(); 2986 generator.emitNode(next.get(), funcExpr); 2987 2988 if (generator.superBinding() == SuperBinding::Needed) { 2989 RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator); 2990 emitPutHomeObject(generator, next.get(), homeObject.get()); 2991 } 2992 2993 // FIXME: Currently, we just create an object and store generator related fields as its properties for ease. 2994 // But to make it efficient, we will introduce JSGenerator class, add opcode new_generator and use its C++ fields instead of these private properties. 2995 // https://bugs.webkit.org/show_bug.cgi?id=151545 2996 2997 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorNextPrivateName, next.get(), PropertyNode::KnownDirect); 2998 2999 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorThisPrivateName, generator.thisRegister(), PropertyNode::KnownDirect); 3000 3001 RegisterID* initialState = generator.emitLoad(nullptr, jsNumber(0)); 3002 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorStatePrivateName, initialState, PropertyNode::KnownDirect); 3003 3004 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorFramePrivateName, generator.emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect); 3005 2985 3006 ASSERT(startOffset() >= lineStartOffset()); 2986 3007 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset()); 2987 generator.emitReturn(r0); 2988 return; 3008 generator.emitReturn(generator.generatorRegister()); 3009 break; 3010 } 3011 3012 case SourceParseMode::GeneratorBodyMode: { 3013 RefPtr<Label> generatorBodyLabel = generator.newLabel(); 3014 { 3015 RefPtr<RegisterID> condition = generator.newTemporary(); 3016 generator.emitEqualityOp(op_stricteq, condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode)))); 3017 generator.emitJumpIfTrue(condition.get(), generatorBodyLabel.get()); 3018 3019 RefPtr<Label> throwLabel = generator.newLabel(); 3020 generator.emitEqualityOp(op_stricteq, condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::ThrowMode)))); 3021 generator.emitJumpIfTrue(condition.get(), throwLabel.get()); 3022 3023 generator.emitReturn(generator.generatorValueRegister()); 3024 3025 generator.emitLabel(throwLabel.get()); 3026 generator.emitThrow(generator.generatorValueRegister()); 3027 } 3028 3029 generator.emitLabel(generatorBodyLabel.get()); 3030 3031 emitStatementsBytecode(generator, generator.ignoredResult()); 3032 3033 RefPtr<Label> done = generator.newLabel(); 3034 generator.emitLabel(done.get()); 3035 generator.emitReturn(generator.emitLoad(nullptr, jsUndefined())); 3036 generator.endGenerator(done.get()); 3037 break; 3038 } 3039 3040 default: { 3041 emitStatementsBytecode(generator, generator.ignoredResult()); 3042 3043 StatementNode* singleStatement = this->singleStatement(); 3044 ReturnNode* returnNode = 0; 3045 3046 // Check for a return statement at the end of a function composed of a single block. 3047 if (singleStatement && singleStatement->isBlock()) { 3048 StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement(); 3049 if (lastStatementInBlock && lastStatementInBlock->isReturnNode()) 3050 returnNode = static_cast<ReturnNode*>(lastStatementInBlock); 3051 } 3052 3053 // If there is no return we must automatically insert one. 3054 if (!returnNode) { 3055 RegisterID* r0 = generator.isConstructor() ? generator.thisRegister() : generator.emitLoad(0, jsUndefined()); 3056 generator.emitProfileType(r0, ProfileTypeBytecodeFunctionReturnStatement); // Do not emit expression info for this profile because it's not in the user's source code. 3057 ASSERT(startOffset() >= lineStartOffset()); 3058 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset()); 3059 generator.emitReturn(r0); 3060 return; 3061 } 3062 break; 3063 } 2989 3064 } 2990 3065 } … … 3014 3089 RegisterID* YieldExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 3015 3090 { 3016 // FIXME: This is just a stub. When completing ES6 Generators, we need to implement it. 3017 generator.emitThrowTypeError(ASCIILiteral("Not implemented yet.")); 3091 if (!delegate()) { 3092 RefPtr<RegisterID> arg = nullptr; 3093 if (argument()) { 3094 arg = generator.newTemporary(); 3095 generator.emitNode(arg.get(), argument()); 3096 } else 3097 arg = generator.emitLoad(nullptr, jsUndefined()); 3098 RefPtr<RegisterID> value = generator.emitYield(arg.get()); 3099 if (dst == generator.ignoredResult()) 3100 return nullptr; 3101 return generator.emitMove(generator.finalDestination(dst), value.get()); 3102 } 3103 RefPtr<RegisterID> arg = generator.newTemporary(); 3104 generator.emitNode(arg.get(), argument()); 3105 RefPtr<RegisterID> value = generator.emitDelegateYield(arg.get(), this); 3018 3106 if (dst == generator.ignoredResult()) 3019 return 0;3020 return generator.emit Load(dst, jsUndefined());3107 return nullptr; 3108 return generator.emitMove(generator.finalDestination(dst), value.get()); 3021 3109 } 3022 3110
Note:
See TracChangeset
for help on using the changeset viewer.