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