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> 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 26 Handle<Code> CodeFactory::RuntimeCEntry(Isolate* isolate, int result_size) { 27 CEntryStub stub(isolate, result_size); 28 return stub.GetCode(); 29 } 30 31 // static 32 Callable CodeFactory::LoadIC(Isolate* isolate) { 33 return Callable(isolate->builtins()->LoadICTrampoline(), 34 LoadDescriptor(isolate)); 35 } 36 37 // static 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 48 Callable CodeFactory::ApiGetter(Isolate* isolate) { 49 CallApiGetterStub stub(isolate); 50 return make_callable(stub); 51 } 52 53 // static 54 Callable CodeFactory::LoadICInOptimizedCode(Isolate* isolate) { 55 return Callable(isolate->builtins()->LoadIC(), 56 LoadWithVectorDescriptor(isolate)); 57 } 58 59 // static 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 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 78 Callable CodeFactory::KeyedLoadIC(Isolate* isolate) { 79 return Callable(isolate->builtins()->KeyedLoadICTrampoline(), 80 LoadDescriptor(isolate)); 81 } 82 83 // static 84 Callable CodeFactory::KeyedLoadICInOptimizedCode(Isolate* isolate) { 85 return Callable(isolate->builtins()->KeyedLoadIC(), 86 LoadWithVectorDescriptor(isolate)); 87 } 88 89 // static 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 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 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 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 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 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 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 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 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 162 Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op) { 163 CompareICStub stub(isolate, op); 164 return make_callable(stub); 165 } 166 167 // static 168 Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op) { 169 BinaryOpICStub stub(isolate, op); 170 return make_callable(stub); 171 } 172 173 // static 174 Callable CodeFactory::GetProperty(Isolate* isolate) { 175 GetPropertyStub stub(isolate); 176 return make_callable(stub); 177 } 178 179 // static 180 Callable CodeFactory::NonPrimitiveToPrimitive(Isolate* isolate, 181 ToPrimitiveHint hint) { 182 return Callable(isolate->builtins()->NonPrimitiveToPrimitive(hint), 183 TypeConversionDescriptor(isolate)); 184 } 185 186 // static 187 Callable CodeFactory::OrdinaryToPrimitive(Isolate* isolate, 188 OrdinaryToPrimitiveHint hint) { 189 return Callable(isolate->builtins()->OrdinaryToPrimitive(hint), 190 TypeConversionDescriptor(isolate)); 191 } 192 193 // static 194 Callable CodeFactory::NumberToString(Isolate* isolate) { 195 NumberToStringStub stub(isolate); 196 return make_callable(stub); 197 } 198 199 // static 200 Callable CodeFactory::RegExpExec(Isolate* isolate) { 201 RegExpExecStub stub(isolate); 202 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 203 } 204 205 // static 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; 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 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 314 Callable CodeFactory::StringIndexOf(Isolate* isolate) { 315 return Callable(isolate->builtins()->StringIndexOf(), 316 StringIndexOfDescriptor(isolate)); 317 } 318 319 // static 320 Callable CodeFactory::SubString(Isolate* isolate) { 321 SubStringStub stub(isolate); 322 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor()); 323 } 324 325 // static 326 Callable CodeFactory::ResumeGenerator(Isolate* isolate) { 327 return Callable(isolate->builtins()->ResumeGeneratorTrampoline(), 328 ResumeGeneratorDescriptor(isolate)); 329 } 330 331 // static 332 Callable CodeFactory::FrameDropperTrampoline(Isolate* isolate) { 333 return Callable(isolate->builtins()->FrameDropperTrampoline(), 334 FrameDropperTrampolineDescriptor(isolate)); 335 } 336 337 // static 338 Callable CodeFactory::HandleDebuggerStatement(Isolate* isolate) { 339 return Callable(isolate->builtins()->HandleDebuggerStatement(), 340 ContextOnlyDescriptor(isolate)); 341 } 342 343 // static 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 351 Callable CodeFactory::FastCloneShallowObject(Isolate* isolate, int length) { 352 return Callable(isolate->builtins()->NewCloneShallowObject(length), 353 FastCloneShallowObjectDescriptor(isolate)); 354 } 355 356 // static 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 364 Callable CodeFactory::FastNewRestParameter(Isolate* isolate) { 365 return Callable(isolate->builtins()->FastNewRestParameter(), 366 FastNewRestParameterDescriptor(isolate)); 367 } 368 369 // static 370 Callable CodeFactory::FastNewSloppyArguments(Isolate* isolate) { 371 return Callable(isolate->builtins()->FastNewSloppyArguments(), 372 FastNewRestParameterDescriptor(isolate)); 373 } 374 375 // static 376 Callable CodeFactory::FastNewStrictArguments(Isolate* isolate) { 377 return Callable(isolate->builtins()->FastNewStrictArguments(), 378 FastNewRestParameterDescriptor(isolate)); 379 } 380 381 // static 382 Callable CodeFactory::ForInPrepare(Isolate* isolate) { 383 return Callable(isolate->builtins()->ForInPrepare(), 384 ForInPrepareDescriptor(isolate)); 385 } 386 387 // static 388 Callable CodeFactory::ForInNext(Isolate* isolate) { 389 return Callable(isolate->builtins()->ForInNext(), 390 ForInNextDescriptor(isolate)); 391 } 392 393 // static 394 Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) { 395 AllocateHeapNumberStub stub(isolate); 396 return make_callable(stub); 397 } 398 399 // static 400 Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) { 401 return Callable(isolate->builtins()->ArgumentsAdaptorTrampoline(), 402 ArgumentAdaptorDescriptor(isolate)); 403 } 404 405 // static 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 413 Callable CodeFactory::CallWithSpread(Isolate* isolate) { 414 return Callable(isolate->builtins()->CallWithSpread(), 415 CallTrampolineDescriptor(isolate)); 416 } 417 418 // static 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 426 Callable CodeFactory::CallForwardVarargs(Isolate* isolate) { 427 return Callable(isolate->builtins()->CallForwardVarargs(), 428 CallForwardVarargsDescriptor(isolate)); 429 } 430 431 // static 432 Callable CodeFactory::CallFunctionForwardVarargs(Isolate* isolate) { 433 return Callable(isolate->builtins()->CallFunctionForwardVarargs(), 434 CallForwardVarargsDescriptor(isolate)); 435 } 436 437 // static 438 Callable CodeFactory::Construct(Isolate* isolate) { 439 return Callable(isolate->builtins()->Construct(), 440 ConstructTrampolineDescriptor(isolate)); 441 } 442 443 // static 444 Callable CodeFactory::ConstructWithSpread(Isolate* isolate) { 445 return Callable(isolate->builtins()->ConstructWithSpread(), 446 ConstructTrampolineDescriptor(isolate)); 447 } 448 449 // static 450 Callable CodeFactory::ConstructFunction(Isolate* isolate) { 451 return Callable(isolate->builtins()->ConstructFunction(), 452 ConstructTrampolineDescriptor(isolate)); 453 } 454 455 // static 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 465 Callable CodeFactory::InterpreterPushArgsAndConstruct( 466 Isolate* isolate, InterpreterPushArgsMode mode) { 467 return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(mode), 468 InterpreterPushArgsAndConstructDescriptor(isolate)); 469 } 470 471 // static 472 Callable CodeFactory::InterpreterPushArgsAndConstructArray(Isolate* isolate) { 473 return Callable(isolate->builtins()->InterpreterPushArgsAndConstructArray(), 474 InterpreterPushArgsAndConstructArrayDescriptor(isolate)); 475 } 476 477 // static 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 486 Callable CodeFactory::InterpreterOnStackReplacement(Isolate* isolate) { 487 return Callable(isolate->builtins()->InterpreterOnStackReplacement(), 488 ContextOnlyDescriptor(isolate)); 489 } 490 491 // static 492 Callable CodeFactory::ArrayConstructor(Isolate* isolate) { 493 ArrayConstructorStub stub(isolate); 494 return make_callable(stub); 495 } 496 497 // static 498 Callable CodeFactory::ArrayPush(Isolate* isolate) { 499 return Callable(isolate->builtins()->ArrayPush(), BuiltinDescriptor(isolate)); 500 } 501 502 // static 503 Callable CodeFactory::FunctionPrototypeBind(Isolate* isolate) { 504 return Callable(isolate->builtins()->FunctionPrototypeBind(), 505 BuiltinDescriptor(isolate)); 506 } 507 508 } // namespace internal 509 } // namespace v8 510