Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 9e8b06c6fc467e8ca7668d039df96b29a9f9c4eb..702b2650524fc4e88d25837011d2e4ec274ca1f3 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -13258,6 +13258,10 @@ Handle<String> JSFunction::ToString(Handle<JSFunction> function) { |
return NativeCodeFunctionSourceString(shared_info); |
} |
+ if (FLAG_harmony_function_tostring) { |
+ return Handle<String>::cast(shared_info->GetSourceCodeHarmony()); |
+ } |
+ |
IncrementalStringBuilder builder(isolate); |
FunctionKind kind = shared_info->kind(); |
if (!IsArrowFunction(kind)) { |
@@ -13673,6 +13677,47 @@ Handle<Object> SharedFunctionInfo::GetSourceCode() { |
source, start_position(), end_position()); |
} |
+namespace { |
+template <typename Char> |
+Handle<Object> NormalizeLineTerminators(FlatStringReader* reader, |
+ IncrementalStringBuilder* builder) { |
+ for (int i = 0; i < reader->length(); i++) { |
+ Char c = reader->Get<Char>(i); |
+ if (c == '\r') { |
+ // normalize CR or CRLF |
+ builder->AppendCharacter('\n'); |
+ if (i + 1 < reader->length() && reader->Get<Char>(i + 1) == '\n') { |
+ // also consume the LF in the CRLF |
+ i++; |
+ } |
+ } else { |
+ builder->Append<Char, Char>(c); |
+ } |
+ } |
+ return builder->Finish().ToHandleChecked(); |
+} |
+} // namespace |
+ |
+Handle<Object> SharedFunctionInfo::GetSourceCodeHarmony() { |
+ Isolate* isolate = GetIsolate(); |
+ if (!HasSourceCode()) return isolate->factory()->undefined_value(); |
+ Handle<String> script_source(String::cast(Script::cast(script())->source())); |
+ int start_pos = function_token_position(); |
+ if (start_pos == kNoSourcePosition) start_pos = start_position(); |
+ Handle<String> function_source = isolate->factory()->NewSubString( |
+ script_source, start_pos, end_position()); |
+ // normalize line terminators |
+ FlatStringReader reader(isolate, function_source); |
+ // TODO(jwolfe): we know the upper bound on the build is reader.length(). how |
+ // to specify it? |
jwolfe
2016/11/01 21:34:19
this is an optional optimization we may want to do
|
+ IncrementalStringBuilder builder(isolate); |
+ if (function_source->IsOneByteRepresentationUnderneath()) { |
+ return NormalizeLineTerminators<uint8_t>(&reader, &builder); |
+ } else { |
+ builder.ChangeEncoding(); |
+ return NormalizeLineTerminators<uc16>(&reader, &builder); |
+ } |
+} |
bool SharedFunctionInfo::IsInlineable() { |
// Check that the function has a script associated with it. |