| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 // triggered during environment creation there may be weak handle | 154 // triggered during environment creation there may be weak handle |
| 155 // processing callbacks which may create new environments. | 155 // processing callbacks which may create new environments. |
| 156 Genesis* previous_; | 156 Genesis* previous_; |
| 157 | 157 |
| 158 Handle<Context> global_context() { return global_context_; } | 158 Handle<Context> global_context() { return global_context_; } |
| 159 | 159 |
| 160 // Creates some basic objects. Used for creating a context from scratch. | 160 // Creates some basic objects. Used for creating a context from scratch. |
| 161 void CreateRoots(); | 161 void CreateRoots(); |
| 162 // Creates the empty function. Used for creating a context from scratch. | 162 // Creates the empty function. Used for creating a context from scratch. |
| 163 Handle<JSFunction> CreateEmptyFunction(); | 163 Handle<JSFunction> CreateEmptyFunction(); |
| 164 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 |
| 165 Handle<JSFunction> CreateThrowTypeErrorFunction(Builtins::Name builtin); |
| 166 |
| 167 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); |
| 164 // Creates the global objects using the global and the template passed in | 168 // Creates the global objects using the global and the template passed in |
| 165 // through the API. We call this regardless of whether we are building a | 169 // through the API. We call this regardless of whether we are building a |
| 166 // context from scratch or using a deserialized one from the partial snapshot | 170 // context from scratch or using a deserialized one from the partial snapshot |
| 167 // but in the latter case we don't use the objects it produces directly, as | 171 // but in the latter case we don't use the objects it produces directly, as |
| 168 // we have to used the deserialized ones that are linked together with the | 172 // we have to used the deserialized ones that are linked together with the |
| 169 // rest of the context snapshot. | 173 // rest of the context snapshot. |
| 170 Handle<JSGlobalProxy> CreateNewGlobals( | 174 Handle<JSGlobalProxy> CreateNewGlobals( |
| 171 v8::Handle<v8::ObjectTemplate> global_template, | 175 v8::Handle<v8::ObjectTemplate> global_template, |
| 172 Handle<Object> global_object, | 176 Handle<Object> global_object, |
| 173 Handle<GlobalObject>* global_proxy_out); | 177 Handle<GlobalObject>* global_proxy_out); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 // 'from'. | 211 // 'from'. |
| 208 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); | 212 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); |
| 209 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); | 213 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); |
| 210 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); | 214 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); |
| 211 | 215 |
| 212 enum PrototypePropertyMode { | 216 enum PrototypePropertyMode { |
| 213 DONT_ADD_PROTOTYPE, | 217 DONT_ADD_PROTOTYPE, |
| 214 ADD_READONLY_PROTOTYPE, | 218 ADD_READONLY_PROTOTYPE, |
| 215 ADD_WRITEABLE_PROTOTYPE | 219 ADD_WRITEABLE_PROTOTYPE |
| 216 }; | 220 }; |
| 221 |
| 222 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode); |
| 223 |
| 217 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( | 224 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( |
| 218 PrototypePropertyMode prototypeMode); | 225 PrototypePropertyMode prototypeMode); |
| 219 void MakeFunctionInstancePrototypeWritable(); | 226 void MakeFunctionInstancePrototypeWritable(); |
| 220 | 227 |
| 228 Handle<Map> CreateStrictModeFunctionMap( |
| 229 PrototypePropertyMode prototype_mode, |
| 230 Handle<JSFunction> empty_function, |
| 231 Handle<FixedArray> arguments_callbacks, |
| 232 Handle<FixedArray> caller_callbacks); |
| 233 |
| 234 Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor( |
| 235 PrototypePropertyMode propertyMode, |
| 236 Handle<FixedArray> arguments, |
| 237 Handle<FixedArray> caller); |
| 238 |
| 221 static bool CompileBuiltin(int index); | 239 static bool CompileBuiltin(int index); |
| 222 static bool CompileNative(Vector<const char> name, Handle<String> source); | 240 static bool CompileNative(Vector<const char> name, Handle<String> source); |
| 223 static bool CompileScriptCached(Vector<const char> name, | 241 static bool CompileScriptCached(Vector<const char> name, |
| 224 Handle<String> source, | 242 Handle<String> source, |
| 225 SourceCodeCache* cache, | 243 SourceCodeCache* cache, |
| 226 v8::Extension* extension, | 244 v8::Extension* extension, |
| 227 Handle<Context> top_context, | 245 Handle<Context> top_context, |
| 228 bool use_runtime_context); | 246 bool use_runtime_context); |
| 229 | 247 |
| 230 Handle<Context> result_; | 248 Handle<Context> result_; |
| 231 Handle<JSFunction> empty_function_; | 249 |
| 250 // Function instance maps. Function literal maps are created initially with |
| 251 // a read only prototype for the processing of JS builtins. Later the function |
| 252 // instance maps are replaced in order to make prototype writable. |
| 253 // These are the final, writable prototype, maps. |
| 254 Handle<Map> function_instance_map_writable_prototype_; |
| 255 Handle<Map> strict_mode_function_instance_map_writable_prototype_; |
| 256 |
| 232 BootstrapperActive active_; | 257 BootstrapperActive active_; |
| 233 friend class Bootstrapper; | 258 friend class Bootstrapper; |
| 234 }; | 259 }; |
| 235 | 260 |
| 236 | 261 |
| 237 void Bootstrapper::Iterate(ObjectVisitor* v) { | 262 void Bootstrapper::Iterate(ObjectVisitor* v) { |
| 238 extensions_cache_.Iterate(v); | 263 extensions_cache_.Iterate(v); |
| 239 v->Synchronize("Extensions"); | 264 v->Synchronize("Extensions"); |
| 240 } | 265 } |
| 241 | 266 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM); | 332 SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM); |
| 308 if (is_ecma_native) { | 333 if (is_ecma_native) { |
| 309 function->shared()->set_instance_class_name(*symbol); | 334 function->shared()->set_instance_class_name(*symbol); |
| 310 } | 335 } |
| 311 return function; | 336 return function; |
| 312 } | 337 } |
| 313 | 338 |
| 314 | 339 |
| 315 Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor( | 340 Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor( |
| 316 PrototypePropertyMode prototypeMode) { | 341 PrototypePropertyMode prototypeMode) { |
| 317 Handle<DescriptorArray> result = FACTORY->empty_descriptor_array(); | 342 Handle<DescriptorArray> descriptors = |
| 318 | 343 FACTORY->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5); |
| 319 if (prototypeMode != DONT_ADD_PROTOTYPE) { | |
| 320 PropertyAttributes attributes = static_cast<PropertyAttributes>( | |
| 321 DONT_ENUM | | |
| 322 DONT_DELETE | | |
| 323 (prototypeMode == ADD_READONLY_PROTOTYPE ? READ_ONLY : 0)); | |
| 324 result = | |
| 325 FACTORY->CopyAppendProxyDescriptor( | |
| 326 result, | |
| 327 FACTORY->prototype_symbol(), | |
| 328 FACTORY->NewProxy(&Accessors::FunctionPrototype), | |
| 329 attributes); | |
| 330 } | |
| 331 | |
| 332 PropertyAttributes attributes = | 344 PropertyAttributes attributes = |
| 333 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); | 345 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
| 334 // Add length. | |
| 335 result = | |
| 336 FACTORY->CopyAppendProxyDescriptor( | |
| 337 result, | |
| 338 FACTORY->length_symbol(), | |
| 339 FACTORY->NewProxy(&Accessors::FunctionLength), | |
| 340 attributes); | |
| 341 | 346 |
| 342 // Add name. | 347 { // Add length. |
| 343 result = | 348 Handle<Proxy> proxy = FACTORY->NewProxy(&Accessors::FunctionLength); |
| 344 FACTORY->CopyAppendProxyDescriptor( | 349 CallbacksDescriptor d(*FACTORY->length_symbol(), *proxy, attributes); |
| 345 result, | 350 descriptors->Set(0, &d); |
| 346 FACTORY->name_symbol(), | 351 } |
| 347 FACTORY->NewProxy(&Accessors::FunctionName), | 352 { // Add name. |
| 348 attributes); | 353 Handle<Proxy> proxy = FACTORY->NewProxy(&Accessors::FunctionName); |
| 354 CallbacksDescriptor d(*FACTORY->name_symbol(), *proxy, attributes); |
| 355 descriptors->Set(1, &d); |
| 356 } |
| 357 { // Add arguments. |
| 358 Handle<Proxy> proxy = FACTORY->NewProxy(&Accessors::FunctionArguments); |
| 359 CallbacksDescriptor d(*FACTORY->arguments_symbol(), *proxy, attributes); |
| 360 descriptors->Set(2, &d); |
| 361 } |
| 362 { // Add caller. |
| 363 Handle<Proxy> proxy = FACTORY->NewProxy(&Accessors::FunctionCaller); |
| 364 CallbacksDescriptor d(*FACTORY->caller_symbol(), *proxy, attributes); |
| 365 descriptors->Set(3, &d); |
| 366 } |
| 367 if (prototypeMode != DONT_ADD_PROTOTYPE) { |
| 368 // Add prototype. |
| 369 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) { |
| 370 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY); |
| 371 } |
| 372 Handle<Proxy> proxy = FACTORY->NewProxy(&Accessors::FunctionPrototype); |
| 373 CallbacksDescriptor d(*FACTORY->prototype_symbol(), *proxy, attributes); |
| 374 descriptors->Set(4, &d); |
| 375 } |
| 376 descriptors->Sort(); |
| 377 return descriptors; |
| 378 } |
| 349 | 379 |
| 350 // Add arguments. | |
| 351 result = | |
| 352 FACTORY->CopyAppendProxyDescriptor( | |
| 353 result, | |
| 354 FACTORY->arguments_symbol(), | |
| 355 FACTORY->NewProxy(&Accessors::FunctionArguments), | |
| 356 attributes); | |
| 357 | 380 |
| 358 // Add caller. | 381 Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) { |
| 359 result = | 382 Handle<Map> map = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
| 360 FACTORY->CopyAppendProxyDescriptor( | 383 Handle<DescriptorArray> descriptors = |
| 361 result, | 384 ComputeFunctionInstanceDescriptor(prototype_mode); |
| 362 FACTORY->caller_symbol(), | 385 map->set_instance_descriptors(*descriptors); |
| 363 FACTORY->NewProxy(&Accessors::FunctionCaller), | 386 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); |
| 364 attributes); | 387 return map; |
| 365 | |
| 366 return result; | |
| 367 } | 388 } |
| 368 | 389 |
| 369 | 390 |
| 370 Handle<JSFunction> Genesis::CreateEmptyFunction() { | 391 Handle<JSFunction> Genesis::CreateEmptyFunction() { |
| 371 // Allocate the map for function instances. | 392 // Allocate the map for function instances. Maps are allocated first and their |
| 372 Handle<Map> fm = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | 393 // prototypes patched later, once empty function is created. |
| 373 global_context()->set_function_instance_map(*fm); | 394 |
| 374 // Please note that the prototype property for function instances must be | 395 // Please note that the prototype property for function instances must be |
| 375 // writable. | 396 // writable. |
| 376 Handle<DescriptorArray> function_map_descriptors = | 397 global_context()->set_function_instance_map( |
| 377 ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE); | 398 *CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE)); |
| 378 fm->set_instance_descriptors(*function_map_descriptors); | |
| 379 fm->set_function_with_prototype(true); | |
| 380 | 399 |
| 381 // Functions with this map will not have a 'prototype' property, and | 400 // Functions with this map will not have a 'prototype' property, and |
| 382 // can not be used as constructors. | 401 // can not be used as constructors. |
| 383 Handle<Map> function_without_prototype_map = | |
| 384 FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | |
| 385 global_context()->set_function_without_prototype_map( | 402 global_context()->set_function_without_prototype_map( |
| 386 *function_without_prototype_map); | 403 *CreateFunctionMap(DONT_ADD_PROTOTYPE)); |
| 387 Handle<DescriptorArray> function_without_prototype_map_descriptors = | |
| 388 ComputeFunctionInstanceDescriptor(DONT_ADD_PROTOTYPE); | |
| 389 function_without_prototype_map->set_instance_descriptors( | |
| 390 *function_without_prototype_map_descriptors); | |
| 391 function_without_prototype_map->set_function_with_prototype(false); | |
| 392 | 404 |
| 393 // Allocate the function map first and then patch the prototype later | 405 // Allocate the function map. This map is temporary, used only for processing |
| 394 fm = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | 406 // of builtins. |
| 395 global_context()->set_function_map(*fm); | 407 // Later the map is replaced with writable prototype map, allocated below. |
| 396 function_map_descriptors = | 408 global_context()->set_function_map( |
| 397 ComputeFunctionInstanceDescriptor(ADD_READONLY_PROTOTYPE); | 409 *CreateFunctionMap(ADD_READONLY_PROTOTYPE)); |
| 398 fm->set_instance_descriptors(*function_map_descriptors); | 410 |
| 399 fm->set_function_with_prototype(true); | 411 // The final map for functions. Writeable prototype. |
| 412 // This map is installed in MakeFunctionInstancePrototypeWritable. |
| 413 function_instance_map_writable_prototype_ = |
| 414 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE); |
| 400 | 415 |
| 401 Handle<String> object_name = Handle<String>(HEAP->Object_symbol()); | 416 Handle<String> object_name = Handle<String>(HEAP->Object_symbol()); |
| 402 | 417 |
| 403 { // --- O b j e c t --- | 418 { // --- O b j e c t --- |
| 404 Handle<JSFunction> object_fun = | 419 Handle<JSFunction> object_fun = |
| 405 FACTORY->NewFunction(object_name, FACTORY->null_value()); | 420 FACTORY->NewFunction(object_name, FACTORY->null_value()); |
| 406 Handle<Map> object_function_map = | 421 Handle<Map> object_function_map = |
| 407 FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 422 FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 408 object_fun->set_initial_map(*object_function_map); | 423 object_fun->set_initial_map(*object_function_map); |
| 409 object_function_map->set_constructor(*object_fun); | 424 object_function_map->set_constructor(*object_fun); |
| 410 | 425 |
| 411 global_context()->set_object_function(*object_fun); | 426 global_context()->set_object_function(*object_fun); |
| 412 | 427 |
| 413 // Allocate a new prototype for the object function. | 428 // Allocate a new prototype for the object function. |
| 414 Handle<JSObject> prototype = FACTORY->NewJSObject( | 429 Handle<JSObject> prototype = FACTORY->NewJSObject( |
| 415 Isolate::Current()->object_function(), | 430 Isolate::Current()->object_function(), |
| 416 TENURED); | 431 TENURED); |
| 417 | 432 |
| 418 global_context()->set_initial_object_prototype(*prototype); | 433 global_context()->set_initial_object_prototype(*prototype); |
| 419 SetPrototype(object_fun, prototype); | 434 SetPrototype(object_fun, prototype); |
| 420 object_function_map-> | 435 object_function_map-> |
| 421 set_instance_descriptors(HEAP->empty_descriptor_array()); | 436 set_instance_descriptors(HEAP->empty_descriptor_array()); |
| 422 } | 437 } |
| 423 | 438 |
| 424 // Allocate the empty function as the prototype for function ECMAScript | 439 // Allocate the empty function as the prototype for function ECMAScript |
| 425 // 262 15.3.4. | 440 // 262 15.3.4. |
| 426 Handle<String> symbol = FACTORY->LookupAsciiSymbol("Empty"); | 441 Handle<String> symbol = FACTORY->LookupAsciiSymbol("Empty"); |
| 427 Handle<JSFunction> empty_function = | 442 Handle<JSFunction> empty_function = |
| 428 FACTORY->NewFunctionWithoutPrototype(symbol); | 443 FACTORY->NewFunctionWithoutPrototype(symbol, kNonStrictMode); |
| 429 | 444 |
| 430 // --- E m p t y --- | 445 // --- E m p t y --- |
| 431 Handle<Code> code = | 446 Handle<Code> code = |
| 432 Handle<Code>(Isolate::Current()->builtins()->builtin( | 447 Handle<Code>(Isolate::Current()->builtins()->builtin( |
| 433 Builtins::EmptyFunction)); | 448 Builtins::EmptyFunction)); |
| 434 empty_function->set_code(*code); | 449 empty_function->set_code(*code); |
| 435 empty_function->shared()->set_code(*code); | 450 empty_function->shared()->set_code(*code); |
| 436 Handle<String> source = FACTORY->NewStringFromAscii(CStrVector("() {}")); | 451 Handle<String> source = FACTORY->NewStringFromAscii(CStrVector("() {}")); |
| 437 Handle<Script> script = FACTORY->NewScript(source); | 452 Handle<Script> script = FACTORY->NewScript(source); |
| 438 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); | 453 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); |
| 439 empty_function->shared()->set_script(*script); | 454 empty_function->shared()->set_script(*script); |
| 440 empty_function->shared()->set_start_position(0); | 455 empty_function->shared()->set_start_position(0); |
| 441 empty_function->shared()->set_end_position(source->length()); | 456 empty_function->shared()->set_end_position(source->length()); |
| 442 empty_function->shared()->DontAdaptArguments(); | 457 empty_function->shared()->DontAdaptArguments(); |
| 458 |
| 459 // Set prototypes for the function maps. |
| 443 global_context()->function_map()->set_prototype(*empty_function); | 460 global_context()->function_map()->set_prototype(*empty_function); |
| 444 global_context()->function_instance_map()->set_prototype(*empty_function); | 461 global_context()->function_instance_map()->set_prototype(*empty_function); |
| 445 global_context()->function_without_prototype_map()-> | 462 global_context()->function_without_prototype_map()-> |
| 446 set_prototype(*empty_function); | 463 set_prototype(*empty_function); |
| 464 function_instance_map_writable_prototype_->set_prototype(*empty_function); |
| 447 | 465 |
| 448 // Allocate the function map first and then patch the prototype later | 466 // Allocate the function map first and then patch the prototype later |
| 467 Handle<Map> function_without_prototype_map( |
| 468 global_context()->function_without_prototype_map()); |
| 449 Handle<Map> empty_fm = FACTORY->CopyMapDropDescriptors( | 469 Handle<Map> empty_fm = FACTORY->CopyMapDropDescriptors( |
| 450 function_without_prototype_map); | 470 function_without_prototype_map); |
| 451 empty_fm->set_instance_descriptors( | 471 empty_fm->set_instance_descriptors( |
| 452 *function_without_prototype_map_descriptors); | 472 function_without_prototype_map->instance_descriptors()); |
| 453 empty_fm->set_prototype(global_context()->object_function()->prototype()); | 473 empty_fm->set_prototype(global_context()->object_function()->prototype()); |
| 454 empty_function->set_map(*empty_fm); | 474 empty_function->set_map(*empty_fm); |
| 455 return empty_function; | 475 return empty_function; |
| 456 } | 476 } |
| 457 | 477 |
| 458 | 478 |
| 479 Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor( |
| 480 PrototypePropertyMode prototypeMode, |
| 481 Handle<FixedArray> arguments, |
| 482 Handle<FixedArray> caller) { |
| 483 Handle<DescriptorArray> descriptors = |
| 484 FACTORY->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5); |
| 485 PropertyAttributes attributes = static_cast<PropertyAttributes>( |
| 486 DONT_ENUM | DONT_DELETE | READ_ONLY); |
| 487 |
| 488 { // length |
| 489 Handle<Proxy> proxy = FACTORY->NewProxy(&Accessors::FunctionLength); |
| 490 CallbacksDescriptor d(*FACTORY->length_symbol(), *proxy, attributes); |
| 491 descriptors->Set(0, &d); |
| 492 } |
| 493 { // name |
| 494 Handle<Proxy> proxy = FACTORY->NewProxy(&Accessors::FunctionName); |
| 495 CallbacksDescriptor d(*FACTORY->name_symbol(), *proxy, attributes); |
| 496 descriptors->Set(1, &d); |
| 497 } |
| 498 { // arguments |
| 499 CallbacksDescriptor d(*FACTORY->arguments_symbol(), *arguments, attributes); |
| 500 descriptors->Set(2, &d); |
| 501 } |
| 502 { // caller |
| 503 CallbacksDescriptor d(*FACTORY->caller_symbol(), *caller, attributes); |
| 504 descriptors->Set(3, &d); |
| 505 } |
| 506 |
| 507 // prototype |
| 508 if (prototypeMode != DONT_ADD_PROTOTYPE) { |
| 509 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) { |
| 510 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY); |
| 511 } |
| 512 Handle<Proxy> proxy = FACTORY->NewProxy(&Accessors::FunctionPrototype); |
| 513 CallbacksDescriptor d(*FACTORY->prototype_symbol(), *proxy, attributes); |
| 514 descriptors->Set(4, &d); |
| 515 } |
| 516 |
| 517 descriptors->Sort(); |
| 518 return descriptors; |
| 519 } |
| 520 |
| 521 |
| 522 // ECMAScript 5th Edition, 13.2.3 |
| 523 Handle<JSFunction> Genesis::CreateThrowTypeErrorFunction( |
| 524 Builtins::Name builtin) { |
| 525 Handle<String> name = FACTORY->LookupAsciiSymbol("ThrowTypeError"); |
| 526 Handle<JSFunction> throw_type_error = |
| 527 FACTORY->NewFunctionWithoutPrototype(name, kStrictMode); |
| 528 Handle<Code> code = Handle<Code>( |
| 529 Isolate::Current()->builtins()->builtin(builtin)); |
| 530 |
| 531 throw_type_error->set_map(global_context()->strict_mode_function_map()); |
| 532 throw_type_error->set_code(*code); |
| 533 throw_type_error->shared()->set_code(*code); |
| 534 throw_type_error->shared()->DontAdaptArguments(); |
| 535 |
| 536 PreventExtensions(throw_type_error); |
| 537 |
| 538 return throw_type_error; |
| 539 } |
| 540 |
| 541 |
| 542 Handle<Map> Genesis::CreateStrictModeFunctionMap( |
| 543 PrototypePropertyMode prototype_mode, |
| 544 Handle<JSFunction> empty_function, |
| 545 Handle<FixedArray> arguments_callbacks, |
| 546 Handle<FixedArray> caller_callbacks) { |
| 547 Handle<Map> map = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
| 548 Handle<DescriptorArray> descriptors = |
| 549 ComputeStrictFunctionInstanceDescriptor(prototype_mode, |
| 550 arguments_callbacks, |
| 551 caller_callbacks); |
| 552 map->set_instance_descriptors(*descriptors); |
| 553 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); |
| 554 map->set_prototype(*empty_function); |
| 555 return map; |
| 556 } |
| 557 |
| 558 |
| 559 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { |
| 560 // Create the callbacks arrays for ThrowTypeError functions. |
| 561 // The get/set callacks are filled in after the maps are created below. |
| 562 Handle<FixedArray> arguments = FACTORY->NewFixedArray(2, TENURED); |
| 563 Handle<FixedArray> caller = FACTORY->NewFixedArray(2, TENURED); |
| 564 |
| 565 // Allocate map for the strict mode function instances. |
| 566 global_context()->set_strict_mode_function_instance_map( |
| 567 *CreateStrictModeFunctionMap( |
| 568 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller)); |
| 569 |
| 570 // Allocate map for the prototype-less strict mode instances. |
| 571 global_context()->set_strict_mode_function_without_prototype_map( |
| 572 *CreateStrictModeFunctionMap( |
| 573 DONT_ADD_PROTOTYPE, empty, arguments, caller)); |
| 574 |
| 575 // Allocate map for the strict mode functions. This map is temporary, used |
| 576 // only for processing of builtins. |
| 577 // Later the map is replaced with writable prototype map, allocated below. |
| 578 global_context()->set_strict_mode_function_map( |
| 579 *CreateStrictModeFunctionMap( |
| 580 ADD_READONLY_PROTOTYPE, empty, arguments, caller)); |
| 581 |
| 582 // The final map for the strict mode functions. Writeable prototype. |
| 583 // This map is installed in MakeFunctionInstancePrototypeWritable. |
| 584 strict_mode_function_instance_map_writable_prototype_ = |
| 585 CreateStrictModeFunctionMap( |
| 586 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller); |
| 587 |
| 588 // Create the ThrowTypeError function instances. |
| 589 Handle<JSFunction> arguments_throw = |
| 590 CreateThrowTypeErrorFunction(Builtins::StrictFunctionArguments); |
| 591 Handle<JSFunction> caller_throw = |
| 592 CreateThrowTypeErrorFunction(Builtins::StrictFunctionCaller); |
| 593 |
| 594 // Complete the callback fixed arrays. |
| 595 arguments->set(0, *arguments_throw); |
| 596 arguments->set(1, *arguments_throw); |
| 597 caller->set(0, *caller_throw); |
| 598 caller->set(1, *caller_throw); |
| 599 } |
| 600 |
| 601 |
| 459 static void AddToWeakGlobalContextList(Context* context) { | 602 static void AddToWeakGlobalContextList(Context* context) { |
| 460 ASSERT(context->IsGlobalContext()); | 603 ASSERT(context->IsGlobalContext()); |
| 461 Heap* heap = Isolate::Current()->heap(); | 604 Heap* heap = Isolate::Current()->heap(); |
| 462 #ifdef DEBUG | 605 #ifdef DEBUG |
| 463 { // NOLINT | 606 { // NOLINT |
| 464 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); | 607 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); |
| 465 // Check that context is not in the list yet. | 608 // Check that context is not in the list yet. |
| 466 for (Object* current = heap->global_contexts_list(); | 609 for (Object* current = heap->global_contexts_list(); |
| 467 !current->IsUndefined(); | 610 !current->IsUndefined(); |
| 468 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) { | 611 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) { |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 JSObject::kHeaderSize, | 979 JSObject::kHeaderSize, |
| 837 prototype, | 980 prototype, |
| 838 code, | 981 code, |
| 839 false); | 982 false); |
| 840 ASSERT(!function->has_initial_map()); | 983 ASSERT(!function->has_initial_map()); |
| 841 function->shared()->set_instance_class_name(*symbol); | 984 function->shared()->set_instance_class_name(*symbol); |
| 842 function->shared()->set_expected_nof_properties(2); | 985 function->shared()->set_expected_nof_properties(2); |
| 843 Handle<JSObject> result = FACTORY->NewJSObject(function); | 986 Handle<JSObject> result = FACTORY->NewJSObject(function); |
| 844 | 987 |
| 845 global_context()->set_arguments_boilerplate(*result); | 988 global_context()->set_arguments_boilerplate(*result); |
| 846 // Note: callee must be added as the first property and | 989 // Note: length must be added as the first property and |
| 847 // length must be added as the second property. | 990 // callee must be added as the second property. |
| 991 SetLocalPropertyNoThrow(result, FACTORY->length_symbol(), |
| 992 FACTORY->undefined_value(), |
| 993 DONT_ENUM); |
| 848 SetLocalPropertyNoThrow(result, FACTORY->callee_symbol(), | 994 SetLocalPropertyNoThrow(result, FACTORY->callee_symbol(), |
| 849 FACTORY->undefined_value(), | 995 FACTORY->undefined_value(), |
| 850 DONT_ENUM); | 996 DONT_ENUM); |
| 851 SetLocalPropertyNoThrow(result, FACTORY->length_symbol(), | |
| 852 FACTORY->undefined_value(), | |
| 853 DONT_ENUM); | |
| 854 | 997 |
| 855 #ifdef DEBUG | 998 #ifdef DEBUG |
| 856 LookupResult lookup; | 999 LookupResult lookup; |
| 857 result->LocalLookup(HEAP->callee_symbol(), &lookup); | 1000 result->LocalLookup(HEAP->callee_symbol(), &lookup); |
| 858 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD)); | 1001 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD)); |
| 859 ASSERT(lookup.GetFieldIndex() == Heap::arguments_callee_index); | 1002 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex); |
| 860 | 1003 |
| 861 result->LocalLookup(HEAP->length_symbol(), &lookup); | 1004 result->LocalLookup(HEAP->length_symbol(), &lookup); |
| 862 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD)); | 1005 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD)); |
| 863 ASSERT(lookup.GetFieldIndex() == Heap::arguments_length_index); | 1006 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex); |
| 864 | 1007 |
| 865 ASSERT(result->map()->inobject_properties() > Heap::arguments_callee_index); | 1008 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex); |
| 866 ASSERT(result->map()->inobject_properties() > Heap::arguments_length_index); | 1009 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex); |
| 867 | 1010 |
| 868 // Check the state of the object. | 1011 // Check the state of the object. |
| 869 ASSERT(result->HasFastProperties()); | 1012 ASSERT(result->HasFastProperties()); |
| 870 ASSERT(result->HasFastElements()); | 1013 ASSERT(result->HasFastElements()); |
| 871 #endif | 1014 #endif |
| 872 } | 1015 } |
| 873 | 1016 |
| 1017 { // --- strict mode arguments boilerplate |
| 1018 const PropertyAttributes attributes = |
| 1019 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
| 1020 |
| 1021 // Create the ThrowTypeError functions. |
| 1022 Handle<FixedArray> callee = FACTORY->NewFixedArray(2, TENURED); |
| 1023 Handle<FixedArray> caller = FACTORY->NewFixedArray(2, TENURED); |
| 1024 |
| 1025 Handle<JSFunction> callee_throw = |
| 1026 CreateThrowTypeErrorFunction(Builtins::StrictArgumentsCallee); |
| 1027 Handle<JSFunction> caller_throw = |
| 1028 CreateThrowTypeErrorFunction(Builtins::StrictArgumentsCaller); |
| 1029 |
| 1030 // Install the ThrowTypeError functions. |
| 1031 callee->set(0, *callee_throw); |
| 1032 callee->set(1, *callee_throw); |
| 1033 caller->set(0, *caller_throw); |
| 1034 caller->set(1, *caller_throw); |
| 1035 |
| 1036 // Create the descriptor array for the arguments object. |
| 1037 Handle<DescriptorArray> descriptors = FACTORY->NewDescriptorArray(3); |
| 1038 { // length |
| 1039 FieldDescriptor d(*FACTORY->length_symbol(), 0, DONT_ENUM); |
| 1040 descriptors->Set(0, &d); |
| 1041 } |
| 1042 { // callee |
| 1043 CallbacksDescriptor d(*FACTORY->callee_symbol(), *callee, attributes); |
| 1044 descriptors->Set(1, &d); |
| 1045 } |
| 1046 { // caller |
| 1047 CallbacksDescriptor d(*FACTORY->caller_symbol(), *caller, attributes); |
| 1048 descriptors->Set(2, &d); |
| 1049 } |
| 1050 descriptors->Sort(); |
| 1051 |
| 1052 // Create the map. Allocate one in-object field for length. |
| 1053 Handle<Map> map = FACTORY->NewMap(JS_OBJECT_TYPE, |
| 1054 Heap::kArgumentsObjectSizeStrict); |
| 1055 map->set_instance_descriptors(*descriptors); |
| 1056 map->set_function_with_prototype(true); |
| 1057 map->set_prototype(global_context()->object_function()->prototype()); |
| 1058 map->set_pre_allocated_property_fields(1); |
| 1059 map->set_inobject_properties(1); |
| 1060 |
| 1061 // Copy constructor from the non-strict arguments boilerplate. |
| 1062 map->set_constructor( |
| 1063 global_context()->arguments_boilerplate()->map()->constructor()); |
| 1064 |
| 1065 // Allocate the arguments boilerplate object. |
| 1066 Handle<JSObject> result = FACTORY->NewJSObjectFromMap(map); |
| 1067 global_context()->set_strict_mode_arguments_boilerplate(*result); |
| 1068 |
| 1069 // Add length property only for strict mode boilerplate. |
| 1070 SetLocalPropertyNoThrow(result, FACTORY->length_symbol(), |
| 1071 FACTORY->undefined_value(), |
| 1072 DONT_ENUM); |
| 1073 |
| 1074 #ifdef DEBUG |
| 1075 LookupResult lookup; |
| 1076 result->LocalLookup(HEAP->length_symbol(), &lookup); |
| 1077 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD)); |
| 1078 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex); |
| 1079 |
| 1080 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex); |
| 1081 |
| 1082 // Check the state of the object. |
| 1083 ASSERT(result->HasFastProperties()); |
| 1084 ASSERT(result->HasFastElements()); |
| 1085 #endif |
| 1086 } |
| 1087 |
| 874 { // --- context extension | 1088 { // --- context extension |
| 875 // Create a function for the context extension objects. | 1089 // Create a function for the context extension objects. |
| 876 Handle<Code> code = Handle<Code>( | 1090 Handle<Code> code = Handle<Code>( |
| 877 Isolate::Current()->builtins()->builtin(Builtins::Illegal)); | 1091 Isolate::Current()->builtins()->builtin(Builtins::Illegal)); |
| 878 Handle<JSFunction> context_extension_fun = | 1092 Handle<JSFunction> context_extension_fun = |
| 879 FACTORY->NewFunction(FACTORY->empty_symbol(), | 1093 FACTORY->NewFunction(FACTORY->empty_symbol(), |
| 880 JS_CONTEXT_EXTENSION_OBJECT_TYPE, | 1094 JS_CONTEXT_EXTENSION_OBJECT_TYPE, |
| 881 JSObject::kHeaderSize, | 1095 JSObject::kHeaderSize, |
| 882 code, | 1096 code, |
| 883 true); | 1097 true); |
| (...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1781 | 1995 |
| 1782 // Transfer the prototype (new map is needed). | 1996 // Transfer the prototype (new map is needed). |
| 1783 Handle<Map> old_to_map = Handle<Map>(to->map()); | 1997 Handle<Map> old_to_map = Handle<Map>(to->map()); |
| 1784 Handle<Map> new_to_map = FACTORY->CopyMapDropTransitions(old_to_map); | 1998 Handle<Map> new_to_map = FACTORY->CopyMapDropTransitions(old_to_map); |
| 1785 new_to_map->set_prototype(from->map()->prototype()); | 1999 new_to_map->set_prototype(from->map()->prototype()); |
| 1786 to->set_map(*new_to_map); | 2000 to->set_map(*new_to_map); |
| 1787 } | 2001 } |
| 1788 | 2002 |
| 1789 | 2003 |
| 1790 void Genesis::MakeFunctionInstancePrototypeWritable() { | 2004 void Genesis::MakeFunctionInstancePrototypeWritable() { |
| 1791 // Make a new function map so all future functions | 2005 // The maps with writable prototype are created in CreateEmptyFunction |
| 1792 // will have settable and enumerable prototype properties. | 2006 // and CreateStrictModeFunctionMaps respectively. Initially the maps are |
| 1793 HandleScope scope; | 2007 // created with read-only prototype for JS builtins processing. |
| 2008 ASSERT(!function_instance_map_writable_prototype_.is_null()); |
| 2009 ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null()); |
| 1794 | 2010 |
| 1795 Handle<DescriptorArray> function_map_descriptors = | 2011 // Replace function instance maps to make prototype writable. |
| 1796 ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE); | 2012 global_context()->set_function_map( |
| 1797 Handle<Map> fm = FACTORY->CopyMapDropDescriptors( | 2013 *function_instance_map_writable_prototype_); |
| 1798 Isolate::Current()->function_map()); | 2014 global_context()->set_strict_mode_function_map( |
| 1799 fm->set_instance_descriptors(*function_map_descriptors); | 2015 *strict_mode_function_instance_map_writable_prototype_); |
| 1800 fm->set_function_with_prototype(true); | |
| 1801 Isolate::Current()->context()->global_context()->set_function_map(*fm); | |
| 1802 } | 2016 } |
| 1803 | 2017 |
| 1804 | 2018 |
| 1805 Genesis::Genesis(Handle<Object> global_object, | 2019 Genesis::Genesis(Handle<Object> global_object, |
| 1806 v8::Handle<v8::ObjectTemplate> global_template, | 2020 v8::Handle<v8::ObjectTemplate> global_template, |
| 1807 v8::ExtensionConfiguration* extensions) { | 2021 v8::ExtensionConfiguration* extensions) { |
| 1808 Isolate* isolate = Isolate::Current(); | 2022 Isolate* isolate = Isolate::Current(); |
| 1809 result_ = Handle<Context>::null(); | 2023 result_ = Handle<Context>::null(); |
| 1810 // If V8 isn't running and cannot be initialized, just return. | 2024 // If V8 isn't running and cannot be initialized, just return. |
| 1811 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; | 2025 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; |
| 1812 | 2026 |
| 1813 // Before creating the roots we must save the context and restore it | 2027 // Before creating the roots we must save the context and restore it |
| 1814 // on all function exits. | 2028 // on all function exits. |
| 1815 HandleScope scope; | 2029 HandleScope scope; |
| 1816 SaveContext saved_context(isolate); | 2030 SaveContext saved_context(isolate); |
| 1817 | 2031 |
| 1818 Handle<Context> new_context = Snapshot::NewContextFromSnapshot(); | 2032 Handle<Context> new_context = Snapshot::NewContextFromSnapshot(); |
| 1819 if (!new_context.is_null()) { | 2033 if (!new_context.is_null()) { |
| 1820 global_context_ = | 2034 global_context_ = |
| 1821 Handle<Context>::cast(isolate->global_handles()->Create(*new_context)); | 2035 Handle<Context>::cast(isolate->global_handles()->Create(*new_context)); |
| 1822 AddToWeakGlobalContextList(*global_context_); | 2036 AddToWeakGlobalContextList(*global_context_); |
| 1823 isolate->set_context(*global_context_); | 2037 isolate->set_context(*global_context_); |
| 1824 isolate->counters()->contexts_created_by_snapshot()->Increment(); | 2038 isolate->counters()->contexts_created_by_snapshot()->Increment(); |
| 1825 JSFunction* empty_function = | |
| 1826 JSFunction::cast(global_context_->function_map()->prototype()); | |
| 1827 empty_function_ = Handle<JSFunction>(empty_function); | |
| 1828 Handle<GlobalObject> inner_global; | 2039 Handle<GlobalObject> inner_global; |
| 1829 Handle<JSGlobalProxy> global_proxy = | 2040 Handle<JSGlobalProxy> global_proxy = |
| 1830 CreateNewGlobals(global_template, | 2041 CreateNewGlobals(global_template, |
| 1831 global_object, | 2042 global_object, |
| 1832 &inner_global); | 2043 &inner_global); |
| 1833 | 2044 |
| 1834 HookUpGlobalProxy(inner_global, global_proxy); | 2045 HookUpGlobalProxy(inner_global, global_proxy); |
| 1835 HookUpInnerGlobal(inner_global); | 2046 HookUpInnerGlobal(inner_global); |
| 1836 | 2047 |
| 1837 if (!ConfigureGlobalObjects(global_template)) return; | 2048 if (!ConfigureGlobalObjects(global_template)) return; |
| 1838 } else { | 2049 } else { |
| 1839 // We get here if there was no context snapshot. | 2050 // We get here if there was no context snapshot. |
| 1840 CreateRoots(); | 2051 CreateRoots(); |
| 1841 Handle<JSFunction> empty_function = CreateEmptyFunction(); | 2052 Handle<JSFunction> empty_function = CreateEmptyFunction(); |
| 2053 CreateStrictModeFunctionMaps(empty_function); |
| 1842 Handle<GlobalObject> inner_global; | 2054 Handle<GlobalObject> inner_global; |
| 1843 Handle<JSGlobalProxy> global_proxy = | 2055 Handle<JSGlobalProxy> global_proxy = |
| 1844 CreateNewGlobals(global_template, global_object, &inner_global); | 2056 CreateNewGlobals(global_template, global_object, &inner_global); |
| 1845 HookUpGlobalProxy(inner_global, global_proxy); | 2057 HookUpGlobalProxy(inner_global, global_proxy); |
| 1846 InitializeGlobal(inner_global, empty_function); | 2058 InitializeGlobal(inner_global, empty_function); |
| 1847 InstallJSFunctionResultCaches(); | 2059 InstallJSFunctionResultCaches(); |
| 1848 InitializeNormalizedMapCaches(); | 2060 InitializeNormalizedMapCaches(); |
| 1849 if (!InstallNatives()) return; | 2061 if (!InstallNatives()) return; |
| 1850 | 2062 |
| 1851 MakeFunctionInstancePrototypeWritable(); | 2063 MakeFunctionInstancePrototypeWritable(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1880 return from + sizeof(NestingCounterType); | 2092 return from + sizeof(NestingCounterType); |
| 1881 } | 2093 } |
| 1882 | 2094 |
| 1883 | 2095 |
| 1884 // Called when the top-level V8 mutex is destroyed. | 2096 // Called when the top-level V8 mutex is destroyed. |
| 1885 void Bootstrapper::FreeThreadResources() { | 2097 void Bootstrapper::FreeThreadResources() { |
| 1886 ASSERT(!IsActive()); | 2098 ASSERT(!IsActive()); |
| 1887 } | 2099 } |
| 1888 | 2100 |
| 1889 } } // namespace v8::internal | 2101 } } // namespace v8::internal |
| OLD | NEW |