Index: src/handles.cc |
=================================================================== |
--- src/handles.cc (revision 1480) |
+++ src/handles.cc (working copy) |
@@ -186,9 +186,7 @@ |
void FlattenString(Handle<String> string) { |
- StringShape shape(*string); |
- if (string->IsFlat(shape)) return; |
- CALL_HEAP_FUNCTION_VOID(string->TryFlatten(shape)); |
+ CALL_HEAP_FUNCTION_VOID(string->TryFlattenIfNotFlat(StringShape(*string))); |
Mads Ager (chromium)
2009/03/10 19:26:58
I think this change makes the code much clearer (a
|
ASSERT(string->IsFlat(StringShape(*string))); |
} |
@@ -343,6 +341,78 @@ |
} |
+// Init line_ends array with code positions of line ends inside script |
+// source. |
+void InitScriptLineEnds(Handle<Script> script) { |
+ if (!script->line_ends()->IsUndefined()) return; |
+ |
+ if (!script->source()->IsString()) { |
+ ASSERT(script->source()->IsUndefined()); |
+ script->set_line_ends(*(Factory::NewJSArray(0))); |
+ ASSERT(script->line_ends()->IsJSArray()); |
+ return; |
+ } |
+ |
+ Handle<String> src(String::cast(script->source())); |
+ const int src_len = src->length(); |
+ Handle<String> new_line = Factory::NewStringFromAscii(CStrVector("\n")); |
+ |
+ // Pass 1: Identify line count. |
+ int line_count = 0; |
+ int position = 0; |
+ while (position != -1 && position < src_len) { |
+ position = Runtime::StringMatch(src, new_line, position); |
+ if (position != -1) { |
+ position++; |
+ } |
+ // Even if the last line misses a line end, it is counted. |
+ line_count++; |
+ } |
+ |
+ // Pass 2: Fill in line ends positions |
+ Handle<FixedArray> array = Factory::NewFixedArray(line_count); |
+ int array_index = 0; |
+ position = 0; |
+ while (position != -1 && position < src_len) { |
+ position = Runtime::StringMatch(src, new_line, position); |
+ // If the script does not end with a line ending add the final end |
+ // position as just past the last line ending. |
+ array->set(array_index++, |
+ Smi::FromInt(position != -1 ? position++ : src_len)); |
+ } |
+ ASSERT(array_index == line_count); |
+ |
+ Handle<JSArray> object = Factory::NewJSArrayWithElements(array); |
+ script->set_line_ends(*object); |
+ ASSERT(script->line_ends()->IsJSArray()); |
+} |
+ |
+ |
+// Convert code position into line number. |
+int GetScriptLineNumber(Handle<Script> script, int code_pos) { |
+ InitScriptLineEnds(script); |
+ AssertNoAllocation no_allocation; |
+ JSArray* line_ends_array = JSArray::cast(script->line_ends()); |
+ const int line_ends_len = (Smi::cast(line_ends_array->length()))->value(); |
+ |
+ int line = -1; |
+ if (line_ends_len > 0 && |
+ code_pos <= (Smi::cast(line_ends_array->GetElement(0)))->value()) { |
+ line = 0; |
+ } else { |
+ for (int i = 1; i < line_ends_len; ++i) { |
+ if ((Smi::cast(line_ends_array->GetElement(i - 1)))->value() < code_pos && |
+ code_pos <= (Smi::cast(line_ends_array->GetElement(i)))->value()) { |
+ line = i; |
+ break; |
+ } |
+ } |
+ } |
+ |
+ return line != -1 ? line + script->line_offset()->value() : line; |
+} |
+ |
+ |
// Compute the property keys from the interceptor. |
v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver, |
Handle<JSObject> object) { |