1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_FACTORY_H_ 29 #define V8_FACTORY_H_ 30 31 #include "globals.h" 32 #include "handles.h" 33 #include "heap.h" 34 35 namespace v8 { 36 namespace internal { 37 38 // Interface for handle based allocation. 39 40 class Factory { 41 public: 42 // Allocate a new boxed value. 43 Handle<Box> NewBox( 44 Handle<Object> value, 45 PretenureFlag pretenure = NOT_TENURED); 46 47 // Allocate a new uninitialized fixed array. 48 Handle<FixedArray> NewFixedArray( 49 int size, 50 PretenureFlag pretenure = NOT_TENURED); 51 52 // Allocate a new fixed array with non-existing entries (the hole). 53 Handle<FixedArray> NewFixedArrayWithHoles( 54 int size, 55 PretenureFlag pretenure = NOT_TENURED); 56 57 // Allocate a new uninitialized fixed double array. 58 Handle<FixedDoubleArray> NewFixedDoubleArray( 59 int size, 60 PretenureFlag pretenure = NOT_TENURED); 61 62 Handle<ConstantPoolArray> NewConstantPoolArray( 63 int number_of_int64_entries, 64 int number_of_ptr_entries, 65 int number_of_int32_entries); 66 67 Handle<SeededNumberDictionary> NewSeededNumberDictionary( 68 int at_least_space_for); 69 70 Handle<UnseededNumberDictionary> NewUnseededNumberDictionary( 71 int at_least_space_for); 72 73 Handle<NameDictionary> NewNameDictionary(int at_least_space_for); 74 75 Handle<ObjectHashSet> NewObjectHashSet(int at_least_space_for); 76 77 Handle<ObjectHashTable> NewObjectHashTable( 78 int at_least_space_for, 79 MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY); 80 81 Handle<WeakHashTable> NewWeakHashTable(int at_least_space_for); 82 83 Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors, 84 int slack = 0); 85 Handle<DeoptimizationInputData> NewDeoptimizationInputData( 86 int deopt_entry_count, 87 PretenureFlag pretenure); 88 Handle<DeoptimizationOutputData> NewDeoptimizationOutputData( 89 int deopt_entry_count, 90 PretenureFlag pretenure); 91 // Allocates a pre-tenured empty AccessorPair. 92 Handle<AccessorPair> NewAccessorPair(); 93 94 Handle<TypeFeedbackInfo> NewTypeFeedbackInfo(); 95 96 Handle<String> InternalizeUtf8String(Vector<const char> str); 97 Handle<String> InternalizeUtf8String(const char* str) { 98 return InternalizeUtf8String(CStrVector(str)); 99 } 100 Handle<String> InternalizeString(Handle<String> str); 101 Handle<String> InternalizeOneByteString(Vector<const uint8_t> str); 102 Handle<String> InternalizeOneByteString(Handle<SeqOneByteString>, 103 int from, 104 int length); 105 Handle<String> InternalizeTwoByteString(Vector<const uc16> str); 106 107 108 // String creation functions. Most of the string creation functions take 109 // a Heap::PretenureFlag argument to optionally request that they be 110 // allocated in the old generation. The pretenure flag defaults to 111 // DONT_TENURE. 112 // 113 // Creates a new String object. There are two String encodings: ASCII and 114 // two byte. One should choose between the three string factory functions 115 // based on the encoding of the string buffer that the string is 116 // initialized from. 117 // - ...FromAscii initializes the string from a buffer that is ASCII 118 // encoded (it does not check that the buffer is ASCII encoded) and 119 // the result will be ASCII encoded. 120 // - ...FromUtf8 initializes the string from a buffer that is UTF-8 121 // encoded. If the characters are all single-byte characters, the 122 // result will be ASCII encoded, otherwise it will converted to two 123 // byte. 124 // - ...FromTwoByte initializes the string from a buffer that is two 125 // byte encoded. If the characters are all single-byte characters, 126 // the result will be converted to ASCII, otherwise it will be left as 127 // two byte. 128 // 129 // ASCII strings are pretenured when used as keys in the SourceCodeCache. 130 Handle<String> NewStringFromOneByte( 131 Vector<const uint8_t> str, 132 PretenureFlag pretenure = NOT_TENURED); 133 // TODO(dcarney): remove this function. 134 inline Handle<String> NewStringFromAscii( 135 Vector<const char> str, 136 PretenureFlag pretenure = NOT_TENURED) { 137 return NewStringFromOneByte(Vector<const uint8_t>::cast(str), pretenure); 138 } 139 140 // UTF8 strings are pretenured when used for regexp literal patterns and 141 // flags in the parser. 142 Handle<String> NewStringFromUtf8( 143 Vector<const char> str, 144 PretenureFlag pretenure = NOT_TENURED); 145 146 Handle<String> NewStringFromTwoByte( 147 Vector<const uc16> str, 148 PretenureFlag pretenure = NOT_TENURED); 149 150 // Allocates and partially initializes an ASCII or TwoByte String. The 151 // characters of the string are uninitialized. Currently used in regexp code 152 // only, where they are pretenured. 153 Handle<SeqOneByteString> NewRawOneByteString( 154 int length, 155 PretenureFlag pretenure = NOT_TENURED); 156 Handle<SeqTwoByteString> NewRawTwoByteString( 157 int length, 158 PretenureFlag pretenure = NOT_TENURED); 159 160 // Create a new cons string object which consists of a pair of strings. 161 Handle<String> NewConsString(Handle<String> first, 162 Handle<String> second); 163 164 // Create a new sequential string containing the concatenation of the inputs. 165 Handle<String> NewFlatConcatString(Handle<String> first, 166 Handle<String> second); 167 168 // Create a new string object which holds a substring of a string. 169 Handle<String> NewSubString(Handle<String> str, 170 int begin, 171 int end); 172 173 // Create a new string object which holds a proper substring of a string. 174 Handle<String> NewProperSubString(Handle<String> str, 175 int begin, 176 int end); 177 178 // Creates a new external String object. There are two String encodings 179 // in the system: ASCII and two byte. Unlike other String types, it does 180 // not make sense to have a UTF-8 factory function for external strings, 181 // because we cannot change the underlying buffer. 182 Handle<String> NewExternalStringFromAscii( 183 const ExternalAsciiString::Resource* resource); 184 Handle<String> NewExternalStringFromTwoByte( 185 const ExternalTwoByteString::Resource* resource); 186 187 // Create a symbol. 188 Handle<Symbol> NewSymbol(); 189 Handle<Symbol> NewPrivateSymbol(); 190 191 // Create a global (but otherwise uninitialized) context. 192 Handle<Context> NewNativeContext(); 193 194 // Create a global context. 195 Handle<Context> NewGlobalContext(Handle<JSFunction> function, 196 Handle<ScopeInfo> scope_info); 197 198 // Create a module context. 199 Handle<Context> NewModuleContext(Handle<ScopeInfo> scope_info); 200 201 // Create a function context. 202 Handle<Context> NewFunctionContext(int length, Handle<JSFunction> function); 203 204 // Create a catch context. 205 Handle<Context> NewCatchContext(Handle<JSFunction> function, 206 Handle<Context> previous, 207 Handle<String> name, 208 Handle<Object> thrown_object); 209 210 // Create a 'with' context. 211 Handle<Context> NewWithContext(Handle<JSFunction> function, 212 Handle<Context> previous, 213 Handle<JSObject> extension); 214 215 // Create a block context. 216 Handle<Context> NewBlockContext(Handle<JSFunction> function, 217 Handle<Context> previous, 218 Handle<ScopeInfo> scope_info); 219 220 // Return the internalized version of the passed in string. 221 Handle<String> InternalizedStringFromString(Handle<String> value); 222 223 // Allocate a new struct. The struct is pretenured (allocated directly in 224 // the old generation). 225 Handle<Struct> NewStruct(InstanceType type); 226 227 Handle<AliasedArgumentsEntry> NewAliasedArgumentsEntry( 228 int aliased_context_slot); 229 230 Handle<DeclaredAccessorDescriptor> NewDeclaredAccessorDescriptor(); 231 232 Handle<DeclaredAccessorInfo> NewDeclaredAccessorInfo(); 233 234 Handle<ExecutableAccessorInfo> NewExecutableAccessorInfo(); 235 236 Handle<Script> NewScript(Handle<String> source); 237 238 // Foreign objects are pretenured when allocated by the bootstrapper. 239 Handle<Foreign> NewForeign(Address addr, 240 PretenureFlag pretenure = NOT_TENURED); 241 242 // Allocate a new foreign object. The foreign is pretenured (allocated 243 // directly in the old generation). 244 Handle<Foreign> NewForeign(const AccessorDescriptor* foreign); 245 246 Handle<ByteArray> NewByteArray(int length, 247 PretenureFlag pretenure = NOT_TENURED); 248 249 Handle<ExternalArray> NewExternalArray( 250 int length, 251 ExternalArrayType array_type, 252 void* external_pointer, 253 PretenureFlag pretenure = NOT_TENURED); 254 255 Handle<Cell> NewCell(Handle<Object> value); 256 257 Handle<PropertyCell> NewPropertyCellWithHole(); 258 259 Handle<PropertyCell> NewPropertyCell(Handle<Object> value); 260 261 Handle<AllocationSite> NewAllocationSite(); 262 263 Handle<Map> NewMap( 264 InstanceType type, 265 int instance_size, 266 ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND); 267 268 Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function); 269 270 Handle<Map> CopyWithPreallocatedFieldDescriptors(Handle<Map> map); 271 272 // Copy the map adding more inobject properties if possible without 273 // overflowing the instance size. 274 Handle<Map> CopyMap(Handle<Map> map, int extra_inobject_props); 275 Handle<Map> CopyMap(Handle<Map> map); 276 277 Handle<Map> GetElementsTransitionMap(Handle<JSObject> object, 278 ElementsKind elements_kind); 279 280 Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array); 281 282 Handle<FixedArray> CopySizeFixedArray(Handle<FixedArray> array, 283 int new_length, 284 PretenureFlag pretenure = NOT_TENURED); 285 286 Handle<FixedDoubleArray> CopyFixedDoubleArray( 287 Handle<FixedDoubleArray> array); 288 289 Handle<ConstantPoolArray> CopyConstantPoolArray( 290 Handle<ConstantPoolArray> array); 291 292 // Numbers (e.g. literals) are pretenured by the parser. 293 Handle<Object> NewNumber(double value, 294 PretenureFlag pretenure = NOT_TENURED); 295 296 Handle<Object> NewNumberFromInt(int32_t value, 297 PretenureFlag pretenure = NOT_TENURED); 298 Handle<Object> NewNumberFromUint(uint32_t value, 299 PretenureFlag pretenure = NOT_TENURED); 300 inline Handle<Object> NewNumberFromSize(size_t value, 301 PretenureFlag pretenure = NOT_TENURED); 302 Handle<HeapNumber> NewHeapNumber(double value, 303 PretenureFlag pretenure = NOT_TENURED); 304 305 306 // These objects are used by the api to create env-independent data 307 // structures in the heap. 308 Handle<JSObject> NewNeanderObject(); 309 310 Handle<JSObject> NewArgumentsObject(Handle<Object> callee, int length); 311 312 // JS objects are pretenured when allocated by the bootstrapper and 313 // runtime. 314 Handle<JSObject> NewJSObject(Handle<JSFunction> constructor, 315 PretenureFlag pretenure = NOT_TENURED); 316 317 // Global objects are pretenured and initialized based on a constructor. 318 Handle<GlobalObject> NewGlobalObject(Handle<JSFunction> constructor); 319 320 // JS objects are pretenured when allocated by the bootstrapper and 321 // runtime. 322 Handle<JSObject> NewJSObjectFromMap(Handle<Map> map, 323 PretenureFlag pretenure = NOT_TENURED, 324 bool allocate_properties = true); 325 326 Handle<JSObject> NewJSObjectFromMapForDeoptimizer( 327 Handle<Map> map, PretenureFlag pretenure = NOT_TENURED); 328 329 // JS modules are pretenured. 330 Handle<JSModule> NewJSModule(Handle<Context> context, 331 Handle<ScopeInfo> scope_info); 332 333 // JS arrays are pretenured when allocated by the parser. 334 Handle<JSArray> NewJSArray( 335 int capacity, 336 ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND, 337 PretenureFlag pretenure = NOT_TENURED); 338 339 Handle<JSArray> NewJSArrayWithElements( 340 Handle<FixedArrayBase> elements, 341 ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND, 342 PretenureFlag pretenure = NOT_TENURED); 343 344 void SetElementsCapacityAndLength(Handle<JSArray> array, 345 int capacity, 346 int length); 347 348 void SetContent(Handle<JSArray> array, Handle<FixedArrayBase> elements); 349 350 Handle<JSGeneratorObject> NewJSGeneratorObject(Handle<JSFunction> function); 351 352 Handle<JSArrayBuffer> NewJSArrayBuffer(); 353 354 Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type); 355 356 Handle<JSDataView> NewJSDataView(); 357 358 Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype); 359 360 // Change the type of the argument into a JS object/function and reinitialize. 361 void BecomeJSObject(Handle<JSReceiver> object); 362 void BecomeJSFunction(Handle<JSReceiver> object); 363 364 Handle<JSFunction> NewFunction(Handle<String> name, 365 Handle<Object> prototype); 366 367 Handle<JSFunction> NewFunctionWithoutPrototype( 368 Handle<String> name, 369 LanguageMode language_mode); 370 371 Handle<JSFunction> NewFunction(Handle<Object> super, bool is_global); 372 373 Handle<JSFunction> BaseNewFunctionFromSharedFunctionInfo( 374 Handle<SharedFunctionInfo> function_info, 375 Handle<Map> function_map, 376 PretenureFlag pretenure); 377 378 Handle<JSFunction> NewFunctionFromSharedFunctionInfo( 379 Handle<SharedFunctionInfo> function_info, 380 Handle<Context> context, 381 PretenureFlag pretenure = TENURED); 382 383 Handle<ScopeInfo> NewScopeInfo(int length); 384 385 Handle<JSObject> NewExternal(void* value); 386 387 Handle<Code> NewCode(const CodeDesc& desc, 388 Code::Flags flags, 389 Handle<Object> self_reference, 390 bool immovable = false, 391 bool crankshafted = false, 392 int prologue_offset = Code::kPrologueOffsetNotSet); 393 394 Handle<Code> CopyCode(Handle<Code> code); 395 396 Handle<Code> CopyCode(Handle<Code> code, Vector<byte> reloc_info); 397 398 Handle<Object> ToObject(Handle<Object> object); 399 Handle<Object> ToObject(Handle<Object> object, 400 Handle<Context> native_context); 401 402 // Interface for creating error objects. 403 404 Handle<Object> NewError(const char* maker, const char* message, 405 Handle<JSArray> args); 406 Handle<String> EmergencyNewError(const char* message, Handle<JSArray> args); 407 Handle<Object> NewError(const char* maker, const char* message, 408 Vector< Handle<Object> > args); 409 Handle<Object> NewError(const char* message, 410 Vector< Handle<Object> > args); 411 Handle<Object> NewError(Handle<String> message); 412 Handle<Object> NewError(const char* constructor, 413 Handle<String> message); 414 415 Handle<Object> NewTypeError(const char* message, 416 Vector< Handle<Object> > args); 417 Handle<Object> NewTypeError(Handle<String> message); 418 419 Handle<Object> NewRangeError(const char* message, 420 Vector< Handle<Object> > args); 421 Handle<Object> NewRangeError(Handle<String> message); 422 423 Handle<Object> NewSyntaxError(const char* message, Handle<JSArray> args); 424 Handle<Object> NewSyntaxError(Handle<String> message); 425 426 Handle<Object> NewReferenceError(const char* message, 427 Vector< Handle<Object> > args); 428 Handle<Object> NewReferenceError(Handle<String> message); 429 430 Handle<Object> NewEvalError(const char* message, 431 Vector< Handle<Object> > args); 432 433 434 Handle<JSFunction> NewFunction(Handle<String> name, 435 InstanceType type, 436 int instance_size, 437 Handle<Code> code, 438 bool force_initial_map); 439 440 Handle<JSFunction> NewFunction(Handle<Map> function_map, 441 Handle<SharedFunctionInfo> shared, Handle<Object> prototype); 442 443 444 Handle<JSFunction> NewFunctionWithPrototype(Handle<String> name, 445 InstanceType type, 446 int instance_size, 447 Handle<JSObject> prototype, 448 Handle<Code> code, 449 bool force_initial_map); 450 451 Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name, 452 Handle<Code> code); 453 454 Handle<String> NumberToString(Handle<Object> number); 455 Handle<String> Uint32ToString(uint32_t value); 456 457 enum ApiInstanceType { 458 JavaScriptObject, 459 InnerGlobalObject, 460 OuterGlobalObject 461 }; 462 463 Handle<JSFunction> CreateApiFunction( 464 Handle<FunctionTemplateInfo> data, 465 ApiInstanceType type = JavaScriptObject); 466 467 Handle<JSFunction> InstallMembers(Handle<JSFunction> function); 468 469 // Installs interceptors on the instance. 'desc' is a function template, 470 // and instance is an object instance created by the function of this 471 // function template. 472 void ConfigureInstance(Handle<FunctionTemplateInfo> desc, 473 Handle<JSObject> instance, 474 bool* pending_exception); 475 476 #define ROOT_ACCESSOR(type, name, camel_name) \ 477 inline Handle<type> name() { \ 478 return Handle<type>(BitCast<type**>( \ 479 &isolate()->heap()->roots_[Heap::k##camel_name##RootIndex])); \ 480 } 481 ROOT_LIST(ROOT_ACCESSOR) 482 #undef ROOT_ACCESSOR 483 484 #define STRUCT_MAP_ACCESSOR(NAME, Name, name) \ 485 inline Handle<Map> name##_map() { \ 486 return Handle<Map>(BitCast<Map**>( \ 487 &isolate()->heap()->roots_[Heap::k##Name##MapRootIndex])); \ 488 } 489 STRUCT_LIST(STRUCT_MAP_ACCESSOR) 490 #undef STRUCT_MAP_ACCESSOR 491 492 #define STRING_ACCESSOR(name, str) \ 493 inline Handle<String> name() { \ 494 return Handle<String>(BitCast<String**>( \ 495 &isolate()->heap()->roots_[Heap::k##name##RootIndex])); \ 496 } 497 INTERNALIZED_STRING_LIST(STRING_ACCESSOR) 498 #undef STRING_ACCESSOR 499 500 Handle<String> hidden_string() { 501 return Handle<String>(&isolate()->heap()->hidden_string_); 502 } 503 504 Handle<SharedFunctionInfo> NewSharedFunctionInfo( 505 Handle<String> name, 506 int number_of_literals, 507 bool is_generator, 508 Handle<Code> code, 509 Handle<ScopeInfo> scope_info); 510 Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name); 511 512 Handle<JSMessageObject> NewJSMessageObject( 513 Handle<String> type, 514 Handle<JSArray> arguments, 515 int start_position, 516 int end_position, 517 Handle<Object> script, 518 Handle<Object> stack_trace, 519 Handle<Object> stack_frames); 520 521 Handle<SeededNumberDictionary> DictionaryAtNumberPut( 522 Handle<SeededNumberDictionary>, 523 uint32_t key, 524 Handle<Object> value); 525 526 Handle<UnseededNumberDictionary> DictionaryAtNumberPut( 527 Handle<UnseededNumberDictionary>, 528 uint32_t key, 529 Handle<Object> value); 530 531 #ifdef ENABLE_DEBUGGER_SUPPORT 532 Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared); 533 #endif 534 535 // Return a map using the map cache in the native context. 536 // The key the an ordered set of property names. 537 Handle<Map> ObjectLiteralMapFromCache(Handle<Context> context, 538 Handle<FixedArray> keys); 539 540 // Creates a new FixedArray that holds the data associated with the 541 // atom regexp and stores it in the regexp. 542 void SetRegExpAtomData(Handle<JSRegExp> regexp, 543 JSRegExp::Type type, 544 Handle<String> source, 545 JSRegExp::Flags flags, 546 Handle<Object> match_pattern); 547 548 // Creates a new FixedArray that holds the data associated with the 549 // irregexp regexp and stores it in the regexp. 550 void SetRegExpIrregexpData(Handle<JSRegExp> regexp, 551 JSRegExp::Type type, 552 Handle<String> source, 553 JSRegExp::Flags flags, 554 int capture_count); 555 556 // Returns the value for a known global constant (a property of the global 557 // object which is neither configurable nor writable) like 'undefined'. 558 // Returns a null handle when the given name is unknown. 559 Handle<Object> GlobalConstantFor(Handle<String> name); 560 561 // Converts the given boolean condition to JavaScript boolean value. 562 Handle<Object> ToBoolean(bool value); 563 564 private: 565 Isolate* isolate() { return reinterpret_cast<Isolate*>(this); } 566 567 Handle<JSFunction> NewFunctionHelper(Handle<String> name, 568 Handle<Object> prototype); 569 570 Handle<JSFunction> NewFunctionWithoutPrototypeHelper( 571 Handle<String> name, 572 LanguageMode language_mode); 573 574 // Create a new map cache. 575 Handle<MapCache> NewMapCache(int at_least_space_for); 576 577 // Update the map cache in the native context with (keys, map) 578 Handle<MapCache> AddToMapCache(Handle<Context> context, 579 Handle<FixedArray> keys, 580 Handle<Map> map); 581 }; 582 583 584 Handle<Object> Factory::NewNumberFromSize(size_t value, 585 PretenureFlag pretenure) { 586 if (Smi::IsValid(static_cast<intptr_t>(value))) { 587 return Handle<Object>(Smi::FromIntptr(static_cast<intptr_t>(value)), 588 isolate()); 589 } else { 590 return NewNumber(static_cast<double>(value), pretenure); 591 } 592 } 593 594 595 } } // namespace v8::internal 596 597 #endif // V8_FACTORY_H_ 598