14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/interpreter/interpreter-inl.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_cinamespace panda::ecmascript { 194514f5e3Sopenharmony_ci// make EcmaRuntimeCallInfo in stack pointer as fallows: 204514f5e3Sopenharmony_ci// +----------------------+ — 214514f5e3Sopenharmony_ci// | args... | ^ 224514f5e3Sopenharmony_ci// |----------------------| | 234514f5e3Sopenharmony_ci// | numArgs | | 244514f5e3Sopenharmony_ci// |----------------------| | 254514f5e3Sopenharmony_ci// | this | | 264514f5e3Sopenharmony_ci// |----------------------| EcmaRuntimeCallInfo 274514f5e3Sopenharmony_ci// | newTarget | | 284514f5e3Sopenharmony_ci// |----------------------| | 294514f5e3Sopenharmony_ci// | func | v 304514f5e3Sopenharmony_ci// +----------------------+ — 314514f5e3Sopenharmony_ci// | base.type | ^ 324514f5e3Sopenharmony_ci// |----------------------| | 334514f5e3Sopenharmony_ci// | base.prev | InterpretedEntryFrame 344514f5e3Sopenharmony_ci// |----------------------| | 354514f5e3Sopenharmony_ci// | pc | v 364514f5e3Sopenharmony_ci// +--------------------------+ 374514f5e3Sopenharmony_ciEcmaRuntimeCallInfo* EcmaInterpreter::NewRuntimeCallInfoBase( 384514f5e3Sopenharmony_ci JSThread *thread, JSTaggedType func, JSTaggedType thisObj, JSTaggedType newTarget, 394514f5e3Sopenharmony_ci uint32_t numArgs, StackCheck needCheckStack) 404514f5e3Sopenharmony_ci{ 414514f5e3Sopenharmony_ci JSTaggedType *prevSp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame()); 424514f5e3Sopenharmony_ci JSTaggedType *newSp = GetInterpreterFrameEnd(thread, prevSp); 434514f5e3Sopenharmony_ci if (needCheckStack == StackCheck::YES && 444514f5e3Sopenharmony_ci UNLIKELY(thread->DoStackOverflowCheck(newSp - numArgs - NUM_MANDATORY_JSFUNC_ARGS))) { 454514f5e3Sopenharmony_ci return nullptr; 464514f5e3Sopenharmony_ci } 474514f5e3Sopenharmony_ci 484514f5e3Sopenharmony_ci for (uint32_t i = 0; i < numArgs; i++) { 494514f5e3Sopenharmony_ci *(--newSp) = JSTaggedValue::VALUE_UNDEFINED; 504514f5e3Sopenharmony_ci } 514514f5e3Sopenharmony_ci *(--newSp) = thisObj; 524514f5e3Sopenharmony_ci *(--newSp) = newTarget; 534514f5e3Sopenharmony_ci *(--newSp) = func; 544514f5e3Sopenharmony_ci *(--newSp) = numArgs + NUM_MANDATORY_JSFUNC_ARGS; 554514f5e3Sopenharmony_ci *(--newSp) = ToUintPtr(thread); 564514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo *>(newSp); 574514f5e3Sopenharmony_ci 584514f5e3Sopenharmony_ci // create entry frame. 594514f5e3Sopenharmony_ci InterpretedEntryFrame *entryState = InterpretedEntryFrame::GetFrameFromSp(newSp); 604514f5e3Sopenharmony_ci entryState->base.type = FrameType::INTERPRETER_ENTRY_FRAME; 614514f5e3Sopenharmony_ci entryState->base.prev = prevSp; 624514f5e3Sopenharmony_ci entryState->pc = nullptr; 634514f5e3Sopenharmony_ci 644514f5e3Sopenharmony_ci thread->SetCurrentSPFrame(newSp); 654514f5e3Sopenharmony_ci return ecmaRuntimeCallInfo; 664514f5e3Sopenharmony_ci} 674514f5e3Sopenharmony_ci 684514f5e3Sopenharmony_ciEcmaRuntimeCallInfo* EcmaInterpreter::NewRuntimeCallInfo( 694514f5e3Sopenharmony_ci JSThread *thread, JSTaggedValue func, JSTaggedValue thisObj, JSTaggedValue newTarget, 704514f5e3Sopenharmony_ci uint32_t numArgs, StackCheck needCheckStack) 714514f5e3Sopenharmony_ci{ 724514f5e3Sopenharmony_ci return NewRuntimeCallInfoBase(thread, func.GetRawData(), thisObj.GetRawData(), newTarget.GetRawData(), 734514f5e3Sopenharmony_ci numArgs, needCheckStack); 744514f5e3Sopenharmony_ci} 754514f5e3Sopenharmony_ci 764514f5e3Sopenharmony_ciEcmaRuntimeCallInfo* EcmaInterpreter::NewRuntimeCallInfo( 774514f5e3Sopenharmony_ci JSThread *thread, JSHandle<JSTaggedValue> func, JSHandle<JSTaggedValue> thisObj, 784514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> newTarget, uint32_t numArgs, StackCheck needCheckStack) 794514f5e3Sopenharmony_ci{ 804514f5e3Sopenharmony_ci return NewRuntimeCallInfoBase(thread, func.GetTaggedType(), thisObj.GetTaggedType(), newTarget.GetTaggedType(), 814514f5e3Sopenharmony_ci numArgs, needCheckStack); 824514f5e3Sopenharmony_ci} 834514f5e3Sopenharmony_ci 844514f5e3Sopenharmony_ciEcmaRuntimeCallInfo* EcmaInterpreter::ReBuildRuntimeCallInfo(JSThread *thread, EcmaRuntimeCallInfo* info, 854514f5e3Sopenharmony_ci int numArgs, StackCheck needCheckStack) 864514f5e3Sopenharmony_ci{ 874514f5e3Sopenharmony_ci JSTaggedValue func = info->GetFunctionValue(); 884514f5e3Sopenharmony_ci JSTaggedValue newTarget = info->GetNewTargetValue(); 894514f5e3Sopenharmony_ci JSTaggedValue thisObj = info->GetThisValue(); 904514f5e3Sopenharmony_ci JSTaggedType *currentSp = reinterpret_cast<JSTaggedType *>(info); 914514f5e3Sopenharmony_ci 924514f5e3Sopenharmony_ci InterpretedEntryFrame *currentEntryState = InterpretedEntryFrame::GetFrameFromSp(currentSp); 934514f5e3Sopenharmony_ci JSTaggedType *prevSp = currentEntryState->base.prev; 944514f5e3Sopenharmony_ci 954514f5e3Sopenharmony_ci int actualArgc = static_cast<int>(info->GetArgsNumber()); 964514f5e3Sopenharmony_ci std::vector<JSTaggedType> args(actualArgc); 974514f5e3Sopenharmony_ci for (int i = 0; i < actualArgc; i++) { 984514f5e3Sopenharmony_ci args[i] = info->GetCallArgValue(actualArgc - i - 1).GetRawData(); 994514f5e3Sopenharmony_ci } 1004514f5e3Sopenharmony_ci currentSp += (info->GetArgsNumber() + NUM_MANDATORY_JSFUNC_ARGS + 2); // 2: include thread_ and numArgs_ 1014514f5e3Sopenharmony_ci if (needCheckStack == StackCheck::YES && 1024514f5e3Sopenharmony_ci UNLIKELY(thread->DoStackOverflowCheck(currentSp - numArgs - NUM_MANDATORY_JSFUNC_ARGS))) { 1034514f5e3Sopenharmony_ci return nullptr; 1044514f5e3Sopenharmony_ci } 1054514f5e3Sopenharmony_ci ASSERT(numArgs != actualArgc); 1064514f5e3Sopenharmony_ci for (int i = 0; i < (numArgs - actualArgc); i++) { 1074514f5e3Sopenharmony_ci *(--currentSp) = JSTaggedValue::VALUE_UNDEFINED; 1084514f5e3Sopenharmony_ci } 1094514f5e3Sopenharmony_ci for (int i = 0; i < actualArgc; i++) { 1104514f5e3Sopenharmony_ci *(--currentSp) = args[i]; 1114514f5e3Sopenharmony_ci } 1124514f5e3Sopenharmony_ci *(--currentSp) = thisObj.GetRawData(); 1134514f5e3Sopenharmony_ci *(--currentSp) = newTarget.GetRawData(); 1144514f5e3Sopenharmony_ci *(--currentSp) = func.GetRawData(); 1154514f5e3Sopenharmony_ci *(--currentSp) = numArgs + static_cast<int>(NUM_MANDATORY_JSFUNC_ARGS); 1164514f5e3Sopenharmony_ci *(--currentSp) = ToUintPtr(thread); 1174514f5e3Sopenharmony_ci EcmaRuntimeCallInfo *ecmaRuntimeCallInfo = reinterpret_cast<EcmaRuntimeCallInfo *>(currentSp); 1184514f5e3Sopenharmony_ci 1194514f5e3Sopenharmony_ci InterpretedEntryFrame *entryState = InterpretedEntryFrame::GetFrameFromSp(currentSp); 1204514f5e3Sopenharmony_ci entryState->base.type = FrameType::INTERPRETER_ENTRY_FRAME; 1214514f5e3Sopenharmony_ci entryState->base.prev = prevSp; 1224514f5e3Sopenharmony_ci entryState->pc = nullptr; 1234514f5e3Sopenharmony_ci 1244514f5e3Sopenharmony_ci thread->SetCurrentSPFrame(currentSp); 1254514f5e3Sopenharmony_ci return ecmaRuntimeCallInfo; 1264514f5e3Sopenharmony_ci} 1274514f5e3Sopenharmony_ci} // namespace panda::ecmascript 128