| 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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 // which we should not have access to. | 147 // which we should not have access to. |
| 148 Handle<Context> context = | 148 Handle<Context> context = |
| 149 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); | 149 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); |
| 150 | 150 |
| 151 bool is_result_from_cache; | 151 bool is_result_from_cache; |
| 152 Handle<Map> map = ComputeObjectLiteralMap(context, | 152 Handle<Map> map = ComputeObjectLiteralMap(context, |
| 153 constant_properties, | 153 constant_properties, |
| 154 &is_result_from_cache); | 154 &is_result_from_cache); |
| 155 | 155 |
| 156 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); | 156 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); |
| 157 { // Add the constant propeties to the boilerplate. | 157 { // Add the constant properties to the boilerplate. |
| 158 int length = constant_properties->length(); | 158 int length = constant_properties->length(); |
| 159 OptimizedObjectForAddingMultipleProperties opt(boilerplate, | 159 OptimizedObjectForAddingMultipleProperties opt(boilerplate, |
| 160 !is_result_from_cache); | 160 !is_result_from_cache); |
| 161 for (int index = 0; index < length; index +=2) { | 161 for (int index = 0; index < length; index +=2) { |
| 162 Handle<Object> key(constant_properties->get(index+0)); | 162 Handle<Object> key(constant_properties->get(index+0)); |
| 163 Handle<Object> value(constant_properties->get(index+1)); | 163 Handle<Object> value(constant_properties->get(index+1)); |
| 164 uint32_t element_index = 0; | 164 uint32_t element_index = 0; |
| 165 if (key->IsSymbol()) { | 165 if (key->IsSymbol()) { |
| 166 // If key is a symbol it is not an array element. | 166 // If key is a symbol it is not an array element. |
| 167 Handle<String> name(String::cast(*key)); | 167 Handle<String> name(String::cast(*key)); |
| (...skipping 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1712 if (key->IsString()) { | 1712 if (key->IsString()) { |
| 1713 name = Handle<String>::cast(key); | 1713 name = Handle<String>::cast(key); |
| 1714 } else { | 1714 } else { |
| 1715 bool has_pending_exception = false; | 1715 bool has_pending_exception = false; |
| 1716 Handle<Object> converted = | 1716 Handle<Object> converted = |
| 1717 Execution::ToString(key, &has_pending_exception); | 1717 Execution::ToString(key, &has_pending_exception); |
| 1718 if (has_pending_exception) return Failure::Exception(); | 1718 if (has_pending_exception) return Failure::Exception(); |
| 1719 name = Handle<String>::cast(converted); | 1719 name = Handle<String>::cast(converted); |
| 1720 } | 1720 } |
| 1721 | 1721 |
| 1722 // Check if the name is trivially convertable to an index and get | 1722 // Check if the name is trivially convertible to an index and get |
| 1723 // the element if so. | 1723 // the element if so. |
| 1724 if (name->AsArrayIndex(&index)) { | 1724 if (name->AsArrayIndex(&index)) { |
| 1725 return GetElementOrCharAt(object, index); | 1725 return GetElementOrCharAt(object, index); |
| 1726 } else { | 1726 } else { |
| 1727 PropertyAttributes attr; | 1727 PropertyAttributes attr; |
| 1728 return object->GetProperty(*name, &attr); | 1728 return object->GetProperty(*name, &attr); |
| 1729 } | 1729 } |
| 1730 } | 1730 } |
| 1731 | 1731 |
| 1732 | 1732 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1744 | 1744 |
| 1745 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. | 1745 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. |
| 1746 static Object* Runtime_KeyedGetProperty(Arguments args) { | 1746 static Object* Runtime_KeyedGetProperty(Arguments args) { |
| 1747 NoHandleAllocation ha; | 1747 NoHandleAllocation ha; |
| 1748 ASSERT(args.length() == 2); | 1748 ASSERT(args.length() == 2); |
| 1749 | 1749 |
| 1750 // Fast cases for getting named properties of the receiver JSObject | 1750 // Fast cases for getting named properties of the receiver JSObject |
| 1751 // itself. | 1751 // itself. |
| 1752 // | 1752 // |
| 1753 // The global proxy objects has to be excluded since LocalLookup on | 1753 // The global proxy objects has to be excluded since LocalLookup on |
| 1754 // the global proxy object can return a valid result eventhough the | 1754 // the global proxy object can return a valid result even though the |
| 1755 // global proxy object never has properties. This is the case | 1755 // global proxy object never has properties. This is the case |
| 1756 // because the global proxy object forwards everything to its hidden | 1756 // because the global proxy object forwards everything to its hidden |
| 1757 // prototype including local lookups. | 1757 // prototype including local lookups. |
| 1758 // | 1758 // |
| 1759 // Additionally, we need to make sure that we do not cache results | 1759 // Additionally, we need to make sure that we do not cache results |
| 1760 // for objects that require access checks. | 1760 // for objects that require access checks. |
| 1761 if (args[0]->IsJSObject() && | 1761 if (args[0]->IsJSObject() && |
| 1762 !args[0]->IsJSGlobalProxy() && | 1762 !args[0]->IsJSGlobalProxy() && |
| 1763 !args[0]->IsAccessCheckNeeded() && | 1763 !args[0]->IsAccessCheckNeeded() && |
| 1764 args[1]->IsString()) { | 1764 args[1]->IsString()) { |
| (...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2980 int x_value = x->value(); | 2980 int x_value = x->value(); |
| 2981 int y_value = y->value(); | 2981 int y_value = y->value(); |
| 2982 | 2982 |
| 2983 // If the integers are equal so are the string representations. | 2983 // If the integers are equal so are the string representations. |
| 2984 if (x_value == y_value) return Smi::FromInt(EQUAL); | 2984 if (x_value == y_value) return Smi::FromInt(EQUAL); |
| 2985 | 2985 |
| 2986 // If one of the integers are zero the normal integer order is the | 2986 // If one of the integers are zero the normal integer order is the |
| 2987 // same as the lexicographic order of the string representations. | 2987 // same as the lexicographic order of the string representations. |
| 2988 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); | 2988 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); |
| 2989 | 2989 |
| 2990 // If only one of the intergers is negative the negative number is | 2990 // If only one of the integers is negative the negative number is |
| 2991 // smallest because the char code of '-' is less than the char code | 2991 // smallest because the char code of '-' is less than the char code |
| 2992 // of any digit. Otherwise, we make both values positive. | 2992 // of any digit. Otherwise, we make both values positive. |
| 2993 if (x_value < 0 || y_value < 0) { | 2993 if (x_value < 0 || y_value < 0) { |
| 2994 if (y_value >= 0) return Smi::FromInt(LESS); | 2994 if (y_value >= 0) return Smi::FromInt(LESS); |
| 2995 if (x_value >= 0) return Smi::FromInt(GREATER); | 2995 if (x_value >= 0) return Smi::FromInt(GREATER); |
| 2996 x_value = -x_value; | 2996 x_value = -x_value; |
| 2997 y_value = -y_value; | 2997 y_value = -y_value; |
| 2998 } | 2998 } |
| 2999 | 2999 |
| 3000 // Convert the integers to arrays of their decimal digits. | 3000 // Convert the integers to arrays of their decimal digits. |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3318 | 3318 |
| 3319 | 3319 |
| 3320 static Object* Runtime_NewObject(Arguments args) { | 3320 static Object* Runtime_NewObject(Arguments args) { |
| 3321 NoHandleAllocation ha; | 3321 NoHandleAllocation ha; |
| 3322 ASSERT(args.length() == 1); | 3322 ASSERT(args.length() == 1); |
| 3323 | 3323 |
| 3324 Object* constructor = args[0]; | 3324 Object* constructor = args[0]; |
| 3325 if (constructor->IsJSFunction()) { | 3325 if (constructor->IsJSFunction()) { |
| 3326 JSFunction* function = JSFunction::cast(constructor); | 3326 JSFunction* function = JSFunction::cast(constructor); |
| 3327 | 3327 |
| 3328 // Handle steping into constructors if step into is active. | 3328 // Handle stepping into constructors if step into is active. |
| 3329 if (Debug::StepInActive()) { | 3329 if (Debug::StepInActive()) { |
| 3330 HandleScope scope; | 3330 HandleScope scope; |
| 3331 Debug::HandleStepIn(Handle<JSFunction>(function), 0, true); | 3331 Debug::HandleStepIn(Handle<JSFunction>(function), 0, true); |
| 3332 } | 3332 } |
| 3333 | 3333 |
| 3334 if (function->has_initial_map() && | 3334 if (function->has_initial_map() && |
| 3335 function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { | 3335 function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { |
| 3336 // The 'Function' function ignores the receiver object when | 3336 // The 'Function' function ignores the receiver object when |
| 3337 // called using 'new' and creates a new JSFunction object that | 3337 // called using 'new' and creates a new JSFunction object that |
| 3338 // is returned. The receiver object is only used for error | 3338 // is returned. The receiver object is only used for error |
| (...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4505 | 4505 |
| 4506 static Object* DebugLookupResultValue(Object* obj, String* name, | 4506 static Object* DebugLookupResultValue(Object* obj, String* name, |
| 4507 LookupResult* result, | 4507 LookupResult* result, |
| 4508 bool* caught_exception) { | 4508 bool* caught_exception) { |
| 4509 switch (result->type()) { | 4509 switch (result->type()) { |
| 4510 case NORMAL: | 4510 case NORMAL: |
| 4511 case FIELD: | 4511 case FIELD: |
| 4512 case CONSTANT_FUNCTION: | 4512 case CONSTANT_FUNCTION: |
| 4513 return obj->GetProperty(name); | 4513 return obj->GetProperty(name); |
| 4514 case CALLBACKS: { | 4514 case CALLBACKS: { |
| 4515 // Get the property value. If there is an exception it must be thown from | 4515 // Get the property value. If there is an exception it must be thrown from |
| 4516 // a JavaScript getter. | 4516 // a JavaScript getter. |
| 4517 Object* value; | 4517 Object* value; |
| 4518 value = obj->GetProperty(name); | 4518 value = obj->GetProperty(name); |
| 4519 if (value->IsException()) { | 4519 if (value->IsException()) { |
| 4520 if (caught_exception != NULL) { | 4520 if (caught_exception != NULL) { |
| 4521 *caught_exception = true; | 4521 *caught_exception = true; |
| 4522 } | 4522 } |
| 4523 value = Top::pending_exception(); | 4523 value = Top::pending_exception(); |
| 4524 Top::optional_reschedule_exception(true); | 4524 Top::optional_reschedule_exception(true); |
| 4525 } | 4525 } |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5084 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj)); | 5084 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(obj)); |
| 5085 if (shared->script() == *script) { | 5085 if (shared->script() == *script) { |
| 5086 // If the SharedFunctionInfo found has the requested script data and | 5086 // If the SharedFunctionInfo found has the requested script data and |
| 5087 // contains the source position it is a candidate. | 5087 // contains the source position it is a candidate. |
| 5088 int start_position = shared->function_token_position(); | 5088 int start_position = shared->function_token_position(); |
| 5089 if (start_position == RelocInfo::kNoPosition) { | 5089 if (start_position == RelocInfo::kNoPosition) { |
| 5090 start_position = shared->start_position(); | 5090 start_position = shared->start_position(); |
| 5091 } | 5091 } |
| 5092 if (start_position <= position && | 5092 if (start_position <= position && |
| 5093 position <= shared->end_position()) { | 5093 position <= shared->end_position()) { |
| 5094 // If there is no candidate or this function is within the currrent | 5094 // If there is no candidate or this function is within the current |
| 5095 // candidate this is the new candidate. | 5095 // candidate this is the new candidate. |
| 5096 if (target.is_null()) { | 5096 if (target.is_null()) { |
| 5097 target_start_position = start_position; | 5097 target_start_position = start_position; |
| 5098 target = shared; | 5098 target = shared; |
| 5099 } else { | 5099 } else { |
| 5100 if (target_start_position < start_position && | 5100 if (target_start_position < start_position && |
| 5101 shared->end_position() < target->end_position()) { | 5101 shared->end_position() < target->end_position()) { |
| 5102 target_start_position = start_position; | 5102 target_start_position = start_position; |
| 5103 target = shared; | 5103 target = shared; |
| 5104 } | 5104 } |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5302 WriteBarrierMode mode = array->GetWriteBarrierMode(); | 5302 WriteBarrierMode mode = array->GetWriteBarrierMode(); |
| 5303 for (int i = 0; i < length; i++) { | 5303 for (int i = 0; i < length; i++) { |
| 5304 array->set(i, frame->GetParameter(i), mode); | 5304 array->set(i, frame->GetParameter(i), mode); |
| 5305 } | 5305 } |
| 5306 arguments->set_elements(*array); | 5306 arguments->set_elements(*array); |
| 5307 return arguments; | 5307 return arguments; |
| 5308 } | 5308 } |
| 5309 | 5309 |
| 5310 | 5310 |
| 5311 // Evaluate a piece of JavaScript in the context of a stack frame for | 5311 // Evaluate a piece of JavaScript in the context of a stack frame for |
| 5312 // debugging. This is acomplished by creating a new context which in its | 5312 // debugging. This is accomplished by creating a new context which in its |
| 5313 // extension part has all the parameters and locals of the function on the | 5313 // extension part has all the parameters and locals of the function on the |
| 5314 // stack frame. A function which calls eval with the code to evaluate is then | 5314 // stack frame. A function which calls eval with the code to evaluate is then |
| 5315 // compiled in this context and called in this context. As this context | 5315 // compiled in this context and called in this context. As this context |
| 5316 // replaces the context of the function on the stack frame a new (empty) | 5316 // replaces the context of the function on the stack frame a new (empty) |
| 5317 // function is created as well to be used as the closure for the context. | 5317 // function is created as well to be used as the closure for the context. |
| 5318 // This function and the context acts as replacements for the function on the | 5318 // This function and the context acts as replacements for the function on the |
| 5319 // stack frame presenting the same view of the values of parameters and | 5319 // stack frame presenting the same view of the values of parameters and |
| 5320 // local variables as if the piece of JavaScript was evaluated at the point | 5320 // local variables as if the piece of JavaScript was evaluated at the point |
| 5321 // where the function on the stack frame is currently stopped. | 5321 // where the function on the stack frame is currently stopped. |
| 5322 static Object* Runtime_DebugEvaluate(Arguments args) { | 5322 static Object* Runtime_DebugEvaluate(Arguments args) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5413 // object build. | 5413 // object build. |
| 5414 Handle<Context> context = | 5414 Handle<Context> context = |
| 5415 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); | 5415 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); |
| 5416 context->set_extension(*context_ext); | 5416 context->set_extension(*context_ext); |
| 5417 // Copy any with contexts present and chain them in front of this context. | 5417 // Copy any with contexts present and chain them in front of this context. |
| 5418 context = CopyWithContextChain(frame_context, context); | 5418 context = CopyWithContextChain(frame_context, context); |
| 5419 | 5419 |
| 5420 // Wrap the evaluation statement in a new function compiled in the newly | 5420 // Wrap the evaluation statement in a new function compiled in the newly |
| 5421 // created context. The function has one parameter which has to be called | 5421 // created context. The function has one parameter which has to be called |
| 5422 // 'arguments'. This it to have access to what would have been 'arguments' in | 5422 // 'arguments'. This it to have access to what would have been 'arguments' in |
| 5423 // the function beeing debugged. | 5423 // the function being debugged. |
| 5424 // function(arguments,__source__) {return eval(__source__);} | 5424 // function(arguments,__source__) {return eval(__source__);} |
| 5425 static const char* source_str = | 5425 static const char* source_str = |
| 5426 "function(arguments,__source__){return eval(__source__);}"; | 5426 "function(arguments,__source__){return eval(__source__);}"; |
| 5427 static const int source_str_length = strlen(source_str); | 5427 static const int source_str_length = strlen(source_str); |
| 5428 Handle<String> function_source = | 5428 Handle<String> function_source = |
| 5429 Factory::NewStringFromAscii(Vector<const char>(source_str, | 5429 Factory::NewStringFromAscii(Vector<const char>(source_str, |
| 5430 source_str_length)); | 5430 source_str_length)); |
| 5431 Handle<JSFunction> boilerplate = | 5431 Handle<JSFunction> boilerplate = |
| 5432 Compiler::CompileEval(function_source, 0, context->IsGlobalContext()); | 5432 Compiler::CompileEval(function_source, 0, context->IsGlobalContext()); |
| 5433 if (boilerplate.is_null()) return Failure::Exception(); | 5433 if (boilerplate.is_null()) return Failure::Exception(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5528 | 5528 |
| 5529 return count; | 5529 return count; |
| 5530 } | 5530 } |
| 5531 | 5531 |
| 5532 | 5532 |
| 5533 static Object* Runtime_DebugGetLoadedScripts(Arguments args) { | 5533 static Object* Runtime_DebugGetLoadedScripts(Arguments args) { |
| 5534 HandleScope scope; | 5534 HandleScope scope; |
| 5535 ASSERT(args.length() == 0); | 5535 ASSERT(args.length() == 0); |
| 5536 | 5536 |
| 5537 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets | 5537 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets |
| 5538 // rid of all the cached script wrappes and the second gets rid of the | 5538 // rid of all the cached script wrappers and the second gets rid of the |
| 5539 // scripts which is no longer referenced. | 5539 // scripts which is no longer referenced. |
| 5540 Heap::CollectAllGarbage(); | 5540 Heap::CollectAllGarbage(); |
| 5541 Heap::CollectAllGarbage(); | 5541 Heap::CollectAllGarbage(); |
| 5542 | 5542 |
| 5543 // Get the number of scripts. | 5543 // Get the number of scripts. |
| 5544 int count; | 5544 int count; |
| 5545 count = DebugGetLoadedScripts(NULL, 0); | 5545 count = DebugGetLoadedScripts(NULL, 0); |
| 5546 | 5546 |
| 5547 // Allocate an array to hold the result. | 5547 // Allocate an array to hold the result. |
| 5548 Handle<FixedArray> instances = Factory::NewFixedArray(count); | 5548 Handle<FixedArray> instances = Factory::NewFixedArray(count); |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5928 } else { | 5928 } else { |
| 5929 // Handle last resort GC and make sure to allow future allocations | 5929 // Handle last resort GC and make sure to allow future allocations |
| 5930 // to grow the heap without causing GCs (if possible). | 5930 // to grow the heap without causing GCs (if possible). |
| 5931 Counters::gc_last_resort_from_js.Increment(); | 5931 Counters::gc_last_resort_from_js.Increment(); |
| 5932 Heap::CollectAllGarbage(); | 5932 Heap::CollectAllGarbage(); |
| 5933 } | 5933 } |
| 5934 } | 5934 } |
| 5935 | 5935 |
| 5936 | 5936 |
| 5937 } } // namespace v8::internal | 5937 } } // namespace v8::internal |
| OLD | NEW |