1// Copyright 2012 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// ------------------------------------------------------------------- 6 7(function(global, utils) { 8 9%CheckIsBootstrapping(); 10 11// ------------------------------------------------------------------- 12// Imports 13 14var ArrayJoin; 15var Bool16x8ToString; 16var Bool32x4ToString; 17var Bool8x16ToString; 18var callSiteReceiverSymbol = 19 utils.ImportNow("call_site_receiver_symbol"); 20var callSiteFunctionSymbol = 21 utils.ImportNow("call_site_function_symbol"); 22var callSitePositionSymbol = 23 utils.ImportNow("call_site_position_symbol"); 24var callSiteStrictSymbol = 25 utils.ImportNow("call_site_strict_symbol"); 26var callSiteWasmObjectSymbol = 27 utils.ImportNow("call_site_wasm_obj_symbol"); 28var callSiteWasmFunctionIndexSymbol = 29 utils.ImportNow("call_site_wasm_func_index_symbol"); 30var Float32x4ToString; 31var formattedStackTraceSymbol = 32 utils.ImportNow("formatted_stack_trace_symbol"); 33var GlobalObject = global.Object; 34var Int16x8ToString; 35var Int32x4ToString; 36var Int8x16ToString; 37var InternalArray = utils.InternalArray; 38var internalErrorSymbol = utils.ImportNow("internal_error_symbol"); 39var ObjectHasOwnProperty; 40var ObjectToString = utils.ImportNow("object_to_string"); 41var Script = utils.ImportNow("Script"); 42var stackTraceSymbol = utils.ImportNow("stack_trace_symbol"); 43var StringIndexOf; 44var SymbolToString; 45var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); 46var Uint16x8ToString; 47var Uint32x4ToString; 48var Uint8x16ToString; 49 50utils.Import(function(from) { 51 ArrayJoin = from.ArrayJoin; 52 Bool16x8ToString = from.Bool16x8ToString; 53 Bool32x4ToString = from.Bool32x4ToString; 54 Bool8x16ToString = from.Bool8x16ToString; 55 Float32x4ToString = from.Float32x4ToString; 56 Int16x8ToString = from.Int16x8ToString; 57 Int32x4ToString = from.Int32x4ToString; 58 Int8x16ToString = from.Int8x16ToString; 59 ObjectHasOwnProperty = from.ObjectHasOwnProperty; 60 StringIndexOf = from.StringIndexOf; 61 SymbolToString = from.SymbolToString; 62 Uint16x8ToString = from.Uint16x8ToString; 63 Uint32x4ToString = from.Uint32x4ToString; 64 Uint8x16ToString = from.Uint8x16ToString; 65}); 66 67// ------------------------------------------------------------------- 68 69var GlobalError; 70var GlobalTypeError; 71var GlobalRangeError; 72var GlobalURIError; 73var GlobalSyntaxError; 74var GlobalReferenceError; 75var GlobalEvalError; 76 77 78function NoSideEffectsObjectToString() { 79 if (IS_UNDEFINED(this)) return "[object Undefined]"; 80 if (IS_NULL(this)) return "[object Null]"; 81 var O = TO_OBJECT(this); 82 var builtinTag = %_ClassOf(O); 83 var tag = %GetDataProperty(O, toStringTagSymbol); 84 if (!IS_STRING(tag)) { 85 tag = builtinTag; 86 } 87 return `[object ${tag}]`; 88} 89 90function IsErrorObject(obj) { 91 return HAS_PRIVATE(obj, stackTraceSymbol); 92} 93 94function NoSideEffectsErrorToString() { 95 var name = %GetDataProperty(this, "name"); 96 var message = %GetDataProperty(this, "message"); 97 name = IS_UNDEFINED(name) ? "Error" : NoSideEffectsToString(name); 98 message = IS_UNDEFINED(message) ? "" : NoSideEffectsToString(message); 99 if (name == "") return message; 100 if (message == "") return name; 101 return `${name}: ${message}`; 102} 103 104function NoSideEffectsToString(obj) { 105 if (IS_STRING(obj)) return obj; 106 if (IS_NUMBER(obj)) return %_NumberToString(obj); 107 if (IS_BOOLEAN(obj)) return obj ? 'true' : 'false'; 108 if (IS_UNDEFINED(obj)) return 'undefined'; 109 if (IS_NULL(obj)) return 'null'; 110 if (IS_FUNCTION(obj)) { 111 var str = %FunctionToString(obj); 112 if (str.length > 128) { 113 str = %_SubString(str, 0, 111) + "...<omitted>..." + 114 %_SubString(str, str.length - 2, str.length); 115 } 116 return str; 117 } 118 if (IS_SYMBOL(obj)) return %_Call(SymbolToString, obj); 119 if (IS_SIMD_VALUE(obj)) { 120 switch (typeof(obj)) { 121 case 'float32x4': return %_Call(Float32x4ToString, obj); 122 case 'int32x4': return %_Call(Int32x4ToString, obj); 123 case 'int16x8': return %_Call(Int16x8ToString, obj); 124 case 'int8x16': return %_Call(Int8x16ToString, obj); 125 case 'uint32x4': return %_Call(Uint32x4ToString, obj); 126 case 'uint16x8': return %_Call(Uint16x8ToString, obj); 127 case 'uint8x16': return %_Call(Uint8x16ToString, obj); 128 case 'bool32x4': return %_Call(Bool32x4ToString, obj); 129 case 'bool16x8': return %_Call(Bool16x8ToString, obj); 130 case 'bool8x16': return %_Call(Bool8x16ToString, obj); 131 } 132 } 133 134 if (IS_RECEIVER(obj)) { 135 // When internally formatting error objects, use a side-effects-free version 136 // of Error.prototype.toString independent of the actually installed 137 // toString method. 138 if (IsErrorObject(obj) || 139 %GetDataProperty(obj, "toString") === ErrorToString) { 140 return %_Call(NoSideEffectsErrorToString, obj); 141 } 142 143 if (%GetDataProperty(obj, "toString") === ObjectToString) { 144 var constructor = %GetDataProperty(obj, "constructor"); 145 if (IS_FUNCTION(constructor)) { 146 var constructor_name = %FunctionGetName(constructor); 147 if (constructor_name != "") return `#<${constructor_name}>`; 148 } 149 } 150 } 151 152 return %_Call(NoSideEffectsObjectToString, obj); 153} 154 155 156function MakeGenericError(constructor, type, arg0, arg1, arg2) { 157 var error = new constructor(FormatMessage(type, arg0, arg1, arg2)); 158 error[internalErrorSymbol] = true; 159 return error; 160} 161 162 163/** 164 * Set up the Script function and constructor. 165 */ 166%FunctionSetInstanceClassName(Script, 'Script'); 167%AddNamedProperty(Script.prototype, 'constructor', Script, 168 DONT_ENUM | DONT_DELETE | READ_ONLY); 169%SetCode(Script, function(x) { 170 // Script objects can only be created by the VM. 171 throw MakeError(kUnsupported); 172}); 173 174 175// Helper functions; called from the runtime system. 176function FormatMessage(type, arg0, arg1, arg2) { 177 var arg0 = NoSideEffectsToString(arg0); 178 var arg1 = NoSideEffectsToString(arg1); 179 var arg2 = NoSideEffectsToString(arg2); 180 try { 181 return %FormatMessageString(type, arg0, arg1, arg2); 182 } catch (e) { 183 return "<error>"; 184 } 185} 186 187 188function GetLineNumber(message) { 189 var start_position = %MessageGetStartPosition(message); 190 if (start_position == -1) return kNoLineNumberInfo; 191 var script = %MessageGetScript(message); 192 var location = script.locationFromPosition(start_position, true); 193 if (location == null) return kNoLineNumberInfo; 194 return location.line + 1; 195} 196 197 198//Returns the offset of the given position within the containing line. 199function GetColumnNumber(message) { 200 var script = %MessageGetScript(message); 201 var start_position = %MessageGetStartPosition(message); 202 var location = script.locationFromPosition(start_position, true); 203 if (location == null) return -1; 204 return location.column; 205} 206 207 208// Returns the source code line containing the given source 209// position, or the empty string if the position is invalid. 210function GetSourceLine(message) { 211 var script = %MessageGetScript(message); 212 var start_position = %MessageGetStartPosition(message); 213 var location = script.locationFromPosition(start_position, true); 214 if (location == null) return ""; 215 return location.sourceText; 216} 217 218 219/** 220 * Get information on a specific source position. 221 * Returns an object with the following following properties: 222 * script : script object for the source 223 * line : source line number 224 * column : source column within the line 225 * position : position within the source 226 * sourceText : a string containing the current line 227 * @param {number} position The source position 228 * @param {boolean} include_resource_offset Set to true to have the resource 229 * offset added to the location 230 * @return If line is negative or not in the source null is returned. 231 */ 232function ScriptLocationFromPosition(position, 233 include_resource_offset) { 234 return %ScriptPositionInfo(this, position, !!include_resource_offset); 235} 236 237 238/** 239 * If sourceURL comment is available returns sourceURL comment contents. 240 * Otherwise, script name is returned. See 241 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt 242 * and Source Map Revision 3 proposal for details on using //# sourceURL and 243 * deprecated //@ sourceURL comment to identify scripts that don't have name. 244 * 245 * @return {?string} script name if present, value for //# sourceURL comment or 246 * deprecated //@ sourceURL comment otherwise. 247 */ 248function ScriptNameOrSourceURL() { 249 if (this.source_url) return this.source_url; 250 return this.name; 251} 252 253 254utils.SetUpLockedPrototype(Script, [ 255 "source", 256 "name", 257 "source_url", 258 "source_mapping_url", 259 "line_offset", 260 "column_offset" 261 ], [ 262 "locationFromPosition", ScriptLocationFromPosition, 263 "nameOrSourceURL", ScriptNameOrSourceURL, 264 ] 265); 266 267 268function GetStackTraceLine(recv, fun, pos, isGlobal) { 269 return new CallSite(recv, fun, pos, false).toString(); 270} 271 272// ---------------------------------------------------------------------------- 273// Error implementation 274 275function CallSite(receiver, fun, pos, strict_mode) { 276 // For wasm frames, receiver is the wasm object and fun is the function index 277 // instead of an actual function. 278 if (!IS_FUNCTION(fun) && !%IsWasmObject(receiver)) { 279 throw MakeTypeError(kCallSiteExpectsFunction, typeof receiver, typeof fun); 280 } 281 282 if (IS_UNDEFINED(new.target)) { 283 return new CallSite(receiver, fun, pos, strict_mode); 284 } 285 286 if (IS_FUNCTION(fun)) { 287 SET_PRIVATE(this, callSiteReceiverSymbol, receiver); 288 SET_PRIVATE(this, callSiteFunctionSymbol, fun); 289 } else { 290 SET_PRIVATE(this, callSiteWasmObjectSymbol, receiver); 291 SET_PRIVATE(this, callSiteWasmFunctionIndexSymbol, TO_UINT32(fun)); 292 } 293 SET_PRIVATE(this, callSitePositionSymbol, TO_INT32(pos)); 294 SET_PRIVATE(this, callSiteStrictSymbol, TO_BOOLEAN(strict_mode)); 295} 296 297function CheckCallSite(obj, name) { 298 if (!IS_RECEIVER(obj) || !HAS_PRIVATE(obj, callSitePositionSymbol)) { 299 throw MakeTypeError(kCallSiteMethod, name); 300 } 301} 302 303function CallSiteGetThis() { 304 CheckCallSite(this, "getThis"); 305 return GET_PRIVATE(this, callSiteStrictSymbol) 306 ? UNDEFINED : GET_PRIVATE(this, callSiteReceiverSymbol); 307} 308 309function CallSiteGetFunction() { 310 CheckCallSite(this, "getFunction"); 311 return GET_PRIVATE(this, callSiteStrictSymbol) 312 ? UNDEFINED : GET_PRIVATE(this, callSiteFunctionSymbol); 313} 314 315function CallSiteGetPosition() { 316 CheckCallSite(this, "getPosition"); 317 return GET_PRIVATE(this, callSitePositionSymbol); 318} 319 320function CallSiteGetTypeName() { 321 CheckCallSite(this, "getTypeName"); 322 return GetTypeName(GET_PRIVATE(this, callSiteReceiverSymbol), false); 323} 324 325function CallSiteIsToplevel() { 326 CheckCallSite(this, "isTopLevel"); 327 return %CallSiteIsToplevelRT(this); 328} 329 330function CallSiteIsEval() { 331 CheckCallSite(this, "isEval"); 332 return %CallSiteIsEvalRT(this); 333} 334 335function CallSiteGetEvalOrigin() { 336 CheckCallSite(this, "getEvalOrigin"); 337 var script = %FunctionGetScript(GET_PRIVATE(this, callSiteFunctionSymbol)); 338 return FormatEvalOrigin(script); 339} 340 341function CallSiteGetScriptNameOrSourceURL() { 342 CheckCallSite(this, "getScriptNameOrSourceURL"); 343 return %CallSiteGetScriptNameOrSourceUrlRT(this); 344} 345 346function CallSiteGetFunctionName() { 347 // See if the function knows its own name 348 CheckCallSite(this, "getFunctionName"); 349 return %CallSiteGetFunctionNameRT(this); 350} 351 352function CallSiteGetMethodName() { 353 // See if we can find a unique property on the receiver that holds 354 // this function. 355 CheckCallSite(this, "getMethodName"); 356 return %CallSiteGetMethodNameRT(this); 357} 358 359function CallSiteGetFileName() { 360 CheckCallSite(this, "getFileName"); 361 return %CallSiteGetFileNameRT(this); 362} 363 364function CallSiteGetLineNumber() { 365 if (HAS_PRIVATE(this, callSiteWasmObjectSymbol)) { 366 return GET_PRIVATE(this, callSiteWasmFunctionIndexSymbol); 367 } 368 CheckCallSite(this, "getLineNumber"); 369 return %CallSiteGetLineNumberRT(this); 370} 371 372function CallSiteGetColumnNumber() { 373 CheckCallSite(this, "getColumnNumber"); 374 return %CallSiteGetColumnNumberRT(this); 375} 376 377function CallSiteIsNative() { 378 CheckCallSite(this, "isNative"); 379 return %CallSiteIsNativeRT(this); 380} 381 382function CallSiteIsConstructor() { 383 CheckCallSite(this, "isConstructor"); 384 return %CallSiteIsConstructorRT(this); 385} 386 387function CallSiteToString() { 388 if (HAS_PRIVATE(this, callSiteWasmObjectSymbol)) { 389 var funName = this.getFunctionName(); 390 var funcIndex = GET_PRIVATE(this, callSiteWasmFunctionIndexSymbol); 391 var pos = this.getPosition(); 392 if (IS_NULL(funName)) funName = "<WASM UNNAMED>"; 393 return funName + " (<WASM>[" + funcIndex + "]+" + pos + ")"; 394 } 395 396 var fileName; 397 var fileLocation = ""; 398 if (this.isNative()) { 399 fileLocation = "native"; 400 } else { 401 fileName = this.getScriptNameOrSourceURL(); 402 if (!fileName && this.isEval()) { 403 fileLocation = this.getEvalOrigin(); 404 fileLocation += ", "; // Expecting source position to follow. 405 } 406 407 if (fileName) { 408 fileLocation += fileName; 409 } else { 410 // Source code does not originate from a file and is not native, but we 411 // can still get the source position inside the source string, e.g. in 412 // an eval string. 413 fileLocation += "<anonymous>"; 414 } 415 var lineNumber = this.getLineNumber(); 416 if (lineNumber != null) { 417 fileLocation += ":" + lineNumber; 418 var columnNumber = this.getColumnNumber(); 419 if (columnNumber) { 420 fileLocation += ":" + columnNumber; 421 } 422 } 423 } 424 425 var line = ""; 426 var functionName = this.getFunctionName(); 427 var addSuffix = true; 428 var isConstructor = this.isConstructor(); 429 var isMethodCall = !(this.isToplevel() || isConstructor); 430 if (isMethodCall) { 431 var typeName = GetTypeName(GET_PRIVATE(this, callSiteReceiverSymbol), true); 432 var methodName = this.getMethodName(); 433 if (functionName) { 434 if (typeName && %_Call(StringIndexOf, functionName, typeName) != 0) { 435 line += typeName + "."; 436 } 437 line += functionName; 438 if (methodName && 439 (%_Call(StringIndexOf, functionName, "." + methodName) != 440 functionName.length - methodName.length - 1)) { 441 line += " [as " + methodName + "]"; 442 } 443 } else { 444 line += typeName + "." + (methodName || "<anonymous>"); 445 } 446 } else if (isConstructor) { 447 line += "new " + (functionName || "<anonymous>"); 448 } else if (functionName) { 449 line += functionName; 450 } else { 451 line += fileLocation; 452 addSuffix = false; 453 } 454 if (addSuffix) { 455 line += " (" + fileLocation + ")"; 456 } 457 return line; 458} 459 460utils.SetUpLockedPrototype(CallSite, ["receiver", "fun", "pos"], [ 461 "getThis", CallSiteGetThis, 462 "getTypeName", CallSiteGetTypeName, 463 "isToplevel", CallSiteIsToplevel, 464 "isEval", CallSiteIsEval, 465 "getEvalOrigin", CallSiteGetEvalOrigin, 466 "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL, 467 "getFunction", CallSiteGetFunction, 468 "getFunctionName", CallSiteGetFunctionName, 469 "getMethodName", CallSiteGetMethodName, 470 "getFileName", CallSiteGetFileName, 471 "getLineNumber", CallSiteGetLineNumber, 472 "getColumnNumber", CallSiteGetColumnNumber, 473 "isNative", CallSiteIsNative, 474 "getPosition", CallSiteGetPosition, 475 "isConstructor", CallSiteIsConstructor, 476 "toString", CallSiteToString 477]); 478 479 480function FormatEvalOrigin(script) { 481 var sourceURL = script.nameOrSourceURL(); 482 if (sourceURL) { 483 return sourceURL; 484 } 485 486 var eval_origin = "eval at "; 487 if (script.eval_from_function_name) { 488 eval_origin += script.eval_from_function_name; 489 } else { 490 eval_origin += "<anonymous>"; 491 } 492 493 var eval_from_script = script.eval_from_script; 494 if (eval_from_script) { 495 if (eval_from_script.compilation_type == COMPILATION_TYPE_EVAL) { 496 // eval script originated from another eval. 497 eval_origin += " (" + FormatEvalOrigin(eval_from_script) + ")"; 498 } else { 499 // eval script originated from "real" source. 500 if (eval_from_script.name) { 501 eval_origin += " (" + eval_from_script.name; 502 var location = eval_from_script.locationFromPosition( 503 script.eval_from_script_position, true); 504 if (location) { 505 eval_origin += ":" + (location.line + 1); 506 eval_origin += ":" + (location.column + 1); 507 } 508 eval_origin += ")"; 509 } else { 510 eval_origin += " (unknown source)"; 511 } 512 } 513 } 514 515 return eval_origin; 516} 517 518 519function FormatErrorString(error) { 520 try { 521 return %_Call(ErrorToString, error); 522 } catch (e) { 523 try { 524 return "<error: " + e + ">"; 525 } catch (ee) { 526 return "<error>"; 527 } 528 } 529} 530 531 532function GetStackFrames(raw_stack) { 533 var internal_raw_stack = new InternalArray(); 534 %MoveArrayContents(raw_stack, internal_raw_stack); 535 var frames = new InternalArray(); 536 var sloppy_frames = internal_raw_stack[0]; 537 for (var i = 1; i < internal_raw_stack.length; i += 4) { 538 var recv = internal_raw_stack[i]; 539 var fun = internal_raw_stack[i + 1]; 540 var code = internal_raw_stack[i + 2]; 541 var pc = internal_raw_stack[i + 3]; 542 // For traps in wasm, the bytecode offset is passed as (-1 - offset). 543 // Otherwise, lookup the position from the pc. 544 var pos = IS_NUMBER(fun) && pc < 0 ? (-1 - pc) : 545 %FunctionGetPositionForOffset(code, pc); 546 sloppy_frames--; 547 frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0))); 548 } 549 return frames; 550} 551 552 553// Flag to prevent recursive call of Error.prepareStackTrace. 554var formatting_custom_stack_trace = false; 555 556 557function FormatStackTrace(obj, raw_stack) { 558 var frames = GetStackFrames(raw_stack); 559 if (IS_FUNCTION(GlobalError.prepareStackTrace) && 560 !formatting_custom_stack_trace) { 561 var array = []; 562 %MoveArrayContents(frames, array); 563 formatting_custom_stack_trace = true; 564 var stack_trace = UNDEFINED; 565 try { 566 stack_trace = GlobalError.prepareStackTrace(obj, array); 567 } catch (e) { 568 throw e; // The custom formatting function threw. Rethrow. 569 } finally { 570 formatting_custom_stack_trace = false; 571 } 572 return stack_trace; 573 } 574 575 var lines = new InternalArray(); 576 lines.push(FormatErrorString(obj)); 577 for (var i = 0; i < frames.length; i++) { 578 var frame = frames[i]; 579 var line; 580 try { 581 line = frame.toString(); 582 } catch (e) { 583 try { 584 line = "<error: " + e + ">"; 585 } catch (ee) { 586 // Any code that reaches this point is seriously nasty! 587 line = "<error>"; 588 } 589 } 590 lines.push(" at " + line); 591 } 592 return %_Call(ArrayJoin, lines, "\n"); 593} 594 595 596function GetTypeName(receiver, requireConstructor) { 597 if (IS_NULL_OR_UNDEFINED(receiver)) return null; 598 if (IS_PROXY(receiver)) return "Proxy"; 599 600 var constructor = %GetDataProperty(TO_OBJECT(receiver), "constructor"); 601 if (!IS_FUNCTION(constructor)) { 602 return requireConstructor ? null : %_Call(NoSideEffectsToString, receiver); 603 } 604 return %FunctionGetName(constructor); 605} 606 607 608// Format the stack trace if not yet done, and return it. 609// Cache the formatted stack trace on the holder. 610var StackTraceGetter = function() { 611 var formatted_stack_trace = UNDEFINED; 612 var holder = this; 613 while (holder) { 614 var formatted_stack_trace = 615 GET_PRIVATE(holder, formattedStackTraceSymbol); 616 if (IS_UNDEFINED(formatted_stack_trace)) { 617 // No formatted stack trace available. 618 var stack_trace = GET_PRIVATE(holder, stackTraceSymbol); 619 if (IS_UNDEFINED(stack_trace)) { 620 // Neither formatted nor structured stack trace available. 621 // Look further up the prototype chain. 622 holder = %object_get_prototype_of(holder); 623 continue; 624 } 625 formatted_stack_trace = FormatStackTrace(holder, stack_trace); 626 SET_PRIVATE(holder, stackTraceSymbol, UNDEFINED); 627 SET_PRIVATE(holder, formattedStackTraceSymbol, formatted_stack_trace); 628 } 629 return formatted_stack_trace; 630 } 631 return UNDEFINED; 632}; 633 634 635// If the receiver equals the holder, set the formatted stack trace that the 636// getter returns. 637var StackTraceSetter = function(v) { 638 if (IsErrorObject(this)) { 639 SET_PRIVATE(this, stackTraceSymbol, UNDEFINED); 640 SET_PRIVATE(this, formattedStackTraceSymbol, v); 641 } 642}; 643 644 645// Use a dummy function since we do not actually want to capture a stack trace 646// when constructing the initial Error prototytpes. 647var captureStackTrace = function() {}; 648 649 650// Set up special error type constructors. 651function SetUpError(error_function) { 652 %FunctionSetInstanceClassName(error_function, 'Error'); 653 var name = error_function.name; 654 var prototype = new GlobalObject(); 655 if (name !== 'Error') { 656 %InternalSetPrototype(error_function, GlobalError); 657 %InternalSetPrototype(prototype, GlobalError.prototype); 658 } 659 %FunctionSetPrototype(error_function, prototype); 660 661 %AddNamedProperty(error_function.prototype, 'name', name, DONT_ENUM); 662 %AddNamedProperty(error_function.prototype, 'message', '', DONT_ENUM); 663 %AddNamedProperty( 664 error_function.prototype, 'constructor', error_function, DONT_ENUM); 665 666 %SetCode(error_function, function(m) { 667 if (IS_UNDEFINED(new.target)) return new error_function(m); 668 669 try { captureStackTrace(this, error_function); } catch (e) { } 670 // Define all the expected properties directly on the error 671 // object. This avoids going through getters and setters defined 672 // on prototype objects. 673 if (!IS_UNDEFINED(m)) { 674 %AddNamedProperty(this, 'message', TO_STRING(m), DONT_ENUM); 675 } 676 }); 677 678 %SetNativeFlag(error_function); 679 return error_function; 680}; 681 682GlobalError = SetUpError(global.Error); 683GlobalEvalError = SetUpError(global.EvalError); 684GlobalRangeError = SetUpError(global.RangeError); 685GlobalReferenceError = SetUpError(global.ReferenceError); 686GlobalSyntaxError = SetUpError(global.SyntaxError); 687GlobalTypeError = SetUpError(global.TypeError); 688GlobalURIError = SetUpError(global.URIError); 689 690utils.InstallFunctions(GlobalError.prototype, DONT_ENUM, 691 ['toString', ErrorToString]); 692 693function ErrorToString() { 694 if (!IS_RECEIVER(this)) { 695 throw MakeTypeError(kCalledOnNonObject, "Error.prototype.toString"); 696 } 697 698 var name = this.name; 699 name = IS_UNDEFINED(name) ? "Error" : TO_STRING(name); 700 701 var message = this.message; 702 message = IS_UNDEFINED(message) ? "" : TO_STRING(message); 703 704 if (name == "") return message; 705 if (message == "") return name; 706 return `${name}: ${message}` 707} 708 709function MakeError(type, arg0, arg1, arg2) { 710 return MakeGenericError(GlobalError, type, arg0, arg1, arg2); 711} 712 713function MakeRangeError(type, arg0, arg1, arg2) { 714 return MakeGenericError(GlobalRangeError, type, arg0, arg1, arg2); 715} 716 717function MakeSyntaxError(type, arg0, arg1, arg2) { 718 return MakeGenericError(GlobalSyntaxError, type, arg0, arg1, arg2); 719} 720 721function MakeTypeError(type, arg0, arg1, arg2) { 722 return MakeGenericError(GlobalTypeError, type, arg0, arg1, arg2); 723} 724 725function MakeURIError() { 726 return MakeGenericError(GlobalURIError, kURIMalformed); 727} 728 729// Boilerplate for exceptions for stack overflows. Used from 730// Isolate::StackOverflow(). 731var StackOverflowBoilerplate = MakeRangeError(kStackOverflow); 732utils.InstallGetterSetter(StackOverflowBoilerplate, 'stack', 733 StackTraceGetter, StackTraceSetter) 734 735// Define actual captureStackTrace function after everything has been set up. 736captureStackTrace = function captureStackTrace(obj, cons_opt) { 737 // Define accessors first, as this may fail and throw. 738 %object_define_property(obj, 'stack', { get: StackTraceGetter, 739 set: StackTraceSetter, 740 configurable: true }); 741 %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace); 742}; 743 744GlobalError.captureStackTrace = captureStackTrace; 745 746%InstallToContext([ 747 "get_stack_trace_line_fun", GetStackTraceLine, 748 "make_error_function", MakeGenericError, 749 "make_range_error", MakeRangeError, 750 "make_type_error", MakeTypeError, 751 "message_get_column_number", GetColumnNumber, 752 "message_get_line_number", GetLineNumber, 753 "message_get_source_line", GetSourceLine, 754 "no_side_effects_to_string_fun", NoSideEffectsToString, 755 "stack_overflow_boilerplate", StackOverflowBoilerplate, 756]); 757 758utils.Export(function(to) { 759 to.ErrorToString = ErrorToString; 760 to.MakeError = MakeError; 761 to.MakeRangeError = MakeRangeError; 762 to.MakeSyntaxError = MakeSyntaxError; 763 to.MakeTypeError = MakeTypeError; 764 to.MakeURIError = MakeURIError; 765}); 766 767}); 768