OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 4310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4321 ASSERT(args.length() == 2); | 4321 ASSERT(args.length() == 2); |
4322 CONVERT_ARG_CHECKED(JSFunction, boilerplate, 0); | 4322 CONVERT_ARG_CHECKED(JSFunction, boilerplate, 0); |
4323 CONVERT_ARG_CHECKED(Context, context, 1); | 4323 CONVERT_ARG_CHECKED(Context, context, 1); |
4324 | 4324 |
4325 Handle<JSFunction> result = | 4325 Handle<JSFunction> result = |
4326 Factory::NewFunctionFromBoilerplate(boilerplate, context); | 4326 Factory::NewFunctionFromBoilerplate(boilerplate, context); |
4327 return *result; | 4327 return *result; |
4328 } | 4328 } |
4329 | 4329 |
4330 | 4330 |
| 4331 static Handle<Code> ComputeConstructStub(Handle<Map> map) { |
| 4332 // TODO(xxx): Change this to create a construct stub specialized for |
| 4333 // the given map to make allocation of simple objects - and maybe |
| 4334 // arrays - much faster. |
| 4335 return Handle<Code>(Builtins::builtin(Builtins::JSConstructStubGeneric)); |
| 4336 } |
| 4337 |
| 4338 |
4331 static Object* Runtime_NewObject(Arguments args) { | 4339 static Object* Runtime_NewObject(Arguments args) { |
4332 NoHandleAllocation ha; | 4340 HandleScope scope; |
4333 ASSERT(args.length() == 1); | 4341 ASSERT(args.length() == 1); |
4334 | 4342 |
4335 Object* constructor = args[0]; | 4343 Handle<Object> constructor = args.at<Object>(0); |
4336 if (constructor->IsJSFunction()) { | |
4337 JSFunction* function = JSFunction::cast(constructor); | |
4338 | 4344 |
4339 // Handle stepping into constructors if step into is active. | 4345 // If the constructor isn't a proper function we throw a type error. |
| 4346 if (!constructor->IsJSFunction()) { |
| 4347 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); |
| 4348 Handle<Object> type_error = |
| 4349 Factory::NewTypeError("not_constructor", arguments); |
| 4350 return Top::Throw(*type_error); |
| 4351 } |
| 4352 |
| 4353 Handle<JSFunction> function = Handle<JSFunction>::cast(constructor); |
4340 #ifdef ENABLE_DEBUGGER_SUPPORT | 4354 #ifdef ENABLE_DEBUGGER_SUPPORT |
4341 if (Debug::StepInActive()) { | 4355 // Handle stepping into constructors if step into is active. |
4342 HandleScope scope; | 4356 if (Debug::StepInActive()) { |
4343 Debug::HandleStepIn(Handle<JSFunction>(function), 0, true); | 4357 Debug::HandleStepIn(function, 0, true); |
4344 } | 4358 } |
4345 #endif | 4359 #endif |
4346 | 4360 |
4347 if (function->has_initial_map() && | 4361 if (function->has_initial_map()) { |
4348 function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { | 4362 if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { |
4349 // The 'Function' function ignores the receiver object when | 4363 // The 'Function' function ignores the receiver object when |
4350 // called using 'new' and creates a new JSFunction object that | 4364 // called using 'new' and creates a new JSFunction object that |
4351 // is returned. The receiver object is only used for error | 4365 // is returned. The receiver object is only used for error |
4352 // reporting if an error occurs when constructing the new | 4366 // reporting if an error occurs when constructing the new |
4353 // JSFunction. AllocateJSObject should not be used to allocate | 4367 // JSFunction. Factory::NewJSObject() should not be used to |
4354 // JSFunctions since it does not properly initialize the shared | 4368 // allocate JSFunctions since it does not properly initialize |
4355 // part of the function. Since the receiver is ignored anyway, | 4369 // the shared part of the function. Since the receiver is |
4356 // we use the global object as the receiver instead of a new | 4370 // ignored anyway, we use the global object as the receiver |
4357 // JSFunction object. This way, errors are reported the same | 4371 // instead of a new JSFunction object. This way, errors are |
4358 // way whether or not 'Function' is called using 'new'. | 4372 // reported the same way whether or not 'Function' is called |
| 4373 // using 'new'. |
4359 return Top::context()->global(); | 4374 return Top::context()->global(); |
4360 } | 4375 } |
4361 return Heap::AllocateJSObject(function); | |
4362 } | 4376 } |
4363 | 4377 |
4364 HandleScope scope; | 4378 bool first_allocation = !function->has_initial_map(); |
4365 Handle<Object> cons(constructor); | 4379 Handle<JSObject> result = Factory::NewJSObject(function); |
4366 // The constructor is not a function; throw a type error. | 4380 if (first_allocation) { |
4367 Handle<Object> type_error = | 4381 Handle<Map> map = Handle<Map>(function->initial_map()); |
4368 Factory::NewTypeError("not_constructor", HandleVector(&cons, 1)); | 4382 Handle<Code> stub = ComputeConstructStub(map); |
4369 return Top::Throw(*type_error); | 4383 function->shared()->set_construct_stub(*stub); |
| 4384 } |
| 4385 return *result; |
4370 } | 4386 } |
4371 | 4387 |
4372 | 4388 |
4373 static Object* Runtime_LazyCompile(Arguments args) { | 4389 static Object* Runtime_LazyCompile(Arguments args) { |
4374 HandleScope scope; | 4390 HandleScope scope; |
4375 ASSERT(args.length() == 1); | 4391 ASSERT(args.length() == 1); |
4376 | 4392 |
4377 Handle<JSFunction> function = args.at<JSFunction>(0); | 4393 Handle<JSFunction> function = args.at<JSFunction>(0); |
4378 #ifdef DEBUG | 4394 #ifdef DEBUG |
4379 if (FLAG_trace_lazy) { | 4395 if (FLAG_trace_lazy) { |
(...skipping 3121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7501 } else { | 7517 } else { |
7502 // Handle last resort GC and make sure to allow future allocations | 7518 // Handle last resort GC and make sure to allow future allocations |
7503 // to grow the heap without causing GCs (if possible). | 7519 // to grow the heap without causing GCs (if possible). |
7504 Counters::gc_last_resort_from_js.Increment(); | 7520 Counters::gc_last_resort_from_js.Increment(); |
7505 Heap::CollectAllGarbage(); | 7521 Heap::CollectAllGarbage(); |
7506 } | 7522 } |
7507 } | 7523 } |
7508 | 7524 |
7509 | 7525 |
7510 } } // namespace v8::internal | 7526 } } // namespace v8::internal |
OLD | NEW |