| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 27 matching lines...) Expand all Loading... |
| 38 #include "cpu.h" | 38 #include "cpu.h" |
| 39 #include "dateparser-inl.h" | 39 #include "dateparser-inl.h" |
| 40 #include "debug.h" | 40 #include "debug.h" |
| 41 #include "deoptimizer.h" | 41 #include "deoptimizer.h" |
| 42 #include "execution.h" | 42 #include "execution.h" |
| 43 #include "global-handles.h" | 43 #include "global-handles.h" |
| 44 #include "jsregexp.h" | 44 #include "jsregexp.h" |
| 45 #include "json-parser.h" | 45 #include "json-parser.h" |
| 46 #include "liveedit.h" | 46 #include "liveedit.h" |
| 47 #include "liveobjectlist-inl.h" | 47 #include "liveobjectlist-inl.h" |
| 48 #include "misc-intrinsics.h" |
| 48 #include "parser.h" | 49 #include "parser.h" |
| 49 #include "platform.h" | 50 #include "platform.h" |
| 50 #include "runtime-profiler.h" | 51 #include "runtime-profiler.h" |
| 51 #include "runtime.h" | 52 #include "runtime.h" |
| 52 #include "scopeinfo.h" | 53 #include "scopeinfo.h" |
| 53 #include "smart-pointer.h" | 54 #include "smart-pointer.h" |
| 54 #include "string-search.h" | 55 #include "string-search.h" |
| 55 #include "stub-cache.h" | 56 #include "stub-cache.h" |
| 56 #include "v8threads.h" | 57 #include "v8threads.h" |
| 57 #include "vm-state-inl.h" | 58 #include "vm-state-inl.h" |
| (...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1229 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { | 1230 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) { |
| 1230 HandleScope scope(isolate); | 1231 HandleScope scope(isolate); |
| 1231 ASSERT(args.length() == 4); | 1232 ASSERT(args.length() == 4); |
| 1232 | 1233 |
| 1233 CONVERT_ARG_CHECKED(Context, context, 0); | 1234 CONVERT_ARG_CHECKED(Context, context, 0); |
| 1234 Handle<String> name(String::cast(args[1])); | 1235 Handle<String> name(String::cast(args[1])); |
| 1235 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2)); | 1236 PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2)); |
| 1236 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); | 1237 RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE); |
| 1237 Handle<Object> initial_value(args[3], isolate); | 1238 Handle<Object> initial_value(args[3], isolate); |
| 1238 | 1239 |
| 1239 // Declarations are always done in the function context. | 1240 // Declarations are always done in a function or global context. |
| 1240 context = Handle<Context>(context->fcontext()); | 1241 context = Handle<Context>(context->declaration_context()); |
| 1241 ASSERT(context->IsFunctionContext() || context->IsGlobalContext()); | |
| 1242 | 1242 |
| 1243 int index; | 1243 int index; |
| 1244 PropertyAttributes attributes; | 1244 PropertyAttributes attributes; |
| 1245 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; | 1245 ContextLookupFlags flags = DONT_FOLLOW_CHAINS; |
| 1246 Handle<Object> holder = | 1246 Handle<Object> holder = |
| 1247 context->Lookup(name, flags, &index, &attributes); | 1247 context->Lookup(name, flags, &index, &attributes); |
| 1248 | 1248 |
| 1249 if (attributes != ABSENT) { | 1249 if (attributes != ABSENT) { |
| 1250 // The name was declared before; check for conflicting | 1250 // The name was declared before; check for conflicting |
| 1251 // re-declarations: This is similar to the code in parser.cc in | 1251 // re-declarations: This is similar to the code in parser.cc in |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1518 | 1518 |
| 1519 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) { | 1519 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) { |
| 1520 HandleScope scope(isolate); | 1520 HandleScope scope(isolate); |
| 1521 ASSERT(args.length() == 3); | 1521 ASSERT(args.length() == 3); |
| 1522 | 1522 |
| 1523 Handle<Object> value(args[0], isolate); | 1523 Handle<Object> value(args[0], isolate); |
| 1524 ASSERT(!value->IsTheHole()); | 1524 ASSERT(!value->IsTheHole()); |
| 1525 CONVERT_ARG_CHECKED(Context, context, 1); | 1525 CONVERT_ARG_CHECKED(Context, context, 1); |
| 1526 Handle<String> name(String::cast(args[2])); | 1526 Handle<String> name(String::cast(args[2])); |
| 1527 | 1527 |
| 1528 // Initializations are always done in the function context. | 1528 // Initializations are always done in a function or global context. |
| 1529 context = Handle<Context>(context->fcontext()); | 1529 context = Handle<Context>(context->declaration_context()); |
| 1530 | 1530 |
| 1531 int index; | 1531 int index; |
| 1532 PropertyAttributes attributes; | 1532 PropertyAttributes attributes; |
| 1533 ContextLookupFlags flags = FOLLOW_CHAINS; | 1533 ContextLookupFlags flags = FOLLOW_CHAINS; |
| 1534 Handle<Object> holder = | 1534 Handle<Object> holder = |
| 1535 context->Lookup(name, flags, &index, &attributes); | 1535 context->Lookup(name, flags, &index, &attributes); |
| 1536 | 1536 |
| 1537 // In most situations, the property introduced by the const | 1537 // In most situations, the property introduced by the const |
| 1538 // declaration should be present in the context extension object. | 1538 // declaration should be present in the context extension object. |
| 1539 // However, because declaration and initialization are separate, the | 1539 // However, because declaration and initialization are separate, the |
| 1540 // property might have been deleted (if it was introduced by eval) | 1540 // property might have been deleted (if it was introduced by eval) |
| 1541 // before we reach the initialization point. | 1541 // before we reach the initialization point. |
| 1542 // | 1542 // |
| 1543 // Example: | 1543 // Example: |
| 1544 // | 1544 // |
| 1545 // function f() { eval("delete x; const x;"); } | 1545 // function f() { eval("delete x; const x;"); } |
| 1546 // | 1546 // |
| 1547 // In that case, the initialization behaves like a normal assignment | 1547 // In that case, the initialization behaves like a normal assignment |
| 1548 // to property 'x'. | 1548 // to property 'x'. |
| 1549 if (index >= 0) { | 1549 if (index >= 0) { |
| 1550 // Property was found in a context. | |
| 1551 if (holder->IsContext()) { | 1550 if (holder->IsContext()) { |
| 1552 // The holder cannot be the function context. If it is, there | 1551 // Property was found in a context. Perform the assignment if we |
| 1553 // should have been a const redeclaration error when declaring | 1552 // found some non-constant or an uninitialized constant. |
| 1554 // the const property. | 1553 Handle<Context> context = Handle<Context>::cast(holder); |
| 1555 ASSERT(!holder.is_identical_to(context)); | 1554 if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) { |
| 1556 if ((attributes & READ_ONLY) == 0) { | 1555 context->set(index, *value); |
| 1557 Handle<Context>::cast(holder)->set(index, *value); | |
| 1558 } | 1556 } |
| 1559 } else { | 1557 } else { |
| 1560 // The holder is an arguments object. | 1558 // The holder is an arguments object. |
| 1561 ASSERT((attributes & READ_ONLY) == 0); | 1559 ASSERT((attributes & READ_ONLY) == 0); |
| 1562 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); | 1560 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); |
| 1563 RETURN_IF_EMPTY_HANDLE( | 1561 RETURN_IF_EMPTY_HANDLE( |
| 1564 isolate, | 1562 isolate, |
| 1565 SetElement(arguments, index, value, kNonStrictMode)); | 1563 SetElement(arguments, index, value, kNonStrictMode)); |
| 1566 } | 1564 } |
| 1567 return *value; | 1565 return *value; |
| (...skipping 5070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6638 | 6636 |
| 6639 // Extract the integer values from the Smis. | 6637 // Extract the integer values from the Smis. |
| 6640 CONVERT_CHECKED(Smi, x, args[0]); | 6638 CONVERT_CHECKED(Smi, x, args[0]); |
| 6641 CONVERT_CHECKED(Smi, y, args[1]); | 6639 CONVERT_CHECKED(Smi, y, args[1]); |
| 6642 int x_value = x->value(); | 6640 int x_value = x->value(); |
| 6643 int y_value = y->value(); | 6641 int y_value = y->value(); |
| 6644 | 6642 |
| 6645 // If the integers are equal so are the string representations. | 6643 // If the integers are equal so are the string representations. |
| 6646 if (x_value == y_value) return Smi::FromInt(EQUAL); | 6644 if (x_value == y_value) return Smi::FromInt(EQUAL); |
| 6647 | 6645 |
| 6648 // If one of the integers are zero the normal integer order is the | 6646 // If one of the integers is zero the normal integer order is the |
| 6649 // same as the lexicographic order of the string representations. | 6647 // same as the lexicographic order of the string representations. |
| 6650 if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value); | 6648 if (x_value == 0 || y_value == 0) |
| 6649 return Smi::FromInt(x_value < y_value ? LESS : GREATER); |
| 6651 | 6650 |
| 6652 // If only one of the integers is negative the negative number is | 6651 // If only one of the integers is negative the negative number is |
| 6653 // smallest because the char code of '-' is less than the char code | 6652 // smallest because the char code of '-' is less than the char code |
| 6654 // of any digit. Otherwise, we make both values positive. | 6653 // of any digit. Otherwise, we make both values positive. |
| 6654 |
| 6655 // Use unsigned values otherwise the logic is incorrect for -MIN_INT on |
| 6656 // architectures using 32-bit Smis. |
| 6657 uint32_t x_scaled = x_value; |
| 6658 uint32_t y_scaled = y_value; |
| 6655 if (x_value < 0 || y_value < 0) { | 6659 if (x_value < 0 || y_value < 0) { |
| 6656 if (y_value >= 0) return Smi::FromInt(LESS); | 6660 if (y_value >= 0) return Smi::FromInt(LESS); |
| 6657 if (x_value >= 0) return Smi::FromInt(GREATER); | 6661 if (x_value >= 0) return Smi::FromInt(GREATER); |
| 6658 x_value = -x_value; | 6662 x_scaled = -x_value; |
| 6659 y_value = -y_value; | 6663 y_scaled = -y_value; |
| 6660 } | 6664 } |
| 6661 | 6665 |
| 6662 // Arrays for the individual characters of the two Smis. Smis are | 6666 static const uint32_t kPowersOf10[] = { |
| 6663 // 31 bit integers and 10 decimal digits are therefore enough. | 6667 1, 10, 100, 1000, 10*1000, 100*1000, |
| 6664 // TODO(isolates): maybe we should simply allocate 20 bytes on the stack. | 6668 1000*1000, 10*1000*1000, 100*1000*1000, |
| 6665 int* x_elms = isolate->runtime_state()->smi_lexicographic_compare_x_elms(); | 6669 1000*1000*1000 |
| 6666 int* y_elms = isolate->runtime_state()->smi_lexicographic_compare_y_elms(); | 6670 }; |
| 6667 | 6671 |
| 6672 // If the integers have the same number of decimal digits they can be |
| 6673 // compared directly as the numeric order is the same as the |
| 6674 // lexicographic order. If one integer has fewer digits, it is scaled |
| 6675 // by some power of 10 to have the same number of digits as the longer |
| 6676 // integer. If the scaled integers are equal it means the shorter |
| 6677 // integer comes first in the lexicographic order. |
| 6668 | 6678 |
| 6669 // Convert the integers to arrays of their decimal digits. | 6679 // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 |
| 6670 int x_index = 0; | 6680 int x_log2 = IntegerLog2(x_scaled); |
| 6671 int y_index = 0; | 6681 int x_log10 = ((x_log2 + 1) * 1233) >> 12; |
| 6672 while (x_value > 0) { | 6682 x_log10 -= x_scaled < kPowersOf10[x_log10]; |
| 6673 x_elms[x_index++] = x_value % 10; | 6683 |
| 6674 x_value /= 10; | 6684 int y_log2 = IntegerLog2(y_scaled); |
| 6675 } | 6685 int y_log10 = ((y_log2 + 1) * 1233) >> 12; |
| 6676 while (y_value > 0) { | 6686 y_log10 -= y_scaled < kPowersOf10[y_log10]; |
| 6677 y_elms[y_index++] = y_value % 10; | 6687 |
| 6678 y_value /= 10; | 6688 int tie = EQUAL; |
| 6689 |
| 6690 if (x_log10 < y_log10) { |
| 6691 // X has fewer digits. We would like to simply scale up X but that |
| 6692 // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would |
| 6693 // be scaled up to 9_000_000_000. So we scale up by the next |
| 6694 // smallest power and scale down Y to drop one digit. It is OK to |
| 6695 // drop one digit from the longer integer since the final digit is |
| 6696 // past the length of the shorter integer. |
| 6697 x_scaled *= kPowersOf10[y_log10 - x_log10 - 1]; |
| 6698 y_scaled /= 10; |
| 6699 tie = LESS; |
| 6700 } else if (y_log10 < x_log10) { |
| 6701 y_scaled *= kPowersOf10[x_log10 - y_log10 - 1]; |
| 6702 x_scaled /= 10; |
| 6703 tie = GREATER; |
| 6679 } | 6704 } |
| 6680 | 6705 |
| 6681 // Loop through the arrays of decimal digits finding the first place | 6706 if (x_scaled < y_scaled) return Smi::FromInt(LESS); |
| 6682 // where they differ. | 6707 if (x_scaled > y_scaled) return Smi::FromInt(GREATER); |
| 6683 while (--x_index >= 0 && --y_index >= 0) { | 6708 return Smi::FromInt(tie); |
| 6684 int diff = x_elms[x_index] - y_elms[y_index]; | |
| 6685 if (diff != 0) return Smi::FromInt(diff); | |
| 6686 } | |
| 6687 | |
| 6688 // If one array is a suffix of the other array, the longest array is | |
| 6689 // the representation of the largest of the Smis in the | |
| 6690 // lexicographic ordering. | |
| 6691 return Smi::FromInt(x_index - y_index); | |
| 6692 } | 6709 } |
| 6693 | 6710 |
| 6694 | 6711 |
| 6695 static Object* StringInputBufferCompare(RuntimeState* state, | 6712 static Object* StringInputBufferCompare(RuntimeState* state, |
| 6696 String* x, | 6713 String* x, |
| 6697 String* y) { | 6714 String* y) { |
| 6698 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx(); | 6715 StringInputBuffer& bufx = *state->string_input_buffer_compare_bufx(); |
| 6699 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy(); | 6716 StringInputBuffer& bufy = *state->string_input_buffer_compare_bufy(); |
| 6700 bufx.Reset(x); | 6717 bufx.Reset(x); |
| 6701 bufy.Reset(y); | 6718 bufy.Reset(y); |
| (...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8045 } | 8062 } |
| 8046 | 8063 |
| 8047 isolate->set_context(Context::cast(result)); | 8064 isolate->set_context(Context::cast(result)); |
| 8048 | 8065 |
| 8049 return result; // non-failure | 8066 return result; // non-failure |
| 8050 } | 8067 } |
| 8051 | 8068 |
| 8052 | 8069 |
| 8053 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) { | 8070 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) { |
| 8054 NoHandleAllocation ha; | 8071 NoHandleAllocation ha; |
| 8055 ASSERT(args.length() == 1); | 8072 ASSERT(args.length() == 2); |
| 8056 JSObject* extension_object; | 8073 JSObject* extension_object; |
| 8057 if (args[0]->IsJSObject()) { | 8074 if (args[0]->IsJSObject()) { |
| 8058 extension_object = JSObject::cast(args[0]); | 8075 extension_object = JSObject::cast(args[0]); |
| 8059 } else { | 8076 } else { |
| 8060 // Convert the object to a proper JavaScript object. | 8077 // Convert the object to a proper JavaScript object. |
| 8061 MaybeObject* maybe_js_object = args[0]->ToObject(); | 8078 MaybeObject* maybe_js_object = args[0]->ToObject(); |
| 8062 if (!maybe_js_object->To(&extension_object)) { | 8079 if (!maybe_js_object->To(&extension_object)) { |
| 8063 if (Failure::cast(maybe_js_object)->IsInternalError()) { | 8080 if (Failure::cast(maybe_js_object)->IsInternalError()) { |
| 8064 HandleScope scope(isolate); | 8081 HandleScope scope(isolate); |
| 8065 Handle<Object> handle = args.at<Object>(0); | 8082 Handle<Object> handle = args.at<Object>(0); |
| 8066 Handle<Object> result = | 8083 Handle<Object> result = |
| 8067 isolate->factory()->NewTypeError("with_expression", | 8084 isolate->factory()->NewTypeError("with_expression", |
| 8068 HandleVector(&handle, 1)); | 8085 HandleVector(&handle, 1)); |
| 8069 return isolate->Throw(*result); | 8086 return isolate->Throw(*result); |
| 8070 } else { | 8087 } else { |
| 8071 return maybe_js_object; | 8088 return maybe_js_object; |
| 8072 } | 8089 } |
| 8073 } | 8090 } |
| 8074 } | 8091 } |
| 8075 | 8092 |
| 8093 JSFunction* function; |
| 8094 if (args[1]->IsSmi()) { |
| 8095 // A smi sentinel indicates a context nested inside global code rather |
| 8096 // than some function. There is a canonical empty function that can be |
| 8097 // gotten from the global context. |
| 8098 function = isolate->context()->global_context()->closure(); |
| 8099 } else { |
| 8100 function = JSFunction::cast(args[1]); |
| 8101 } |
| 8102 |
| 8076 Context* context; | 8103 Context* context; |
| 8077 MaybeObject* maybe_context = | 8104 MaybeObject* maybe_context = |
| 8078 isolate->heap()->AllocateWithContext(isolate->context(), | 8105 isolate->heap()->AllocateWithContext(function, |
| 8106 isolate->context(), |
| 8079 extension_object); | 8107 extension_object); |
| 8080 if (!maybe_context->To(&context)) return maybe_context; | 8108 if (!maybe_context->To(&context)) return maybe_context; |
| 8081 isolate->set_context(context); | 8109 isolate->set_context(context); |
| 8082 return context; | 8110 return context; |
| 8083 } | 8111 } |
| 8084 | 8112 |
| 8085 | 8113 |
| 8086 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) { | 8114 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) { |
| 8087 NoHandleAllocation ha; | 8115 NoHandleAllocation ha; |
| 8088 ASSERT(args.length() == 2); | 8116 ASSERT(args.length() == 3); |
| 8089 String* name = String::cast(args[0]); | 8117 String* name = String::cast(args[0]); |
| 8090 Object* thrown_object = args[1]; | 8118 Object* thrown_object = args[1]; |
| 8119 JSFunction* function; |
| 8120 if (args[2]->IsSmi()) { |
| 8121 // A smi sentinel indicates a context nested inside global code rather |
| 8122 // than some function. There is a canonical empty function that can be |
| 8123 // gotten from the global context. |
| 8124 function = isolate->context()->global_context()->closure(); |
| 8125 } else { |
| 8126 function = JSFunction::cast(args[2]); |
| 8127 } |
| 8091 Context* context; | 8128 Context* context; |
| 8092 MaybeObject* maybe_context = | 8129 MaybeObject* maybe_context = |
| 8093 isolate->heap()->AllocateCatchContext(isolate->context(), | 8130 isolate->heap()->AllocateCatchContext(function, |
| 8131 isolate->context(), |
| 8094 name, | 8132 name, |
| 8095 thrown_object); | 8133 thrown_object); |
| 8096 if (!maybe_context->To(&context)) return maybe_context; | 8134 if (!maybe_context->To(&context)) return maybe_context; |
| 8097 isolate->set_context(context); | 8135 isolate->set_context(context); |
| 8098 return context; | 8136 return context; |
| 8099 } | 8137 } |
| 8100 | 8138 |
| 8101 | 8139 |
| 8102 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { | 8140 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { |
| 8103 HandleScope scope(isolate); | 8141 HandleScope scope(isolate); |
| (...skipping 1875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9979 it.frame()->LookupCode()->SourcePosition(it.frame()->pc()); | 10017 it.frame()->LookupCode()->SourcePosition(it.frame()->pc()); |
| 9980 | 10018 |
| 9981 // Check for constructor frame. | 10019 // Check for constructor frame. |
| 9982 bool constructor = it.frame()->IsConstructor(); | 10020 bool constructor = it.frame()->IsConstructor(); |
| 9983 | 10021 |
| 9984 // Get scope info and read from it for local variable information. | 10022 // Get scope info and read from it for local variable information. |
| 9985 Handle<JSFunction> function(JSFunction::cast(it.frame()->function())); | 10023 Handle<JSFunction> function(JSFunction::cast(it.frame()->function())); |
| 9986 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); | 10024 Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); |
| 9987 ScopeInfo<> info(*scope_info); | 10025 ScopeInfo<> info(*scope_info); |
| 9988 | 10026 |
| 9989 // Get the nearest enclosing function context. | |
| 9990 Handle<Context> context(Context::cast(it.frame()->context())->fcontext()); | |
| 9991 | |
| 9992 // Get the locals names and values into a temporary array. | 10027 // Get the locals names and values into a temporary array. |
| 9993 // | 10028 // |
| 9994 // TODO(1240907): Hide compiler-introduced stack variables | 10029 // TODO(1240907): Hide compiler-introduced stack variables |
| 9995 // (e.g. .result)? For users of the debugger, they will probably be | 10030 // (e.g. .result)? For users of the debugger, they will probably be |
| 9996 // confusing. | 10031 // confusing. |
| 9997 Handle<FixedArray> locals = | 10032 Handle<FixedArray> locals = |
| 9998 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2); | 10033 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2); |
| 9999 | 10034 |
| 10000 // Fill in the names of the locals. | |
| 10001 for (int i = 0; i < info.NumberOfLocals(); i++) { | |
| 10002 locals->set(i * 2, *info.LocalName(i)); | |
| 10003 } | |
| 10004 | |
| 10005 // Fill in the values of the locals. | 10035 // Fill in the values of the locals. |
| 10006 if (is_optimized_frame) { | 10036 if (is_optimized_frame) { |
| 10007 // If we are inspecting an optimized frame use undefined as the | 10037 // If we are inspecting an optimized frame use undefined as the |
| 10008 // value for all locals. | 10038 // value for all locals. |
| 10009 // | 10039 // |
| 10010 // TODO(1140): We should be able to get the correct values | 10040 // TODO(1140): We should be able to get the correct values |
| 10011 // for locals in optimized frames. | 10041 // for locals in optimized frames. |
| 10012 for (int i = 0; i < info.NumberOfLocals(); i++) { | 10042 for (int i = 0; i < info.NumberOfLocals(); i++) { |
| 10043 locals->set(i * 2, *info.LocalName(i)); |
| 10013 locals->set(i * 2 + 1, isolate->heap()->undefined_value()); | 10044 locals->set(i * 2 + 1, isolate->heap()->undefined_value()); |
| 10014 } | 10045 } |
| 10015 } else { | 10046 } else { |
| 10016 for (int i = 0; i < info.number_of_stack_slots(); i++) { | 10047 int i = 0; |
| 10017 // Get the value from the stack. | 10048 for (; i < info.number_of_stack_slots(); ++i) { |
| 10049 // Use the value from the stack. |
| 10050 locals->set(i * 2, *info.LocalName(i)); |
| 10018 locals->set(i * 2 + 1, it.frame()->GetExpression(i)); | 10051 locals->set(i * 2 + 1, it.frame()->GetExpression(i)); |
| 10019 } | 10052 } |
| 10020 for (int i = info.number_of_stack_slots(); i < info.NumberOfLocals(); i++) { | 10053 // Get the context containing declarations. |
| 10054 Handle<Context> context( |
| 10055 Context::cast(it.frame()->context())->declaration_context()); |
| 10056 for (; i < info.NumberOfLocals(); ++i) { |
| 10021 Handle<String> name = info.LocalName(i); | 10057 Handle<String> name = info.LocalName(i); |
| 10058 locals->set(i * 2, *name); |
| 10022 locals->set(i * 2 + 1, | 10059 locals->set(i * 2 + 1, |
| 10023 context->get(scope_info->ContextSlotIndex(*name, NULL))); | 10060 context->get(scope_info->ContextSlotIndex(*name, NULL))); |
| 10024 } | 10061 } |
| 10025 } | 10062 } |
| 10026 | 10063 |
| 10027 // Check whether this frame is positioned at return. If not top | 10064 // Check whether this frame is positioned at return. If not top |
| 10028 // frame or if the frame is optimized it cannot be at a return. | 10065 // frame or if the frame is optimized it cannot be at a return. |
| 10029 bool at_return = false; | 10066 bool at_return = false; |
| 10030 if (!is_optimized_frame && index == 0) { | 10067 if (!is_optimized_frame && index == 0) { |
| 10031 at_return = isolate->debug()->IsBreakAtReturn(it.frame()); | 10068 at_return = isolate->debug()->IsBreakAtReturn(it.frame()); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10232 SetProperty(local_scope, | 10269 SetProperty(local_scope, |
| 10233 scope_info.stack_slot_name(i), | 10270 scope_info.stack_slot_name(i), |
| 10234 Handle<Object>(frame->GetExpression(i), isolate), | 10271 Handle<Object>(frame->GetExpression(i), isolate), |
| 10235 NONE, | 10272 NONE, |
| 10236 kNonStrictMode), | 10273 kNonStrictMode), |
| 10237 Handle<JSObject>()); | 10274 Handle<JSObject>()); |
| 10238 } | 10275 } |
| 10239 | 10276 |
| 10240 // Third fill all context locals. | 10277 // Third fill all context locals. |
| 10241 Handle<Context> frame_context(Context::cast(frame->context())); | 10278 Handle<Context> frame_context(Context::cast(frame->context())); |
| 10242 Handle<Context> function_context(frame_context->fcontext()); | 10279 Handle<Context> function_context(frame_context->declaration_context()); |
| 10243 if (!CopyContextLocalsToScopeObject(isolate, | 10280 if (!CopyContextLocalsToScopeObject(isolate, |
| 10244 serialized_scope_info, scope_info, | 10281 serialized_scope_info, scope_info, |
| 10245 function_context, local_scope)) { | 10282 function_context, local_scope)) { |
| 10246 return Handle<JSObject>(); | 10283 return Handle<JSObject>(); |
| 10247 } | 10284 } |
| 10248 | 10285 |
| 10249 // Finally copy any properties from the function context extension. This will | 10286 // Finally copy any properties from the function context extension. This will |
| 10250 // be variables introduced by eval. | 10287 // be variables introduced by eval. |
| 10251 if (function_context->closure() == *function) { | 10288 if (function_context->closure() == *function) { |
| 10252 if (function_context->has_extension() && | 10289 if (function_context->has_extension() && |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10964 HandleScope scope(isolate); | 11001 HandleScope scope(isolate); |
| 10965 ASSERT(args.length() == 0); | 11002 ASSERT(args.length() == 0); |
| 10966 isolate->debug()->ClearStepping(); | 11003 isolate->debug()->ClearStepping(); |
| 10967 return isolate->heap()->undefined_value(); | 11004 return isolate->heap()->undefined_value(); |
| 10968 } | 11005 } |
| 10969 | 11006 |
| 10970 | 11007 |
| 10971 // Creates a copy of the with context chain. The copy of the context chain is | 11008 // Creates a copy of the with context chain. The copy of the context chain is |
| 10972 // is linked to the function context supplied. | 11009 // is linked to the function context supplied. |
| 10973 static Handle<Context> CopyWithContextChain(Isolate* isolate, | 11010 static Handle<Context> CopyWithContextChain(Isolate* isolate, |
| 11011 Handle<JSFunction> function, |
| 10974 Handle<Context> current, | 11012 Handle<Context> current, |
| 10975 Handle<Context> base) { | 11013 Handle<Context> base) { |
| 10976 // At the end of the chain. Return the base context to link to. | 11014 // At the end of the chain. Return the base context to link to. |
| 10977 if (current->IsFunctionContext() || current->IsGlobalContext()) { | 11015 if (current->IsFunctionContext() || current->IsGlobalContext()) { |
| 10978 return base; | 11016 return base; |
| 10979 } | 11017 } |
| 10980 | 11018 |
| 10981 // Recursively copy the with and catch contexts. | 11019 // Recursively copy the with and catch contexts. |
| 10982 HandleScope scope(isolate); | 11020 HandleScope scope(isolate); |
| 10983 Handle<Context> previous(current->previous()); | 11021 Handle<Context> previous(current->previous()); |
| 10984 Handle<Context> new_previous = CopyWithContextChain(isolate, previous, base); | 11022 Handle<Context> new_previous = |
| 11023 CopyWithContextChain(isolate, function, previous, base); |
| 10985 Handle<Context> new_current; | 11024 Handle<Context> new_current; |
| 10986 if (current->IsCatchContext()) { | 11025 if (current->IsCatchContext()) { |
| 10987 Handle<String> name(String::cast(current->extension())); | 11026 Handle<String> name(String::cast(current->extension())); |
| 10988 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); | 11027 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); |
| 10989 new_current = | 11028 new_current = |
| 10990 isolate->factory()->NewCatchContext(new_previous, name, thrown_object); | 11029 isolate->factory()->NewCatchContext(function, |
| 11030 new_previous, |
| 11031 name, |
| 11032 thrown_object); |
| 10991 } else { | 11033 } else { |
| 10992 Handle<JSObject> extension(JSObject::cast(current->extension())); | 11034 Handle<JSObject> extension(JSObject::cast(current->extension())); |
| 10993 new_current = | 11035 new_current = |
| 10994 isolate->factory()->NewWithContext(new_previous, extension); | 11036 isolate->factory()->NewWithContext(function, new_previous, extension); |
| 10995 } | 11037 } |
| 10996 return scope.CloseAndEscape(new_current); | 11038 return scope.CloseAndEscape(new_current); |
| 10997 } | 11039 } |
| 10998 | 11040 |
| 10999 | 11041 |
| 11000 // Helper function to find or create the arguments object for | 11042 // Helper function to find or create the arguments object for |
| 11001 // Runtime_DebugEvaluate. | 11043 // Runtime_DebugEvaluate. |
| 11002 static Handle<Object> GetArgumentsObject(Isolate* isolate, | 11044 static Handle<Object> GetArgumentsObject(Isolate* isolate, |
| 11003 JavaScriptFrame* frame, | 11045 JavaScriptFrame* frame, |
| 11004 Handle<JSFunction> function, | 11046 Handle<JSFunction> function, |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11114 RETURN_IF_EMPTY_HANDLE(isolate, local_scope); | 11156 RETURN_IF_EMPTY_HANDLE(isolate, local_scope); |
| 11115 | 11157 |
| 11116 // Allocate a new context for the debug evaluation and set the extension | 11158 // Allocate a new context for the debug evaluation and set the extension |
| 11117 // object build. | 11159 // object build. |
| 11118 Handle<Context> context = | 11160 Handle<Context> context = |
| 11119 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, | 11161 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, |
| 11120 go_between); | 11162 go_between); |
| 11121 context->set_extension(*local_scope); | 11163 context->set_extension(*local_scope); |
| 11122 // Copy any with contexts present and chain them in front of this context. | 11164 // Copy any with contexts present and chain them in front of this context. |
| 11123 Handle<Context> frame_context(Context::cast(frame->context())); | 11165 Handle<Context> frame_context(Context::cast(frame->context())); |
| 11124 Handle<Context> function_context(frame_context->fcontext()); | 11166 Handle<Context> function_context(frame_context->declaration_context()); |
| 11125 context = CopyWithContextChain(isolate, frame_context, context); | 11167 context = CopyWithContextChain(isolate, go_between, frame_context, context); |
| 11126 | 11168 |
| 11127 if (additional_context->IsJSObject()) { | 11169 if (additional_context->IsJSObject()) { |
| 11128 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); | 11170 Handle<JSObject> extension = Handle<JSObject>::cast(additional_context); |
| 11129 context = isolate->factory()->NewWithContext(context, extension); | 11171 context = |
| 11172 isolate->factory()->NewWithContext(go_between, context, extension); |
| 11130 } | 11173 } |
| 11131 | 11174 |
| 11132 // Wrap the evaluation statement in a new function compiled in the newly | 11175 // Wrap the evaluation statement in a new function compiled in the newly |
| 11133 // created context. The function has one parameter which has to be called | 11176 // created context. The function has one parameter which has to be called |
| 11134 // 'arguments'. This it to have access to what would have been 'arguments' in | 11177 // 'arguments'. This it to have access to what would have been 'arguments' in |
| 11135 // the function being debugged. | 11178 // the function being debugged. |
| 11136 // function(arguments,__source__) {return eval(__source__);} | 11179 // function(arguments,__source__) {return eval(__source__);} |
| 11137 | 11180 |
| 11138 Handle<String> function_source = | 11181 Handle<String> function_source = |
| 11139 isolate->factory()->NewStringFromAscii( | 11182 isolate->factory()->NewStringFromAscii( |
| (...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12481 } else { | 12524 } else { |
| 12482 // Handle last resort GC and make sure to allow future allocations | 12525 // Handle last resort GC and make sure to allow future allocations |
| 12483 // to grow the heap without causing GCs (if possible). | 12526 // to grow the heap without causing GCs (if possible). |
| 12484 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12527 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 12485 isolate->heap()->CollectAllGarbage(false); | 12528 isolate->heap()->CollectAllGarbage(false); |
| 12486 } | 12529 } |
| 12487 } | 12530 } |
| 12488 | 12531 |
| 12489 | 12532 |
| 12490 } } // namespace v8::internal | 12533 } } // namespace v8::internal |
| OLD | NEW |