Line data Source code
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/builtins/builtins.h"
6 : #include "src/api.h"
7 : #include "src/assembler-inl.h"
8 : #include "src/builtins/builtins-descriptors.h"
9 : #include "src/callable.h"
10 : #include "src/isolate.h"
11 : #include "src/macro-assembler.h"
12 : #include "src/objects-inl.h"
13 : #include "src/visitors.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 : // Forward declarations for C++ builtins.
19 : #define FORWARD_DECLARE(Name) \
20 : Object* Builtin_##Name(int argc, Object** args, Isolate* isolate);
21 : BUILTIN_LIST_C(FORWARD_DECLARE)
22 :
23 60782 : Builtins::Builtins() : initialized_(false) {
24 60782 : memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count);
25 60782 : }
26 :
27 59284 : Builtins::~Builtins() {}
28 :
29 59285 : void Builtins::TearDown() { initialized_ = false; }
30 :
31 172396 : void Builtins::IterateBuiltins(RootVisitor* v) {
32 : v->VisitRootPointers(Root::kBuiltins, &builtins_[0],
33 172396 : &builtins_[0] + builtin_count);
34 172396 : }
35 :
36 0 : const char* Builtins::Lookup(byte* pc) {
37 : // may be called during initialization (disassembler!)
38 0 : if (initialized_) {
39 0 : for (int i = 0; i < builtin_count; i++) {
40 0 : Code* entry = Code::cast(builtins_[i]);
41 0 : if (entry->contains(pc)) return name(i);
42 : }
43 : }
44 : return NULL;
45 : }
46 :
47 45327 : Handle<Code> Builtins::NewFunctionContext(ScopeType scope_type) {
48 45327 : switch (scope_type) {
49 : case ScopeType::EVAL_SCOPE:
50 : return FastNewFunctionContextEval();
51 : case ScopeType::FUNCTION_SCOPE:
52 : return FastNewFunctionContextFunction();
53 : default:
54 0 : UNREACHABLE();
55 : }
56 : return Handle<Code>::null();
57 : }
58 :
59 92354 : Handle<Code> Builtins::NewCloneShallowArray(
60 : AllocationSiteMode allocation_mode) {
61 92354 : switch (allocation_mode) {
62 : case TRACK_ALLOCATION_SITE:
63 : return FastCloneShallowArrayTrack();
64 : case DONT_TRACK_ALLOCATION_SITE:
65 : return FastCloneShallowArrayDontTrack();
66 : default:
67 0 : UNREACHABLE();
68 : }
69 : return Handle<Code>::null();
70 : }
71 :
72 47983 : Handle<Code> Builtins::NewCloneShallowObject(int length) {
73 47983 : switch (length) {
74 : case 0:
75 : return FastCloneShallowObject0();
76 : case 1:
77 : return FastCloneShallowObject1();
78 : case 2:
79 : return FastCloneShallowObject2();
80 : case 3:
81 : return FastCloneShallowObject3();
82 : case 4:
83 : return FastCloneShallowObject4();
84 : case 5:
85 : return FastCloneShallowObject5();
86 : case 6:
87 : return FastCloneShallowObject6();
88 : default:
89 0 : UNREACHABLE();
90 : }
91 : return Handle<Code>::null();
92 : }
93 :
94 2200 : Handle<Code> Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) {
95 2200 : switch (hint) {
96 : case ToPrimitiveHint::kDefault:
97 : return NonPrimitiveToPrimitive_Default();
98 : case ToPrimitiveHint::kNumber:
99 : return NonPrimitiveToPrimitive_Number();
100 : case ToPrimitiveHint::kString:
101 : return NonPrimitiveToPrimitive_String();
102 : }
103 0 : UNREACHABLE();
104 : return Handle<Code>::null();
105 : }
106 :
107 215 : Handle<Code> Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) {
108 215 : switch (hint) {
109 : case OrdinaryToPrimitiveHint::kNumber:
110 : return OrdinaryToPrimitive_Number();
111 : case OrdinaryToPrimitiveHint::kString:
112 : return OrdinaryToPrimitive_String();
113 : }
114 0 : UNREACHABLE();
115 : return Handle<Code>::null();
116 : }
117 :
118 : // static
119 5739 : Callable Builtins::CallableFor(Isolate* isolate, Name name) {
120 5739 : switch (name) {
121 : #define CASE(Name, ...) \
122 : case k##Name: { \
123 : Handle<Code> code = isolate->builtins()->Name(); \
124 : auto descriptor = Builtin_##Name##_InterfaceDescriptor(isolate); \
125 : return Callable(code, descriptor); \
126 : }
127 5696 : BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, CASE, CASE,
128 : CASE, IGNORE_BUILTIN, IGNORE_BUILTIN)
129 : #undef CASE
130 : case kConsoleAssert: {
131 : Handle<Code> code = isolate->builtins()->ConsoleAssert();
132 86 : return Callable(code, BuiltinDescriptor(isolate));
133 : }
134 : default:
135 0 : UNREACHABLE();
136 : return Callable(Handle<Code>::null(), VoidDescriptor(isolate));
137 : }
138 : }
139 :
140 : // static
141 283062 : const char* Builtins::name(int index) {
142 283062 : switch (index) {
143 : #define CASE(Name, ...) \
144 : case k##Name: \
145 : return #Name;
146 426 : BUILTIN_LIST_ALL(CASE)
147 : #undef CASE
148 : default:
149 0 : UNREACHABLE();
150 : break;
151 : }
152 : return "";
153 : }
154 :
155 : // static
156 11764 : Address Builtins::CppEntryOf(int index) {
157 : DCHECK(0 <= index && index < builtin_count);
158 11764 : switch (index) {
159 : #define CASE(Name, ...) \
160 : case k##Name: \
161 : return FUNCTION_ADDR(Builtin_##Name);
162 : BUILTIN_LIST_C(CASE)
163 : #undef CASE
164 : default:
165 : return nullptr;
166 : }
167 : UNREACHABLE();
168 : }
169 :
170 : // static
171 11764 : bool Builtins::IsCpp(int index) {
172 : DCHECK(0 <= index && index < builtin_count);
173 11764 : switch (index) {
174 : #define CASE(Name, ...) \
175 : case k##Name: \
176 : return true;
177 : #define BUILTIN_LIST_CPP(V) \
178 : BUILTIN_LIST(V, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, \
179 : IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
180 : BUILTIN_LIST_CPP(CASE)
181 : #undef BUILTIN_LIST_CPP
182 : #undef CASE
183 : default:
184 93 : return false;
185 : }
186 : UNREACHABLE();
187 : }
188 :
189 : // static
190 0 : bool Builtins::IsApi(int index) {
191 : DCHECK(0 <= index && index < builtin_count);
192 0 : switch (index) {
193 : #define CASE(Name, ...) \
194 : case k##Name: \
195 : return true;
196 : #define BUILTIN_LIST_API(V) \
197 : BUILTIN_LIST(IGNORE_BUILTIN, V, IGNORE_BUILTIN, IGNORE_BUILTIN, \
198 : IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
199 : BUILTIN_LIST_API(CASE);
200 : #undef BUILTIN_LIST_API
201 : #undef CASE
202 : default:
203 0 : return false;
204 : }
205 : UNREACHABLE();
206 : }
207 :
208 : // static
209 135428 : bool Builtins::HasCppImplementation(int index) {
210 : DCHECK(0 <= index && index < builtin_count);
211 135428 : switch (index) {
212 : #define CASE(Name, ...) \
213 : case k##Name: \
214 : return true;
215 : BUILTIN_LIST_C(CASE)
216 : #undef CASE
217 : default:
218 123651 : return false;
219 : }
220 : UNREACHABLE();
221 : }
222 :
223 : #define DEFINE_BUILTIN_ACCESSOR(Name, ...) \
224 : Handle<Code> Builtins::Name() { \
225 : Code** code_address = reinterpret_cast<Code**>(builtin_address(k##Name)); \
226 : return Handle<Code>(code_address); \
227 : }
228 102124325 : BUILTIN_LIST_ALL(DEFINE_BUILTIN_ACCESSOR)
229 : #undef DEFINE_BUILTIN_ACCESSOR
230 :
231 : // static
232 3599990 : bool Builtins::AllowDynamicFunction(Isolate* isolate, Handle<JSFunction> target,
233 : Handle<JSObject> target_global_proxy) {
234 1800191 : if (FLAG_allow_unsafe_function_constructor) return true;
235 : HandleScopeImplementer* impl = isolate->handle_scope_implementer();
236 : Handle<Context> responsible_context =
237 : impl->MicrotaskContextIsLastEnteredContext() ? impl->MicrotaskContext()
238 1799799 : : impl->LastEnteredContext();
239 : // TODO(jochen): Remove this.
240 1799799 : if (responsible_context.is_null()) {
241 : return true;
242 : }
243 1799799 : if (*responsible_context == target->context()) return true;
244 406 : return isolate->MayAccess(responsible_context, target_global_proxy);
245 : }
246 :
247 : } // namespace internal
248 : } // namespace v8
|