V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
runtime.cc
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/runtime/runtime.h"
6 
7 #include "src/base/hashmap.h"
8 #include "src/contexts.h"
9 #include "src/handles-inl.h"
10 #include "src/heap/heap.h"
11 #include "src/isolate.h"
12 #include "src/objects-inl.h"
13 #include "src/reloc-info.h"
14 #include "src/runtime/runtime-utils.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 // Header of runtime functions.
20 #define F(name, number_of_args, result_size) \
21  Object* Runtime_##name(int args_length, Address* args_object, \
22  Isolate* isolate);
23 FOR_EACH_INTRINSIC_RETURN_OBJECT(F)
24 #undef F
25 
26 #define P(name, number_of_args, result_size) \
27  ObjectPair Runtime_##name(int args_length, Address* args_object, \
28  Isolate* isolate);
29 FOR_EACH_INTRINSIC_RETURN_PAIR(P)
30 #undef P
31 
32 #define F(name, number_of_args, result_size) \
33  { \
34  Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
35  number_of_args, result_size \
36  } \
37  ,
38 
39 
40 #define I(name, number_of_args, result_size) \
41  { \
42  Runtime::kInline##name, Runtime::INLINE, "_" #name, \
43  FUNCTION_ADDR(Runtime_##name), number_of_args, result_size \
44  } \
45  ,
46 
47 static const Runtime::Function kIntrinsicFunctions[] = {
48  FOR_EACH_INTRINSIC(F) FOR_EACH_INLINE_INTRINSIC(I)};
49 
50 #undef I
51 #undef F
52 
53 namespace {
54 
55 V8_DECLARE_ONCE(initialize_function_name_map_once);
56 static const base::CustomMatcherHashMap* kRuntimeFunctionNameMap;
57 
58 struct IntrinsicFunctionIdentifier {
59  IntrinsicFunctionIdentifier(const unsigned char* data, const int length)
60  : data_(data), length_(length) {}
61 
62  static bool Match(void* key1, void* key2) {
63  const IntrinsicFunctionIdentifier* lhs =
64  static_cast<IntrinsicFunctionIdentifier*>(key1);
65  const IntrinsicFunctionIdentifier* rhs =
66  static_cast<IntrinsicFunctionIdentifier*>(key2);
67  if (lhs->length_ != rhs->length_) return false;
68  return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs->data_),
69  reinterpret_cast<const uint8_t*>(rhs->data_),
70  rhs->length_) == 0;
71  }
72 
73  uint32_t Hash() {
74  return StringHasher::HashSequentialString<uint8_t>(
75  data_, length_, v8::internal::kZeroHashSeed);
76  }
77 
78  const unsigned char* data_;
79  const int length_;
80 };
81 
82 void InitializeIntrinsicFunctionNames() {
83  base::CustomMatcherHashMap* function_name_map =
84  new base::CustomMatcherHashMap(IntrinsicFunctionIdentifier::Match);
85  for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
86  const Runtime::Function* function = &kIntrinsicFunctions[i];
87  IntrinsicFunctionIdentifier* identifier = new IntrinsicFunctionIdentifier(
88  reinterpret_cast<const unsigned char*>(function->name),
89  static_cast<int>(strlen(function->name)));
90  base::HashMap::Entry* entry =
91  function_name_map->InsertNew(identifier, identifier->Hash());
92  entry->value = const_cast<Runtime::Function*>(function);
93  }
94  kRuntimeFunctionNameMap = function_name_map;
95 }
96 
97 } // namespace
98 
99 bool Runtime::NeedsExactContext(FunctionId id) {
100  switch (id) {
101  case Runtime::kInlineAsyncFunctionReject:
102  case Runtime::kInlineAsyncFunctionResolve:
103  // For %_AsyncFunctionReject and %_AsyncFunctionResolve we don't
104  // really need the current context, which in particular allows
105  // us to usually eliminate the catch context for the implicit
106  // try-catch in async function.
107  return false;
108  case Runtime::kAddPrivateField:
109  case Runtime::kCopyDataProperties:
110  case Runtime::kCreateDataProperty:
111  case Runtime::kCreatePrivateNameSymbol:
112  case Runtime::kReThrow:
113  case Runtime::kThrow:
114  case Runtime::kThrowApplyNonFunction:
115  case Runtime::kThrowCalledNonCallable:
116  case Runtime::kThrowConstAssignError:
117  case Runtime::kThrowConstructorNonCallableError:
118  case Runtime::kThrowConstructedNonConstructable:
119  case Runtime::kThrowConstructorReturnedNonObject:
120  case Runtime::kThrowInvalidStringLength:
121  case Runtime::kThrowInvalidTypedArrayAlignment:
122  case Runtime::kThrowIteratorError:
123  case Runtime::kThrowIteratorResultNotAnObject:
124  case Runtime::kThrowNotConstructor:
125  case Runtime::kThrowRangeError:
126  case Runtime::kThrowReferenceError:
127  case Runtime::kThrowStackOverflow:
128  case Runtime::kThrowStaticPrototypeError:
129  case Runtime::kThrowSuperAlreadyCalledError:
130  case Runtime::kThrowSuperNotCalled:
131  case Runtime::kThrowSymbolAsyncIteratorInvalid:
132  case Runtime::kThrowSymbolIteratorInvalid:
133  case Runtime::kThrowThrowMethodMissing:
134  case Runtime::kThrowTypeError:
135  case Runtime::kThrowUnsupportedSuperError:
136  case Runtime::kThrowWasmError:
137  case Runtime::kThrowWasmStackOverflow:
138  return false;
139  default:
140  return true;
141  }
142 }
143 
144 bool Runtime::IsNonReturning(FunctionId id) {
145  switch (id) {
146  case Runtime::kThrowUnsupportedSuperError:
147  case Runtime::kThrowConstructorNonCallableError:
148  case Runtime::kThrowStaticPrototypeError:
149  case Runtime::kThrowSuperAlreadyCalledError:
150  case Runtime::kThrowSuperNotCalled:
151  case Runtime::kReThrow:
152  case Runtime::kThrow:
153  case Runtime::kThrowApplyNonFunction:
154  case Runtime::kThrowCalledNonCallable:
155  case Runtime::kThrowConstructedNonConstructable:
156  case Runtime::kThrowConstructorReturnedNonObject:
157  case Runtime::kThrowInvalidStringLength:
158  case Runtime::kThrowInvalidTypedArrayAlignment:
159  case Runtime::kThrowIteratorError:
160  case Runtime::kThrowIteratorResultNotAnObject:
161  case Runtime::kThrowThrowMethodMissing:
162  case Runtime::kThrowSymbolIteratorInvalid:
163  case Runtime::kThrowNotConstructor:
164  case Runtime::kThrowRangeError:
165  case Runtime::kThrowReferenceError:
166  case Runtime::kThrowStackOverflow:
167  case Runtime::kThrowSymbolAsyncIteratorInvalid:
168  case Runtime::kThrowTypeError:
169  case Runtime::kThrowConstAssignError:
170  case Runtime::kThrowWasmError:
171  case Runtime::kThrowWasmStackOverflow:
172  return true;
173  default:
174  return false;
175  }
176 }
177 
178 const Runtime::Function* Runtime::FunctionForName(const unsigned char* name,
179  int length) {
180  base::CallOnce(&initialize_function_name_map_once,
181  &InitializeIntrinsicFunctionNames);
182  IntrinsicFunctionIdentifier identifier(name, length);
183  base::HashMap::Entry* entry =
184  kRuntimeFunctionNameMap->Lookup(&identifier, identifier.Hash());
185  if (entry) {
186  return reinterpret_cast<Function*>(entry->value);
187  }
188  return nullptr;
189 }
190 
191 
192 const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
193  for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
194  if (entry == kIntrinsicFunctions[i].entry) {
195  return &(kIntrinsicFunctions[i]);
196  }
197  }
198  return nullptr;
199 }
200 
201 
202 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
203  return &(kIntrinsicFunctions[static_cast<int>(id)]);
204 }
205 
206 const Runtime::Function* Runtime::RuntimeFunctionTable(Isolate* isolate) {
207 #ifdef USE_SIMULATOR
208  // When running with the simulator we need to provide a table which has
209  // redirected runtime entry addresses.
210  if (!isolate->runtime_state()->redirected_intrinsic_functions()) {
211  size_t function_count = arraysize(kIntrinsicFunctions);
212  Function* redirected_functions = new Function[function_count];
213  memcpy(redirected_functions, kIntrinsicFunctions,
214  sizeof(kIntrinsicFunctions));
215  for (size_t i = 0; i < function_count; i++) {
216  ExternalReference redirected_entry =
217  ExternalReference::Create(static_cast<Runtime::FunctionId>(i));
218  redirected_functions[i].entry = redirected_entry.address();
219  }
220  isolate->runtime_state()->set_redirected_intrinsic_functions(
221  redirected_functions);
222  }
223 
224  return isolate->runtime_state()->redirected_intrinsic_functions();
225 #else
226  return kIntrinsicFunctions;
227 #endif
228 }
229 
230 std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
231  return os << Runtime::FunctionForId(id)->name;
232 }
233 
234 
235 } // namespace internal
236 } // namespace v8
Definition: libplatform.h:13