1 // Copyright 2014 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/code-factory.h"
6
7 #include "src/bootstrapper.h"
8 #include "src/ic/ic.h"
9 #include "src/objects-inl.h"
10
11 namespace v8 {
12 namespace internal {
13
14 namespace {
15
16 // TODO(ishell): make it (const Stub& stub) once CodeStub::GetCode() is const.
17 template <typename Stub>
make_callable(Stub & stub)18 Callable make_callable(Stub& stub) {
19 typedef typename Stub::Descriptor Descriptor;
20 return Callable(stub.GetCode(), Descriptor(stub.isolate()));
21 }
22
23 } // namespace
24
25 // static
RuntimeCEntry(Isolate * isolate,int result_size)26 Handle<Code> CodeFactory::RuntimeCEntry(Isolate* isolate, int result_size) {
27 CEntryStub stub(isolate, result_size);
28 return stub.GetCode();
29 }
30
31 // static
LoadIC(Isolate * isolate)32 Callable CodeFactory::LoadIC(Isolate* isolate) {
33 return Callable(isolate->builtins()->LoadICTrampoline(),
34 LoadDescriptor(isolate));
35 }
36
37 // static
LoadICProtoArray(Isolate * isolate,bool throw_if_nonexistent)38 Callable CodeFactory::LoadICProtoArray(Isolate* isolate,
39 bool throw_if_nonexistent) {
40 return Callable(
41 throw_if_nonexistent
42 ? isolate->builtins()->LoadICProtoArrayThrowIfNonexistent()
43 : isolate->builtins()->LoadICProtoArray(),
44 LoadICProtoArrayDescriptor(isolate));
45 }
46
47 // static
ApiGetter(Isolate * isolate)48 Callable CodeFactory::ApiGetter(Isolate* isolate) {
49 CallApiGetterStub stub(isolate);
50 return make_callable(stub);
51 }
52
53 // static
LoadICInOptimizedCode(Isolate * isolate)54 Callable CodeFactory::LoadICInOptimizedCode(Isolate* isolate) {
55 return Callable(isolate->builtins()->LoadIC(),
56 LoadWithVectorDescriptor(isolate));
57 }
58
59 // static
LoadGlobalIC(Isolate * isolate,TypeofMode typeof_mode)60 Callable CodeFactory::LoadGlobalIC(Isolate* isolate, TypeofMode typeof_mode) {
61 return Callable(
62 typeof_mode == NOT_INSIDE_TYPEOF
63 ? isolate->builtins()->LoadGlobalICTrampoline()
64 : isolate->builtins()->LoadGlobalICInsideTypeofTrampoline(),
65 LoadGlobalDescriptor(isolate));
66 }
67
68 // static
LoadGlobalICInOptimizedCode(Isolate * isolate,TypeofMode typeof_mode)69 Callable CodeFactory::LoadGlobalICInOptimizedCode(Isolate* isolate,
70 TypeofMode typeof_mode) {
71 return Callable(typeof_mode == NOT_INSIDE_TYPEOF
72 ? isolate->builtins()->LoadGlobalIC()
73 : isolate->builtins()->LoadGlobalICInsideTypeof(),
74 LoadGlobalWithVectorDescriptor(isolate));
75 }
76
77 // static
KeyedLoadIC(Isolate * isolate)78 Callable CodeFactory::KeyedLoadIC(Isolate* isolate) {
79 return Callable(isolate->builtins()->KeyedLoadICTrampoline(),
80 LoadDescriptor(isolate));
81 }
82
83 // static
KeyedLoadICInOptimizedCode(Isolate * isolate)84 Callable CodeFactory::KeyedLoadICInOptimizedCode(Isolate* isolate) {
85 return Callable(isolate->builtins()->KeyedLoadIC(),
86 LoadWithVectorDescriptor(isolate));
87 }
88
89 // static
CallIC(Isolate * isolate,ConvertReceiverMode mode,TailCallMode tail_call_mode)90 Callable CodeFactory::CallIC(Isolate* isolate, ConvertReceiverMode mode,
91 TailCallMode tail_call_mode) {
92 CallICStub stub(isolate, mode, tail_call_mode);
93 return make_callable(stub);
94 }
95
96 // static
CallICTrampoline(Isolate * isolate,ConvertReceiverMode mode,TailCallMode tail_call_mode)97 Callable CodeFactory::CallICTrampoline(Isolate* isolate,
98 ConvertReceiverMode mode,
99 TailCallMode tail_call_mode) {
100 CallICTrampolineStub stub(isolate, mode, tail_call_mode);
101 return make_callable(stub);
102 }
103
104 // static
StoreIC(Isolate * isolate,LanguageMode language_mode)105 Callable CodeFactory::StoreIC(Isolate* isolate, LanguageMode language_mode) {
106 return Callable(language_mode == STRICT
107 ? isolate->builtins()->StoreICStrictTrampoline()
108 : isolate->builtins()->StoreICTrampoline(),
109 StoreDescriptor(isolate));
110 }
111
112 // static
StoreICInOptimizedCode(Isolate * isolate,LanguageMode language_mode)113 Callable CodeFactory::StoreICInOptimizedCode(Isolate* isolate,
114 LanguageMode language_mode) {
115 return Callable(language_mode == STRICT ? isolate->builtins()->StoreICStrict()
116 : isolate->builtins()->StoreIC(),
117 StoreWithVectorDescriptor(isolate));
118 }
119
StoreOwnIC(Isolate * isolate)120 Callable CodeFactory::StoreOwnIC(Isolate* isolate) {
121 // TODO(ishell): Currently we use StoreOwnIC only for storing properties that
122 // already exist in the boilerplate therefore we can use StoreIC.
123 return Callable(isolate->builtins()->StoreICStrictTrampoline(),
124 StoreDescriptor(isolate));
125 }
126
StoreOwnICInOptimizedCode(Isolate * isolate)127 Callable CodeFactory::StoreOwnICInOptimizedCode(Isolate* isolate) {
128 // TODO(ishell): Currently we use StoreOwnIC only for storing properties that
129 // already exist in the boilerplate therefore we can use StoreIC.
130 return Callable(isolate->builtins()->StoreICStrict(),
131 StoreWithVectorDescriptor(isolate));
132 }
133
134 // static
KeyedStoreIC(Isolate * isolate,LanguageMode language_mode)135 Callable CodeFactory::KeyedStoreIC(Isolate* isolate,
136 LanguageMode language_mode) {
137 return Callable(language_mode == STRICT
138 ? isolate->builtins()->KeyedStoreICStrictTrampoline()
139 : isolate->builtins()->KeyedStoreICTrampoline(),
140 StoreDescriptor(isolate));
141 }
142
143 // static
KeyedStoreICInOptimizedCode(Isolate * isolate,LanguageMode language_mode)144 Callable CodeFactory::KeyedStoreICInOptimizedCode(Isolate* isolate,
145 LanguageMode language_mode) {
146 return Callable(language_mode == STRICT
147 ? isolate->builtins()->KeyedStoreICStrict()
148 : isolate->builtins()->KeyedStoreIC(),
149 StoreWithVectorDescriptor(isolate));
150 }
151
152 // static
KeyedStoreIC_Megamorphic(Isolate * isolate,LanguageMode language_mode)153 Callable CodeFactory::KeyedStoreIC_Megamorphic(Isolate* isolate,
154 LanguageMode language_mode) {
155 return Callable(language_mode == STRICT
156 ? isolate->builtins()->KeyedStoreIC_Megamorphic_Strict()
157 : isolate->builtins()->KeyedStoreIC_Megamorphic(),
158 StoreWithVectorDescriptor(isolate));
159 }
160
161 // static
CompareIC(Isolate * isolate,Token::Value op)162 Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op) {
163 CompareICStub stub(isolate, op);
164 return make_callable(stub);
165 }
166
167 // static
BinaryOpIC(Isolate * isolate,Token::Value op)168 Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op) {
169 BinaryOpICStub stub(isolate, op);
170 return make_callable(stub);
171 }
172
173 // static
GetProperty(Isolate * isolate)174 Callable CodeFactory::GetProperty(Isolate* isolate) {
175 GetPropertyStub stub(isolate);
176 return make_callable(stub);
177 }
178
179 // static
NonPrimitiveToPrimitive(Isolate * isolate,ToPrimitiveHint hint)180 Callable CodeFactory::NonPrimitiveToPrimitive(Isolate* isolate,
181 ToPrimitiveHint hint) {
182 return Callable(isolate->builtins()->NonPrimitiveToPrimitive(hint),
183 TypeConversionDescriptor(isolate));
184 }
185
186 // static
OrdinaryToPrimitive(Isolate * isolate,OrdinaryToPrimitiveHint hint)187 Callable CodeFactory::OrdinaryToPrimitive(Isolate* isolate,
188 OrdinaryToPrimitiveHint hint) {
189 return Callable(isolate->builtins()->OrdinaryToPrimitive(hint),
190 TypeConversionDescriptor(isolate));
191 }
192
193 // static
NumberToString(Isolate * isolate)194 Callable CodeFactory::NumberToString(Isolate* isolate) {
195 NumberToStringStub stub(isolate);
196 return make_callable(stub);
197 }
198
199 // static
RegExpExec(Isolate * isolate)200 Callable CodeFactory::RegExpExec(Isolate* isolate) {
201 RegExpExecStub stub(isolate);
202 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
203 }
204
205 // static
StringFromCharCode(Isolate * isolate)206 Callable CodeFactory::StringFromCharCode(Isolate* isolate) {
207 Handle<Code> code(isolate->builtins()->StringFromCharCode());
208 return Callable(code, BuiltinDescriptor(isolate));
209 }
210
211 #define DECLARE_TFS(Name, Kind, Extra, InterfaceDescriptor, result_size) \
212 typedef InterfaceDescriptor##Descriptor Name##Descriptor;
BUILTIN_LIST(IGNORE_BUILTIN,IGNORE_BUILTIN,IGNORE_BUILTIN,DECLARE_TFS,IGNORE_BUILTIN,IGNORE_BUILTIN,IGNORE_BUILTIN)213 BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, DECLARE_TFS,
214 IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
215 #undef DECLARE_TFS
216
217 #define TFS_BUILTIN(Name) \
218 Callable CodeFactory::Name(Isolate* isolate) { \
219 Handle<Code> code(isolate->builtins()->Name()); \
220 return Callable(code, Name##Descriptor(isolate)); \
221 }
222
223 TFS_BUILTIN(ToString)
224 TFS_BUILTIN(Add)
225 TFS_BUILTIN(Subtract)
226 TFS_BUILTIN(Multiply)
227 TFS_BUILTIN(Divide)
228 TFS_BUILTIN(Modulus)
229 TFS_BUILTIN(BitwiseAnd)
230 TFS_BUILTIN(BitwiseOr)
231 TFS_BUILTIN(BitwiseXor)
232 TFS_BUILTIN(ShiftLeft)
233 TFS_BUILTIN(ShiftRight)
234 TFS_BUILTIN(ShiftRightLogical)
235 TFS_BUILTIN(LessThan)
236 TFS_BUILTIN(LessThanOrEqual)
237 TFS_BUILTIN(GreaterThan)
238 TFS_BUILTIN(GreaterThanOrEqual)
239 TFS_BUILTIN(Equal)
240 TFS_BUILTIN(NotEqual)
241 TFS_BUILTIN(StrictEqual)
242 TFS_BUILTIN(StrictNotEqual)
243 TFS_BUILTIN(CreateIterResultObject)
244 TFS_BUILTIN(HasProperty)
245 TFS_BUILTIN(NonNumberToNumber)
246 TFS_BUILTIN(StringToNumber)
247 TFS_BUILTIN(ToBoolean)
248 TFS_BUILTIN(ToInteger)
249 TFS_BUILTIN(ToLength)
250 TFS_BUILTIN(ToName)
251 TFS_BUILTIN(ToNumber)
252 TFS_BUILTIN(ToObject)
253 TFS_BUILTIN(ClassOf)
254 TFS_BUILTIN(Typeof)
255 TFS_BUILTIN(InstanceOf)
256 TFS_BUILTIN(OrdinaryHasInstance)
257 TFS_BUILTIN(CopyFastSmiOrObjectElements)
258 TFS_BUILTIN(GrowFastDoubleElements)
259 TFS_BUILTIN(GrowFastSmiOrObjectElements)
260 TFS_BUILTIN(NewUnmappedArgumentsElements)
261 TFS_BUILTIN(NewRestParameterElements)
262 TFS_BUILTIN(FastCloneRegExp)
263 TFS_BUILTIN(FastNewClosure)
264 TFS_BUILTIN(FastNewObject)
265 TFS_BUILTIN(ForInFilter)
266 TFS_BUILTIN(GetSuperConstructor)
267 TFS_BUILTIN(KeyedLoadIC_Megamorphic)
268 TFS_BUILTIN(PromiseHandleReject)
269 TFS_BUILTIN(RegExpReplace)
270 TFS_BUILTIN(RegExpSplit)
271 TFS_BUILTIN(StringCharAt)
272 TFS_BUILTIN(StringCharCodeAt)
273 TFS_BUILTIN(StringEqual)
274 TFS_BUILTIN(StringNotEqual)
275 TFS_BUILTIN(StringLessThan)
276 TFS_BUILTIN(StringLessThanOrEqual)
277 TFS_BUILTIN(StringGreaterThan)
278 TFS_BUILTIN(StringGreaterThanOrEqual)
279
280 #undef TFS_BUILTIN
281
282 // static
283 Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags,
284 PretenureFlag pretenure_flag) {
285 StringAddStub stub(isolate, flags, pretenure_flag);
286 return make_callable(stub);
287 }
288
289 // static
StringCompare(Isolate * isolate,Token::Value token)290 Callable CodeFactory::StringCompare(Isolate* isolate, Token::Value token) {
291 switch (token) {
292 case Token::EQ:
293 case Token::EQ_STRICT:
294 return StringEqual(isolate);
295 case Token::NE:
296 case Token::NE_STRICT:
297 return StringNotEqual(isolate);
298 case Token::LT:
299 return StringLessThan(isolate);
300 case Token::GT:
301 return StringGreaterThan(isolate);
302 case Token::LTE:
303 return StringLessThanOrEqual(isolate);
304 case Token::GTE:
305 return StringGreaterThanOrEqual(isolate);
306 default:
307 break;
308 }
309 UNREACHABLE();
310 return StringEqual(isolate);
311 }
312
313 // static
StringIndexOf(Isolate * isolate)314 Callable CodeFactory::StringIndexOf(Isolate* isolate) {
315 return Callable(isolate->builtins()->StringIndexOf(),
316 StringIndexOfDescriptor(isolate));
317 }
318
319 // static
SubString(Isolate * isolate)320 Callable CodeFactory::SubString(Isolate* isolate) {
321 SubStringStub stub(isolate);
322 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
323 }
324
325 // static
ResumeGenerator(Isolate * isolate)326 Callable CodeFactory::ResumeGenerator(Isolate* isolate) {
327 return Callable(isolate->builtins()->ResumeGeneratorTrampoline(),
328 ResumeGeneratorDescriptor(isolate));
329 }
330
331 // static
FrameDropperTrampoline(Isolate * isolate)332 Callable CodeFactory::FrameDropperTrampoline(Isolate* isolate) {
333 return Callable(isolate->builtins()->FrameDropperTrampoline(),
334 FrameDropperTrampolineDescriptor(isolate));
335 }
336
337 // static
HandleDebuggerStatement(Isolate * isolate)338 Callable CodeFactory::HandleDebuggerStatement(Isolate* isolate) {
339 return Callable(isolate->builtins()->HandleDebuggerStatement(),
340 ContextOnlyDescriptor(isolate));
341 }
342
343 // static
FastCloneShallowArray(Isolate * isolate,AllocationSiteMode allocation_mode)344 Callable CodeFactory::FastCloneShallowArray(
345 Isolate* isolate, AllocationSiteMode allocation_mode) {
346 return Callable(isolate->builtins()->NewCloneShallowArray(allocation_mode),
347 FastCloneShallowArrayDescriptor(isolate));
348 }
349
350 // static
FastCloneShallowObject(Isolate * isolate,int length)351 Callable CodeFactory::FastCloneShallowObject(Isolate* isolate, int length) {
352 return Callable(isolate->builtins()->NewCloneShallowObject(length),
353 FastCloneShallowObjectDescriptor(isolate));
354 }
355
356 // static
FastNewFunctionContext(Isolate * isolate,ScopeType scope_type)357 Callable CodeFactory::FastNewFunctionContext(Isolate* isolate,
358 ScopeType scope_type) {
359 return Callable(isolate->builtins()->NewFunctionContext(scope_type),
360 FastNewFunctionContextDescriptor(isolate));
361 }
362
363 // static
FastNewRestParameter(Isolate * isolate)364 Callable CodeFactory::FastNewRestParameter(Isolate* isolate) {
365 return Callable(isolate->builtins()->FastNewRestParameter(),
366 FastNewRestParameterDescriptor(isolate));
367 }
368
369 // static
FastNewSloppyArguments(Isolate * isolate)370 Callable CodeFactory::FastNewSloppyArguments(Isolate* isolate) {
371 return Callable(isolate->builtins()->FastNewSloppyArguments(),
372 FastNewRestParameterDescriptor(isolate));
373 }
374
375 // static
FastNewStrictArguments(Isolate * isolate)376 Callable CodeFactory::FastNewStrictArguments(Isolate* isolate) {
377 return Callable(isolate->builtins()->FastNewStrictArguments(),
378 FastNewRestParameterDescriptor(isolate));
379 }
380
381 // static
ForInPrepare(Isolate * isolate)382 Callable CodeFactory::ForInPrepare(Isolate* isolate) {
383 return Callable(isolate->builtins()->ForInPrepare(),
384 ForInPrepareDescriptor(isolate));
385 }
386
387 // static
ForInNext(Isolate * isolate)388 Callable CodeFactory::ForInNext(Isolate* isolate) {
389 return Callable(isolate->builtins()->ForInNext(),
390 ForInNextDescriptor(isolate));
391 }
392
393 // static
AllocateHeapNumber(Isolate * isolate)394 Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) {
395 AllocateHeapNumberStub stub(isolate);
396 return make_callable(stub);
397 }
398
399 // static
ArgumentAdaptor(Isolate * isolate)400 Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) {
401 return Callable(isolate->builtins()->ArgumentsAdaptorTrampoline(),
402 ArgumentAdaptorDescriptor(isolate));
403 }
404
405 // static
Call(Isolate * isolate,ConvertReceiverMode mode,TailCallMode tail_call_mode)406 Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode,
407 TailCallMode tail_call_mode) {
408 return Callable(isolate->builtins()->Call(mode, tail_call_mode),
409 CallTrampolineDescriptor(isolate));
410 }
411
412 // static
CallWithSpread(Isolate * isolate)413 Callable CodeFactory::CallWithSpread(Isolate* isolate) {
414 return Callable(isolate->builtins()->CallWithSpread(),
415 CallTrampolineDescriptor(isolate));
416 }
417
418 // static
CallFunction(Isolate * isolate,ConvertReceiverMode mode,TailCallMode tail_call_mode)419 Callable CodeFactory::CallFunction(Isolate* isolate, ConvertReceiverMode mode,
420 TailCallMode tail_call_mode) {
421 return Callable(isolate->builtins()->CallFunction(mode, tail_call_mode),
422 CallTrampolineDescriptor(isolate));
423 }
424
425 // static
CallForwardVarargs(Isolate * isolate)426 Callable CodeFactory::CallForwardVarargs(Isolate* isolate) {
427 return Callable(isolate->builtins()->CallForwardVarargs(),
428 CallForwardVarargsDescriptor(isolate));
429 }
430
431 // static
CallFunctionForwardVarargs(Isolate * isolate)432 Callable CodeFactory::CallFunctionForwardVarargs(Isolate* isolate) {
433 return Callable(isolate->builtins()->CallFunctionForwardVarargs(),
434 CallForwardVarargsDescriptor(isolate));
435 }
436
437 // static
Construct(Isolate * isolate)438 Callable CodeFactory::Construct(Isolate* isolate) {
439 return Callable(isolate->builtins()->Construct(),
440 ConstructTrampolineDescriptor(isolate));
441 }
442
443 // static
ConstructWithSpread(Isolate * isolate)444 Callable CodeFactory::ConstructWithSpread(Isolate* isolate) {
445 return Callable(isolate->builtins()->ConstructWithSpread(),
446 ConstructTrampolineDescriptor(isolate));
447 }
448
449 // static
ConstructFunction(Isolate * isolate)450 Callable CodeFactory::ConstructFunction(Isolate* isolate) {
451 return Callable(isolate->builtins()->ConstructFunction(),
452 ConstructTrampolineDescriptor(isolate));
453 }
454
455 // static
InterpreterPushArgsAndCall(Isolate * isolate,TailCallMode tail_call_mode,InterpreterPushArgsMode mode)456 Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate,
457 TailCallMode tail_call_mode,
458 InterpreterPushArgsMode mode) {
459 return Callable(
460 isolate->builtins()->InterpreterPushArgsAndCall(tail_call_mode, mode),
461 InterpreterPushArgsAndCallDescriptor(isolate));
462 }
463
464 // static
InterpreterPushArgsAndConstruct(Isolate * isolate,InterpreterPushArgsMode mode)465 Callable CodeFactory::InterpreterPushArgsAndConstruct(
466 Isolate* isolate, InterpreterPushArgsMode mode) {
467 return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(mode),
468 InterpreterPushArgsAndConstructDescriptor(isolate));
469 }
470
471 // static
InterpreterPushArgsAndConstructArray(Isolate * isolate)472 Callable CodeFactory::InterpreterPushArgsAndConstructArray(Isolate* isolate) {
473 return Callable(isolate->builtins()->InterpreterPushArgsAndConstructArray(),
474 InterpreterPushArgsAndConstructArrayDescriptor(isolate));
475 }
476
477 // static
InterpreterCEntry(Isolate * isolate,int result_size)478 Callable CodeFactory::InterpreterCEntry(Isolate* isolate, int result_size) {
479 // Note: If we ever use fpregs in the interpreter then we will need to
480 // save fpregs too.
481 CEntryStub stub(isolate, result_size, kDontSaveFPRegs, kArgvInRegister);
482 return Callable(stub.GetCode(), InterpreterCEntryDescriptor(isolate));
483 }
484
485 // static
InterpreterOnStackReplacement(Isolate * isolate)486 Callable CodeFactory::InterpreterOnStackReplacement(Isolate* isolate) {
487 return Callable(isolate->builtins()->InterpreterOnStackReplacement(),
488 ContextOnlyDescriptor(isolate));
489 }
490
491 // static
ArrayConstructor(Isolate * isolate)492 Callable CodeFactory::ArrayConstructor(Isolate* isolate) {
493 ArrayConstructorStub stub(isolate);
494 return make_callable(stub);
495 }
496
497 // static
ArrayPush(Isolate * isolate)498 Callable CodeFactory::ArrayPush(Isolate* isolate) {
499 return Callable(isolate->builtins()->ArrayPush(), BuiltinDescriptor(isolate));
500 }
501
502 // static
FunctionPrototypeBind(Isolate * isolate)503 Callable CodeFactory::FunctionPrototypeBind(Isolate* isolate) {
504 return Callable(isolate->builtins()->FunctionPrototypeBind(),
505 BuiltinDescriptor(isolate));
506 }
507
508 } // namespace internal
509 } // namespace v8
510