Revision: 22137
Author:   [email protected]
Date:     Wed Jul  2 07:01:31 2014 UTC
Log:      Handle "//# sourceURL" comments in the Parser instead of the JS.

BUG=v8:2948
LOG=N
[email protected], [email protected]

Review URL: https://codereview.chromium.org/316173002
http://code.google.com/p/v8/source/detail?r=22137

Modified:
 /branches/bleeding_edge/include/v8.h
 /branches/bleeding_edge/src/accessors.cc
 /branches/bleeding_edge/src/accessors.h
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/messages.js
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/src/scanner.cc
 /branches/bleeding_edge/src/scanner.h
 /branches/bleeding_edge/src/vector.h
 /branches/bleeding_edge/test/cctest/test-api.cc
 /branches/bleeding_edge/test/mjsunit/debug-compile-event.js

=======================================
--- /branches/bleeding_edge/include/v8.h        Tue Jul  1 15:02:31 2014 UTC
+++ /branches/bleeding_edge/include/v8.h        Wed Jul  2 07:01:31 2014 UTC
@@ -946,6 +946,15 @@
   int GetId();
   Handle<Value> GetScriptName();

+  /**
+   * Data read from magic sourceURL comments.
+   */
+  Handle<Value> GetSourceURL();
+  /**
+   * Data read from magic sourceMappingURL comments.
+   */
+  Handle<Value> GetSourceMappingURL();
+
   /**
    * Returns zero based line number of the code_pos location in the script.
    * -1 will be returned if no information available.
=======================================
--- /branches/bleeding_edge/src/accessors.cc    Tue Jul  1 12:12:34 2014 UTC
+++ /branches/bleeding_edge/src/accessors.cc    Wed Jul  2 07:01:31 2014 UTC
@@ -583,6 +583,77 @@
                       &ScriptLineEndsSetter,
                       attributes);
 }
+
+
+//
+// Accessors::ScriptSourceUrl
+//
+
+
+void Accessors::ScriptSourceUrlGetter(
+    v8::Local<v8::String> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* url = Script::cast(JSValue::cast(object)->value())->source_url();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
+}
+
+
+void Accessors::ScriptSourceUrlSetter(
+    v8::Local<v8::String> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->source_url_string(),
+                      &ScriptSourceUrlGetter,
+                      &ScriptSourceUrlSetter,
+                      attributes);
+}
+
+
+//
+// Accessors::ScriptSourceMappingUrl
+//
+
+
+void Accessors::ScriptSourceMappingUrlGetter(
+    v8::Local<v8::String> name,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  DisallowHeapAllocation no_allocation;
+  HandleScope scope(isolate);
+  Object* object = *Utils::OpenHandle(*info.This());
+  Object* url =
+      Script::cast(JSValue::cast(object)->value())->source_mapping_url();
+  info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
+}
+
+
+void Accessors::ScriptSourceMappingUrlSetter(
+    v8::Local<v8::String> name,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
+      Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate,
+                      isolate->factory()->source_mapping_url_string(),
+                      &ScriptSourceMappingUrlGetter,
+                      &ScriptSourceMappingUrlSetter,
+                      attributes);
+}


 //
=======================================
--- /branches/bleeding_edge/src/accessors.h     Tue Jun  3 08:12:43 2014 UTC
+++ /branches/bleeding_edge/src/accessors.h     Wed Jul  2 07:01:31 2014 UTC
@@ -32,6 +32,8 @@
   V(ScriptName)                     \
   V(ScriptSource)                   \
   V(ScriptType)                     \
+  V(ScriptSourceUrl)                \
+  V(ScriptSourceMappingUrl)         \
   V(StringLength)

 // Accessors contains all predefined proxy accessors.
=======================================
--- /branches/bleeding_edge/src/api.cc  Tue Jul  1 12:12:34 2014 UTC
+++ /branches/bleeding_edge/src/api.cc  Wed Jul  2 07:01:31 2014 UTC
@@ -1631,6 +1631,38 @@
     return Handle<String>();
   }
 }
+
+
+Handle<Value> UnboundScript::GetSourceURL() {
+  i::Handle<i::SharedFunctionInfo> obj =
+      i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
+  i::Isolate* isolate = obj->GetIsolate();
+  ON_BAILOUT(isolate, "v8::UnboundScript::GetSourceURL()",
+             return Handle<String>());
+  LOG_API(isolate, "UnboundScript::GetSourceURL");
+  if (obj->script()->IsScript()) {
+    i::Object* url = i::Script::cast(obj->script())->source_url();
+    return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
+  } else {
+    return Handle<String>();
+  }
+}
+
+
+Handle<Value> UnboundScript::GetSourceMappingURL() {
+  i::Handle<i::SharedFunctionInfo> obj =
+      i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
+  i::Isolate* isolate = obj->GetIsolate();
+  ON_BAILOUT(isolate, "v8::UnboundScript::GetSourceMappingURL()",
+             return Handle<String>());
+  LOG_API(isolate, "UnboundScript::GetSourceMappingURL");
+  if (obj->script()->IsScript()) {
+    i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
+    return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
+  } else {
+    return Handle<String>();
+  }
+}


 Local<Value> Script::Run() {
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Tue Jul  1 12:12:34 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Wed Jul  2 07:01:31 2014 UTC
@@ -1762,7 +1762,7 @@
     native_context()->set_script_function(*script_fun);

     Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
-    Map::EnsureDescriptorSlack(script_map, 13);
+    Map::EnsureDescriptorSlack(script_map, 14);

     PropertyAttributes attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
@@ -1868,6 +1868,23 @@
           script_eval_from_function_name, attribs);
       script_map->AppendDescriptor(&d);
     }
+
+    Handle<AccessorInfo> script_source_url =
+        Accessors::ScriptSourceUrlInfo(isolate(), attribs);
+    {
+ CallbacksDescriptor d(Handle<Name>(Name::cast(script_source_url->name())),
+                            script_source_url, attribs);
+      script_map->AppendDescriptor(&d);
+    }
+
+    Handle<AccessorInfo> script_source_mapping_url =
+        Accessors::ScriptSourceMappingUrlInfo(isolate(), attribs);
+    {
+      CallbacksDescriptor d(
+          Handle<Name>(Name::cast(script_source_mapping_url->name())),
+          script_source_mapping_url, attribs);
+      script_map->AppendDescriptor(&d);
+    }

     // Allocate the empty script.
Handle<Script> script = factory()->NewScript(factory()->empty_string());
=======================================
--- /branches/bleeding_edge/src/heap.h  Tue Jul  1 18:48:02 2014 UTC
+++ /branches/bleeding_edge/src/heap.h  Wed Jul  2 07:01:31 2014 UTC
@@ -290,6 +290,8 @@
   V(nan_string, "NaN")                                                   \
   V(RegExp_string, "RegExp")                                             \
   V(source_string, "source")                                             \
+  V(source_url_string, "source_url")                                     \
+  V(source_mapping_url_string, "source_mapping_url")                     \
   V(global_string, "global")                                             \
   V(ignore_case_string, "ignoreCase")                                    \
   V(multiline_string, "multiline")                                       \
=======================================
--- /branches/bleeding_edge/src/messages.js     Tue Jul  1 10:00:19 2014 UTC
+++ /branches/bleeding_edge/src/messages.js     Wed Jul  2 07:01:31 2014 UTC
@@ -560,44 +560,16 @@
   if (this.line_offset > 0 || this.column_offset > 0) {
     return this.name;
   }
-
- // The result is cached as on long scripts it takes noticable time to search
-  // for the sourceURL.
-  if (this.hasCachedNameOrSourceURL) {
-    return this.cachedNameOrSourceURL;
+  if (this.source_url) {
+    return this.source_url;
   }
-  this.hasCachedNameOrSourceURL = true;
-
-  // TODO(608): the spaces in a regexp below had to be escaped as \040
-  // because this file is being processed by js2c whose handling of spaces
-  // in regexps is broken. Also, ['"] are excluded from allowed URLs to
-  // avoid matches against sources that invoke evals with sourceURL.
-  // A better solution would be to detect these special comments in
-  // the scanner/parser.
-  var source = ToString(this.source);
-  var sourceUrlPos = %StringIndexOf(source, "sourceURL=", 0);
-  this.cachedNameOrSourceURL = this.name;
-  if (sourceUrlPos > 4) {
-    var sourceUrlPattern =
-        /\/\/[#@][\040\t]sourceURL=[\040\t]*([^\s\'\"]*)[\040\t]*$/gm;
-    // Don't reuse lastMatchInfo here, so we create a new array with room
-    // for four captures (array with length one longer than the index
-    // of the fourth capture, where the numbering is zero-based).
-    var matchInfo = new InternalArray(CAPTURE(3) + 1);
-    var match =
- %_RegExpExec(sourceUrlPattern, source, sourceUrlPos - 4, matchInfo);
-    if (match) {
-      this.cachedNameOrSourceURL =
- %_SubString(source, matchInfo[CAPTURE(2)], matchInfo[CAPTURE(3)]);
-    }
-  }
-  return this.cachedNameOrSourceURL;
+  return this.name;
 }


 SetUpLockedPrototype(Script,
-  $Array("source", "name", "line_ends", "line_offset", "column_offset",
-         "cachedNameOrSourceURL", "hasCachedNameOrSourceURL" ),
+  $Array("source", "name", "source_url", "source_mapping_url", "line_ends",
+         "line_offset", "column_offset"),
   $Array(
     "lineFromPosition", ScriptLineFromPosition,
     "locationFromPosition", ScriptLocationFromPosition,
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Tue Jul  1 15:02:31 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Wed Jul  2 07:01:31 2014 UTC
@@ -5263,6 +5263,8 @@
                  kEvalFrominstructionsOffsetOffset)
 ACCESSORS_TO_SMI(Script, flags, kFlagsOffset)
BOOL_ACCESSORS(Script, flags, is_shared_cross_origin, kIsSharedCrossOriginBit)
+ACCESSORS(Script, source_url, Object, kSourceUrlOffset)
+ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset)

 Script::CompilationType Script::compilation_type() {
   return BooleanBit::get(flags(), kCompilationTypeBit) ?
=======================================
--- /branches/bleeding_edge/src/objects.h       Tue Jul  1 15:02:31 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Wed Jul  2 07:01:31 2014 UTC
@@ -6911,6 +6911,12 @@
   // [flags]: Holds an exciting bitfield.
   DECL_ACCESSORS(flags, Smi)

+  // [source_url]: sourceURL from magic comment
+  DECL_ACCESSORS(source_url, Object)
+
+  // [source_url]: sourceMappingURL magic comment
+  DECL_ACCESSORS(source_mapping_url, Object)
+
   // [compilation_type]: how the the script was compiled. Encoded in the
   // 'flags' field.
   inline CompilationType compilation_type();
@@ -6967,7 +6973,9 @@
       kEvalFromSharedOffset + kPointerSize;
   static const int kFlagsOffset =
       kEvalFrominstructionsOffsetOffset + kPointerSize;
-  static const int kSize = kFlagsOffset + kPointerSize;
+  static const int kSourceUrlOffset = kFlagsOffset + kPointerSize;
+ static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
+  static const int kSize = kSourceMappingUrlOffset + kPointerSize;

  private:
   int GetLineNumberWithArray(int code_pos);
=======================================
--- /branches/bleeding_edge/src/parser.cc       Mon Jun 30 13:35:16 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc       Wed Jul  2 07:01:31 2014 UTC
@@ -895,6 +895,9 @@
     bool ok = true;
     int beg_pos = scanner()->location().beg_pos;
     ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok);
+
+    HandleSourceURLComments();
+
     if (ok && strict_mode() == STRICT) {
       CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
     }
@@ -3880,6 +3883,18 @@
     if (collector != NULL) collector->AddTarget(target, zone());
   }
 }
+
+
+void Parser::HandleSourceURLComments() {
+  if (scanner_.source_url()->length() > 0) {
+    info_->script()->set_source_url(
+        *scanner_.source_url()->Internalize(isolate()));
+  }
+  if (scanner_.source_mapping_url()->length() > 0) {
+    info_->script()->set_source_mapping_url(
+        *scanner_.source_mapping_url()->Internalize(isolate()));
+  }
+}


 void Parser::ThrowPendingError() {
=======================================
--- /branches/bleeding_edge/src/parser.h        Mon Jun 30 13:35:16 2014 UTC
+++ /branches/bleeding_edge/src/parser.h        Wed Jul  2 07:01:31 2014 UTC
@@ -796,6 +796,8 @@
       const AstRawString* function_name, int pos, Variable* fvar,
       Token::Value fvar_init_op, bool is_generator, bool* ok);

+  void HandleSourceURLComments();
+
   void ThrowPendingError();

   void InternalizeUseCounts();
=======================================
--- /branches/bleeding_edge/src/scanner.cc      Tue Jun 24 14:03:24 2014 UTC
+++ /branches/bleeding_edge/src/scanner.cc      Wed Jul  2 07:01:31 2014 UTC
@@ -19,6 +19,15 @@
 namespace v8 {
 namespace internal {

+
+Handle<String> LiteralBuffer::Internalize(Isolate* isolate) const {
+  if (is_one_byte()) {
+ return isolate->factory()->InternalizeOneByteString(one_byte_literal());
+  }
+  return isolate->factory()->InternalizeTwoByteString(two_byte_literal());
+}
+
+
// ----------------------------------------------------------------------------
 // Scanner

@@ -293,6 +302,68 @@

   return Token::WHITESPACE;
 }
+
+
+Token::Value Scanner::SkipSourceURLComment() {
+  TryToParseSourceURLComment();
+  while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
+    Advance();
+  }
+
+  return Token::WHITESPACE;
+}
+
+
+void Scanner::TryToParseSourceURLComment() {
+ // Magic comments are of the form: //[#@]\s<name>=\s*<value>\s*.* and this
+  // function will just return if it cannot parse a magic comment.
+  if (!unicode_cache_->IsWhiteSpace(c0_))
+    return;
+  Advance();
+  LiteralBuffer name;
+  while (c0_ >= 0 && !unicode_cache_->IsWhiteSpaceOrLineTerminator(c0_) &&
+         c0_ != '=') {
+    name.AddChar(c0_);
+    Advance();
+  }
+  if (!name.is_one_byte()) return;
+  Vector<const uint8_t> name_literal = name.one_byte_literal();
+  LiteralBuffer* value;
+  if (name_literal == STATIC_ASCII_VECTOR("sourceURL")) {
+    value = &source_url_;
+  } else if (name_literal == STATIC_ASCII_VECTOR("sourceMappingURL")) {
+    value = &source_mapping_url_;
+  } else {
+    return;
+  }
+  if (c0_ != '=')
+    return;
+  Advance();
+  value->Reset();
+  while (c0_ >= 0 && unicode_cache_->IsWhiteSpace(c0_)) {
+    Advance();
+  }
+  while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
+    // Disallowed characters.
+    if (c0_ == '"' || c0_ == '\'') {
+      value->Reset();
+      return;
+    }
+    if (unicode_cache_->IsWhiteSpace(c0_)) {
+      break;
+    }
+    value->AddChar(c0_);
+    Advance();
+  }
+  // Allow whitespace at the end.
+  while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
+    if (!unicode_cache_->IsWhiteSpace(c0_)) {
+      value->Reset();
+      break;
+    }
+    Advance();
+  }
+}


 Token::Value Scanner::SkipMultiLineComment() {
@@ -459,7 +530,14 @@
         // /  // /* /=
         Advance();
         if (c0_ == '/') {
-          token = SkipSingleLineComment();
+          Advance();
+          if (c0_ == '@' || c0_ == '#') {
+            Advance();
+            token = SkipSourceURLComment();
+          } else {
+            PushBack(c0_);
+            token = SkipSingleLineComment();
+          }
         } else if (c0_ == '*') {
           token = SkipMultiLineComment();
         } else if (c0_ == '=') {
=======================================
--- /branches/bleeding_edge/src/scanner.h       Mon Jun 30 13:25:46 2014 UTC
+++ /branches/bleeding_edge/src/scanner.h       Wed Jul  2 07:01:31 2014 UTC
@@ -216,14 +216,14 @@
     position_ += kUC16Size;
   }

-  bool is_one_byte() { return is_one_byte_; }
+  bool is_one_byte() const { return is_one_byte_; }

-  bool is_contextual_keyword(Vector<const char> keyword) {
+  bool is_contextual_keyword(Vector<const char> keyword) const {
     return is_one_byte() && keyword.length() == position_ &&
         (memcmp(keyword.start(), backing_store_.start(), position_) == 0);
   }

-  Vector<const uint16_t> two_byte_literal() {
+  Vector<const uint16_t> two_byte_literal() const {
     ASSERT(!is_one_byte_);
     ASSERT((position_ & 0x1) == 0);
     return Vector<const uint16_t>(
@@ -231,14 +231,14 @@
         position_ >> 1);
   }

-  Vector<const uint8_t> one_byte_literal() {
+  Vector<const uint8_t> one_byte_literal() const {
     ASSERT(is_one_byte_);
     return Vector<const uint8_t>(
         reinterpret_cast<const uint8_t*>(backing_store_.start()),
         position_);
   }

-  int length() {
+  int length() const {
     return is_one_byte_ ? position_ : (position_ >> 1);
   }

@@ -246,6 +246,8 @@
     position_ = 0;
     is_one_byte_ = true;
   }
+
+  Handle<String> Internalize(Isolate* isolate) const;

  private:
   static const int kInitialCapacity = 16;
@@ -450,6 +452,11 @@
   // Returns true if regexp flags are scanned (always since flags can
   // be empty).
   bool ScanRegExpFlags();
+
+  const LiteralBuffer* source_url() const { return &source_url_; }
+  const LiteralBuffer* source_mapping_url() const {
+    return &source_mapping_url_;
+  }

  private:
   // The current and look-ahead token.
@@ -572,6 +579,8 @@

   bool SkipWhiteSpace();
   Token::Value SkipSingleLineComment();
+  Token::Value SkipSourceURLComment();
+  void TryToParseSourceURLComment();
   Token::Value SkipMultiLineComment();
   // Scans a possible HTML comment -- begins with '<!'.
   Token::Value ScanHtmlComment();
@@ -606,6 +615,10 @@
   LiteralBuffer literal_buffer1_;
   LiteralBuffer literal_buffer2_;

+  // Values parsed from magic comments.
+  LiteralBuffer source_url_;
+  LiteralBuffer source_mapping_url_;
+
   TokenDesc current_;  // desc for current token (as returned by Next())
   TokenDesc next_;     // desc for next token (one token look-ahead)

=======================================
--- /branches/bleeding_edge/src/vector.h        Tue Jun  3 08:12:43 2014 UTC
+++ /branches/bleeding_edge/src/vector.h        Wed Jul  2 07:01:31 2014 UTC
@@ -99,6 +99,17 @@
     return Vector<T>(reinterpret_cast<T*>(input.start()),
                      input.length() * sizeof(S) / sizeof(T));
   }
+
+  bool operator==(const Vector<T>& other) const {
+    if (length_ != other.length_) return false;
+    if (start_ == other.start_) return true;
+    for (int i = 0; i < length_; ++i) {
+      if (start_[i] != other.start_[i]) {
+        return false;
+      }
+    }
+    return true;
+  }

  protected:
   void set_start(T* start) { start_ = start; }
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Mon Jun 30 13:25:46 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-api.cc Wed Jul 2 07:01:31 2014 UTC
@@ -22761,3 +22761,85 @@
   Local<Value> result = CompileRun("CallEval();");
   CHECK_EQ(result, v8::Integer::New(isolate, 1));
 }
+
+
+void SourceURLHelper(const char* source, const char* expected_source_url,
+                     const char* expected_source_mapping_url) {
+  Local<Script> script = v8_compile(source);
+  if (expected_source_url != NULL) {
+    v8::String::Utf8Value url(script->GetUnboundScript()->GetSourceURL());
+    CHECK_EQ(expected_source_url, *url);
+  } else {
+    CHECK(script->GetUnboundScript()->GetSourceURL()->IsUndefined());
+  }
+  if (expected_source_mapping_url != NULL) {
+    v8::String::Utf8Value url(
+        script->GetUnboundScript()->GetSourceMappingURL());
+    CHECK_EQ(expected_source_mapping_url, *url);
+  } else {
+ CHECK(script->GetUnboundScript()->GetSourceMappingURL()->IsUndefined());
+  }
+}
+
+
+TEST(ScriptSourceURLAndSourceMappingURL) {
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceURL=bar1.js\n", "bar1.js", NULL);
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceMappingURL=bar2.js\n", NULL, "bar2.js");
+
+  // Both sourceURL and sourceMappingURL.
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceURL=bar3.js\n"
+                  "//# sourceMappingURL=bar4.js\n", "bar3.js", "bar4.js");
+
+  // Two source URLs; the first one is ignored.
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceURL=ignoreme.js\n"
+                  "//# sourceURL=bar5.js\n", "bar5.js", NULL);
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceMappingURL=ignoreme.js\n"
+                  "//# sourceMappingURL=bar6.js\n", NULL, "bar6.js");
+
+  // SourceURL or sourceMappingURL in the middle of the script.
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceURL=bar7.js\n"
+                  "function baz() {}\n", "bar7.js", NULL);
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceMappingURL=bar8.js\n"
+                  "function baz() {}\n", NULL, "bar8.js");
+
+  // Too much whitespace.
+  SourceURLHelper("function foo() {}\n"
+                  "//#  sourceURL=bar9.js\n"
+                  "//#  sourceMappingURL=bar10.js\n", NULL, NULL);
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceURL =bar11.js\n"
+                  "//# sourceMappingURL =bar12.js\n", NULL, NULL);
+
+  // Disallowed characters in value.
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceURL=bar13 .js   \n"
+                  "//# sourceMappingURL=bar14 .js \n",
+                  NULL, NULL);
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceURL=bar15\t.js   \n"
+                  "//# sourceMappingURL=bar16\t.js \n",
+                  NULL, NULL);
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceURL=bar17'.js   \n"
+                  "//# sourceMappingURL=bar18'.js \n",
+                  NULL, NULL);
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceURL=bar19\".js   \n"
+                  "//# sourceMappingURL=bar20\".js \n",
+                  NULL, NULL);
+
+  // Not too much whitespace.
+  SourceURLHelper("function foo() {}\n"
+                  "//# sourceURL=  bar21.js   \n"
+ "//# sourceMappingURL= bar22.js \n", "bar21.js", "bar22.js");
+}
=======================================
--- /branches/bleeding_edge/test/mjsunit/debug-compile-event.js Thu Jun 26 16:03:52 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/debug-compile-event.js Wed Jul 2 07:01:31 2014 UTC
@@ -85,9 +85,11 @@
       assertTrue('context' in msg.body.script);

       // Check that we pick script name from //# sourceURL, iff present
-      assertEquals(current_source.indexOf('sourceURL') >= 0 ?
-                     'myscript.js' : undefined,
-                   event_data.script().name());
+      if (event == Debug.DebugEvent.AfterCompile) {
+        assertEquals(current_source.indexOf('sourceURL') >= 0 ?
+            'myscript.js' : undefined,
+                     event_data.script().name());
+      }
     }
   } catch (e) {
     exception = e

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to