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 10 namespace v8 { 11 namespace internal { 12 13 14 // static 15 Callable CodeFactory::LoadIC(Isolate* isolate) { 16 if (FLAG_tf_load_ic_stub) { 17 LoadICTrampolineTFStub stub(isolate); 18 return Callable(stub.GetCode(), LoadDescriptor(isolate)); 19 } 20 LoadICTrampolineStub stub(isolate); 21 return Callable(stub.GetCode(), LoadDescriptor(isolate)); 22 } 23 24 // static 25 Callable CodeFactory::ApiGetter(Isolate* isolate) { 26 CallApiGetterStub stub(isolate); 27 return Callable(stub.GetCode(), ApiGetterDescriptor(isolate)); 28 } 29 30 // static 31 Callable CodeFactory::LoadICInOptimizedCode(Isolate* isolate) { 32 auto code = LoadIC::initialize_stub_in_optimized_code(isolate); 33 return Callable(code, LoadWithVectorDescriptor(isolate)); 34 } 35 36 // static 37 Callable CodeFactory::LoadGlobalIC(Isolate* isolate, TypeofMode typeof_mode) { 38 LoadGlobalICTrampolineStub stub(isolate, LoadGlobalICState(typeof_mode)); 39 return Callable(stub.GetCode(), LoadGlobalDescriptor(isolate)); 40 } 41 42 // static 43 Callable CodeFactory::LoadGlobalICInOptimizedCode(Isolate* isolate, 44 TypeofMode typeof_mode) { 45 auto code = LoadGlobalIC::initialize_stub_in_optimized_code( 46 isolate, LoadGlobalICState(typeof_mode).GetExtraICState()); 47 return Callable(code, LoadGlobalWithVectorDescriptor(isolate)); 48 } 49 50 // static 51 Callable CodeFactory::KeyedLoadIC(Isolate* isolate) { 52 KeyedLoadICTrampolineStub stub(isolate); 53 return Callable(stub.GetCode(), LoadDescriptor(isolate)); 54 } 55 56 57 // static 58 Callable CodeFactory::KeyedLoadICInOptimizedCode(Isolate* isolate) { 59 auto code = 60 KeyedLoadIC::initialize_stub_in_optimized_code(isolate, kNoExtraICState); 61 return Callable(code, LoadWithVectorDescriptor(isolate)); 62 } 63 64 65 // static 66 Callable CodeFactory::CallIC(Isolate* isolate, int argc, 67 ConvertReceiverMode mode, 68 TailCallMode tail_call_mode) { 69 CallICTrampolineStub stub(isolate, CallICState(argc, mode, tail_call_mode)); 70 return Callable(stub.GetCode(), CallFunctionWithFeedbackDescriptor(isolate)); 71 } 72 73 74 // static 75 Callable CodeFactory::CallICInOptimizedCode(Isolate* isolate, int argc, 76 ConvertReceiverMode mode, 77 TailCallMode tail_call_mode) { 78 return Callable(CallIC::initialize_stub_in_optimized_code(isolate, argc, mode, 79 tail_call_mode), 80 CallFunctionWithFeedbackAndVectorDescriptor(isolate)); 81 } 82 83 84 // static 85 Callable CodeFactory::StoreIC(Isolate* isolate, LanguageMode language_mode) { 86 VectorStoreICTrampolineStub stub(isolate, StoreICState(language_mode)); 87 return Callable(stub.GetCode(), VectorStoreICTrampolineDescriptor(isolate)); 88 } 89 90 91 // static 92 Callable CodeFactory::StoreICInOptimizedCode(Isolate* isolate, 93 LanguageMode language_mode) { 94 CallInterfaceDescriptor descriptor = VectorStoreICDescriptor(isolate); 95 return Callable( 96 StoreIC::initialize_stub_in_optimized_code(isolate, language_mode), 97 descriptor); 98 } 99 100 101 // static 102 Callable CodeFactory::KeyedStoreIC(Isolate* isolate, 103 LanguageMode language_mode) { 104 VectorKeyedStoreICTrampolineStub stub(isolate, StoreICState(language_mode)); 105 return Callable(stub.GetCode(), VectorStoreICTrampolineDescriptor(isolate)); 106 } 107 108 109 // static 110 Callable CodeFactory::KeyedStoreICInOptimizedCode(Isolate* isolate, 111 LanguageMode language_mode) { 112 CallInterfaceDescriptor descriptor = VectorStoreICDescriptor(isolate); 113 return Callable( 114 KeyedStoreIC::initialize_stub_in_optimized_code(isolate, language_mode), 115 descriptor); 116 } 117 118 119 // static 120 Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op) { 121 Handle<Code> code = CompareIC::GetUninitialized(isolate, op); 122 return Callable(code, CompareDescriptor(isolate)); 123 } 124 125 126 // static 127 Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op) { 128 BinaryOpICStub stub(isolate, op); 129 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 130 } 131 132 133 // static 134 Callable CodeFactory::InstanceOf(Isolate* isolate) { 135 InstanceOfStub stub(isolate); 136 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 137 } 138 139 140 // static 141 Callable CodeFactory::ToBoolean(Isolate* isolate) { 142 ToBooleanStub stub(isolate); 143 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 144 } 145 146 147 // static 148 Callable CodeFactory::ToNumber(Isolate* isolate) { 149 return Callable(isolate->builtins()->ToNumber(), 150 TypeConversionDescriptor(isolate)); 151 } 152 153 154 // static 155 Callable CodeFactory::NonNumberToNumber(Isolate* isolate) { 156 return Callable(isolate->builtins()->NonNumberToNumber(), 157 TypeConversionDescriptor(isolate)); 158 } 159 160 // static 161 Callable CodeFactory::StringToNumber(Isolate* isolate) { 162 return Callable(isolate->builtins()->StringToNumber(), 163 TypeConversionDescriptor(isolate)); 164 } 165 166 // static 167 Callable CodeFactory::ToString(Isolate* isolate) { 168 ToStringStub stub(isolate); 169 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 170 } 171 172 173 // static 174 Callable CodeFactory::ToName(Isolate* isolate) { 175 ToNameStub stub(isolate); 176 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 177 } 178 179 180 // static 181 Callable CodeFactory::ToInteger(Isolate* isolate) { 182 ToIntegerStub stub(isolate); 183 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 184 } 185 186 // static 187 Callable CodeFactory::ToLength(Isolate* isolate) { 188 ToLengthStub stub(isolate); 189 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 190 } 191 192 193 // static 194 Callable CodeFactory::ToObject(Isolate* isolate) { 195 ToObjectStub stub(isolate); 196 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 197 } 198 199 200 // static 201 Callable CodeFactory::NumberToString(Isolate* isolate) { 202 NumberToStringStub stub(isolate); 203 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 204 } 205 206 207 // static 208 Callable CodeFactory::RegExpConstructResult(Isolate* isolate) { 209 RegExpConstructResultStub stub(isolate); 210 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 211 } 212 213 214 // static 215 Callable CodeFactory::RegExpExec(Isolate* isolate) { 216 RegExpExecStub stub(isolate); 217 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 218 } 219 220 // static 221 Callable CodeFactory::Add(Isolate* isolate) { 222 AddStub stub(isolate); 223 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 224 } 225 226 // static 227 Callable CodeFactory::Subtract(Isolate* isolate) { 228 SubtractStub stub(isolate); 229 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 230 } 231 232 // static 233 Callable CodeFactory::Multiply(Isolate* isolate) { 234 MultiplyStub stub(isolate); 235 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 236 } 237 238 // static 239 Callable CodeFactory::Divide(Isolate* isolate) { 240 DivideStub stub(isolate); 241 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 242 } 243 244 // static 245 Callable CodeFactory::Modulus(Isolate* isolate) { 246 ModulusStub stub(isolate); 247 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 248 } 249 250 // static 251 Callable CodeFactory::ShiftRight(Isolate* isolate) { 252 ShiftRightStub stub(isolate); 253 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 254 } 255 256 // static 257 Callable CodeFactory::ShiftRightLogical(Isolate* isolate) { 258 ShiftRightLogicalStub stub(isolate); 259 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 260 } 261 262 // static 263 Callable CodeFactory::ShiftLeft(Isolate* isolate) { 264 ShiftLeftStub stub(isolate); 265 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 266 } 267 268 // static 269 Callable CodeFactory::BitwiseAnd(Isolate* isolate) { 270 BitwiseAndStub stub(isolate); 271 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 272 } 273 274 // static 275 Callable CodeFactory::BitwiseOr(Isolate* isolate) { 276 BitwiseOrStub stub(isolate); 277 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 278 } 279 280 // static 281 Callable CodeFactory::BitwiseXor(Isolate* isolate) { 282 BitwiseXorStub stub(isolate); 283 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 284 } 285 286 // static 287 Callable CodeFactory::Inc(Isolate* isolate) { 288 IncStub stub(isolate); 289 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 290 } 291 292 // static 293 Callable CodeFactory::Dec(Isolate* isolate) { 294 DecStub stub(isolate); 295 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 296 } 297 298 // static 299 Callable CodeFactory::LessThan(Isolate* isolate) { 300 LessThanStub stub(isolate); 301 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 302 } 303 304 // static 305 Callable CodeFactory::LessThanOrEqual(Isolate* isolate) { 306 LessThanOrEqualStub stub(isolate); 307 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 308 } 309 310 // static 311 Callable CodeFactory::GreaterThan(Isolate* isolate) { 312 GreaterThanStub stub(isolate); 313 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 314 } 315 316 // static 317 Callable CodeFactory::GreaterThanOrEqual(Isolate* isolate) { 318 GreaterThanOrEqualStub stub(isolate); 319 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 320 } 321 322 // static 323 Callable CodeFactory::Equal(Isolate* isolate) { 324 EqualStub stub(isolate); 325 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 326 } 327 328 // static 329 Callable CodeFactory::NotEqual(Isolate* isolate) { 330 NotEqualStub stub(isolate); 331 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 332 } 333 334 // static 335 Callable CodeFactory::StrictEqual(Isolate* isolate) { 336 StrictEqualStub stub(isolate); 337 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 338 } 339 340 // static 341 Callable CodeFactory::StrictNotEqual(Isolate* isolate) { 342 StrictNotEqualStub stub(isolate); 343 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 344 } 345 346 // static 347 Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags, 348 PretenureFlag pretenure_flag) { 349 StringAddStub stub(isolate, flags, pretenure_flag); 350 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 351 } 352 353 // static 354 Callable CodeFactory::StringCompare(Isolate* isolate, Token::Value token) { 355 switch (token) { 356 case Token::EQ: 357 case Token::EQ_STRICT: 358 return StringEqual(isolate); 359 case Token::NE: 360 case Token::NE_STRICT: 361 return StringNotEqual(isolate); 362 case Token::LT: 363 return StringLessThan(isolate); 364 case Token::GT: 365 return StringGreaterThan(isolate); 366 case Token::LTE: 367 return StringLessThanOrEqual(isolate); 368 case Token::GTE: 369 return StringGreaterThanOrEqual(isolate); 370 default: 371 break; 372 } 373 UNREACHABLE(); 374 return StringEqual(isolate); 375 } 376 377 // static 378 Callable CodeFactory::StringEqual(Isolate* isolate) { 379 StringEqualStub stub(isolate); 380 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 381 } 382 383 // static 384 Callable CodeFactory::StringNotEqual(Isolate* isolate) { 385 StringNotEqualStub stub(isolate); 386 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 387 } 388 389 // static 390 Callable CodeFactory::StringLessThan(Isolate* isolate) { 391 StringLessThanStub stub(isolate); 392 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 393 } 394 395 // static 396 Callable CodeFactory::StringLessThanOrEqual(Isolate* isolate) { 397 StringLessThanOrEqualStub stub(isolate); 398 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 399 } 400 401 // static 402 Callable CodeFactory::StringGreaterThan(Isolate* isolate) { 403 StringGreaterThanStub stub(isolate); 404 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 405 } 406 407 // static 408 Callable CodeFactory::StringGreaterThanOrEqual(Isolate* isolate) { 409 StringGreaterThanOrEqualStub stub(isolate); 410 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 411 } 412 413 // static 414 Callable CodeFactory::SubString(Isolate* isolate) { 415 SubStringStub stub(isolate); 416 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 417 } 418 419 420 // static 421 Callable CodeFactory::ResumeGenerator(Isolate* isolate) { 422 return Callable(isolate->builtins()->ResumeGeneratorTrampoline(), 423 ResumeGeneratorDescriptor(isolate)); 424 } 425 426 // static 427 Callable CodeFactory::Typeof(Isolate* isolate) { 428 TypeofStub stub(isolate); 429 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 430 } 431 432 433 // static 434 Callable CodeFactory::FastCloneRegExp(Isolate* isolate) { 435 FastCloneRegExpStub stub(isolate); 436 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 437 } 438 439 440 // static 441 Callable CodeFactory::FastCloneShallowArray(Isolate* isolate) { 442 // TODO(mstarzinger): Thread through AllocationSiteMode at some point. 443 FastCloneShallowArrayStub stub(isolate, DONT_TRACK_ALLOCATION_SITE); 444 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 445 } 446 447 448 // static 449 Callable CodeFactory::FastCloneShallowObject(Isolate* isolate, int length) { 450 FastCloneShallowObjectStub stub(isolate, length); 451 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 452 } 453 454 455 // static 456 Callable CodeFactory::FastNewContext(Isolate* isolate, int slot_count) { 457 FastNewContextStub stub(isolate, slot_count); 458 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 459 } 460 461 462 // static 463 Callable CodeFactory::FastNewClosure(Isolate* isolate, 464 LanguageMode language_mode, 465 FunctionKind kind) { 466 FastNewClosureStub stub(isolate, language_mode, kind); 467 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 468 } 469 470 471 // static 472 Callable CodeFactory::FastNewObject(Isolate* isolate) { 473 FastNewObjectStub stub(isolate); 474 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 475 } 476 477 478 // static 479 Callable CodeFactory::FastNewRestParameter(Isolate* isolate, 480 bool skip_stub_frame) { 481 FastNewRestParameterStub stub(isolate, skip_stub_frame); 482 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 483 } 484 485 486 // static 487 Callable CodeFactory::FastNewSloppyArguments(Isolate* isolate, 488 bool skip_stub_frame) { 489 FastNewSloppyArgumentsStub stub(isolate, skip_stub_frame); 490 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 491 } 492 493 494 // static 495 Callable CodeFactory::FastNewStrictArguments(Isolate* isolate, 496 bool skip_stub_frame) { 497 FastNewStrictArgumentsStub stub(isolate, skip_stub_frame); 498 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 499 } 500 501 502 // static 503 Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) { 504 AllocateHeapNumberStub stub(isolate); 505 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 506 } 507 508 #define SIMD128_ALLOC(TYPE, Type, type, lane_count, lane_type) \ 509 Callable CodeFactory::Allocate##Type(Isolate* isolate) { \ 510 Allocate##Type##Stub stub(isolate); \ 511 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); \ 512 } 513 SIMD128_TYPES(SIMD128_ALLOC) 514 #undef SIMD128_ALLOC 515 516 // static 517 Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) { 518 return Callable(isolate->builtins()->ArgumentsAdaptorTrampoline(), 519 ArgumentAdaptorDescriptor(isolate)); 520 } 521 522 523 // static 524 Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode, 525 TailCallMode tail_call_mode) { 526 return Callable(isolate->builtins()->Call(mode, tail_call_mode), 527 CallTrampolineDescriptor(isolate)); 528 } 529 530 531 // static 532 Callable CodeFactory::CallFunction(Isolate* isolate, ConvertReceiverMode mode) { 533 return Callable(isolate->builtins()->CallFunction(mode), 534 CallTrampolineDescriptor(isolate)); 535 } 536 537 538 // static 539 Callable CodeFactory::Construct(Isolate* isolate) { 540 return Callable(isolate->builtins()->Construct(), 541 ConstructTrampolineDescriptor(isolate)); 542 } 543 544 545 // static 546 Callable CodeFactory::ConstructFunction(Isolate* isolate) { 547 return Callable(isolate->builtins()->ConstructFunction(), 548 ConstructTrampolineDescriptor(isolate)); 549 } 550 551 // static 552 Callable CodeFactory::HasProperty(Isolate* isolate) { 553 HasPropertyStub stub(isolate); 554 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 555 } 556 557 // static 558 Callable CodeFactory::MathPow(Isolate* isolate) { 559 MathPowStub stub(isolate, MathPowStub::ON_STACK); 560 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 561 } 562 563 // static 564 Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate, 565 TailCallMode tail_call_mode) { 566 return Callable( 567 isolate->builtins()->InterpreterPushArgsAndCall(tail_call_mode), 568 InterpreterPushArgsAndCallDescriptor(isolate)); 569 } 570 571 572 // static 573 Callable CodeFactory::InterpreterPushArgsAndConstruct(Isolate* isolate) { 574 return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(), 575 InterpreterPushArgsAndConstructDescriptor(isolate)); 576 } 577 578 579 // static 580 Callable CodeFactory::InterpreterCEntry(Isolate* isolate, int result_size) { 581 // Note: If we ever use fpregs in the interpreter then we will need to 582 // save fpregs too. 583 CEntryStub stub(isolate, result_size, kDontSaveFPRegs, kArgvInRegister); 584 return Callable(stub.GetCode(), InterpreterCEntryDescriptor(isolate)); 585 } 586 587 } // namespace internal 588 } // namespace v8 589