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 
     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