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