Home | History | Annotate | Download | only in src
      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