diff options
Diffstat (limited to 'deps/v8/src/messages.js')
-rw-r--r-- | deps/v8/src/messages.js | 230 |
1 files changed, 99 insertions, 131 deletions
diff --git a/deps/v8/src/messages.js b/deps/v8/src/messages.js index 2a00ba846..a3adcf863 100644 --- a/deps/v8/src/messages.js +++ b/deps/v8/src/messages.js @@ -61,21 +61,18 @@ function FormatString(format, message) { // To check if something is a native error we need to check the -// concrete native error types. It is not sufficient to use instanceof -// since it possible to create an object that has Error.prototype on -// its prototype chain. This is the case for DOMException for example. +// concrete native error types. It is not enough to check "obj +// instanceof $Error" because user code can replace +// NativeError.prototype.__proto__. User code cannot replace +// NativeError.prototype though and therefore this is a safe test. function IsNativeErrorObject(obj) { - switch (%_ClassOf(obj)) { - case 'Error': - case 'EvalError': - case 'RangeError': - case 'ReferenceError': - case 'SyntaxError': - case 'TypeError': - case 'URIError': - return true; - } - return false; + return (obj instanceof $Error) || + (obj instanceof $EvalError) || + (obj instanceof $RangeError) || + (obj instanceof $ReferenceError) || + (obj instanceof $SyntaxError) || + (obj instanceof $TypeError) || + (obj instanceof $URIError); } @@ -748,7 +745,7 @@ function GetPositionInLine(message) { function GetStackTraceLine(recv, fun, pos, isGlobal) { - return new CallSite(recv, fun, pos).toString(); + return FormatSourcePosition(new CallSite(recv, fun, pos)); } // ---------------------------------------------------------------------------- @@ -788,7 +785,15 @@ function CallSiteGetThis() { } function CallSiteGetTypeName() { - return GetTypeName(this, false); + var constructor = this.receiver.constructor; + if (!constructor) { + return %_CallFunction(this.receiver, ObjectToString); + } + var constructorName = constructor.name; + if (!constructorName) { + return %_CallFunction(this.receiver, ObjectToString); + } + return constructorName; } function CallSiteIsToplevel() { @@ -822,10 +827,8 @@ function CallSiteGetFunctionName() { var name = this.fun.name; if (name) { return name; - } - name = %FunctionGetInferredName(this.fun); - if (name) { - return name; + } else { + return %FunctionGetInferredName(this.fun); } // Maybe this is an evaluation? var script = %FunctionGetScript(this.fun); @@ -916,69 +919,6 @@ function CallSiteIsConstructor() { return this.fun === constructor; } -function CallSiteToString() { - var fileName; - var fileLocation = ""; - if (this.isNative()) { - fileLocation = "native"; - } else if (this.isEval()) { - fileName = this.getScriptNameOrSourceURL(); - if (!fileName) { - fileLocation = this.getEvalOrigin(); - } - } else { - fileName = this.getFileName(); - } - - if (fileName) { - fileLocation += fileName; - var lineNumber = this.getLineNumber(); - if (lineNumber != null) { - fileLocation += ":" + lineNumber; - var columnNumber = this.getColumnNumber(); - if (columnNumber) { - fileLocation += ":" + columnNumber; - } - } - } - - if (!fileLocation) { - fileLocation = "unknown source"; - } - var line = ""; - var functionName = this.getFunctionName(); - var addSuffix = true; - var isConstructor = this.isConstructor(); - var isMethodCall = !(this.isToplevel() || isConstructor); - if (isMethodCall) { - var typeName = GetTypeName(this, true); - var methodName = this.getMethodName(); - if (functionName) { - if (typeName && functionName.indexOf(typeName) != 0) { - line += typeName + "."; - } - line += functionName; - if (methodName && functionName.lastIndexOf("." + methodName) != - functionName.length - methodName.length - 1) { - line += " [as " + methodName + "]"; - } - } else { - line += typeName + "." + (methodName || "<anonymous>"); - } - } else if (isConstructor) { - line += "new " + (functionName || "<anonymous>"); - } else if (functionName) { - line += functionName; - } else { - line += fileLocation; - addSuffix = false; - } - if (addSuffix) { - line += " (" + fileLocation + ")"; - } - return line; -} - SetUpLockedPrototype(CallSite, $Array("receiver", "fun", "pos"), $Array( "getThis", CallSiteGetThis, "getTypeName", CallSiteGetTypeName, @@ -994,8 +934,7 @@ SetUpLockedPrototype(CallSite, $Array("receiver", "fun", "pos"), $Array( "getColumnNumber", CallSiteGetColumnNumber, "isNative", CallSiteIsNative, "getPosition", CallSiteGetPosition, - "isConstructor", CallSiteIsConstructor, - "toString", CallSiteToString + "isConstructor", CallSiteIsConstructor )); @@ -1037,6 +976,65 @@ function FormatEvalOrigin(script) { return eval_origin; } +function FormatSourcePosition(frame) { + var fileName; + var fileLocation = ""; + if (frame.isNative()) { + fileLocation = "native"; + } else if (frame.isEval()) { + fileName = frame.getScriptNameOrSourceURL(); + if (!fileName) { + fileLocation = frame.getEvalOrigin(); + } + } else { + fileName = frame.getFileName(); + } + + if (fileName) { + fileLocation += fileName; + var lineNumber = frame.getLineNumber(); + if (lineNumber != null) { + fileLocation += ":" + lineNumber; + var columnNumber = frame.getColumnNumber(); + if (columnNumber) { + fileLocation += ":" + columnNumber; + } + } + } + + if (!fileLocation) { + fileLocation = "unknown source"; + } + var line = ""; + var functionName = frame.getFunction().name; + var addPrefix = true; + var isConstructor = frame.isConstructor(); + var isMethodCall = !(frame.isToplevel() || isConstructor); + if (isMethodCall) { + var methodName = frame.getMethodName(); + line += frame.getTypeName() + "."; + if (functionName) { + line += functionName; + if (methodName && (methodName != functionName)) { + line += " [as " + methodName + "]"; + } + } else { + line += methodName || "<anonymous>"; + } + } else if (isConstructor) { + line += "new " + (functionName || "<anonymous>"); + } else if (functionName) { + line += functionName; + } else { + line += fileLocation; + addPrefix = false; + } + if (addPrefix) { + line += " (" + fileLocation + ")"; + } + return line; +} + function FormatStackTrace(error, frames) { var lines = []; try { @@ -1052,7 +1050,7 @@ function FormatStackTrace(error, frames) { var frame = frames[i]; var line; try { - line = frame.toString(); + line = FormatSourcePosition(frame); } catch (e) { try { line = "<error: " + e + ">"; @@ -1083,19 +1081,6 @@ function FormatRawStackTrace(error, raw_stack) { } } -function GetTypeName(obj, requireConstructor) { - var constructor = obj.receiver.constructor; - if (!constructor) { - return requireConstructor ? null : - %_CallFunction(obj.receiver, ObjectToString); - } - var constructorName = constructor.name; - if (!constructorName) { - return requireConstructor ? null : - %_CallFunction(obj.receiver, ObjectToString); - } - return constructorName; -} function captureStackTrace(obj, cons_opt) { var stackTraceLimit = $Error.stackTraceLimit; @@ -1140,7 +1125,13 @@ function SetUpError() { } %FunctionSetInstanceClassName(f, 'Error'); %SetProperty(f.prototype, 'constructor', f, DONT_ENUM); - %SetProperty(f.prototype, "name", name, DONT_ENUM); + // The name property on the prototype of error objects is not + // specified as being read-one and dont-delete. However, allowing + // overwriting allows leaks of error objects between script blocks + // in the same context in a browser setting. Therefore we fix the + // name. + %SetProperty(f.prototype, "name", name, + DONT_ENUM | DONT_DELETE | READ_ONLY) ; %SetCode(f, function(m) { if (%_IsConstructCall()) { // Define all the expected properties directly on the error @@ -1156,8 +1147,10 @@ function SetUpError() { return FormatMessage(%NewMessageObject(obj.type, obj.arguments)); }); } else if (!IS_UNDEFINED(m)) { - %IgnoreAttributesAndSetProperty( - this, 'message', ToString(m), DONT_ENUM); + %IgnoreAttributesAndSetProperty(this, + 'message', + ToString(m), + DONT_ENUM); } captureStackTrace(this, f); } else { @@ -1187,41 +1180,16 @@ $Error.captureStackTrace = captureStackTrace; var visited_errors = new InternalArray(); var cyclic_error_marker = new $Object(); -function GetPropertyWithoutInvokingMonkeyGetters(error, name) { - // Climb the prototype chain until we find the holder. - while (error && !%HasLocalProperty(error, name)) { - error = error.__proto__; - } - if (error === null) return void 0; - if (!IS_OBJECT(error)) return error[name]; - // If the property is an accessor on one of the predefined errors that can be - // generated statically by the compiler, don't touch it. This is to address - // http://code.google.com/p/chromium/issues/detail?id=69187 - var desc = %GetOwnProperty(error, name); - if (desc && desc[IS_ACCESSOR_INDEX]) { - var isName = name === "name"; - if (error === $ReferenceError.prototype) - return isName ? "ReferenceError" : void 0; - if (error === $SyntaxError.prototype) - return isName ? "SyntaxError" : void 0; - if (error === $TypeError.prototype) - return isName ? "TypeError" : void 0; - } - // Otherwise, read normally. - return error[name]; -} - function ErrorToStringDetectCycle(error) { if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker; try { - var type = GetPropertyWithoutInvokingMonkeyGetters(error, "type"); - var name = GetPropertyWithoutInvokingMonkeyGetters(error, "name"); + var type = error.type; + var name = error.name; name = IS_UNDEFINED(name) ? "Error" : TO_STRING_INLINE(name); - var message = GetPropertyWithoutInvokingMonkeyGetters(error, "message"); + var message = error.message; var hasMessage = %_CallFunction(error, "message", ObjectHasOwnProperty); if (type && !hasMessage) { - var args = GetPropertyWithoutInvokingMonkeyGetters(error, "arguments"); - message = FormatMessage(%NewMessageObject(type, args)); + message = FormatMessage(%NewMessageObject(type, error.arguments)); } message = IS_UNDEFINED(message) ? "" : TO_STRING_INLINE(message); if (name === "") return message; |