Changeset 192935 in webkit for trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
- Timestamp:
- Dec 1, 2015, 5:37:19 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r192914 r192935 35 35 #include "JIT.h" 36 36 #include "JSFunction.h" 37 #include "JSGeneratorFunction.h"38 37 #include "JSGlobalObject.h" 39 38 #include "JSONObject.h" … … 147 146 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 148 147 { 149 if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived || generator.generatorThisMode() == GeneratorThisMode::Empty)148 if (m_shouldAlwaysEmitTDZCheck || generator.constructorKind() == ConstructorKind::Derived) 150 149 generator.emitTDZCheck(generator.thisRegister()); 151 150 … … 172 171 } 173 172 174 static RegisterID* emit HomeObjectForCallee(BytecodeGenerator& generator)173 static RegisterID* emitSuperBaseForCallee(BytecodeGenerator& generator) 175 174 { 176 175 RegisterID callee; 177 176 callee.setIndex(JSStack::Callee); 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); 177 178 RefPtr<RegisterID> homeObject = generator.emitGetById(generator.newTemporary(), &callee, generator.propertyNames().homeObjectPrivateName); 184 179 return generator.emitGetById(generator.newTemporary(), homeObject.get(), generator.propertyNames().underscoreProto); 185 180 } … … 2590 2585 2591 2586 RefPtr<RegisterID> returnRegister = m_value ? generator.emitNodeInTailPosition(dst, m_value) : generator.emitLoad(dst, jsUndefined()); 2592 2593 2587 generator.emitProfileType(returnRegister.get(), ProfileTypeBytecodeFunctionReturnStatement, divotStart(), divotEnd()); 2594 2588 if (generator.isInFinallyBlock()) { … … 2973 2967 generator.emitProfileControlFlow(startStartOffset()); 2974 2968 generator.emitDebugHook(DidEnterCallFrame, startLine(), startStartOffset(), startLineStartOffset()); 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 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. 3006 2985 ASSERT(startOffset() >= lineStartOffset()); 3007 2986 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset()); 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 } 2987 generator.emitReturn(r0); 2988 return; 3064 2989 } 3065 2990 } … … 3089 3014 RegisterID* YieldExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 3090 3015 { 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); 3016 // FIXME: This is just a stub. When completing ES6 Generators, we need to implement it. 3017 generator.emitThrowTypeError(ASCIILiteral("Not implemented yet.")); 3106 3018 if (dst == generator.ignoredResult()) 3107 return nullptr;3108 return generator.emit Move(generator.finalDestination(dst), value.get());3019 return 0; 3020 return generator.emitLoad(dst, jsUndefined()); 3109 3021 } 3110 3022
Note:
See TracChangeset
for help on using the changeset viewer.