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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
241 Handle<ObjectTemplateInfo> object_template); | 241 Handle<ObjectTemplateInfo> object_template); |
242 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); | 242 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); |
243 | 243 |
244 // Migrates all properties from the 'from' object to the 'to' | 244 // Migrates all properties from the 'from' object to the 'to' |
245 // object and overrides the prototype in 'to' with the one from | 245 // object and overrides the prototype in 'to' with the one from |
246 // 'from'. | 246 // 'from'. |
247 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); | 247 void TransferObject(Handle<JSObject> from, Handle<JSObject> to); |
248 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); | 248 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); |
249 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); | 249 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); |
250 | 250 |
251 enum PrototypePropertyMode { | |
252 DONT_ADD_PROTOTYPE, | |
253 ADD_READONLY_PROTOTYPE, | |
254 ADD_WRITEABLE_PROTOTYPE | |
255 }; | |
251 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( | 256 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor( |
252 bool make_prototype_read_only, | 257 PrototypePropertyMode prototypeMode); |
253 bool make_prototype_enumerable = false); | |
254 void MakeFunctionInstancePrototypeWritable(); | 258 void MakeFunctionInstancePrototypeWritable(); |
255 | 259 |
256 static bool CompileBuiltin(int index); | 260 static bool CompileBuiltin(int index); |
257 static bool CompileNative(Vector<const char> name, Handle<String> source); | 261 static bool CompileNative(Vector<const char> name, Handle<String> source); |
258 static bool CompileScriptCached(Vector<const char> name, | 262 static bool CompileScriptCached(Vector<const char> name, |
259 Handle<String> source, | 263 Handle<String> source, |
260 SourceCodeCache* cache, | 264 SourceCodeCache* cache, |
261 v8::Extension* extension, | 265 v8::Extension* extension, |
262 Handle<Context> top_context, | 266 Handle<Context> top_context, |
263 bool use_runtime_context); | 267 bool use_runtime_context); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
323 | 327 |
324 static Handle<JSFunction> InstallFunction(Handle<JSObject> target, | 328 static Handle<JSFunction> InstallFunction(Handle<JSObject> target, |
325 const char* name, | 329 const char* name, |
326 InstanceType type, | 330 InstanceType type, |
327 int instance_size, | 331 int instance_size, |
328 Handle<JSObject> prototype, | 332 Handle<JSObject> prototype, |
329 Builtins::Name call, | 333 Builtins::Name call, |
330 bool is_ecma_native) { | 334 bool is_ecma_native) { |
331 Handle<String> symbol = Factory::LookupAsciiSymbol(name); | 335 Handle<String> symbol = Factory::LookupAsciiSymbol(name); |
332 Handle<Code> call_code = Handle<Code>(Builtins::builtin(call)); | 336 Handle<Code> call_code = Handle<Code>(Builtins::builtin(call)); |
333 Handle<JSFunction> function = | 337 Handle<JSFunction> function = prototype.is_null() ? |
338 Factory::NewFunctionWithoutPrototype(symbol, call_code) : | |
334 Factory::NewFunctionWithPrototype(symbol, | 339 Factory::NewFunctionWithPrototype(symbol, |
335 type, | 340 type, |
336 instance_size, | 341 instance_size, |
337 prototype, | 342 prototype, |
338 call_code, | 343 call_code, |
339 is_ecma_native); | 344 is_ecma_native); |
340 SetProperty(target, symbol, function, DONT_ENUM); | 345 SetProperty(target, symbol, function, DONT_ENUM); |
341 if (is_ecma_native) { | 346 if (is_ecma_native) { |
342 function->shared()->set_instance_class_name(*symbol); | 347 function->shared()->set_instance_class_name(*symbol); |
343 } | 348 } |
344 return function; | 349 return function; |
345 } | 350 } |
346 | 351 |
347 | 352 |
348 Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor( | 353 Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor( |
349 bool make_prototype_read_only, | 354 PrototypePropertyMode prototypeMode) { |
350 bool make_prototype_enumerable) { | |
351 Handle<DescriptorArray> result = Factory::empty_descriptor_array(); | 355 Handle<DescriptorArray> result = Factory::empty_descriptor_array(); |
352 | 356 |
353 // Add prototype. | 357 if (prototypeMode != DONT_ADD_PROTOTYPE) { |
354 PropertyAttributes attributes = static_cast<PropertyAttributes>( | 358 PropertyAttributes attributes = static_cast<PropertyAttributes>( |
355 (make_prototype_enumerable ? 0 : DONT_ENUM) | 359 DONT_ENUM | |
356 | DONT_DELETE | 360 DONT_DELETE | |
357 | (make_prototype_read_only ? READ_ONLY : 0)); | 361 (prototypeMode == ADD_READONLY_PROTOTYPE ? READ_ONLY : 0)); |
358 result = | 362 result = |
359 Factory::CopyAppendProxyDescriptor( | 363 Factory::CopyAppendProxyDescriptor( |
360 result, | 364 result, |
361 Factory::prototype_symbol(), | 365 Factory::prototype_symbol(), |
362 Factory::NewProxy(&Accessors::FunctionPrototype), | 366 Factory::NewProxy(&Accessors::FunctionPrototype), |
363 attributes); | 367 attributes); |
368 } | |
364 | 369 |
365 attributes = | 370 PropertyAttributes attributes = |
366 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); | 371 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); |
367 // Add length. | 372 // Add length. |
368 result = | 373 result = |
369 Factory::CopyAppendProxyDescriptor( | 374 Factory::CopyAppendProxyDescriptor( |
370 result, | 375 result, |
371 Factory::length_symbol(), | 376 Factory::length_symbol(), |
372 Factory::NewProxy(&Accessors::FunctionLength), | 377 Factory::NewProxy(&Accessors::FunctionLength), |
373 attributes); | 378 attributes); |
374 | 379 |
375 // Add name. | 380 // Add name. |
(...skipping 24 matching lines...) Expand all Loading... | |
400 } | 405 } |
401 | 406 |
402 | 407 |
403 Handle<JSFunction> Genesis::CreateEmptyFunction() { | 408 Handle<JSFunction> Genesis::CreateEmptyFunction() { |
404 // Allocate the map for function instances. | 409 // Allocate the map for function instances. |
405 Handle<Map> fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | 410 Handle<Map> fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
406 global_context()->set_function_instance_map(*fm); | 411 global_context()->set_function_instance_map(*fm); |
407 // Please note that the prototype property for function instances must be | 412 // Please note that the prototype property for function instances must be |
408 // writable. | 413 // writable. |
409 Handle<DescriptorArray> function_map_descriptors = | 414 Handle<DescriptorArray> function_map_descriptors = |
410 ComputeFunctionInstanceDescriptor(false, false); | 415 ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE); |
411 fm->set_instance_descriptors(*function_map_descriptors); | 416 fm->set_instance_descriptors(*function_map_descriptors); |
417 fm->set_function_with_prototype(true); | |
418 | |
419 // Functions with this map will not have a 'prototype' property, and | |
420 // can not be used as constructors. | |
421 fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | |
422 global_context()->set_function_without_prototype_map(*fm); | |
423 function_map_descriptors = | |
424 ComputeFunctionInstanceDescriptor(DONT_ADD_PROTOTYPE); | |
425 fm->set_instance_descriptors(*function_map_descriptors); | |
426 fm->set_function_with_prototype(false); | |
412 | 427 |
413 // Allocate the function map first and then patch the prototype later | 428 // Allocate the function map first and then patch the prototype later |
414 fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); | 429 fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); |
415 global_context()->set_function_map(*fm); | 430 global_context()->set_function_map(*fm); |
416 function_map_descriptors = ComputeFunctionInstanceDescriptor(true); | 431 function_map_descriptors = |
432 ComputeFunctionInstanceDescriptor(ADD_READONLY_PROTOTYPE); | |
417 fm->set_instance_descriptors(*function_map_descriptors); | 433 fm->set_instance_descriptors(*function_map_descriptors); |
434 fm->set_function_with_prototype(true); | |
418 | 435 |
419 Handle<String> object_name = Handle<String>(Heap::Object_symbol()); | 436 Handle<String> object_name = Handle<String>(Heap::Object_symbol()); |
420 | 437 |
421 { // --- O b j e c t --- | 438 { // --- O b j e c t --- |
422 Handle<JSFunction> object_fun = | 439 Handle<JSFunction> object_fun = |
423 Factory::NewFunction(object_name, Factory::null_value()); | 440 Factory::NewFunction(object_name, Factory::null_value()); |
424 Handle<Map> object_function_map = | 441 Handle<Map> object_function_map = |
425 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 442 Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
426 object_fun->set_initial_map(*object_function_map); | 443 object_fun->set_initial_map(*object_function_map); |
427 object_function_map->set_constructor(*object_fun); | 444 object_function_map->set_constructor(*object_fun); |
(...skipping 23 matching lines...) Expand all Loading... | |
451 Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}")); | 468 Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}")); |
452 Handle<Script> script = Factory::NewScript(source); | 469 Handle<Script> script = Factory::NewScript(source); |
453 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); | 470 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); |
454 empty_function->shared()->set_script(*script); | 471 empty_function->shared()->set_script(*script); |
455 empty_function->shared()->set_start_position(0); | 472 empty_function->shared()->set_start_position(0); |
456 empty_function->shared()->set_end_position(source->length()); | 473 empty_function->shared()->set_end_position(source->length()); |
457 empty_function->shared()->DontAdaptArguments(); | 474 empty_function->shared()->DontAdaptArguments(); |
458 global_context()->function_map()->set_prototype(*empty_function); | 475 global_context()->function_map()->set_prototype(*empty_function); |
459 global_context()->function_instance_map()->set_prototype(*empty_function); | 476 global_context()->function_instance_map()->set_prototype(*empty_function); |
460 | 477 |
478 // Allocate a distinct prototype for this function map, so it will not add | |
Mads Ager (chromium)
2010/04/28 10:40:04
Make the comment a bit more explicit? How about:
dgozman
2010/04/28 11:16:59
Done.
| |
479 // 'prototype' property in the proto chain. | |
480 global_context()->function_without_prototype_map()->set_prototype( | |
481 *Factory::NewJSObject(Top::object_function(), TENURED)); | |
482 | |
461 // Allocate the function map first and then patch the prototype later | 483 // Allocate the function map first and then patch the prototype later |
462 Handle<Map> empty_fm = Factory::CopyMapDropDescriptors(fm); | 484 Handle<Map> empty_fm = Factory::CopyMapDropDescriptors(fm); |
463 empty_fm->set_instance_descriptors(*function_map_descriptors); | 485 empty_fm->set_instance_descriptors(*function_map_descriptors); |
464 empty_fm->set_prototype(global_context()->object_function()->prototype()); | 486 empty_fm->set_prototype(global_context()->object_function()->prototype()); |
465 empty_function->set_map(*empty_fm); | 487 empty_function->set_map(*empty_fm); |
466 return empty_function; | 488 return empty_function; |
467 } | 489 } |
468 | 490 |
469 | 491 |
470 void Genesis::CreateRoots() { | 492 void Genesis::CreateRoots() { |
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1208 // Install Function.prototype.call and apply. | 1230 // Install Function.prototype.call and apply. |
1209 { Handle<String> key = Factory::function_class_symbol(); | 1231 { Handle<String> key = Factory::function_class_symbol(); |
1210 Handle<JSFunction> function = | 1232 Handle<JSFunction> function = |
1211 Handle<JSFunction>::cast(GetProperty(Top::global(), key)); | 1233 Handle<JSFunction>::cast(GetProperty(Top::global(), key)); |
1212 Handle<JSObject> proto = | 1234 Handle<JSObject> proto = |
1213 Handle<JSObject>(JSObject::cast(function->instance_prototype())); | 1235 Handle<JSObject>(JSObject::cast(function->instance_prototype())); |
1214 | 1236 |
1215 // Install the call and the apply functions. | 1237 // Install the call and the apply functions. |
1216 Handle<JSFunction> call = | 1238 Handle<JSFunction> call = |
1217 InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize, | 1239 InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize, |
1218 Factory::NewJSObject(Top::object_function(), TENURED), | 1240 Handle<JSObject>::null(), |
1219 Builtins::FunctionCall, | 1241 Builtins::FunctionCall, |
1220 false); | 1242 false); |
1221 Handle<JSFunction> apply = | 1243 Handle<JSFunction> apply = |
1222 InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize, | 1244 InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize, |
1223 Factory::NewJSObject(Top::object_function(), TENURED), | 1245 Handle<JSObject>::null(), |
1224 Builtins::FunctionApply, | 1246 Builtins::FunctionApply, |
1225 false); | 1247 false); |
1226 | 1248 |
1227 // Make sure that Function.prototype.call appears to be compiled. | 1249 // Make sure that Function.prototype.call appears to be compiled. |
1228 // The code will never be called, but inline caching for call will | 1250 // The code will never be called, but inline caching for call will |
1229 // only work if it appears to be compiled. | 1251 // only work if it appears to be compiled. |
1230 call->shared()->DontAdaptArguments(); | 1252 call->shared()->DontAdaptArguments(); |
1231 ASSERT(call->is_compiled()); | 1253 ASSERT(call->is_compiled()); |
1232 | 1254 |
1233 // Set the expected parameters for apply to 2; required by builtin. | 1255 // Set the expected parameters for apply to 2; required by builtin. |
1234 apply->shared()->set_formal_parameter_count(2); | 1256 apply->shared()->set_formal_parameter_count(2); |
1235 | 1257 |
1236 // Set the lengths for the functions to satisfy ECMA-262. | 1258 // Set the lengths for the functions to satisfy ECMA-262. |
1237 call->shared()->set_length(1); | 1259 call->shared()->set_length(1); |
1238 apply->shared()->set_length(2); | 1260 apply->shared()->set_length(2); |
1261 | |
1262 // Install the call, apply, toString and constructor properties | |
1263 // for the functions without prototype. | |
1264 Handle<JSObject> wp_proto = Handle<JSObject>( | |
1265 JSObject::cast(Top::function_without_prototype_map()->prototype())); | |
1266 | |
1267 Handle<String> call_symbol = Factory::LookupAsciiSymbol("call"); | |
1268 SetProperty(wp_proto, call_symbol, call, DONT_ENUM); | |
1269 | |
1270 Handle<String> apply_symbol = Factory::LookupAsciiSymbol("apply"); | |
1271 SetProperty(wp_proto, apply_symbol, apply, DONT_ENUM); | |
1272 | |
1273 Handle<Object> to_string = GetProperty(proto, "toString"); | |
1274 Handle<String> to_string_symbol = Factory::LookupAsciiSymbol("toString"); | |
1275 SetProperty(wp_proto, to_string_symbol, to_string, DONT_ENUM); | |
1276 | |
1277 SetProperty(wp_proto, Factory::constructor_symbol(), function, DONT_ENUM); | |
1239 } | 1278 } |
1240 | 1279 |
1241 // Create a constructor for RegExp results (a variant of Array that | 1280 // Create a constructor for RegExp results (a variant of Array that |
1242 // predefines the two properties index and match). | 1281 // predefines the two properties index and match). |
1243 { | 1282 { |
1244 // RegExpResult initial map. | 1283 // RegExpResult initial map. |
1245 | 1284 |
1246 // Find global.Array.prototype to inherit from. | 1285 // Find global.Array.prototype to inherit from. |
1247 Handle<JSFunction> array_constructor(global_context()->array_function()); | 1286 Handle<JSFunction> array_constructor(global_context()->array_function()); |
1248 Handle<JSObject> array_prototype( | 1287 Handle<JSObject> array_prototype( |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1648 to->set_map(*new_to_map); | 1687 to->set_map(*new_to_map); |
1649 } | 1688 } |
1650 | 1689 |
1651 | 1690 |
1652 void Genesis::MakeFunctionInstancePrototypeWritable() { | 1691 void Genesis::MakeFunctionInstancePrototypeWritable() { |
1653 // Make a new function map so all future functions | 1692 // Make a new function map so all future functions |
1654 // will have settable and enumerable prototype properties. | 1693 // will have settable and enumerable prototype properties. |
1655 HandleScope scope; | 1694 HandleScope scope; |
1656 | 1695 |
1657 Handle<DescriptorArray> function_map_descriptors = | 1696 Handle<DescriptorArray> function_map_descriptors = |
1658 ComputeFunctionInstanceDescriptor(false); | 1697 ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE); |
1659 Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map()); | 1698 Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map()); |
1660 fm->set_instance_descriptors(*function_map_descriptors); | 1699 fm->set_instance_descriptors(*function_map_descriptors); |
1700 fm->set_function_with_prototype(true); | |
1661 Top::context()->global_context()->set_function_map(*fm); | 1701 Top::context()->global_context()->set_function_map(*fm); |
1662 } | 1702 } |
1663 | 1703 |
1664 | 1704 |
1665 Genesis::Genesis(Handle<Object> global_object, | 1705 Genesis::Genesis(Handle<Object> global_object, |
1666 v8::Handle<v8::ObjectTemplate> global_template, | 1706 v8::Handle<v8::ObjectTemplate> global_template, |
1667 v8::ExtensionConfiguration* extensions) { | 1707 v8::ExtensionConfiguration* extensions) { |
1668 result_ = Handle<Context>::null(); | 1708 result_ = Handle<Context>::null(); |
1669 // If V8 isn't running and cannot be initialized, just return. | 1709 // If V8 isn't running and cannot be initialized, just return. |
1670 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; | 1710 if (!V8::IsRunning() && !V8::Initialize(NULL)) return; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1756 } | 1796 } |
1757 | 1797 |
1758 | 1798 |
1759 // Restore statics that are thread local. | 1799 // Restore statics that are thread local. |
1760 char* BootstrapperActive::RestoreState(char* from) { | 1800 char* BootstrapperActive::RestoreState(char* from) { |
1761 nesting_ = *reinterpret_cast<int*>(from); | 1801 nesting_ = *reinterpret_cast<int*>(from); |
1762 return from + sizeof(nesting_); | 1802 return from + sizeof(nesting_); |
1763 } | 1803 } |
1764 | 1804 |
1765 } } // namespace v8::internal | 1805 } } // namespace v8::internal |
OLD | NEW |