Flutter Engine
The Flutter Engine
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 }
35#else
36#define CHECK_STACK_ALIGNMENT \
37 { \
38 uword (*func)() = reinterpret_cast<uword (*)()>( \
39 StubCode::GetCStackPointer().EntryPoint()); \
40 uword current_sp = func(); \
41 ASSERT(Utils::IsAligned(current_sp, OS::ActivationFrameAlignment())); \
42 }
43#endif
44
45#define DEOPTIMIZE_ALOT \
46 if (FLAG_deoptimize_alot) { \
47 DeoptimizeFunctionsOnStack(); \
48 }
49
50#else
51
52#define CHECK_STACK_ALIGNMENT \
53 { \
54 }
55#define DEOPTIMIZE_ALOT \
56 { \
57 }
58
59#endif
60
61// Class NativeArguments is used to access arguments passed in from
62// generated dart code to a runtime function or a dart library native
63// function. It is also used to set the return value if any at the slot
64// reserved for return values.
65// All runtime function/dart library native functions have the
66// following signature:
67// void function_name(NativeArguments arguments);
68// Inside the function, arguments are accessed as follows:
69// const Instance& arg0 = Instance::CheckedHandle(arguments.NativeArgAt(0));
70// const Smi& arg1 = Smi::CheckedHandle(arguments.NativeArgAt(1));
71// If the function is generic, type arguments are accessed as follows:
72// const TypeArguments& type_args =
73// TypeArguments::Handle(arguments.NativeTypeArgs());
74// The return value is set as follows:
75// arguments.SetReturn(result);
76// NOTE: Since we pass 'this' as a pass-by-value argument in the stubs we don't
77// have DISALLOW_COPY_AND_ASSIGN in the class definition and do not make it a
78// subclass of ValueObject.
80 public:
81 Thread* thread() const { return thread_; }
82
83 // Includes type arguments vector.
84 int ArgCount() const { return ArgcBits::decode(argc_tag_); }
85
86 ObjectPtr ArgAt(int index) const {
87 ASSERT((index >= 0) && (index < ArgCount()));
88 ObjectPtr* arg_ptr = &(argv_[-index]);
89 // Tell MemorySanitizer the ObjectPtr was initialized (by generated code).
90 MSAN_UNPOISON(arg_ptr, kWordSize);
91 return *arg_ptr;
92 }
93
94 void SetArgAt(int index, const Object& value) const {
96 ASSERT((index >= 0) && (index < ArgCount()));
97 argv_[-index] = value.ptr();
98 }
99
100 // Does not include hidden type arguments vector.
101 int NativeArgCount() const {
102 int function_bits = FunctionBits::decode(argc_tag_);
103 return ArgCount() - NumHiddenArgs(function_bits);
104 }
105
107 int function_bits = FunctionBits::decode(argc_tag_);
108 return ArgAt(NumHiddenArgs(function_bits));
109 }
110
111 ObjectPtr NativeArgAt(int index) const {
112 ASSERT((index >= 0) && (index < NativeArgCount()));
113 if (index == 0) {
114 return NativeArg0();
115 }
116 int function_bits = FunctionBits::decode(argc_tag_);
117 const int actual_index = index + NumHiddenArgs(function_bits);
118 return ArgAt(actual_index);
119 }
120
121 TypeArgumentsPtr NativeTypeArgs() const {
122 ASSERT(ToGenericFunction());
123 return TypeArguments::RawCast(ArgAt(0));
124 }
125
126 int NativeTypeArgCount() const {
127 if (ToGenericFunction()) {
129 if (type_args.IsNull()) {
130 // null vector represents infinite list of dynamics
131 return INT_MAX;
132 }
133 return type_args.Length();
134 }
135 return 0;
136 }
137
138 AbstractTypePtr NativeTypeArgAt(int index) const {
139 ASSERT((index >= 0) && (index < NativeTypeArgCount()));
141 if (type_args.IsNull()) {
142 // null vector represents infinite list of dynamics
143 return Type::dynamic_type().ptr();
144 }
145 return type_args.TypeAt(index);
146 }
147
148 void SetReturn(const Object& value) const {
150 *retval_ = value.ptr();
151 }
152
154 // Tell MemorySanitizer the retval_ was initialized (by generated code).
155 MSAN_UNPOISON(retval_, kWordSize);
156 return *retval_;
157 }
158
159 static intptr_t thread_offset() {
160 return OFFSET_OF(NativeArguments, thread_);
161 }
162 static intptr_t argc_tag_offset() {
163 return OFFSET_OF(NativeArguments, argc_tag_);
164 }
165 static intptr_t argv_offset() { return OFFSET_OF(NativeArguments, argv_); }
166 static intptr_t retval_offset() {
167 return OFFSET_OF(NativeArguments, retval_);
168 }
169
171 ASSERT(function.is_old_native());
172 ASSERT(!function.IsGenerativeConstructor()); // Not supported.
173 ASSERT(!function.IsClosureFunction()); // Not supported.
174 return function.NumParameters();
175 }
176
177 static int ComputeArgcTag(const Function& function) {
178 ASSERT(function.is_old_native());
179 ASSERT(!function.IsGenerativeConstructor()); // Not supported.
180 ASSERT(!function.IsClosureFunction()); // Not supported.
181 int argc = function.NumParameters();
182 int function_bits = 0;
183 if (function.IsGeneric()) {
184 function_bits |= kGenericFunctionBit;
185 argc++;
186 }
187 int tag = ArgcBits::encode(argc);
188 tag = FunctionBits::update(function_bits, tag);
189 return tag;
190 }
191
192 private:
193 enum {
194 kGenericFunctionBit = 1,
195 };
196 enum ArgcTagBits {
197 kArgcBit = 0,
198 kArgcSize = 24,
199 kFunctionBit = kArgcBit + kArgcSize,
200 kFunctionSize = 1,
201 };
202 class ArgcBits : public BitField<intptr_t, int32_t, kArgcBit, kArgcSize> {};
203 class FunctionBits
204 : public BitField<intptr_t, int, kFunctionBit, kFunctionSize> {};
205 friend class Api;
206 friend class NativeEntry;
207 friend class Simulator;
208
209 // Since this function is passed an ObjectPtr directly, we need to be
210 // exceedingly careful when we use it. If there are any other side
211 // effects in the statement that may cause GC, it could lead to
212 // bugs.
213 void SetReturnUnsafe(ObjectPtr value) const {
215 *retval_ = value;
216 }
217
218 // Returns true if the arguments are those of a generic function call.
219 bool ToGenericFunction() const {
220 return (FunctionBits::decode(argc_tag_) & kGenericFunctionBit) != 0;
221 }
222
223 int NumHiddenArgs(int function_bits) const {
224 int num_hidden_args = 0;
225 if ((function_bits & kGenericFunctionBit) == kGenericFunctionBit) {
226 num_hidden_args++;
227 }
228 return num_hidden_args;
229 }
230
231 Thread* thread_; // Current thread pointer.
232 intptr_t argc_tag_; // Encodes argument count and invoked native call type.
233 ObjectPtr* argv_; // Pointer to an array of arguments to runtime call.
234 ObjectPtr* retval_; // Pointer to the return value area.
235};
236
237} // namespace dart
238
239#endif // RUNTIME_VM_NATIVE_ARGUMENTS_H_
static void encode(uint8_t output[16], const uint32_t input[4])
Definition: SkMD5.cpp:240
Thread * thread() const
AbstractTypePtr NativeTypeArgAt(int index) const
void SetReturn(const Object &value) const
static intptr_t retval_offset()
int NativeTypeArgCount() const
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:1040
intptr_t Length() const
Definition: object.cc:7294
AbstractTypePtr TypeAt(intptr_t index) const
Definition: object.cc:7308
#define ASSERT(E)
uint8_t value
Dart_NativeFunction function
Definition: fuchsia.cc:51
#define MSAN_UNPOISON(ptr, len)
Definition: dart_vm.cc:33
constexpr intptr_t kWordSize
Definition: globals.h:509
static DecodeResult decode(std::string path)
Definition: png_codec.cpp:124
#define OFFSET_OF(type, field)
Definition: globals.h:138