Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 7767f23d86d6190885d47d56c9d182f23ea43053..14172bc8f82d658aba8ae00d57b539fd9dc644dc 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -38,6 +38,7 @@ |
#include "debug.h" |
#include "execution.h" |
#include "jsregexp.h" |
+#include "liveedit.h" |
#include "parser.h" |
#include "platform.h" |
#include "runtime.h" |
@@ -7911,8 +7912,90 @@ static Object* Runtime_FunctionGetInferredName(Arguments args) { |
return f->shared()->inferred_name(); |
} |
+ |
+static int FindFunctionInfoForScript(Script* script, |
+ FixedArray* buffer) { |
+ AssertNoAllocation no_allocations; |
+ |
+ int counter = 0; |
+ int buffer_size = buffer->length(); |
+ HeapIterator iterator; |
+ for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
+ ASSERT(obj != NULL); |
+ if (!obj->IsSharedFunctionInfo()) { |
+ continue; |
+ } |
+ SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
+ if (shared->script() != script) { |
+ continue; |
+ } |
+ if (counter < buffer_size) { |
+ buffer->set(counter, shared, SKIP_WRITE_BARRIER); |
+ } |
+ counter++; |
+ } |
+ return counter; |
+} |
+ |
+static Object* Runtime_DebugChangeScriptLive(Arguments args) { |
+ ASSERT(args.length() == 4); |
+ HandleScope scope; |
+ CONVERT_CHECKED(JSValue, script, args[0]); |
+ CONVERT_NUMBER_CHECKED(int32_t, change_pos, Int32, args[1]); |
+ CONVERT_NUMBER_CHECKED(int32_t, orig_len, Int32, args[2]); |
+ CONVERT_ARG_CHECKED(String, new_str, 3); |
+ |
+ Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); |
+ |
+ const int kBufferSize = 32; |
+ |
+ Handle<FixedArray> array; |
+ array = Factory::NewFixedArray(kBufferSize); |
+ int number = FindFunctionInfoForScript(*script_handle, *array); |
+ if (number > kBufferSize) { |
+ array = Factory::NewFixedArray(number); |
+ FindFunctionInfoForScript(*script_handle, *array); |
+ } |
+ |
+ int new_len = new_str->length(); |
+ |
+ int diff = new_len - orig_len; |
+ |
+ i::Handle<String> orig_source = |
+ i::Handle<String>(String::cast(script_handle->source())); |
+ |
+ int new_script_len = orig_source->length() + diff; |
+ |
+ Object* str_object = Heap::AllocateRawTwoByteString(new_script_len); |
+ if (str_object->IsFailure()) { |
+ return Heap::undefined_value(); |
+ } |
+ |
+ i::Handle<FixedArray> param_array = Factory::NewFixedArray(3); |
+ param_array->set(0, *Factory::NewSubString(orig_source, 0, change_pos)); |
+ param_array->set(1, *new_str); |
+ param_array->set(2, *Factory::NewSubString(orig_source, change_pos + orig_len, |
+ orig_source->length())); |
+ |
+ i::Handle<SeqTwoByteString> answer = |
+ i::Handle<SeqTwoByteString>(SeqTwoByteString::cast(str_object)); |
+ |
+ StringBuilderConcatHelper(Heap::empty_string(), |
+ answer->GetChars(), |
+ *param_array, |
+ 3); |
+ |
+ ChangeScriptLive(script_handle, orig_source, answer, |
+ array, number, |
+ change_pos, orig_len, new_len); |
+ |
+ return Heap::undefined_value(); |
+} |
+ |
#endif // ENABLE_DEBUGGER_SUPPORT |
+ |
+ |
#ifdef ENABLE_LOGGING_AND_PROFILING |
static Object* Runtime_ProfilerResume(Arguments args) { |