Chromium Code Reviews| 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) { |