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 |