• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ECMASCRIPT_ECMA_RUNTIM_CALL_INFO_H
17 #define ECMASCRIPT_ECMA_RUNTIM_CALL_INFO_H
18 
19 #include <algorithm>
20 
21 #include "ecmascript/common.h"
22 #include "ecmascript/js_tagged_value.h"
23 #include "ecmascript/js_thread.h"
24 #include "js_handle.h"
25 
26 namespace panda::ecmascript {
27 class EcmaRuntimeCallInfo;
28 using EcmaEntrypoint = JSTaggedValue (*)(EcmaRuntimeCallInfo *);
29 
30 class EcmaRuntimeCallInfo {
31 public:
32     // For builtins interpreter call
EcmaRuntimeCallInfo(JSThread * thread,uint32_t numArgs,JSTaggedValue * args)33     EcmaRuntimeCallInfo(JSThread *thread, uint32_t numArgs, JSTaggedValue *args)
34         : thread_(thread), numArgs_(numArgs), gprArgs_(args, numArgs), stackArgs_(nullptr, static_cast<size_t>(0))
35     {
36         ASSERT(numArgs_ >= NUM_MANDATORY_JSFUNC_ARGS);
37     }
38 
39     ~EcmaRuntimeCallInfo() = default;
40 
GetThread()41     inline JSThread *GetThread() const
42     {
43         return thread_;
44     }
45 
46     inline void SetNewTarget(JSTaggedValue tagged, [[maybe_unused]] int64_t tag = 0)
47     {
48         SetArg(NEW_TARGET_INDEX, tagged);
49     }
50 
51     inline void SetFunction(JSTaggedValue tagged, [[maybe_unused]] int64_t tag = 0)
52     {
53         SetArg(FUNC_INDEX, tagged);
54     }
55 
56     inline void SetThis(JSTaggedValue tagged, [[maybe_unused]] int64_t tag = 0)
57     {
58         SetArg(THIS_INDEX, tagged);
59     }
60 
61     inline void SetCallArg(uint32_t idx, JSTaggedValue tagged, [[maybe_unused]] int64_t tag = 0)
62     {
63         ASSERT_PRINT(idx < GetArgsNumber(), "Can not set values out of index range");
64         SetArg(idx + FIRST_ARGS_INDEX, tagged);
65     }
66 
GetArg(uint32_t idx)67     inline JSHandle<JSTaggedValue> GetArg(uint32_t idx) const
68     {
69         return JSHandle<JSTaggedValue>(GetArgAddress(idx));
70     }
71 
GetFunction()72     inline JSHandle<JSTaggedValue> GetFunction() const
73     {
74         return GetArg(FUNC_INDEX);
75     }
76 
GetNewTarget()77     inline JSHandle<JSTaggedValue> GetNewTarget() const
78     {
79         return GetArg(NEW_TARGET_INDEX);
80     }
81 
GetThis()82     inline JSHandle<JSTaggedValue> GetThis() const
83     {
84         return GetArg(THIS_INDEX);
85     }
86 
GetCallArg(uint32_t idx)87     inline JSHandle<JSTaggedValue> GetCallArg(uint32_t idx) const
88     {
89         return GetArg(idx + FIRST_ARGS_INDEX);
90     }
91 
92     /*
93      * The number of arguments pairs excluding the 'func', 'new.target' and 'this'. For instance:
94      * for code fragment: " foo(v1); ", GetArgsNumber() returns 1
95      */
GetArgsNumber()96     inline uint32_t GetArgsNumber() const
97     {
98         return numArgs_ - NUM_MANDATORY_JSFUNC_ARGS;
99     }
100 
GetArgAddress(uint32_t idx)101     inline uintptr_t GetArgAddress(uint32_t idx) const
102     {
103         if (idx < gprArgs_.size()) {
104             return reinterpret_cast<uintptr_t>(&gprArgs_[idx]);
105         }
106         return reinterpret_cast<uintptr_t>(&stackArgs_[idx - gprArgs_.size()]);
107     }
108 
109 private:
110     DEFAULT_COPY_SEMANTIC(EcmaRuntimeCallInfo);
111     DEFAULT_MOVE_SEMANTIC(EcmaRuntimeCallInfo);
112 
113     enum ArgsIndex : uint8_t { FUNC_INDEX = 0, NEW_TARGET_INDEX, THIS_INDEX, FIRST_ARGS_INDEX };
114 
SetArg(uint32_t idx,JSTaggedValue tagged)115     inline void SetArg(uint32_t idx, JSTaggedValue tagged)
116     {
117         *reinterpret_cast<JSTaggedValue *>(GetArgAddress(idx)) = tagged;
118     }
119 
120 private:
121     JSThread *thread_;
122     uint32_t numArgs_;
123     Span<JSTaggedValue> gprArgs_;
124     Span<JSTaggedValue> stackArgs_;
125 };
126 }  // namespace panda::ecmascript
127 
128 #endif  // ECMASCRIPT_ECMA_RUNTIM_CALL_INFO_H