Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
native_arguments.h
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_NATIVE_ARGUMENTS_H_
6#define RUNTIME_VM_NATIVE_ARGUMENTS_H_
7
8#include "platform/assert.h"
10#include "vm/globals.h"
11#include "vm/simulator.h"
12#include "vm/stub_code.h"
13
14namespace dart {
15
16// Forward declarations.
17class BootstrapNatives;
18class Object;
19class Simulator;
20class Thread;
21
22#if defined(TESTING) || defined(DEBUG)
23
24#if defined(USING_SIMULATOR)
25#define CHECK_STACK_ALIGNMENT \
26 { \
27 uword current_sp = Simulator::Current()->get_register(SPREG); \
28 ASSERT(Utils::IsAligned(current_sp, OS::ActivationFrameAlignment())); \
29 }
30#elif defined(DART_HOST_OS_WINDOWS)
31// The compiler may dynamically align the stack on Windows, so do not check.
32#define CHECK_STACK_ALIGNMENT \
33 {}
34#else
35#define CHECK_STACK_ALIGNMENT \
36 { \
37 uword (*func)() = reinterpret_cast<uword (*)()>( \
38 StubCode::GetCStackPointer().EntryPoint()); \
39 uword current_sp = func(); \
40 ASSERT(Utils::IsAligned(current_sp, OS::ActivationFrameAlignment())); \
41 }
42#endif
43
44#define DEOPTIMIZE_ALOT \
45 if (FLAG_deoptimize_alot) { \
46 DeoptimizeFunctionsOnStack(); \
47 }
48
49#else
50
51#define CHECK_STACK_ALIGNMENT \
52 {}
53#define DEOPTIMIZE_ALOT \
54 {}
55
56#endif
57
58// Class NativeArguments is used to access arguments passed in from
59// generated dart code to a runtime function or a dart library native
60// function. It is also used to set the return value if any at the slot
61// reserved for return values.
62// All runtime function/dart library native functions have the
63// following signature:
64// void function_name(NativeArguments arguments);
65// Inside the function, arguments are accessed as follows:
66// const Instance& arg0 = Instance::CheckedHandle(arguments.NativeArgAt(0));
67// const Smi& arg1 = Smi::CheckedHandle(arguments.NativeArgAt(1));
68// If the function is generic, type arguments are accessed as follows:
69// const TypeArguments& type_args =
70// TypeArguments::Handle(arguments.NativeTypeArgs());
71// The return value is set as follows:
72// arguments.SetReturn(result);
73// NOTE: Since we pass 'this' as a pass-by-value argument in the stubs we don't
74// have DISALLOW_COPY_AND_ASSIGN in the class definition and do not make it a
75// subclass of ValueObject.
77 public:
78 Thread* thread() const { return thread_; }
79
80 // Includes type arguments vector.
81 int ArgCount() const { return ArgcBits::decode(argc_tag_); }
82
83 ObjectPtr ArgAt(int index) const {
84 ASSERT((index >= 0) && (index < ArgCount()));
85 ObjectPtr* arg_ptr = &(argv_[-index]);
86 // Tell MemorySanitizer the ObjectPtr was initialized (by generated code).
87 MSAN_UNPOISON(arg_ptr, kWordSize);
88 return *arg_ptr;
89 }
90
91 void SetArgAt(int index, const Object& value) const {
93 ASSERT((index >= 0) && (index < ArgCount()));
94 argv_[-index] = value.ptr();
95 }
96
97 // Does not include hidden type arguments vector.
98 int NativeArgCount() const {
99 int function_bits = FunctionBits::decode(argc_tag_);
100 return ArgCount() - NumHiddenArgs(function_bits);
101 }
102
104 int function_bits = FunctionBits::decode(argc_tag_);
105 return ArgAt(NumHiddenArgs(function_bits));
106 }
107
108 ObjectPtr NativeArgAt(int index) const {
109 ASSERT((index >= 0) && (index < NativeArgCount()));
110 if (index == 0) {
111 return NativeArg0();
112 }
113 int function_bits = FunctionBits::decode(argc_tag_);
114 const int actual_index = index + NumHiddenArgs(function_bits);
115 return ArgAt(actual_index);
116 }
117
118 TypeArgumentsPtr NativeTypeArgs() const {
119 ASSERT(ToGenericFunction());
120 return TypeArguments::RawCast(ArgAt(0));
121 }
122
123 int NativeTypeArgCount() const {
124 if (ToGenericFunction()) {
126 if (type_args.IsNull()) {
127 // null vector represents infinite list of dynamics
128 return INT_MAX;
129 }
130 return type_args.Length();
131 }
132 return 0;
133 }
134
135 AbstractTypePtr NativeTypeArgAt(int index) const {
136 ASSERT((index >= 0) && (index < NativeTypeArgCount()));
138 if (type_args.IsNull()) {
139 // null vector represents infinite list of dynamics
140 return Type::dynamic_type().ptr();
141 }
142 return type_args.TypeAt(index);
143 }
144
145 void SetReturn(const Object& value) const {
147 *retval_ = value.ptr();
148 }
149
151 // Tell MemorySanitizer the retval_ was initialized (by generated code).
152 MSAN_UNPOISON(retval_, kWordSize);
153 return *retval_;
154 }
155
156 static intptr_t thread_offset() {
157 return OFFSET_OF(NativeArguments, thread_);
158 }
159 static intptr_t argc_tag_offset() {
160 return OFFSET_OF(NativeArguments, argc_tag_);
161 }
162 static intptr_t argv_offset() { return OFFSET_OF(NativeArguments, argv_); }
163 static intptr_t retval_offset() {
164 return OFFSET_OF(NativeArguments, retval_);
165 }
166
168 ASSERT(function.is_old_native());
169 ASSERT(!function.IsGenerativeConstructor()); // Not supported.
170 ASSERT(!function.IsClosureFunction()); // Not supported.
171 return function.NumParameters();
172 }
173
174 static int ComputeArgcTag(const Function& function) {
175 ASSERT(function.is_old_native());
176 ASSERT(!function.IsGenerativeConstructor()); // Not supported.
177 ASSERT(!function.IsClosureFunction()); // Not supported.
178 int argc = function.NumParameters();
179 int function_bits = 0;
180 if (function.IsGeneric()) {
181 function_bits |= kGenericFunctionBit;
182 argc++;
183 }
184 int tag = ArgcBits::encode(argc);
185 tag = FunctionBits::update(function_bits, tag);
186 return tag;
187 }
188
189 private:
190 enum {
191 kGenericFunctionBit = 1,
192 };
193 enum ArgcTagBits {
194 kArgcBit = 0,
195 kArgcSize = 24,
196 kFunctionBit = kArgcBit + kArgcSize,
197 kFunctionSize = 1,
198 };
199 class ArgcBits : public BitField<intptr_t, int32_t, kArgcBit, kArgcSize> {};
200 class FunctionBits
201 : public BitField<intptr_t, int, kFunctionBit, kFunctionSize> {};
202 friend class Api;
203 friend class NativeEntry;
204 friend class Simulator;
205
206 // Since this function is passed an ObjectPtr directly, we need to be
207 // exceedingly careful when we use it. If there are any other side
208 // effects in the statement that may cause GC, it could lead to
209 // bugs.
210 void SetReturnUnsafe(ObjectPtr value) const {
212 *retval_ = value;
213 }
214
215 // Returns true if the arguments are those of a generic function call.
216 bool ToGenericFunction() const {
217 return (FunctionBits::decode(argc_tag_) & kGenericFunctionBit) != 0;
218 }
219
220 int NumHiddenArgs(int function_bits) const {
221 int num_hidden_args = 0;
222 if ((function_bits & kGenericFunctionBit) == kGenericFunctionBit) {
223 num_hidden_args++;
224 }
225 return num_hidden_args;
226 }
227
228 Thread* thread_; // Current thread pointer.
229 intptr_t argc_tag_; // Encodes argument count and invoked native call type.
230 ObjectPtr* argv_; // Pointer to an array of arguments to runtime call.
231 ObjectPtr* retval_; // Pointer to the return value area.
232};
233
234} // namespace dart
235
236#endif // RUNTIME_VM_NATIVE_ARGUMENTS_H_
static constexpr int32_t decode(intptr_t value)
Definition bitfield.h:173
static constexpr intptr_t update(int value, intptr_t original)
Definition bitfield.h:190
static constexpr intptr_t encode(int32_t value)
Definition bitfield.h:167
Thread * thread() const
AbstractTypePtr NativeTypeArgAt(int index) const
void SetReturn(const Object &value) const
static intptr_t retval_offset()
static intptr_t argc_tag_offset()
static intptr_t thread_offset()
ObjectPtr ArgAt(int index) const
static intptr_t argv_offset()
void SetArgAt(int index, const Object &value) const
TypeArgumentsPtr NativeTypeArgs() const
ObjectPtr NativeArgAt(int index) const
static intptr_t ParameterCountForResolution(const Function &function)
ObjectPtr NativeArg0() const
ObjectPtr ReturnValue() const
static int ComputeArgcTag(const Function &function)
bool IsNull() const
Definition object.h:363
static Object & Handle()
Definition object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition object.h:325
ExecutionState execution_state() const
Definition thread.h:1027
intptr_t Length() const
Definition object.cc:7352
AbstractTypePtr TypeAt(intptr_t index) const
Definition object.cc:7366
#define ASSERT(E)
uint8_t value
Dart_NativeFunction function
Definition fuchsia.cc:51
#define MSAN_UNPOISON(ptr, len)
constexpr intptr_t kWordSize
Definition globals.h:509
#define OFFSET_OF(type, field)
Definition globals.h:138