13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/messages.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <memory>
8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/api.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/execution.h"
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h"
12bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/keys.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/string-builder.h"
14bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/wasm/wasm-module.h"
15c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/wasm/wasm-objects.h"
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochMessageLocation::MessageLocation(Handle<Script> script, int start_pos,
21bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 int end_pos)
22bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    : script_(script), start_pos_(start_pos), end_pos_(end_pos) {}
23bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochMessageLocation::MessageLocation(Handle<Script> script, int start_pos,
2462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 int end_pos, Handle<SharedFunctionInfo> shared)
25bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    : script_(script),
26bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      start_pos_(start_pos),
27bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      end_pos_(end_pos),
2862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      shared_(shared) {}
29bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochMessageLocation::MessageLocation() : start_pos_(-1), end_pos_(-1) {}
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If no message listeners have been registered this one is called
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// by default.
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MessageHandler::DefaultMessageReport(Isolate* isolate,
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          const MessageLocation* loc,
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          Handle<Object> message_obj) {
36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  std::unique_ptr<char[]> str = GetLocalizedMessage(isolate, message_obj);
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (loc == NULL) {
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("%s\n", str.get());
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HandleScope scope(isolate);
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Object> data(loc->script()->name(), isolate);
42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    std::unique_ptr<char[]> data_str;
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (data->IsString())
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS);
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PrintF("%s:%i: %s\n", data_str.get() ? data_str.get() : "<unknown>",
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           loc->start_pos(), str.get());
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
501e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockHandle<JSMessageObject> MessageHandler::MakeMessageObject(
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, MessageTemplate::Template message,
5262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    const MessageLocation* location, Handle<Object> argument,
533bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    Handle<JSArray> stack_frames) {
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Factory* factory = isolate->factory();
551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int start = -1;
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int end = -1;
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> script_handle = factory->undefined_value();
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (location != NULL) {
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    start = location->start_pos();
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    end = location->end_pos();
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    script_handle = Script::GetWrapper(location->script());
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    script_handle = Script::GetWrapper(isolate->factory()->empty_script());
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Handle<Object> stack_frames_handle = stack_frames.is_null()
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? Handle<Object>::cast(factory->undefined_value())
691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      : Handle<Object>::cast(stack_frames);
701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<JSMessageObject> message_obj = factory->NewJSMessageObject(
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      message, argument, start, end, script_handle, stack_frames_handle);
731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return message_obj;
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid MessageHandler::ReportMessage(Isolate* isolate, const MessageLocation* loc,
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   Handle<JSMessageObject> message) {
7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message);
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (api_message_obj->ErrorLevel() == v8::Isolate::kMessageError) {
8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // We are calling into embedder's code which can throw exceptions.
8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Thus we need to save current exception state, reset it to the clean one
8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // and ignore scheduled exceptions callbacks can throw.
858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // We pass the exception object into the message handler callback though.
8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Object* exception_object = isolate->heap()->undefined_value();
8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (isolate->has_pending_exception()) {
8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      exception_object = isolate->pending_exception();
9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Handle<Object> exception(exception_object, isolate);
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Isolate::ExceptionScope exception_scope(isolate);
9462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    isolate->clear_pending_exception();
9562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    isolate->set_external_caught_exception(false);
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
9762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Turn the exception on the message into a string if it is an object.
9862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (message->argument()->IsJSObject()) {
9962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      HandleScope scope(isolate);
10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> argument(message->argument(), isolate);
10162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
10262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      MaybeHandle<Object> maybe_stringified;
10362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> stringified;
10462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // Make sure we don't leak uncaught internally generated Error objects.
10562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (argument->IsJSError()) {
10662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        maybe_stringified = Object::NoSideEffectsToString(isolate, argument);
10762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else {
10862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate));
10962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        catcher.SetVerbose(false);
11062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        catcher.SetCaptureMessage(false);
11162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
11262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        maybe_stringified = Object::ToString(isolate, argument);
11362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
11562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (!maybe_stringified.ToHandle(&stringified)) {
11662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        stringified =
11762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            isolate->factory()->NewStringFromAsciiChecked("exception");
11862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
11962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      message->set_argument(*stringified);
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Value> api_exception_obj = v8::Utils::ToLocal(exception);
12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ReportMessageNoExceptions(isolate, loc, message, api_exception_obj);
12462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
12562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ReportMessageNoExceptions(isolate, loc, message, v8::Local<v8::Value>());
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid MessageHandler::ReportMessageNoExceptions(
13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Isolate* isolate, const MessageLocation* loc, Handle<Object> message,
13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Value> api_exception_obj) {
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message);
13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int error_level = api_message_obj->ErrorLevel();
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<TemplateList> global_listeners =
136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate->factory()->message_listeners();
137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int global_length = global_listeners->length();
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (global_length == 0) {
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DefaultMessageReport(isolate, loc, message);
1408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    if (isolate->has_scheduled_exception()) {
1418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      isolate->clear_scheduled_exception();
1428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    }
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < global_length; i++) {
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      HandleScope scope(isolate);
146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (global_listeners->get(i)->IsUndefined(isolate)) continue;
147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      FixedArray* listener = FixedArray::cast(global_listeners->get(i));
148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Foreign* callback_obj = Foreign::cast(listener->get(0));
14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      int32_t message_levels =
15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          static_cast<int32_t>(Smi::cast(listener->get(2))->value());
15162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (!(message_levels & error_level)) {
15262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        continue;
15362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::MessageCallback callback =
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          FUNCTION_CAST<v8::MessageCallback>(callback_obj->foreign_address());
156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Handle<Object> callback_data(listener->get(1), isolate);
1578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      {
1588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        // Do not allow exceptions to propagate.
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
16013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        callback(api_message_obj, callback_data->IsUndefined(isolate)
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      ? api_exception_obj
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      : v8::Utils::ToLocal(callback_data));
1638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      }
1648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      if (isolate->has_scheduled_exception()) {
1658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        isolate->clear_scheduled_exception();
1668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      }
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<String> MessageHandler::GetMessage(Isolate* isolate,
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          Handle<Object> data) {
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSMessageObject> message = Handle<JSMessageObject>::cast(data);
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Object> arg = Handle<Object>(message->argument(), isolate);
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return MessageTemplate::FormatMessage(isolate, message->type(), arg);
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstd::unique_ptr<char[]> MessageHandler::GetLocalizedMessage(
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Handle<Object> data) {
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HandleScope scope(isolate);
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return GetMessage(isolate, data)->ToCString(DISALLOW_NULLS);
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
18562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace {
18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochObject* EvalFromFunctionName(Isolate* isolate, Handle<Script> script) {
18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (script->eval_from_shared()->IsUndefined(isolate))
18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return isolate->heap()->undefined_value();
19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<SharedFunctionInfo> shared(
19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      SharedFunctionInfo::cast(script->eval_from_shared()));
19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Find the name of the function calling eval.
19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (shared->name()->BooleanValue()) {
19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return shared->name();
19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return shared->inferred_name();
19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
20062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochObject* EvalFromScript(Isolate* isolate, Handle<Script> script) {
20262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (script->eval_from_shared()->IsUndefined(isolate))
20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return isolate->heap()->undefined_value();
20462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
20562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<SharedFunctionInfo> eval_from_shared(
20662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      SharedFunctionInfo::cast(script->eval_from_shared()));
20762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return eval_from_shared->script()->IsScript()
20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             ? eval_from_shared->script()
20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             : isolate->heap()->undefined_value();
21062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
21162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochMaybeHandle<String> FormatEvalOrigin(Isolate* isolate, Handle<Script> script) {
21362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<Object> sourceURL(script->GetNameOrSourceURL(), isolate);
21462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!sourceURL->IsUndefined(isolate)) {
21562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(sourceURL->IsString());
21662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return Handle<String>::cast(sourceURL);
21762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
21862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  IncrementalStringBuilder builder(isolate);
22062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  builder.AppendCString("eval at ");
22162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
22262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<Object> eval_from_function_name =
22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      handle(EvalFromFunctionName(isolate, script), isolate);
22462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (eval_from_function_name->BooleanValue()) {
22562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Handle<String> str;
22662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ASSIGN_RETURN_ON_EXCEPTION(
22762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        isolate, str, Object::ToString(isolate, eval_from_function_name),
22862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        String);
22962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    builder.AppendString(str);
23062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
23162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    builder.AppendCString("<anonymous>");
23262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<Object> eval_from_script_obj =
23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      handle(EvalFromScript(isolate, script), isolate);
23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (eval_from_script_obj->IsScript()) {
23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Handle<Script> eval_from_script =
23862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Handle<Script>::cast(eval_from_script_obj);
23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    builder.AppendCString(" (");
24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (eval_from_script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // Eval script originated from another eval.
24262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<String> str;
24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ASSIGN_RETURN_ON_EXCEPTION(
24462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          isolate, str, FormatEvalOrigin(isolate, eval_from_script), String);
24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      builder.AppendString(str);
24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else {
24762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      DCHECK(eval_from_script->compilation_type() !=
24862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             Script::COMPILATION_TYPE_EVAL);
24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // eval script originated from "real" source.
25062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<Object> name_obj = handle(eval_from_script->name(), isolate);
25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (eval_from_script->name()->IsString()) {
25262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        builder.AppendString(Handle<String>::cast(name_obj));
25362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
25462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Script::PositionInfo info;
25562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (Script::GetPositionInfo(eval_from_script, script->GetEvalPosition(),
25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    &info, Script::NO_OFFSET)) {
25762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          builder.AppendCString(":");
25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
25962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Handle<String> str = isolate->factory()->NumberToString(
26062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              handle(Smi::FromInt(info.line + 1), isolate));
26162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          builder.AppendString(str);
26262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          builder.AppendCString(":");
26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          str = isolate->factory()->NumberToString(
26662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              handle(Smi::FromInt(info.column + 1), isolate));
26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          builder.AppendString(str);
26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
26962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else {
27062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        DCHECK(!eval_from_script->name()->IsString());
27162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        builder.AppendCString("unknown source");
27262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
27362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
27462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    builder.AppendCString(")");
27562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
27662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
27762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<String> result;
27862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String);
27962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return result;
28062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
28162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
28262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // namespace
28362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<Object> StackFrameBase::GetEvalOrigin() {
28562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!HasScript()) return isolate_->factory()->undefined_value();
28662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return FormatEvalOrigin(isolate_, GetScript()).ToHandleChecked();
28762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
28862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
28962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool StackFrameBase::IsEval() {
29062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return HasScript() &&
29162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch         GetScript()->compilation_type() == Script::COMPILATION_TYPE_EVAL;
29262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
29362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
294f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid JSStackFrame::FromFrameArray(Isolate* isolate, Handle<FrameArray> array,
295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  int frame_ix) {
296f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!array->IsWasmFrame(frame_ix));
297f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  isolate_ = isolate;
298f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  receiver_ = handle(array->Receiver(frame_ix), isolate);
299f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  function_ = handle(array->Function(frame_ix), isolate);
300f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  code_ = handle(array->Code(frame_ix), isolate);
301f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  offset_ = array->Offset(frame_ix)->value();
302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
303f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const int flags = array->Flags(frame_ix)->value();
304f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  force_constructor_ = (flags & FrameArray::kForceConstructor) != 0;
305f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  is_strict_ = (flags & FrameArray::kIsStrict) != 0;
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochJSStackFrame::JSStackFrame() {}
30962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochJSStackFrame::JSStackFrame(Isolate* isolate, Handle<Object> receiver,
311f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                           Handle<JSFunction> function,
312f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                           Handle<AbstractCode> code, int offset)
31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    : StackFrameBase(isolate),
314f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      receiver_(receiver),
315f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      function_(function),
316f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      code_(code),
317f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      offset_(offset),
318f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      force_constructor_(false),
319f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      is_strict_(false) {}
320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
321f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<Object> JSStackFrame::GetFunction() const {
322f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return Handle<Object>::cast(function_);
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
325f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<Object> JSStackFrame::GetFileName() {
326f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!HasScript()) return isolate_->factory()->null_value();
327f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return handle(GetScript()->name(), isolate_);
328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
330f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<Object> JSStackFrame::GetFunctionName() {
331f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<String> result = JSFunction::GetName(function_);
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (result->length() != 0) return result;
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
334f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (HasScript() &&
335f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      GetScript()->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return isolate_->factory()->eval_string();
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return isolate_->factory()->null_value();
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
341f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochnamespace {
342f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool CheckMethodName(Isolate* isolate, Handle<JSObject> obj, Handle<Name> name,
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     Handle<JSFunction> fun,
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     LookupIterator::Configuration config) {
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LookupIterator iter =
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LookupIterator::PropertyOrElement(isolate, obj, name, config);
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (iter.state() == LookupIterator::DATA) {
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return iter.GetDataValue().is_identical_to(fun);
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (iter.state() == LookupIterator::ACCESSOR) {
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Object> accessors = iter.GetAccessors();
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (accessors->IsAccessorPair()) {
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<AccessorPair> pair = Handle<AccessorPair>::cast(accessors);
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return pair->getter() == *fun || pair->setter() == *fun;
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
360c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochHandle<Object> ScriptNameOrSourceUrl(Handle<Script> script, Isolate* isolate) {
361c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Object* name_or_url = script->source_url();
362c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!name_or_url->IsString()) name_or_url = script->name();
363c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return handle(name_or_url, isolate);
364c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
365c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
366f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}  // namespace
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
368c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochHandle<Object> JSStackFrame::GetScriptNameOrSourceUrl() {
369c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!HasScript()) return isolate_->factory()->null_value();
370c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return ScriptNameOrSourceUrl(GetScript(), isolate_);
371c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
372c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
373f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<Object> JSStackFrame::GetMethodName() {
37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (receiver_->IsNullOrUndefined(isolate_)) {
375109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return isolate_->factory()->null_value();
376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
377f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
378109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Handle<JSReceiver> receiver =
379109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Object::ToObject(isolate_, receiver_).ToHandleChecked();
380109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!receiver->IsJSObject()) {
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return isolate_->factory()->null_value();
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<JSObject> obj = Handle<JSObject>::cast(receiver);
385f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> function_name(function_->shared()->name(), isolate_);
386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (function_name->IsString()) {
387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Handle<String> name = Handle<String>::cast(function_name);
3883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // ES2015 gives getters and setters name prefixes which must
3893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // be stripped to find the property name.
390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (name->IsUtf8EqualTo(CStrVector("get "), true) ||
391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        name->IsUtf8EqualTo(CStrVector("set "), true)) {
392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      name = isolate_->factory()->NewProperSubString(name, 4, name->length());
3933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
394f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (CheckMethodName(isolate_, obj, name, function_,
3953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                        LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR)) {
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return name;
3973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  HandleScope outer_scope(isolate_);
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> result;
40213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for (PrototypeIterator iter(isolate_, obj, kStartAtReceiver); !iter.IsAtEnd();
40313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch       iter.Advance()) {
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Object> current = PrototypeIterator::GetCurrent(iter);
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!current->IsJSObject()) break;
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<JSObject> current_obj = Handle<JSObject>::cast(current);
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (current_obj->IsAccessCheckNeeded()) break;
408bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Handle<FixedArray> keys =
409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        KeyAccumulator::GetOwnEnumPropertyKeys(isolate_, current_obj);
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < keys->length(); i++) {
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      HandleScope inner_scope(isolate_);
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!keys->get(i)->IsName()) continue;
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Handle<Name> name_key(Name::cast(keys->get(i)), isolate_);
414f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!CheckMethodName(isolate_, current_obj, name_key, function_,
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           LookupIterator::OWN_SKIP_INTERCEPTOR))
416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Return null in case of duplicates to avoid confusion.
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!result.is_null()) return isolate_->factory()->null_value();
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      result = inner_scope.CloseAndEscape(name_key);
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!result.is_null()) return outer_scope.CloseAndEscape(result);
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return isolate_->factory()->null_value();
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<Object> JSStackFrame::GetTypeName() {
428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TODO(jgruber): Check for strict/constructor here as in
429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // CallSitePrototypeGetThis.
430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
43162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (receiver_->IsNullOrUndefined(isolate_))
432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return isolate_->factory()->null_value();
433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (receiver_->IsJSProxy()) return isolate_->factory()->Proxy_string();
435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<JSReceiver> receiver_object =
437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Object::ToObject(isolate_, receiver_).ToHandleChecked();
438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return JSReceiver::GetConstructorName(receiver_object);
439f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
441f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint JSStackFrame::GetLineNumber() {
442f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_LE(0, GetPosition());
443f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (HasScript()) return Script::GetLineNumber(GetScript(), GetPosition()) + 1;
444f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return -1;
445f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
447f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint JSStackFrame::GetColumnNumber() {
448f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_LE(0, GetPosition());
449f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (HasScript()) {
450f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return Script::GetColumnNumber(GetScript(), GetPosition()) + 1;
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -1;
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
455f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool JSStackFrame::IsNative() {
456f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return HasScript() && GetScript()->type() == Script::TYPE_NATIVE;
457f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
458f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
459f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool JSStackFrame::IsToplevel() {
46062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return receiver_->IsJSGlobalProxy() || receiver_->IsNullOrUndefined(isolate_);
461f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
462f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
463f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool JSStackFrame::IsConstructor() {
464f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (force_constructor_) return true;
465f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!receiver_->IsJSObject()) return false;
466f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> constructor =
467f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      JSReceiver::GetDataProperty(Handle<JSObject>::cast(receiver_),
468f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  isolate_->factory()->constructor_string());
469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return constructor.is_identical_to(function_);
470f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
471f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
472f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochnamespace {
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
474f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool IsNonEmptyString(Handle<Object> object) {
475f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return (object->IsString() && String::cast(*object)->length() > 0);
476f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
477f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
478c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid AppendFileLocation(Isolate* isolate, StackFrameBase* call_site,
479f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        IncrementalStringBuilder* builder) {
480f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (call_site->IsNative()) {
481f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder->AppendCString("native");
482f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return;
483f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
484f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
485f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> file_name = call_site->GetScriptNameOrSourceUrl();
486f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!file_name->IsString() && call_site->IsEval()) {
487f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Handle<Object> eval_origin = call_site->GetEvalOrigin();
488f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK(eval_origin->IsString());
489f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder->AppendString(Handle<String>::cast(eval_origin));
490f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder->AppendCString(", ");  // Expecting source position to follow.
491f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
492f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (IsNonEmptyString(file_name)) {
494f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder->AppendString(Handle<String>::cast(file_name));
495f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Source code does not originate from a file and is not native, but we
497f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // can still get the source position inside the source string, e.g. in
498f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // an eval string.
499f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder->AppendCString("<anonymous>");
500f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
501f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int line_number = call_site->GetLineNumber();
503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (line_number != -1) {
504f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder->AppendCharacter(':');
505f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Handle<String> line_string = isolate->factory()->NumberToString(
506f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        handle(Smi::FromInt(line_number), isolate), isolate);
507f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder->AppendString(line_string);
508f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
509f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int column_number = call_site->GetColumnNumber();
510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (column_number != -1) {
511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      builder->AppendCharacter(':');
512f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Handle<String> column_string = isolate->factory()->NumberToString(
513f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          handle(Smi::FromInt(column_number), isolate), isolate);
514f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      builder->AppendString(column_string);
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint StringIndexOf(Isolate* isolate, Handle<String> subject,
520f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  Handle<String> pattern) {
521f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (pattern->length() > subject->length()) return -1;
522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return String::IndexOf(isolate, subject, pattern, 0);
523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Returns true iff
526f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// 1. the subject ends with '.' + pattern, or
527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// 2. subject == pattern.
528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool StringEndsWithMethodName(Isolate* isolate, Handle<String> subject,
529f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              Handle<String> pattern) {
530f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (String::Equals(subject, pattern)) return true;
531f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
532f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FlatStringReader subject_reader(isolate, String::Flatten(subject));
533f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FlatStringReader pattern_reader(isolate, String::Flatten(pattern));
534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
535f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int pattern_index = pattern_reader.length() - 1;
536f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int subject_index = subject_reader.length() - 1;
537f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (int i = 0; i <= pattern_reader.length(); i++) {  // Iterate over len + 1.
538f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (subject_index < 0) {
539f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return false;
540f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
541f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
542f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    const uc32 subject_char = subject_reader.Get(subject_index);
543f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (i == pattern_reader.length()) {
544f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (subject_char != '.') return false;
545f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else if (subject_char != pattern_reader.Get(pattern_index)) {
546f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return false;
547f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
548f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
549f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    pattern_index--;
550f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    subject_index--;
551f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
552f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
553f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return true;
554f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
555f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
556f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid AppendMethodCall(Isolate* isolate, JSStackFrame* call_site,
557f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      IncrementalStringBuilder* builder) {
558f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> type_name = call_site->GetTypeName();
559f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> method_name = call_site->GetMethodName();
560f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> function_name = call_site->GetFunctionName();
561f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
562f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (IsNonEmptyString(function_name)) {
563f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Handle<String> function_string = Handle<String>::cast(function_name);
564f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (IsNonEmptyString(type_name)) {
565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Handle<String> type_string = Handle<String>::cast(type_name);
566f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      bool starts_with_type_name =
567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          (StringIndexOf(isolate, function_string, type_string) == 0);
568f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!starts_with_type_name) {
569f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        builder->AppendString(type_string);
570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        builder->AppendCharacter('.');
571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
572f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder->AppendString(function_string);
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
575f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (IsNonEmptyString(method_name)) {
576f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Handle<String> method_string = Handle<String>::cast(method_name);
577f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!StringEndsWithMethodName(isolate, function_string, method_string)) {
578f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        builder->AppendCString(" [as ");
579f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        builder->AppendString(method_string);
580f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        builder->AppendCharacter(']');
581f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
582f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
583f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
584f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder->AppendString(Handle<String>::cast(type_name));
585f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder->AppendCharacter('.');
586f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (IsNonEmptyString(method_name)) {
587f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      builder->AppendString(Handle<String>::cast(method_name));
588f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
589f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      builder->AppendCString("<anonymous>");
590f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
591f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
594f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}  // namespace
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
596f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochMaybeHandle<String> JSStackFrame::ToString() {
597f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IncrementalStringBuilder builder(isolate_);
598f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
599f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> function_name = GetFunctionName();
600f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
601f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const bool is_toplevel = IsToplevel();
602f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const bool is_constructor = IsConstructor();
603f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const bool is_method_call = !(is_toplevel || is_constructor);
604f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
605f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (is_method_call) {
606f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AppendMethodCall(isolate_, this, &builder);
607f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else if (is_constructor) {
608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder.AppendCString("new ");
609f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (IsNonEmptyString(function_name)) {
610f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      builder.AppendString(Handle<String>::cast(function_name));
611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    } else {
612f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      builder.AppendCString("<anonymous>");
613f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
614f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else if (IsNonEmptyString(function_name)) {
615f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder.AppendString(Handle<String>::cast(function_name));
616f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
617f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    AppendFileLocation(isolate_, this, &builder);
618c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return builder.Finish();
619f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
620f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
621f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  builder.AppendCString(" (");
622f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AppendFileLocation(isolate_, this, &builder);
623f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  builder.AppendCString(")");
624f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
625c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return builder.Finish();
626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
628f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint JSStackFrame::GetPosition() const { return code_->SourcePosition(offset_); }
629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
630f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool JSStackFrame::HasScript() const {
631f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return function_->shared()->script()->IsScript();
632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<Script> JSStackFrame::GetScript() const {
635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return handle(Script::cast(function_->shared()->script()), isolate_);
636f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
63862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochWasmStackFrame::WasmStackFrame() {}
63962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
640f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid WasmStackFrame::FromFrameArray(Isolate* isolate, Handle<FrameArray> array,
641f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    int frame_ix) {
642c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // This function is called for both wasm and asm.js->wasm frames.
643c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK(array->IsWasmFrame(frame_ix) || array->IsAsmJsWasmFrame(frame_ix));
644f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  isolate_ = isolate;
645c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  wasm_instance_ = handle(array->WasmInstance(frame_ix), isolate);
646f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  wasm_func_index_ = array->WasmFunctionIndex(frame_ix)->value();
647f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  code_ = handle(array->Code(frame_ix), isolate);
648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  offset_ = array->Offset(frame_ix)->value();
649f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
650f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<Object> WasmStackFrame::GetFunction() const {
652f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> obj(Smi::FromInt(wasm_func_index_), isolate_);
653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return obj;
654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<Object> WasmStackFrame::GetFunctionName() {
657c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<Object> name;
658c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<WasmCompiledModule> compiled_module(
65962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Handle<WasmInstanceObject>::cast(wasm_instance_)->compiled_module(),
660c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      isolate_);
66162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!WasmCompiledModule::GetFunctionNameOrNull(isolate_, compiled_module,
66262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                 wasm_func_index_)
663c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch           .ToHandle(&name)) {
664c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    name = isolate_->factory()->null_value();
665c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
666c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return name;
667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochMaybeHandle<String> WasmStackFrame::ToString() {
670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  IncrementalStringBuilder builder(isolate_);
671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> name = GetFunctionName();
673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (name->IsNull(isolate_)) {
674f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder.AppendCString("<WASM UNNAMED>");
675f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  } else {
676f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK(name->IsString());
677f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    builder.AppendString(Handle<String>::cast(name));
678f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  builder.AppendCString(" (<WASM>[");
681f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Smi> ix(Smi::FromInt(wasm_func_index_), isolate_);
683f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  builder.AppendString(isolate_->factory()->NumberToString(ix));
684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  builder.AppendCString("]+");
686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
687f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> pos(Smi::FromInt(GetPosition()), isolate_);
688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  builder.AppendString(isolate_->factory()->NumberToString(pos));
689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  builder.AppendCString(")");
690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return builder.Finish();
692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochint WasmStackFrame::GetPosition() const {
69562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // TODO(wasm): Clean this up (bug 5007).
696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return (offset_ < 0) ? (-1 - offset_) : code_->SourcePosition(offset_);
697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochHandle<Object> WasmStackFrame::Null() const {
700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return isolate_->factory()->null_value();
701f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
70362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool WasmStackFrame::HasScript() const { return true; }
70462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
70562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochHandle<Script> WasmStackFrame::GetScript() const {
70662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return handle(
70762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      WasmInstanceObject::cast(*wasm_instance_)->compiled_module()->script(),
70862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      isolate_);
70962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
71062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
71162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochAsmJsWasmStackFrame::AsmJsWasmStackFrame() {}
71262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
71362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid AsmJsWasmStackFrame::FromFrameArray(Isolate* isolate,
71462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         Handle<FrameArray> array,
71562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         int frame_ix) {
71662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(array->IsAsmJsWasmFrame(frame_ix));
71762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  WasmStackFrame::FromFrameArray(isolate, array, frame_ix);
71862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  is_at_number_conversion_ =
71962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      array->Flags(frame_ix)->value() & FrameArray::kAsmJsAtNumberConversion;
72062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
72162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
722c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochHandle<Object> AsmJsWasmStackFrame::GetReceiver() const {
723c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return isolate_->global_proxy();
724c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
725c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
726c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochHandle<Object> AsmJsWasmStackFrame::GetFunction() const {
727c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // TODO(clemensh): Return lazily created JSFunction.
728c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return Null();
729c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
730c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
731c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochHandle<Object> AsmJsWasmStackFrame::GetFileName() {
732c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<Script> script =
733c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      wasm::GetScript(Handle<JSObject>::cast(wasm_instance_));
734c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(Script::TYPE_NORMAL, script->type());
735c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return handle(script->name(), isolate_);
736c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
737c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
738c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochHandle<Object> AsmJsWasmStackFrame::GetScriptNameOrSourceUrl() {
739c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<Script> script =
740c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      wasm::GetScript(Handle<JSObject>::cast(wasm_instance_));
741c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(Script::TYPE_NORMAL, script->type());
742c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return ScriptNameOrSourceUrl(script, isolate_);
743c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
744c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochint AsmJsWasmStackFrame::GetPosition() const {
746c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_LE(0, offset_);
747c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int byte_offset = code_->SourcePosition(offset_);
74862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Handle<WasmCompiledModule> compiled_module(
74962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      WasmInstanceObject::cast(*wasm_instance_)->compiled_module(), isolate_);
75062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK_LE(0, byte_offset);
75162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return WasmCompiledModule::GetAsmJsSourcePosition(
75262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      compiled_module, wasm_func_index_, static_cast<uint32_t>(byte_offset),
75362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      is_at_number_conversion_);
754c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
755c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
756c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochint AsmJsWasmStackFrame::GetLineNumber() {
757c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_LE(0, GetPosition());
758c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<Script> script =
759c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      wasm::GetScript(Handle<JSObject>::cast(wasm_instance_));
760c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(Script::TYPE_NORMAL, script->type());
761c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return Script::GetLineNumber(script, GetPosition()) + 1;
762c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
763c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
764c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochint AsmJsWasmStackFrame::GetColumnNumber() {
765c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_LE(0, GetPosition());
766c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<Script> script =
767c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      wasm::GetScript(Handle<JSObject>::cast(wasm_instance_));
768c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(Script::TYPE_NORMAL, script->type());
769c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return Script::GetColumnNumber(script, GetPosition()) + 1;
770c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
771c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
772c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochMaybeHandle<String> AsmJsWasmStackFrame::ToString() {
773c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // The string should look exactly as the respective javascript frame string.
774c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Keep this method in line to JSStackFrame::ToString().
775c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
776c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  IncrementalStringBuilder builder(isolate_);
777c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
778c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Handle<Object> function_name = GetFunctionName();
779c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
780c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (IsNonEmptyString(function_name)) {
781c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    builder.AppendString(Handle<String>::cast(function_name));
782c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    builder.AppendCString(" (");
783c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
784c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
785c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  AppendFileLocation(isolate_, this, &builder);
786c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
787c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (IsNonEmptyString(function_name)) builder.AppendCString(")");
788c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
789c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return builder.Finish();
790c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
791c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochFrameArrayIterator::FrameArrayIterator(Isolate* isolate,
793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                       Handle<FrameArray> array, int frame_ix)
794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    : isolate_(isolate), array_(array), next_frame_ix_(frame_ix) {}
795f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool FrameArrayIterator::HasNext() const {
797f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return (next_frame_ix_ < array_->FrameCount());
798f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
799f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
800f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid FrameArrayIterator::Next() { next_frame_ix_++; }
801f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
802f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochStackFrameBase* FrameArrayIterator::Frame() {
803f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(HasNext());
804f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const int flags = array_->Flags(next_frame_ix_)->value();
805c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  switch (flags & (FrameArray::kIsWasmFrame | FrameArray::kIsAsmJsWasmFrame)) {
806c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case 0:
807c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // JavaScript Frame.
808c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      js_frame_.FromFrameArray(isolate_, array_, next_frame_ix_);
809c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return &js_frame_;
810c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case FrameArray::kIsWasmFrame:
811c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Wasm Frame;
812c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      wasm_frame_.FromFrameArray(isolate_, array_, next_frame_ix_);
813c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return &wasm_frame_;
814c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case FrameArray::kIsAsmJsWasmFrame:
815c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Asm.js Wasm Frame:
816c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      asm_wasm_frame_.FromFrameArray(isolate_, array_, next_frame_ix_);
817c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return &asm_wasm_frame_;
818c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    default:
819c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      UNREACHABLE();
820c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return nullptr;
821f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace {
825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochMaybeHandle<Object> ConstructCallSite(Isolate* isolate,
827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                      Handle<FrameArray> frame_array,
828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                      int frame_index) {
829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<JSFunction> target =
830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      handle(isolate->native_context()->callsite_function(), isolate);
831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
832f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<JSObject> obj;
833f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, JSObject::New(target, target),
834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                             Object);
835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
836f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Symbol> key = isolate->factory()->call_site_frame_array_symbol();
837f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  RETURN_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
838f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   obj, key, frame_array, DONT_ENUM),
839f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      Object);
840f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
841f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  key = isolate->factory()->call_site_frame_index_symbol();
842f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Object> value(Smi::FromInt(frame_index), isolate);
843f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  RETURN_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
844f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   obj, key, value, DONT_ENUM),
845f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      Object);
846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
847f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return obj;
848f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
849f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
850f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Convert the raw frames as written by Isolate::CaptureSimpleStackTrace into
851f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// a JSArray of JSCallSite objects.
852f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochMaybeHandle<JSArray> GetStackFrames(Isolate* isolate,
853f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    Handle<FrameArray> elems) {
854f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const int frame_count = elems->FrameCount();
855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
856f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<FixedArray> frames = isolate->factory()->NewFixedArray(frame_count);
857f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (int i = 0; i < frame_count; i++) {
858f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Handle<Object> site;
859f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ASSIGN_RETURN_ON_EXCEPTION(isolate, site,
860f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               ConstructCallSite(isolate, elems, i), JSArray);
861f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    frames->set(i, *site);
862f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return isolate->factory()->NewJSArrayWithElements(frames);
865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochMaybeHandle<Object> AppendErrorString(Isolate* isolate, Handle<Object> error,
868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                      IncrementalStringBuilder* builder) {
869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  MaybeHandle<String> err_str =
870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ErrorUtils::ToString(isolate, Handle<Object>::cast(error));
871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (err_str.is_null()) {
872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Error.toString threw. Try to return a string representation of the thrown
873f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // exception instead.
874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK(isolate->has_pending_exception());
876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Handle<Object> pending_exception =
877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        handle(isolate->pending_exception(), isolate);
878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    isolate->clear_pending_exception();
879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
880f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    err_str = ErrorUtils::ToString(isolate, pending_exception);
881f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (err_str.is_null()) {
882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Formatting the thrown exception threw again, give up.
883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DCHECK(isolate->has_pending_exception());
884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate->clear_pending_exception();
885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      builder->AppendCString("<error>");
887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {
888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Formatted thrown exception successfully, append it.
889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      builder->AppendCString("<error: ");
890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      builder->AppendString(err_str.ToHandleChecked());
891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      builder->AppendCharacter('>');
892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    builder->AppendString(err_str.ToHandleChecked());
895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
896f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return error;
898f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
899f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass PrepareStackTraceScope {
901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit PrepareStackTraceScope(Isolate* isolate) : isolate_(isolate) {
903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK(!isolate_->formatting_stack_trace());
904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    isolate_->set_formatting_stack_trace(true);
905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ~PrepareStackTraceScope() { isolate_->set_formatting_stack_trace(false); }
908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Isolate* isolate_;
911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DISALLOW_COPY_AND_ASSIGN(PrepareStackTraceScope);
913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
915f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace
916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
918f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochMaybeHandle<Object> ErrorUtils::FormatStackTrace(Isolate* isolate,
919f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                 Handle<JSObject> error,
920f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                 Handle<Object> raw_stack) {
921f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(raw_stack->IsJSArray());
922f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<JSArray> raw_stack_array = Handle<JSArray>::cast(raw_stack);
923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
924f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(raw_stack_array->elements()->IsFixedArray());
925f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<FrameArray> elems(FrameArray::cast(raw_stack_array->elements()));
926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // If there's a user-specified "prepareStackFrames" function, call it on the
928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // frames and use its result.
929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<JSFunction> global_error = isolate->error_function();
931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> prepare_stack_trace;
932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION(
933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate, prepare_stack_trace,
934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      JSFunction::GetProperty(isolate, global_error, "prepareStackTrace"),
935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Object);
936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
937f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const bool in_recursion = isolate->formatting_stack_trace();
938f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (prepare_stack_trace->IsJSFunction() && !in_recursion) {
939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    PrepareStackTraceScope scope(isolate);
940f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
941f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Handle<JSArray> sites;
942f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ASSIGN_RETURN_ON_EXCEPTION(isolate, sites, GetStackFrames(isolate, elems),
943f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               Object);
944f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
945f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    const int argc = 2;
946f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ScopedVector<Handle<Object>> argv(argc);
947f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
948f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    argv[0] = error;
949f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    argv[1] = sites;
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Object> result;
952f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ASSIGN_RETURN_ON_EXCEPTION(
953f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        isolate, result, Execution::Call(isolate, prepare_stack_trace,
954f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         global_error, argc, argv.start()),
955f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Object);
956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
957f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return result;
958f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
959f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
960f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Otherwise, run our internal formatting logic.
961f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
962f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IncrementalStringBuilder builder(isolate);
963f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
964f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RETURN_ON_EXCEPTION(isolate, AppendErrorString(isolate, error, &builder),
965f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      Object);
966f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
967f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (FrameArrayIterator it(isolate, elems); it.HasNext(); it.Next()) {
968f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    builder.AppendCString("\n    at ");
969f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
970f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    StackFrameBase* frame = it.Frame();
971f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    MaybeHandle<String> maybe_frame_string = frame->ToString();
972f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (maybe_frame_string.is_null()) {
973f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // CallSite.toString threw. Try to return a string representation of the
974f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // thrown exception instead.
975f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
976f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DCHECK(isolate->has_pending_exception());
977f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Handle<Object> pending_exception =
978f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          handle(isolate->pending_exception(), isolate);
979f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate->clear_pending_exception();
980f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
981f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      maybe_frame_string = ErrorUtils::ToString(isolate, pending_exception);
982f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (maybe_frame_string.is_null()) {
983f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // Formatting the thrown exception threw again, give up.
984f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        builder.AppendCString("<error>");
986f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
987f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // Formatted thrown exception successfully, append it.
988f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        builder.AppendCString("<error: ");
989f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        builder.AppendString(maybe_frame_string.ToHandleChecked());
990f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        builder.AppendCString("<error>");
991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
992f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {
993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // CallSite.toString completed without throwing.
994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      builder.AppendString(maybe_frame_string.ToHandleChecked());
995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
998c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return builder.Finish();
999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochHandle<String> MessageTemplate::FormatMessage(Isolate* isolate,
1002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              int template_index,
1003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              Handle<Object> arg) {
1004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Factory* factory = isolate->factory();
1005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> result_string = Object::NoSideEffectsToString(isolate, arg);
1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaybeHandle<String> maybe_result_string = MessageTemplate::FormatMessage(
1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      template_index, result_string, factory->empty_string(),
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      factory->empty_string());
1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!maybe_result_string.ToHandle(&result_string)) {
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("<error>"));
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // A string that has been obtained from JS code in this way is
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // likely to be a complicated ConsString of some sort.  We flatten it
1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // here to improve the efficiency of converting it to a C string and
1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // other operations that are likely to take place (see GetLocalizedMessage
1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for example).
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return String::Flatten(result_string);
1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* MessageTemplate::TemplateString(int template_index) {
1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (template_index) {
1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define CASE(NAME, STRING) \
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  case k##NAME:            \
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return STRING;
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MESSAGE_TEMPLATES(CASE)
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef CASE
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kLastMessage:
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return NULL;
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMaybeHandle<String> MessageTemplate::FormatMessage(int template_index,
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   Handle<String> arg0,
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   Handle<String> arg1,
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   Handle<String> arg2) {
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate = arg0->GetIsolate();
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const char* template_string = TemplateString(template_index);
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (template_string == NULL) {
1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    isolate->ThrowIllegalOperation();
1043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return MaybeHandle<String>();
1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IncrementalStringBuilder builder(isolate);
1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unsigned int i = 0;
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<String> args[] = {arg0, arg1, arg2};
1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const char* c = template_string; *c != '\0'; c++) {
1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (*c == '%') {
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // %% results in verbatim %.
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (*(c + 1) == '%') {
1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        c++;
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        builder.AppendCharacter('%');
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(i < arraysize(args));
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<String> arg = args[i++];
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        builder.AppendString(arg);
1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      builder.AppendCharacter(*c);
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return builder.Finish();
1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1069f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochMaybeHandle<Object> ErrorUtils::Construct(
1070f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Isolate* isolate, Handle<JSFunction> target, Handle<Object> new_target,
1071f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Handle<Object> message, FrameSkipMode mode, Handle<Object> caller,
1072f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    bool suppress_detailed_trace) {
1073f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 1. If NewTarget is undefined, let newTarget be the active function object,
1074f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // else let newTarget be NewTarget.
1075f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1076f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<JSReceiver> new_target_recv =
1077f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      new_target->IsJSReceiver() ? Handle<JSReceiver>::cast(new_target)
1078f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 : Handle<JSReceiver>::cast(target);
1079f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1080f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%ErrorPrototype%",
1081f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //    « [[ErrorData]] »).
1082f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<JSObject> err;
1083f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION(isolate, err,
1084f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             JSObject::New(target, new_target_recv), Object);
1085f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1086f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 3. If message is not undefined, then
1087f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //  a. Let msg be ? ToString(message).
1088f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //  b. Let msgDesc be the PropertyDescriptor{[[Value]]: msg, [[Writable]]:
1089f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //     true, [[Enumerable]]: false, [[Configurable]]: true}.
1090f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //  c. Perform ! DefinePropertyOrThrow(O, "message", msgDesc).
1091f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 4. Return O.
1092f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1093f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!message->IsUndefined(isolate)) {
1094f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Handle<String> msg_string;
1095f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ASSIGN_RETURN_ON_EXCEPTION(isolate, msg_string,
1096f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               Object::ToString(isolate, message), Object);
1097f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    RETURN_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
1098f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     err, isolate->factory()->message_string(),
1099f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     msg_string, DONT_ENUM),
1100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        Object);
1101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Optionally capture a more detailed stack trace for the message.
1104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!suppress_detailed_trace) {
1105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    RETURN_ON_EXCEPTION(isolate, isolate->CaptureAndSetDetailedStackTrace(err),
1106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        Object);
1107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Capture a simple stack trace for the stack property.
1110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RETURN_ON_EXCEPTION(isolate,
1111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      isolate->CaptureAndSetSimpleStackTrace(err, mode, caller),
1112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                      Object);
1113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return err;
1115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace {
1118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochMaybeHandle<String> GetStringPropertyOrDefault(Isolate* isolate,
1120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                               Handle<JSReceiver> recv,
1121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                               Handle<String> key,
1122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                               Handle<String> default_str) {
1123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> obj;
1124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION(isolate, obj, JSObject::GetProperty(recv, key),
1125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             String);
1126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> str;
1128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (obj->IsUndefined(isolate)) {
1129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    str = default_str;
1130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
1131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ASSIGN_RETURN_ON_EXCEPTION(isolate, str, Object::ToString(isolate, obj),
1132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               String);
1133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return str;
1136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace
1139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ES6 section 19.5.3.4 Error.prototype.toString ( )
1141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochMaybeHandle<String> ErrorUtils::ToString(Isolate* isolate,
1142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         Handle<Object> receiver) {
1143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 1. Let O be the this value.
1144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 2. If Type(O) is not Object, throw a TypeError exception.
1145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!receiver->IsJSReceiver()) {
1146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return isolate->Throw<String>(isolate->factory()->NewTypeError(
1147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        MessageTemplate::kIncompatibleMethodReceiver,
1148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        isolate->factory()->NewStringFromAsciiChecked(
1149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            "Error.prototype.toString"),
1150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        receiver));
1151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<JSReceiver> recv = Handle<JSReceiver>::cast(receiver);
1153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 3. Let name be ? Get(O, "name").
1155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 4. If name is undefined, let name be "Error"; otherwise let name be
1156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // ? ToString(name).
1157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> name_key = isolate->factory()->name_string();
1158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> name_default = isolate->factory()->Error_string();
1159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> name;
1160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION(
1161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate, name,
1162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      GetStringPropertyOrDefault(isolate, recv, name_key, name_default),
1163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      String);
1164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 5. Let msg be ? Get(O, "message").
1166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 6. If msg is undefined, let msg be the empty String; otherwise let msg be
1167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // ? ToString(msg).
1168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> msg_key = isolate->factory()->message_string();
1169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> msg_default = isolate->factory()->empty_string();
1170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> msg;
1171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION(
1172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      isolate, msg,
1173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      GetStringPropertyOrDefault(isolate, recv, msg_key, msg_default), String);
1174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 7. If name is the empty String, return msg.
1176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 8. If msg is the empty String, return name.
1177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (name->length() == 0) return msg;
1178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (msg->length() == 0) return name;
1179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // 9. Return the result of concatenating name, the code unit 0x003A (COLON),
1181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // the code unit 0x0020 (SPACE), and msg.
1182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IncrementalStringBuilder builder(isolate);
1183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  builder.AppendString(name);
1184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  builder.AppendCString(": ");
1185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  builder.AppendString(msg);
1186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> result;
1188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String);
1189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return result;
1190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace {
1193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochHandle<String> FormatMessage(Isolate* isolate, int template_index,
1195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             Handle<Object> arg0, Handle<Object> arg1,
1196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             Handle<Object> arg2) {
1197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> arg0_str = Object::NoSideEffectsToString(isolate, arg0);
1198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> arg1_str = Object::NoSideEffectsToString(isolate, arg1);
1199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> arg2_str = Object::NoSideEffectsToString(isolate, arg2);
1200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  isolate->native_context()->IncrementErrorsThrown();
1202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> msg;
1204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!MessageTemplate::FormatMessage(template_index, arg0_str, arg1_str,
1205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                      arg2_str)
1206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch           .ToHandle(&msg)) {
1207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK(isolate->has_pending_exception());
1208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    isolate->clear_pending_exception();
1209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return isolate->factory()->NewStringFromAsciiChecked("<error>");
1210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return msg;
1213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace
1216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static
1218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochMaybeHandle<Object> ErrorUtils::MakeGenericError(
1219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Isolate* isolate, Handle<JSFunction> constructor, int template_index,
1220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Handle<Object> arg0, Handle<Object> arg1, Handle<Object> arg2,
1221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    FrameSkipMode mode) {
1222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (FLAG_clear_exceptions_on_js_entry) {
1223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // This function used to be implemented in JavaScript, and JSEntryStub
1224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // clears
1225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // any pending exceptions - so whenever we'd call this from C++, pending
1226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // exceptions would be cleared. Preserve this behavior.
1227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    isolate->clear_pending_exception();
1228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(mode != SKIP_UNTIL_SEEN);
1231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<Object> no_caller;
1233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> msg = FormatMessage(isolate, template_index, arg0, arg1, arg2);
1234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return ErrorUtils::Construct(isolate, constructor, constructor, msg, mode,
1235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                               no_caller, false);
1236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
1240