Make the runtime entry for setting/changing accessors "atomic".
Previously, there were 1 or 2 calls to the runtime when accessors were changed
or set. This doesn't really work well with property attributes, leading to some
hacks and complicates things even further when trying to share maps in presence
of accessors. Therefore, the runtime entry now takes the full triple (getter,
setter, attributes), where the getter and/or the setter can be null in case they
shouldn't be changed.
For now, we do basically the same on the native side as we did before on the
JavaScript side, but this will change in future CLs, the current CL is already
large enough.
Note that object literals with a getter and a setter for the same property still
do 2 calls, but this is a little bit more tricky to fix and will be handled in a
separate CL.
Review URL: https://chromiumcodereview.appspot.com/9616016
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10956 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2012-03-07 13:24:44 +00:00
|
|
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
2014-04-29 06:42:26 +00:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
|
2015-04-27 12:33:58 +00:00
|
|
|
var $errorToString;
|
|
|
|
var $getStackTraceLine;
|
2015-08-11 09:15:27 +00:00
|
|
|
var $internalErrorSymbol;
|
2015-04-27 12:33:58 +00:00
|
|
|
var $messageGetPositionInLine;
|
|
|
|
var $messageGetLineNumber;
|
|
|
|
var $messageGetSourceLine;
|
2015-05-18 08:34:05 +00:00
|
|
|
var $noSideEffectToString;
|
2015-04-27 12:33:58 +00:00
|
|
|
var $stackOverflowBoilerplate;
|
|
|
|
var $stackTraceSymbol;
|
|
|
|
var $toDetailString;
|
|
|
|
var $Error;
|
|
|
|
var $EvalError;
|
|
|
|
var $RangeError;
|
|
|
|
var $ReferenceError;
|
|
|
|
var $SyntaxError;
|
|
|
|
var $TypeError;
|
|
|
|
var $URIError;
|
|
|
|
var MakeError;
|
|
|
|
var MakeEvalError;
|
|
|
|
var MakeRangeError;
|
|
|
|
var MakeReferenceError;
|
|
|
|
var MakeSyntaxError;
|
|
|
|
var MakeTypeError;
|
|
|
|
var MakeURIError;
|
|
|
|
|
2015-05-21 06:15:33 +00:00
|
|
|
(function(global, utils) {
|
2015-04-27 12:33:58 +00:00
|
|
|
|
|
|
|
%CheckIsBootstrapping();
|
|
|
|
|
2015-05-12 14:00:47 +00:00
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Imports
|
|
|
|
|
2015-04-27 12:33:58 +00:00
|
|
|
var GlobalObject = global.Object;
|
2015-05-21 06:15:33 +00:00
|
|
|
var InternalArray = utils.InternalArray;
|
2015-05-26 07:24:13 +00:00
|
|
|
var ObjectDefineProperty = utils.ObjectDefineProperty;
|
2015-05-21 06:15:33 +00:00
|
|
|
|
2015-05-26 07:24:13 +00:00
|
|
|
var ArrayJoin;
|
|
|
|
var ObjectToString;
|
2015-05-21 06:15:33 +00:00
|
|
|
var StringCharAt;
|
|
|
|
var StringIndexOf;
|
|
|
|
var StringSubstring;
|
|
|
|
|
V8: Add SIMD functions for Phase 1.
Float32x4:
abs, neg, sqrt, reciprocalApproximation, reciprocalSqrtApproximation, add, sub, mul, div,
min, max, minNum, maxNum, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromInt32x4, fromInt32x4Bits, fromInt16x8Bits,
fromInt8x16Bits.
Int32x4:
neg, add, sub, mul, min, max, and, or, xor, not, shiftLeftByScalar, shiftRightLogicalByScalar,
shiftRightArithmeticByScalar, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromFloat32x4, fromFloat32x4Bits, fromInt16x8Bits,
fromInt8x16Bits.
Int16x8:
neg, add, sub, mul, min, max, and, or, xor, not, shiftLeftByScalar, shiftRightLogicalByScalar,
shiftRightArithmeticByScalar, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromFloat32x4Bits, fromInt32x4Bits, fromInt8x16Bits.
Int8x16:
neg, add, sub, mul, min, max, and, or, xor, not, shiftLeftByScalar, shiftRightLogicalByScalar,
shiftRightArithmeticByScalar, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromFloat32x4Bits, fromInt32x4Bits, fromInt16x8Bitss.
Bool32x4, Bool16x8, Bool8x16:
and, or, not, anyTrue, allTrue, select, swizzle, shuffle.
I might have forgotten a few.
LOG=N
BUG=v8:4124
Review URL: https://codereview.chromium.org/1230343003
Cr-Commit-Position: refs/heads/master@{#30051}
2015-08-06 20:24:45 +00:00
|
|
|
var Float32x4ToString;
|
|
|
|
var Int32x4ToString;
|
|
|
|
var Bool32x4ToString;
|
|
|
|
var Int16x8ToString;
|
|
|
|
var Bool16x8ToString;
|
|
|
|
var Int8x16ToString;
|
|
|
|
var Bool8x16ToString;
|
|
|
|
|
|
|
|
|
2015-05-21 06:15:33 +00:00
|
|
|
utils.Import(function(from) {
|
2015-05-26 07:24:13 +00:00
|
|
|
ArrayJoin = from.ArrayJoin;
|
|
|
|
ObjectToString = from.ObjectToString;
|
2015-05-21 06:15:33 +00:00
|
|
|
StringCharAt = from.StringCharAt;
|
|
|
|
StringIndexOf = from.StringIndexOf;
|
|
|
|
StringSubstring = from.StringSubstring;
|
V8: Add SIMD functions for Phase 1.
Float32x4:
abs, neg, sqrt, reciprocalApproximation, reciprocalSqrtApproximation, add, sub, mul, div,
min, max, minNum, maxNum, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromInt32x4, fromInt32x4Bits, fromInt16x8Bits,
fromInt8x16Bits.
Int32x4:
neg, add, sub, mul, min, max, and, or, xor, not, shiftLeftByScalar, shiftRightLogicalByScalar,
shiftRightArithmeticByScalar, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromFloat32x4, fromFloat32x4Bits, fromInt16x8Bits,
fromInt8x16Bits.
Int16x8:
neg, add, sub, mul, min, max, and, or, xor, not, shiftLeftByScalar, shiftRightLogicalByScalar,
shiftRightArithmeticByScalar, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromFloat32x4Bits, fromInt32x4Bits, fromInt8x16Bits.
Int8x16:
neg, add, sub, mul, min, max, and, or, xor, not, shiftLeftByScalar, shiftRightLogicalByScalar,
shiftRightArithmeticByScalar, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromFloat32x4Bits, fromInt32x4Bits, fromInt16x8Bitss.
Bool32x4, Bool16x8, Bool8x16:
and, or, not, anyTrue, allTrue, select, swizzle, shuffle.
I might have forgotten a few.
LOG=N
BUG=v8:4124
Review URL: https://codereview.chromium.org/1230343003
Cr-Commit-Position: refs/heads/master@{#30051}
2015-08-06 20:24:45 +00:00
|
|
|
Float32x4ToString = from.Float32x4ToString;
|
|
|
|
Int32x4ToString = from.Int32x4ToString;
|
|
|
|
Bool32x4ToString = from.Bool32x4ToString;
|
|
|
|
Int16x8ToString = from.Int16x8ToString;
|
|
|
|
Bool16x8ToString = from.Bool16x8ToString;
|
|
|
|
Int8x16ToString = from.Int8x16ToString;
|
|
|
|
Bool8x16ToString = from.Bool8x16ToString;
|
2015-05-21 06:15:33 +00:00
|
|
|
});
|
2015-05-12 14:00:47 +00:00
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
|
2015-04-27 12:33:58 +00:00
|
|
|
var GlobalError;
|
|
|
|
var GlobalTypeError;
|
|
|
|
var GlobalRangeError;
|
|
|
|
var GlobalURIError;
|
|
|
|
var GlobalSyntaxError;
|
|
|
|
var GlobalReferenceError;
|
|
|
|
var GlobalEvalError;
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2015-05-05 09:15:56 +00:00
|
|
|
function NoSideEffectsObjectToString() {
|
2015-08-12 13:44:06 +00:00
|
|
|
if (IS_UNDEFINED(this)) return "[object Undefined]";
|
2015-05-05 09:15:56 +00:00
|
|
|
if (IS_NULL(this)) return "[object Null]";
|
2015-07-31 12:25:28 +00:00
|
|
|
return "[object " + %_ClassOf(TO_OBJECT(this)) + "]";
|
2015-05-05 09:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-12 10:33:20 +00:00
|
|
|
function NoSideEffectToString(obj) {
|
|
|
|
if (IS_STRING(obj)) return obj;
|
|
|
|
if (IS_NUMBER(obj)) return %_NumberToString(obj);
|
2014-05-09 13:14:09 +00:00
|
|
|
if (IS_BOOLEAN(obj)) return obj ? 'true' : 'false';
|
2012-11-12 10:33:20 +00:00
|
|
|
if (IS_UNDEFINED(obj)) return 'undefined';
|
|
|
|
if (IS_NULL(obj)) return 'null';
|
2014-05-09 13:14:09 +00:00
|
|
|
if (IS_FUNCTION(obj)) {
|
2015-05-05 09:15:56 +00:00
|
|
|
var str = %_CallFunction(obj, obj, $functionSourceString);
|
2014-05-09 13:14:09 +00:00
|
|
|
if (str.length > 128) {
|
|
|
|
str = %_SubString(str, 0, 111) + "...<omitted>..." +
|
|
|
|
%_SubString(str, str.length - 2, str.length);
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
2015-03-13 15:08:12 +00:00
|
|
|
if (IS_SYMBOL(obj)) return %_CallFunction(obj, $symbolToString);
|
2015-08-04 14:36:53 +00:00
|
|
|
if (IS_SIMD_VALUE(obj)) {
|
2015-08-03 13:02:39 +00:00
|
|
|
switch (typeof(obj)) {
|
V8: Add SIMD functions for Phase 1.
Float32x4:
abs, neg, sqrt, reciprocalApproximation, reciprocalSqrtApproximation, add, sub, mul, div,
min, max, minNum, maxNum, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromInt32x4, fromInt32x4Bits, fromInt16x8Bits,
fromInt8x16Bits.
Int32x4:
neg, add, sub, mul, min, max, and, or, xor, not, shiftLeftByScalar, shiftRightLogicalByScalar,
shiftRightArithmeticByScalar, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromFloat32x4, fromFloat32x4Bits, fromInt16x8Bits,
fromInt8x16Bits.
Int16x8:
neg, add, sub, mul, min, max, and, or, xor, not, shiftLeftByScalar, shiftRightLogicalByScalar,
shiftRightArithmeticByScalar, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromFloat32x4Bits, fromInt32x4Bits, fromInt8x16Bits.
Int8x16:
neg, add, sub, mul, min, max, and, or, xor, not, shiftLeftByScalar, shiftRightLogicalByScalar,
shiftRightArithmeticByScalar, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual,
equal, notEqual, select, swizzle, shuffle, fromFloat32x4Bits, fromInt32x4Bits, fromInt16x8Bitss.
Bool32x4, Bool16x8, Bool8x16:
and, or, not, anyTrue, allTrue, select, swizzle, shuffle.
I might have forgotten a few.
LOG=N
BUG=v8:4124
Review URL: https://codereview.chromium.org/1230343003
Cr-Commit-Position: refs/heads/master@{#30051}
2015-08-06 20:24:45 +00:00
|
|
|
case 'float32x4': return %_CallFunction(obj, Float32x4ToString);
|
|
|
|
case 'int32x4': return %_CallFunction(obj, Int32x4ToString);
|
|
|
|
case 'bool32x4': return %_CallFunction(obj, Bool32x4ToString);
|
|
|
|
case 'int16x8': return %_CallFunction(obj, Int16x8ToString);
|
|
|
|
case 'bool16x8': return %_CallFunction(obj, Bool16x8ToString);
|
|
|
|
case 'int16x8': return %_CallFunction(obj, Int16x8ToString);
|
|
|
|
case 'bool16x8': return %_CallFunction(obj, Bool16x8ToString);
|
2015-08-03 13:02:39 +00:00
|
|
|
}
|
|
|
|
}
|
2014-10-21 17:21:32 +00:00
|
|
|
if (IS_OBJECT(obj)
|
2015-05-26 07:24:13 +00:00
|
|
|
&& %GetDataProperty(obj, "toString") === ObjectToString) {
|
2012-12-17 14:00:50 +00:00
|
|
|
var constructor = %GetDataProperty(obj, "constructor");
|
2012-11-12 10:33:20 +00:00
|
|
|
if (typeof constructor == "function") {
|
|
|
|
var constructorName = constructor.name;
|
|
|
|
if (IS_STRING(constructorName) && constructorName !== "") {
|
|
|
|
return "#<" + constructorName + ">";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-08-06 13:58:21 +00:00
|
|
|
if (CanBeSafelyTreatedAsAnErrorObject(obj)) {
|
|
|
|
return %_CallFunction(obj, ErrorToString);
|
|
|
|
}
|
2014-10-21 17:21:32 +00:00
|
|
|
|
|
|
|
return %_CallFunction(obj, NoSideEffectsObjectToString);
|
2012-11-12 10:33:20 +00:00
|
|
|
}
|
|
|
|
|
2013-08-06 13:58:21 +00:00
|
|
|
// To determine whether we can safely stringify an object using ErrorToString
|
|
|
|
// without the risk of side-effects, we need to check whether the object is
|
2015-04-27 12:33:58 +00:00
|
|
|
// either an instance of a native error type (via '%_ClassOf'), or has Error
|
2013-08-06 13:58:21 +00:00
|
|
|
// in its prototype chain and hasn't overwritten 'toString' with something
|
|
|
|
// strange and unusual.
|
|
|
|
function CanBeSafelyTreatedAsAnErrorObject(obj) {
|
2012-05-18 09:45:10 +00:00
|
|
|
switch (%_ClassOf(obj)) {
|
|
|
|
case 'Error':
|
|
|
|
case 'EvalError':
|
|
|
|
case 'RangeError':
|
|
|
|
case 'ReferenceError':
|
|
|
|
case 'SyntaxError':
|
|
|
|
case 'TypeError':
|
|
|
|
case 'URIError':
|
|
|
|
return true;
|
|
|
|
}
|
2013-08-06 13:58:21 +00:00
|
|
|
|
|
|
|
var objToString = %GetDataProperty(obj, "toString");
|
2015-04-27 12:33:58 +00:00
|
|
|
return obj instanceof GlobalError && objToString === ErrorToString;
|
2011-01-25 08:48:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-24 07:59:40 +00:00
|
|
|
// When formatting internally created error messages, do not
|
|
|
|
// invoke overwritten error toString methods but explicitly use
|
|
|
|
// the error to string method. This is to avoid leaking error
|
|
|
|
// objects between script tags in a browser setting.
|
|
|
|
function ToStringCheckErrorObject(obj) {
|
2013-08-06 13:58:21 +00:00
|
|
|
if (CanBeSafelyTreatedAsAnErrorObject(obj)) {
|
2011-10-26 10:41:52 +00:00
|
|
|
return %_CallFunction(obj, ErrorToString);
|
2011-01-24 07:59:40 +00:00
|
|
|
} else {
|
2015-05-07 08:39:53 +00:00
|
|
|
return $toString(obj);
|
2011-01-24 07:59:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
function ToDetailString(obj) {
|
2015-05-26 07:24:13 +00:00
|
|
|
if (obj != null && IS_OBJECT(obj) && obj.toString === ObjectToString) {
|
2008-07-03 15:10:15 +00:00
|
|
|
var constructor = obj.constructor;
|
2011-09-01 07:39:22 +00:00
|
|
|
if (typeof constructor == "function") {
|
|
|
|
var constructorName = constructor.name;
|
|
|
|
if (IS_STRING(constructorName) && constructorName !== "") {
|
|
|
|
return "#<" + constructorName + ">";
|
|
|
|
}
|
2011-01-26 15:16:13 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
2011-09-01 07:39:22 +00:00
|
|
|
return ToStringCheckErrorObject(obj);
|
2008-10-03 07:14:31 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
|
2015-04-17 08:35:59 +00:00
|
|
|
function MakeGenericError(constructor, type, arg0, arg1, arg2) {
|
|
|
|
if (IS_UNDEFINED(arg0) && IS_STRING(type)) arg0 = [];
|
2015-08-11 09:15:27 +00:00
|
|
|
var error = new constructor(FormatMessage(type, arg0, arg1, arg2));
|
|
|
|
error[$internalErrorSymbol] = true;
|
|
|
|
return error;
|
2015-04-16 07:01:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
/**
|
2011-09-05 07:30:35 +00:00
|
|
|
* Set up the Script function and constructor.
|
2008-07-03 15:10:15 +00:00
|
|
|
*/
|
|
|
|
%FunctionSetInstanceClassName(Script, 'Script');
|
2014-07-14 14:05:30 +00:00
|
|
|
%AddNamedProperty(Script.prototype, 'constructor', Script,
|
|
|
|
DONT_ENUM | DONT_DELETE | READ_ONLY);
|
2008-07-03 15:10:15 +00:00
|
|
|
%SetCode(Script, function(x) {
|
|
|
|
// Script objects can only be created by the VM.
|
2015-04-24 10:22:00 +00:00
|
|
|
throw MakeError(kUnsupported);
|
2008-07-03 15:10:15 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// Helper functions; called from the runtime system.
|
2015-04-16 07:01:20 +00:00
|
|
|
function FormatMessage(type, arg0, arg1, arg2) {
|
2015-05-18 08:34:05 +00:00
|
|
|
var arg0 = NoSideEffectToString(arg0);
|
|
|
|
var arg1 = NoSideEffectToString(arg1);
|
|
|
|
var arg2 = NoSideEffectToString(arg2);
|
|
|
|
try {
|
|
|
|
return %FormatMessageString(type, arg0, arg1, arg2);
|
|
|
|
} catch (e) {
|
|
|
|
return "<error>";
|
2015-04-16 07:01:20 +00:00
|
|
|
}
|
2008-10-03 07:14:31 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
function GetLineNumber(message) {
|
2011-02-02 13:31:52 +00:00
|
|
|
var start_position = %MessageGetStartPosition(message);
|
|
|
|
if (start_position == -1) return kNoLineNumberInfo;
|
|
|
|
var script = %MessageGetScript(message);
|
|
|
|
var location = script.locationFromPosition(start_position, true);
|
2010-05-06 07:32:44 +00:00
|
|
|
if (location == null) return kNoLineNumberInfo;
|
2008-07-03 15:10:15 +00:00
|
|
|
return location.line + 1;
|
2008-10-03 07:14:31 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Returns the source code line containing the given source
|
|
|
|
// position, or the empty string if the position is invalid.
|
|
|
|
function GetSourceLine(message) {
|
2011-02-02 13:31:52 +00:00
|
|
|
var script = %MessageGetScript(message);
|
|
|
|
var start_position = %MessageGetStartPosition(message);
|
|
|
|
var location = script.locationFromPosition(start_position, true);
|
2008-07-03 15:10:15 +00:00
|
|
|
if (location == null) return "";
|
|
|
|
return location.sourceText();
|
2008-10-03 07:14:31 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2009-06-09 07:03:21 +00:00
|
|
|
/**
|
|
|
|
* Find a line number given a specific source position.
|
|
|
|
* @param {number} position The source position.
|
2015-06-08 14:24:25 +00:00
|
|
|
* @return {number} 0 if input too small, -1 if input too large,
|
|
|
|
else the line number.
|
2009-06-09 07:03:21 +00:00
|
|
|
*/
|
2011-09-05 07:30:35 +00:00
|
|
|
function ScriptLineFromPosition(position) {
|
2015-06-08 14:24:25 +00:00
|
|
|
var lower = 0;
|
|
|
|
var upper = this.lineCount() - 1;
|
2009-11-27 14:10:48 +00:00
|
|
|
var line_ends = this.line_ends;
|
2009-06-09 07:03:21 +00:00
|
|
|
|
2015-06-08 14:24:25 +00:00
|
|
|
// We'll never find invalid positions so bail right away.
|
|
|
|
if (position > line_ends[upper]) {
|
|
|
|
return -1;
|
|
|
|
}
|
2015-04-01 10:11:13 +00:00
|
|
|
|
2015-06-08 14:24:25 +00:00
|
|
|
// This means we don't have to safe-guard indexing line_ends[i - 1].
|
|
|
|
if (position <= line_ends[0]) {
|
|
|
|
return 0;
|
|
|
|
}
|
2015-04-01 10:11:13 +00:00
|
|
|
|
|
|
|
// Binary search to find line # from position range.
|
2015-06-08 14:24:25 +00:00
|
|
|
while (upper >= 1) {
|
|
|
|
var i = (lower + upper) >> 1;
|
|
|
|
|
|
|
|
if (position > line_ends[i]) {
|
|
|
|
lower = i + 1;
|
|
|
|
} else if (position <= line_ends[i - 1]) {
|
|
|
|
upper = i - 1;
|
|
|
|
} else {
|
|
|
|
return i;
|
2009-06-09 07:03:21 +00:00
|
|
|
}
|
|
|
|
}
|
2015-04-01 10:11:13 +00:00
|
|
|
|
2015-06-08 14:24:25 +00:00
|
|
|
return -1;
|
2009-06-09 07:03:21 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get information on a specific source position.
|
|
|
|
* @param {number} position The source position
|
2009-03-09 17:59:25 +00:00
|
|
|
* @param {boolean} include_resource_offset Set to true to have the resource
|
|
|
|
* offset added to the location
|
2008-07-03 15:10:15 +00:00
|
|
|
* @return {SourceLocation}
|
|
|
|
* If line is negative or not in the source null is returned.
|
|
|
|
*/
|
2011-09-05 07:30:35 +00:00
|
|
|
function ScriptLocationFromPosition(position,
|
|
|
|
include_resource_offset) {
|
2009-06-09 07:03:21 +00:00
|
|
|
var line = this.lineFromPosition(position);
|
2008-07-03 15:10:15 +00:00
|
|
|
if (line == -1) return null;
|
2008-08-22 13:33:59 +00:00
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
// Determine start, end and column.
|
2015-06-08 14:24:25 +00:00
|
|
|
var line_ends = this.line_ends;
|
|
|
|
var start = line == 0 ? 0 : line_ends[line - 1] + 1;
|
|
|
|
var end = line_ends[line];
|
|
|
|
if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') {
|
2011-09-05 07:30:35 +00:00
|
|
|
end--;
|
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
var column = position - start;
|
|
|
|
|
|
|
|
// Adjust according to the offset within the resource.
|
2009-03-09 17:59:25 +00:00
|
|
|
if (include_resource_offset) {
|
|
|
|
line += this.line_offset;
|
|
|
|
if (line == this.line_offset) {
|
|
|
|
column += this.column_offset;
|
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return new SourceLocation(this, position, line, column, start, end);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get information on a specific source line and column possibly offset by a
|
|
|
|
* fixed source position. This function is used to find a source position from
|
|
|
|
* a line and column position. The fixed source position offset is typically
|
|
|
|
* used to find a source position in a function based on a line and column in
|
|
|
|
* the source for the function alone. The offset passed will then be the
|
|
|
|
* start position of the source for the function within the full script source.
|
|
|
|
* @param {number} opt_line The line within the source. Default value is 0
|
|
|
|
* @param {number} opt_column The column in within the line. Default value is 0
|
|
|
|
* @param {number} opt_offset_position The offset from the begining of the
|
2011-09-05 07:30:35 +00:00
|
|
|
* source from where the line and column calculation starts.
|
|
|
|
* Default value is 0
|
2008-07-03 15:10:15 +00:00
|
|
|
* @return {SourceLocation}
|
|
|
|
* If line is negative or not in the source null is returned.
|
|
|
|
*/
|
2011-09-05 07:30:35 +00:00
|
|
|
function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) {
|
2008-07-03 15:10:15 +00:00
|
|
|
// Default is the first line in the script. Lines in the script is relative
|
|
|
|
// to the offset within the resource.
|
|
|
|
var line = 0;
|
|
|
|
if (!IS_UNDEFINED(opt_line)) {
|
|
|
|
line = opt_line - this.line_offset;
|
|
|
|
}
|
2008-08-22 13:33:59 +00:00
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
// Default is first column. If on the first line add the offset within the
|
|
|
|
// resource.
|
|
|
|
var column = opt_column || 0;
|
|
|
|
if (line == 0) {
|
2011-11-28 12:11:00 +00:00
|
|
|
column -= this.column_offset;
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var offset_position = opt_offset_position || 0;
|
|
|
|
if (line < 0 || column < 0 || offset_position < 0) return null;
|
|
|
|
if (line == 0) {
|
2009-03-12 14:03:05 +00:00
|
|
|
return this.locationFromPosition(offset_position + column, false);
|
2008-07-03 15:10:15 +00:00
|
|
|
} else {
|
2009-06-09 07:03:21 +00:00
|
|
|
// Find the line where the offset position is located.
|
|
|
|
var offset_line = this.lineFromPosition(offset_position);
|
|
|
|
|
|
|
|
if (offset_line == -1 || offset_line + line >= this.lineCount()) {
|
|
|
|
return null;
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
2009-06-09 07:03:21 +00:00
|
|
|
|
2011-11-28 12:11:00 +00:00
|
|
|
return this.locationFromPosition(
|
2015-06-08 14:24:25 +00:00
|
|
|
this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here.
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a slice of source code from the script. The boundaries for the slice is
|
|
|
|
* specified in lines.
|
|
|
|
* @param {number} opt_from_line The first line (zero bound) in the slice.
|
|
|
|
* Default is 0
|
|
|
|
* @param {number} opt_to_column The last line (zero bound) in the slice (non
|
|
|
|
* inclusive). Default is the number of lines in the script
|
|
|
|
* @return {SourceSlice} The source slice or null of the parameters where
|
|
|
|
* invalid
|
|
|
|
*/
|
2011-09-05 07:30:35 +00:00
|
|
|
function ScriptSourceSlice(opt_from_line, opt_to_line) {
|
2011-11-28 12:11:00 +00:00
|
|
|
var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset
|
|
|
|
: opt_from_line;
|
|
|
|
var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
|
|
|
|
: opt_to_line;
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// Adjust according to the offset within the resource.
|
|
|
|
from_line -= this.line_offset;
|
|
|
|
to_line -= this.line_offset;
|
|
|
|
if (from_line < 0) from_line = 0;
|
|
|
|
if (to_line > this.lineCount()) to_line = this.lineCount();
|
|
|
|
|
2009-02-04 12:07:45 +00:00
|
|
|
// Check parameters.
|
2008-07-03 15:10:15 +00:00
|
|
|
if (from_line >= this.lineCount() ||
|
|
|
|
to_line < 0 ||
|
|
|
|
from_line > to_line) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-06-08 14:24:25 +00:00
|
|
|
var line_ends = this.line_ends;
|
|
|
|
var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1;
|
|
|
|
var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1;
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// Return a source slice with line numbers re-adjusted to the resource.
|
2011-11-28 12:11:00 +00:00
|
|
|
return new SourceSlice(this,
|
|
|
|
from_line + this.line_offset,
|
|
|
|
to_line + this.line_offset,
|
2015-06-08 14:24:25 +00:00
|
|
|
from_position, to_position);
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function ScriptSourceLine(opt_line) {
|
2008-07-03 15:10:15 +00:00
|
|
|
// Default is the first line in the script. Lines in the script are relative
|
|
|
|
// to the offset within the resource.
|
|
|
|
var line = 0;
|
|
|
|
if (!IS_UNDEFINED(opt_line)) {
|
|
|
|
line = opt_line - this.line_offset;
|
|
|
|
}
|
2009-02-04 12:07:45 +00:00
|
|
|
|
|
|
|
// Check parameter.
|
2008-07-03 15:10:15 +00:00
|
|
|
if (line < 0 || this.lineCount() <= line) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2009-02-04 12:07:45 +00:00
|
|
|
// Return the source line.
|
2015-06-08 14:24:25 +00:00
|
|
|
var line_ends = this.line_ends;
|
|
|
|
var start = line == 0 ? 0 : line_ends[line - 1] + 1;
|
|
|
|
var end = line_ends[line];
|
2015-05-21 06:15:33 +00:00
|
|
|
return %_CallFunction(this.source, start, end, StringSubstring);
|
2008-07-03 15:10:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the number of source lines.
|
|
|
|
* @return {number}
|
|
|
|
* Number of source lines.
|
|
|
|
*/
|
2011-09-05 07:30:35 +00:00
|
|
|
function ScriptLineCount() {
|
2009-02-04 12:07:45 +00:00
|
|
|
// Return number of source lines.
|
2015-06-08 14:24:25 +00:00
|
|
|
return this.line_ends.length;
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
|
2015-06-26 14:58:51 +00:00
|
|
|
/**
|
|
|
|
* Returns the position of the nth line end.
|
|
|
|
* @return {number}
|
|
|
|
* Zero-based position of the nth line end in the script.
|
|
|
|
*/
|
|
|
|
function ScriptLineEnd(n) {
|
|
|
|
return this.line_ends[n];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-01 16:25:07 +00:00
|
|
|
/**
|
2015-03-31 19:35:59 +00:00
|
|
|
* If sourceURL comment is available returns sourceURL comment contents.
|
|
|
|
* Otherwise, script name is returned. See
|
2010-04-01 16:25:07 +00:00
|
|
|
* http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
|
2013-05-29 12:40:21 +00:00
|
|
|
* and Source Map Revision 3 proposal for details on using //# sourceURL and
|
|
|
|
* deprecated //@ sourceURL comment to identify scripts that don't have name.
|
2010-10-15 13:03:59 +00:00
|
|
|
*
|
2013-05-29 12:40:21 +00:00
|
|
|
* @return {?string} script name if present, value for //# sourceURL or
|
|
|
|
* deprecated //@ sourceURL comment otherwise.
|
2010-04-01 16:25:07 +00:00
|
|
|
*/
|
2011-09-05 07:30:35 +00:00
|
|
|
function ScriptNameOrSourceURL() {
|
2015-03-31 19:35:59 +00:00
|
|
|
if (this.source_url) return this.source_url;
|
2014-07-02 07:01:31 +00:00
|
|
|
return this.name;
|
2010-04-01 16:25:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-26 07:24:13 +00:00
|
|
|
utils.SetUpLockedPrototype(Script, [
|
2015-04-10 20:51:33 +00:00
|
|
|
"source",
|
|
|
|
"name",
|
|
|
|
"source_url",
|
|
|
|
"source_mapping_url",
|
|
|
|
"line_ends",
|
|
|
|
"line_offset",
|
|
|
|
"column_offset"
|
|
|
|
], [
|
2011-09-05 07:30:35 +00:00
|
|
|
"lineFromPosition", ScriptLineFromPosition,
|
|
|
|
"locationFromPosition", ScriptLocationFromPosition,
|
|
|
|
"locationFromLine", ScriptLocationFromLine,
|
|
|
|
"sourceSlice", ScriptSourceSlice,
|
|
|
|
"sourceLine", ScriptSourceLine,
|
|
|
|
"lineCount", ScriptLineCount,
|
2015-06-26 14:58:51 +00:00
|
|
|
"nameOrSourceURL", ScriptNameOrSourceURL,
|
|
|
|
"lineEnd", ScriptLineEnd
|
2015-04-10 20:51:33 +00:00
|
|
|
]
|
2011-09-05 07:30:35 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
/**
|
|
|
|
* Class for source location. A source location is a position within some
|
|
|
|
* source with the following properties:
|
|
|
|
* script : script object for the source
|
|
|
|
* line : source line number
|
|
|
|
* column : source column within the line
|
|
|
|
* position : position within the source
|
|
|
|
* start : position of start of source context (inclusive)
|
|
|
|
* end : position of end of source context (not inclusive)
|
2011-11-28 12:11:00 +00:00
|
|
|
* Source text for the source context is the character interval
|
|
|
|
* [start, end[. In most cases end will point to a newline character.
|
|
|
|
* It might point just past the final position of the source if the last
|
|
|
|
* source line does not end with a newline character.
|
2008-07-03 15:10:15 +00:00
|
|
|
* @param {Script} script The Script object for which this is a location
|
|
|
|
* @param {number} position Source position for the location
|
|
|
|
* @param {number} line The line number for the location
|
|
|
|
* @param {number} column The column within the line for the location
|
|
|
|
* @param {number} start Source position for start of source context
|
|
|
|
* @param {number} end Source position for end of source context
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
function SourceLocation(script, position, line, column, start, end) {
|
|
|
|
this.script = script;
|
|
|
|
this.position = position;
|
|
|
|
this.line = line;
|
|
|
|
this.column = column;
|
|
|
|
this.start = start;
|
|
|
|
this.end = end;
|
2008-10-03 07:14:31 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the source text for a SourceLocation
|
|
|
|
* @return {String}
|
|
|
|
* Source text for this location.
|
|
|
|
*/
|
2011-09-05 07:30:35 +00:00
|
|
|
function SourceLocationSourceText() {
|
2011-11-28 12:11:00 +00:00
|
|
|
return %_CallFunction(this.script.source,
|
|
|
|
this.start,
|
|
|
|
this.end,
|
2015-05-21 06:15:33 +00:00
|
|
|
StringSubstring);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
|
2015-05-26 07:24:13 +00:00
|
|
|
utils.SetUpLockedPrototype(SourceLocation,
|
2015-04-10 20:51:33 +00:00
|
|
|
["script", "position", "line", "column", "start", "end"],
|
|
|
|
["sourceText", SourceLocationSourceText]
|
2011-09-05 07:30:35 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
/**
|
|
|
|
* Class for a source slice. A source slice is a part of a script source with
|
|
|
|
* the following properties:
|
|
|
|
* script : script object for the source
|
|
|
|
* from_line : line number for the first line in the slice
|
|
|
|
* to_line : source line number for the last line in the slice
|
|
|
|
* from_position : position of the first character in the slice
|
|
|
|
* to_position : position of the last character in the slice
|
|
|
|
* The to_line and to_position are not included in the slice, that is the lines
|
|
|
|
* in the slice are [from_line, to_line[. Likewise the characters in the slice
|
|
|
|
* are [from_position, to_position[.
|
|
|
|
* @param {Script} script The Script object for the source slice
|
|
|
|
* @param {number} from_line
|
|
|
|
* @param {number} to_line
|
|
|
|
* @param {number} from_position
|
|
|
|
* @param {number} to_position
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
function SourceSlice(script, from_line, to_line, from_position, to_position) {
|
|
|
|
this.script = script;
|
|
|
|
this.from_line = from_line;
|
|
|
|
this.to_line = to_line;
|
|
|
|
this.from_position = from_position;
|
|
|
|
this.to_position = to_position;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the source text for a SourceSlice
|
|
|
|
* @return {String} Source text for this slice. The last line will include
|
|
|
|
* the line terminating characters (if any)
|
|
|
|
*/
|
2011-09-05 07:30:35 +00:00
|
|
|
function SourceSliceSourceText() {
|
2011-01-28 10:33:10 +00:00
|
|
|
return %_CallFunction(this.script.source,
|
|
|
|
this.from_position,
|
|
|
|
this.to_position,
|
2015-05-21 06:15:33 +00:00
|
|
|
StringSubstring);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2015-05-26 07:24:13 +00:00
|
|
|
utils.SetUpLockedPrototype(SourceSlice,
|
2015-04-10 20:51:33 +00:00
|
|
|
["script", "from_line", "to_line", "from_position", "to_position"],
|
|
|
|
["sourceText", SourceSliceSourceText]
|
2011-09-05 07:30:35 +00:00
|
|
|
);
|
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// Returns the offset of the given position within the containing
|
|
|
|
// line.
|
|
|
|
function GetPositionInLine(message) {
|
2011-02-02 13:31:52 +00:00
|
|
|
var script = %MessageGetScript(message);
|
|
|
|
var start_position = %MessageGetStartPosition(message);
|
2015-07-20 15:56:11 +00:00
|
|
|
var location = script.locationFromPosition(start_position, true);
|
2008-07-03 15:10:15 +00:00
|
|
|
if (location == null) return -1;
|
2015-07-16 12:08:01 +00:00
|
|
|
return location.column;
|
2008-10-03 07:14:31 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
function GetStackTraceLine(recv, fun, pos, isGlobal) {
|
2013-03-28 10:40:07 +00:00
|
|
|
return new CallSite(recv, fun, pos, false).toString();
|
2008-10-03 07:14:31 +00:00
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Error implementation
|
|
|
|
|
2015-06-16 08:13:33 +00:00
|
|
|
var CallSiteReceiverKey = NEW_PRIVATE("CallSite#receiver");
|
|
|
|
var CallSiteFunctionKey = NEW_PRIVATE("CallSite#function");
|
|
|
|
var CallSitePositionKey = NEW_PRIVATE("CallSite#position");
|
|
|
|
var CallSiteStrictModeKey = NEW_PRIVATE("CallSite#strict_mode");
|
2013-03-28 10:40:07 +00:00
|
|
|
|
|
|
|
function CallSite(receiver, fun, pos, strict_mode) {
|
Provide private symbols through internal APIs
Adds a notion of private symbols, mainly intended for internal use, especially, self-hosting of built-in types that would otherwise require new C++ classes.
On the JS side (i.e., in built-ins), private properties can be created and accessed through a set of macros:
NEW_PRIVATE(print_name)
HAS_PRIVATE(obj, sym)
GET_PRIVATE(obj, sym)
SET_PRIVATE(obj, sym, val)
DELETE_PRIVATE(obj, sym)
In the V8 API, they are accessible via a new class Private, and respective HasPrivate/Get/Private/SetPrivate/DeletePrivate methods on calss Object.
These APIs are designed and restricted such that their implementation can later be replaced by whatever ES7+ will officially provide.
R=yangguo@chromium.org
BUG=
Review URL: https://codereview.chromium.org/48923002
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17683 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2013-11-13 10:34:06 +00:00
|
|
|
SET_PRIVATE(this, CallSiteReceiverKey, receiver);
|
|
|
|
SET_PRIVATE(this, CallSiteFunctionKey, fun);
|
|
|
|
SET_PRIVATE(this, CallSitePositionKey, pos);
|
|
|
|
SET_PRIVATE(this, CallSiteStrictModeKey, strict_mode);
|
2009-06-30 11:08:37 +00:00
|
|
|
}
|
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteGetThis() {
|
Provide private symbols through internal APIs
Adds a notion of private symbols, mainly intended for internal use, especially, self-hosting of built-in types that would otherwise require new C++ classes.
On the JS side (i.e., in built-ins), private properties can be created and accessed through a set of macros:
NEW_PRIVATE(print_name)
HAS_PRIVATE(obj, sym)
GET_PRIVATE(obj, sym)
SET_PRIVATE(obj, sym, val)
DELETE_PRIVATE(obj, sym)
In the V8 API, they are accessible via a new class Private, and respective HasPrivate/Get/Private/SetPrivate/DeletePrivate methods on calss Object.
These APIs are designed and restricted such that their implementation can later be replaced by whatever ES7+ will officially provide.
R=yangguo@chromium.org
BUG=
Review URL: https://codereview.chromium.org/48923002
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17683 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2013-11-13 10:34:06 +00:00
|
|
|
return GET_PRIVATE(this, CallSiteStrictModeKey)
|
|
|
|
? UNDEFINED : GET_PRIVATE(this, CallSiteReceiverKey);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2015-04-28 08:53:12 +00:00
|
|
|
function CallSiteGetFunction() {
|
|
|
|
return GET_PRIVATE(this, CallSiteStrictModeKey)
|
|
|
|
? UNDEFINED : GET_PRIVATE(this, CallSiteFunctionKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
function CallSiteGetPosition() {
|
|
|
|
return GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
}
|
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteGetTypeName() {
|
Provide private symbols through internal APIs
Adds a notion of private symbols, mainly intended for internal use, especially, self-hosting of built-in types that would otherwise require new C++ classes.
On the JS side (i.e., in built-ins), private properties can be created and accessed through a set of macros:
NEW_PRIVATE(print_name)
HAS_PRIVATE(obj, sym)
GET_PRIVATE(obj, sym)
SET_PRIVATE(obj, sym, val)
DELETE_PRIVATE(obj, sym)
In the V8 API, they are accessible via a new class Private, and respective HasPrivate/Get/Private/SetPrivate/DeletePrivate methods on calss Object.
These APIs are designed and restricted such that their implementation can later be replaced by whatever ES7+ will officially provide.
R=yangguo@chromium.org
BUG=
Review URL: https://codereview.chromium.org/48923002
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17683 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2013-11-13 10:34:06 +00:00
|
|
|
return GetTypeName(GET_PRIVATE(this, CallSiteReceiverKey), false);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteIsToplevel() {
|
2015-04-28 08:53:12 +00:00
|
|
|
var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
|
|
|
|
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
|
|
|
|
var pos = GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
return %CallSiteIsToplevelRT(receiver, fun, pos);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteIsEval() {
|
2015-04-28 08:53:12 +00:00
|
|
|
var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
|
|
|
|
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
|
|
|
|
var pos = GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
return %CallSiteIsEvalRT(receiver, fun, pos);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteGetEvalOrigin() {
|
Provide private symbols through internal APIs
Adds a notion of private symbols, mainly intended for internal use, especially, self-hosting of built-in types that would otherwise require new C++ classes.
On the JS side (i.e., in built-ins), private properties can be created and accessed through a set of macros:
NEW_PRIVATE(print_name)
HAS_PRIVATE(obj, sym)
GET_PRIVATE(obj, sym)
SET_PRIVATE(obj, sym, val)
DELETE_PRIVATE(obj, sym)
In the V8 API, they are accessible via a new class Private, and respective HasPrivate/Get/Private/SetPrivate/DeletePrivate methods on calss Object.
These APIs are designed and restricted such that their implementation can later be replaced by whatever ES7+ will officially provide.
R=yangguo@chromium.org
BUG=
Review URL: https://codereview.chromium.org/48923002
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17683 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2013-11-13 10:34:06 +00:00
|
|
|
var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
|
2009-12-01 14:36:45 +00:00
|
|
|
return FormatEvalOrigin(script);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteGetScriptNameOrSourceURL() {
|
2015-04-28 08:53:12 +00:00
|
|
|
var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
|
|
|
|
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
|
|
|
|
var pos = GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
return %CallSiteGetScriptNameOrSourceUrlRT(receiver, fun, pos);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-07-02 15:30:03 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteGetFunctionName() {
|
2009-06-30 11:08:37 +00:00
|
|
|
// See if the function knows its own name
|
2015-04-28 08:53:12 +00:00
|
|
|
var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
|
2015-03-13 15:11:47 +00:00
|
|
|
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
|
2015-04-28 08:53:12 +00:00
|
|
|
var pos = GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
return %CallSiteGetFunctionNameRT(receiver, fun, pos);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-07-02 12:26:31 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteGetMethodName() {
|
2009-06-30 11:08:37 +00:00
|
|
|
// See if we can find a unique property on the receiver that holds
|
|
|
|
// this function.
|
Provide private symbols through internal APIs
Adds a notion of private symbols, mainly intended for internal use, especially, self-hosting of built-in types that would otherwise require new C++ classes.
On the JS side (i.e., in built-ins), private properties can be created and accessed through a set of macros:
NEW_PRIVATE(print_name)
HAS_PRIVATE(obj, sym)
GET_PRIVATE(obj, sym)
SET_PRIVATE(obj, sym, val)
DELETE_PRIVATE(obj, sym)
In the V8 API, they are accessible via a new class Private, and respective HasPrivate/Get/Private/SetPrivate/DeletePrivate methods on calss Object.
These APIs are designed and restricted such that their implementation can later be replaced by whatever ES7+ will officially provide.
R=yangguo@chromium.org
BUG=
Review URL: https://codereview.chromium.org/48923002
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17683 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2013-11-13 10:34:06 +00:00
|
|
|
var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
|
|
|
|
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
|
2015-05-05 13:55:28 +00:00
|
|
|
var pos = GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
return %CallSiteGetMethodNameRT(receiver, fun, pos);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteGetFileName() {
|
2015-04-28 08:53:12 +00:00
|
|
|
var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
|
|
|
|
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
|
|
|
|
var pos = GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
return %CallSiteGetFileNameRT(receiver, fun, pos);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteGetLineNumber() {
|
2015-04-28 08:53:12 +00:00
|
|
|
var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
|
|
|
|
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
|
|
|
|
var pos = GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
return %CallSiteGetLineNumberRT(receiver, fun, pos);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteGetColumnNumber() {
|
2015-04-28 08:53:12 +00:00
|
|
|
var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
|
|
|
|
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
|
|
|
|
var pos = GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
return %CallSiteGetColumnNumberRT(receiver, fun, pos);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteIsNative() {
|
2015-04-28 08:53:12 +00:00
|
|
|
var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
|
|
|
|
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
|
|
|
|
var pos = GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
return %CallSiteIsNativeRT(receiver, fun, pos);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2011-09-05 07:30:35 +00:00
|
|
|
function CallSiteIsConstructor() {
|
Provide private symbols through internal APIs
Adds a notion of private symbols, mainly intended for internal use, especially, self-hosting of built-in types that would otherwise require new C++ classes.
On the JS side (i.e., in built-ins), private properties can be created and accessed through a set of macros:
NEW_PRIVATE(print_name)
HAS_PRIVATE(obj, sym)
GET_PRIVATE(obj, sym)
SET_PRIVATE(obj, sym, val)
DELETE_PRIVATE(obj, sym)
In the V8 API, they are accessible via a new class Private, and respective HasPrivate/Get/Private/SetPrivate/DeletePrivate methods on calss Object.
These APIs are designed and restricted such that their implementation can later be replaced by whatever ES7+ will officially provide.
R=yangguo@chromium.org
BUG=
Review URL: https://codereview.chromium.org/48923002
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17683 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2013-11-13 10:34:06 +00:00
|
|
|
var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
|
2015-05-05 13:55:28 +00:00
|
|
|
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
|
|
|
|
var pos = GET_PRIVATE(this, CallSitePositionKey);
|
|
|
|
return %CallSiteIsConstructorRT(receiver, fun, pos);
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-06-30 11:08:37 +00:00
|
|
|
|
2012-05-15 12:24:44 +00:00
|
|
|
function CallSiteToString() {
|
|
|
|
var fileName;
|
|
|
|
var fileLocation = "";
|
|
|
|
if (this.isNative()) {
|
|
|
|
fileLocation = "native";
|
|
|
|
} else {
|
2014-02-12 15:50:23 +00:00
|
|
|
fileName = this.getScriptNameOrSourceURL();
|
|
|
|
if (!fileName && this.isEval()) {
|
|
|
|
fileLocation = this.getEvalOrigin();
|
|
|
|
fileLocation += ", "; // Expecting source position to follow.
|
2012-06-18 13:39:24 +00:00
|
|
|
}
|
2012-05-15 12:24:44 +00:00
|
|
|
|
2012-06-18 13:39:24 +00:00
|
|
|
if (fileName) {
|
|
|
|
fileLocation += fileName;
|
|
|
|
} else {
|
|
|
|
// Source code does not originate from a file and is not native, but we
|
|
|
|
// can still get the source position inside the source string, e.g. in
|
|
|
|
// an eval string.
|
|
|
|
fileLocation += "<anonymous>";
|
|
|
|
}
|
2012-05-15 12:24:44 +00:00
|
|
|
var lineNumber = this.getLineNumber();
|
|
|
|
if (lineNumber != null) {
|
|
|
|
fileLocation += ":" + lineNumber;
|
|
|
|
var columnNumber = this.getColumnNumber();
|
|
|
|
if (columnNumber) {
|
|
|
|
fileLocation += ":" + columnNumber;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var line = "";
|
2012-05-24 11:00:05 +00:00
|
|
|
var functionName = this.getFunctionName();
|
|
|
|
var addSuffix = true;
|
2012-05-15 12:24:44 +00:00
|
|
|
var isConstructor = this.isConstructor();
|
|
|
|
var isMethodCall = !(this.isToplevel() || isConstructor);
|
|
|
|
if (isMethodCall) {
|
Provide private symbols through internal APIs
Adds a notion of private symbols, mainly intended for internal use, especially, self-hosting of built-in types that would otherwise require new C++ classes.
On the JS side (i.e., in built-ins), private properties can be created and accessed through a set of macros:
NEW_PRIVATE(print_name)
HAS_PRIVATE(obj, sym)
GET_PRIVATE(obj, sym)
SET_PRIVATE(obj, sym, val)
DELETE_PRIVATE(obj, sym)
In the V8 API, they are accessible via a new class Private, and respective HasPrivate/Get/Private/SetPrivate/DeletePrivate methods on calss Object.
These APIs are designed and restricted such that their implementation can later be replaced by whatever ES7+ will officially provide.
R=yangguo@chromium.org
BUG=
Review URL: https://codereview.chromium.org/48923002
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17683 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2013-11-13 10:34:06 +00:00
|
|
|
var typeName = GetTypeName(GET_PRIVATE(this, CallSiteReceiverKey), true);
|
2012-05-15 12:24:44 +00:00
|
|
|
var methodName = this.getMethodName();
|
|
|
|
if (functionName) {
|
2013-01-14 13:19:27 +00:00
|
|
|
if (typeName &&
|
2015-05-21 06:15:33 +00:00
|
|
|
%_CallFunction(functionName, typeName, StringIndexOf) != 0) {
|
2012-05-24 11:00:05 +00:00
|
|
|
line += typeName + ".";
|
|
|
|
}
|
2012-05-15 12:24:44 +00:00
|
|
|
line += functionName;
|
2013-01-14 13:19:27 +00:00
|
|
|
if (methodName &&
|
2015-05-21 06:15:33 +00:00
|
|
|
(%_CallFunction(functionName, "." + methodName, StringIndexOf) !=
|
2013-01-14 13:19:27 +00:00
|
|
|
functionName.length - methodName.length - 1)) {
|
2012-05-15 12:24:44 +00:00
|
|
|
line += " [as " + methodName + "]";
|
|
|
|
}
|
|
|
|
} else {
|
2012-05-24 11:00:05 +00:00
|
|
|
line += typeName + "." + (methodName || "<anonymous>");
|
2012-05-15 12:24:44 +00:00
|
|
|
}
|
|
|
|
} else if (isConstructor) {
|
|
|
|
line += "new " + (functionName || "<anonymous>");
|
|
|
|
} else if (functionName) {
|
|
|
|
line += functionName;
|
|
|
|
} else {
|
|
|
|
line += fileLocation;
|
2012-05-24 11:00:05 +00:00
|
|
|
addSuffix = false;
|
2012-05-15 12:24:44 +00:00
|
|
|
}
|
2012-05-24 11:00:05 +00:00
|
|
|
if (addSuffix) {
|
2012-05-15 12:24:44 +00:00
|
|
|
line += " (" + fileLocation + ")";
|
|
|
|
}
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
2015-05-26 07:24:13 +00:00
|
|
|
utils.SetUpLockedPrototype(CallSite, ["receiver", "fun", "pos"], [
|
2011-09-05 07:30:35 +00:00
|
|
|
"getThis", CallSiteGetThis,
|
|
|
|
"getTypeName", CallSiteGetTypeName,
|
|
|
|
"isToplevel", CallSiteIsToplevel,
|
|
|
|
"isEval", CallSiteIsEval,
|
|
|
|
"getEvalOrigin", CallSiteGetEvalOrigin,
|
|
|
|
"getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL,
|
|
|
|
"getFunction", CallSiteGetFunction,
|
|
|
|
"getFunctionName", CallSiteGetFunctionName,
|
|
|
|
"getMethodName", CallSiteGetMethodName,
|
|
|
|
"getFileName", CallSiteGetFileName,
|
|
|
|
"getLineNumber", CallSiteGetLineNumber,
|
|
|
|
"getColumnNumber", CallSiteGetColumnNumber,
|
|
|
|
"isNative", CallSiteIsNative,
|
|
|
|
"getPosition", CallSiteGetPosition,
|
2012-05-15 12:24:44 +00:00
|
|
|
"isConstructor", CallSiteIsConstructor,
|
|
|
|
"toString", CallSiteToString
|
2015-04-10 20:51:33 +00:00
|
|
|
]);
|
2011-09-05 07:30:35 +00:00
|
|
|
|
|
|
|
|
2009-12-01 14:36:45 +00:00
|
|
|
function FormatEvalOrigin(script) {
|
2010-09-20 15:55:28 +00:00
|
|
|
var sourceURL = script.nameOrSourceURL();
|
2011-08-22 09:51:56 +00:00
|
|
|
if (sourceURL) {
|
2010-09-20 15:55:28 +00:00
|
|
|
return sourceURL;
|
2011-08-22 09:51:56 +00:00
|
|
|
}
|
2010-09-20 15:55:28 +00:00
|
|
|
|
|
|
|
var eval_origin = "eval at ";
|
2009-12-01 14:36:45 +00:00
|
|
|
if (script.eval_from_function_name) {
|
|
|
|
eval_origin += script.eval_from_function_name;
|
|
|
|
} else {
|
|
|
|
eval_origin += "<anonymous>";
|
|
|
|
}
|
2010-03-30 07:15:23 +00:00
|
|
|
|
2009-12-01 14:36:45 +00:00
|
|
|
var eval_from_script = script.eval_from_script;
|
|
|
|
if (eval_from_script) {
|
2010-03-23 11:40:38 +00:00
|
|
|
if (eval_from_script.compilation_type == COMPILATION_TYPE_EVAL) {
|
2009-12-01 14:36:45 +00:00
|
|
|
// eval script originated from another eval.
|
2010-09-20 15:55:28 +00:00
|
|
|
eval_origin += " (" + FormatEvalOrigin(eval_from_script) + ")";
|
2009-12-01 14:36:45 +00:00
|
|
|
} else {
|
2010-09-20 15:55:28 +00:00
|
|
|
// eval script originated from "real" source.
|
2009-12-01 14:36:45 +00:00
|
|
|
if (eval_from_script.name) {
|
|
|
|
eval_origin += " (" + eval_from_script.name;
|
2011-11-28 12:11:00 +00:00
|
|
|
var location = eval_from_script.locationFromPosition(
|
|
|
|
script.eval_from_script_position, true);
|
2009-12-01 14:36:45 +00:00
|
|
|
if (location) {
|
|
|
|
eval_origin += ":" + (location.line + 1);
|
|
|
|
eval_origin += ":" + (location.column + 1);
|
|
|
|
}
|
2011-11-28 12:11:00 +00:00
|
|
|
eval_origin += ")";
|
2009-12-01 14:36:45 +00:00
|
|
|
} else {
|
|
|
|
eval_origin += " (unknown source)";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-03-30 07:15:23 +00:00
|
|
|
|
2009-12-01 14:36:45 +00:00
|
|
|
return eval_origin;
|
2011-11-28 12:11:00 +00:00
|
|
|
}
|
2009-12-01 14:36:45 +00:00
|
|
|
|
2013-01-14 13:19:27 +00:00
|
|
|
|
|
|
|
function FormatErrorString(error) {
|
2009-06-30 11:08:37 +00:00
|
|
|
try {
|
2013-01-14 13:19:27 +00:00
|
|
|
return %_CallFunction(error, ErrorToString);
|
2009-06-30 11:08:37 +00:00
|
|
|
} catch (e) {
|
|
|
|
try {
|
2013-01-14 13:19:27 +00:00
|
|
|
return "<error: " + e + ">";
|
2009-06-30 11:08:37 +00:00
|
|
|
} catch (ee) {
|
2013-01-14 13:19:27 +00:00
|
|
|
return "<error>";
|
2009-06-30 11:08:37 +00:00
|
|
|
}
|
|
|
|
}
|
2013-01-14 13:19:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function GetStackFrames(raw_stack) {
|
2013-02-15 16:21:03 +00:00
|
|
|
var frames = new InternalArray();
|
2014-03-11 14:39:08 +00:00
|
|
|
var sloppy_frames = raw_stack[0];
|
2013-03-28 10:40:07 +00:00
|
|
|
for (var i = 1; i < raw_stack.length; i += 4) {
|
2013-01-14 13:19:27 +00:00
|
|
|
var recv = raw_stack[i];
|
|
|
|
var fun = raw_stack[i + 1];
|
|
|
|
var code = raw_stack[i + 2];
|
|
|
|
var pc = raw_stack[i + 3];
|
2015-04-28 11:13:22 +00:00
|
|
|
var pos = %_IsSmi(code) ? code : %FunctionGetPositionForOffset(code, pc);
|
2014-03-11 14:39:08 +00:00
|
|
|
sloppy_frames--;
|
|
|
|
frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
|
2013-01-14 13:19:27 +00:00
|
|
|
}
|
|
|
|
return frames;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-07-26 11:28:08 +00:00
|
|
|
// Flag to prevent recursive call of Error.prepareStackTrace.
|
|
|
|
var formatting_custom_stack_trace = false;
|
|
|
|
|
|
|
|
|
2014-07-02 14:18:10 +00:00
|
|
|
function FormatStackTrace(obj, raw_stack) {
|
|
|
|
var frames = GetStackFrames(raw_stack);
|
2015-04-27 12:33:58 +00:00
|
|
|
if (IS_FUNCTION(GlobalError.prepareStackTrace) &&
|
|
|
|
!formatting_custom_stack_trace) {
|
2013-07-26 11:28:08 +00:00
|
|
|
var array = [];
|
|
|
|
%MoveArrayContents(frames, array);
|
|
|
|
formatting_custom_stack_trace = true;
|
2013-10-17 10:02:45 +00:00
|
|
|
var stack_trace = UNDEFINED;
|
2013-07-26 11:28:08 +00:00
|
|
|
try {
|
2015-04-27 12:33:58 +00:00
|
|
|
stack_trace = GlobalError.prepareStackTrace(obj, array);
|
2013-07-26 11:28:08 +00:00
|
|
|
} catch (e) {
|
|
|
|
throw e; // The custom formatting function threw. Rethrow.
|
|
|
|
} finally {
|
|
|
|
formatting_custom_stack_trace = false;
|
|
|
|
}
|
|
|
|
return stack_trace;
|
|
|
|
}
|
|
|
|
|
2013-02-15 16:21:03 +00:00
|
|
|
var lines = new InternalArray();
|
2014-07-02 14:18:10 +00:00
|
|
|
lines.push(FormatErrorString(obj));
|
2009-06-30 11:08:37 +00:00
|
|
|
for (var i = 0; i < frames.length; i++) {
|
|
|
|
var frame = frames[i];
|
2009-09-23 12:32:24 +00:00
|
|
|
var line;
|
2009-06-30 11:08:37 +00:00
|
|
|
try {
|
2012-05-15 12:24:44 +00:00
|
|
|
line = frame.toString();
|
2009-06-30 11:08:37 +00:00
|
|
|
} catch (e) {
|
|
|
|
try {
|
2009-09-23 12:32:24 +00:00
|
|
|
line = "<error: " + e + ">";
|
2009-06-30 11:08:37 +00:00
|
|
|
} catch (ee) {
|
|
|
|
// Any code that reaches this point is seriously nasty!
|
2009-09-23 12:32:24 +00:00
|
|
|
line = "<error>";
|
2009-06-30 11:08:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
lines.push(" at " + line);
|
|
|
|
}
|
2015-05-26 07:24:13 +00:00
|
|
|
return %_CallFunction(lines, "\n", ArrayJoin);
|
2009-06-30 11:08:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-28 10:40:07 +00:00
|
|
|
function GetTypeName(receiver, requireConstructor) {
|
2015-06-08 13:02:15 +00:00
|
|
|
if (IS_NULL_OR_UNDEFINED(receiver)) return null;
|
2013-03-28 10:40:07 +00:00
|
|
|
var constructor = receiver.constructor;
|
2012-05-24 11:00:05 +00:00
|
|
|
if (!constructor) {
|
|
|
|
return requireConstructor ? null :
|
2014-10-21 17:21:32 +00:00
|
|
|
%_CallFunction(receiver, NoSideEffectsObjectToString);
|
2012-05-24 11:00:05 +00:00
|
|
|
}
|
|
|
|
var constructorName = constructor.name;
|
|
|
|
if (!constructorName) {
|
|
|
|
return requireConstructor ? null :
|
2014-10-21 17:21:32 +00:00
|
|
|
%_CallFunction(receiver, NoSideEffectsObjectToString);
|
2012-05-24 11:00:05 +00:00
|
|
|
}
|
|
|
|
return constructorName;
|
|
|
|
}
|
2011-09-05 07:30:35 +00:00
|
|
|
|
2015-06-16 08:13:33 +00:00
|
|
|
var formatted_stack_trace_symbol = NEW_PRIVATE("formatted stack trace");
|
2014-07-02 14:18:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Format the stack trace if not yet done, and return it.
|
|
|
|
// Cache the formatted stack trace on the holder.
|
|
|
|
var StackTraceGetter = function() {
|
2014-09-24 08:12:58 +00:00
|
|
|
var formatted_stack_trace = UNDEFINED;
|
|
|
|
var holder = this;
|
2014-09-24 08:39:04 +00:00
|
|
|
while (holder) {
|
|
|
|
var formatted_stack_trace =
|
|
|
|
GET_PRIVATE(holder, formatted_stack_trace_symbol);
|
|
|
|
if (IS_UNDEFINED(formatted_stack_trace)) {
|
|
|
|
// No formatted stack trace available.
|
2015-04-27 12:33:58 +00:00
|
|
|
var stack_trace = GET_PRIVATE(holder, $stackTraceSymbol);
|
2014-09-24 08:39:04 +00:00
|
|
|
if (IS_UNDEFINED(stack_trace)) {
|
|
|
|
// Neither formatted nor structured stack trace available.
|
|
|
|
// Look further up the prototype chain.
|
2014-12-05 20:36:39 +00:00
|
|
|
holder = %_GetPrototype(holder);
|
2014-09-24 08:39:04 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
formatted_stack_trace = FormatStackTrace(holder, stack_trace);
|
2015-04-27 12:33:58 +00:00
|
|
|
SET_PRIVATE(holder, $stackTraceSymbol, UNDEFINED);
|
2014-09-24 08:39:04 +00:00
|
|
|
SET_PRIVATE(holder, formatted_stack_trace_symbol, formatted_stack_trace);
|
2014-06-30 13:16:42 +00:00
|
|
|
}
|
2014-09-24 08:39:04 +00:00
|
|
|
return formatted_stack_trace;
|
2014-07-02 14:18:10 +00:00
|
|
|
}
|
2014-09-24 08:39:04 +00:00
|
|
|
return UNDEFINED;
|
2014-07-02 14:18:10 +00:00
|
|
|
};
|
2014-06-30 11:48:20 +00:00
|
|
|
|
|
|
|
|
2014-07-02 14:18:10 +00:00
|
|
|
// If the receiver equals the holder, set the formatted stack trace that the
|
|
|
|
// getter returns.
|
|
|
|
var StackTraceSetter = function(v) {
|
2015-04-27 12:33:58 +00:00
|
|
|
if (HAS_PRIVATE(this, $stackTraceSymbol)) {
|
|
|
|
SET_PRIVATE(this, $stackTraceSymbol, UNDEFINED);
|
2014-07-02 14:18:10 +00:00
|
|
|
SET_PRIVATE(this, formatted_stack_trace_symbol, v);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Use a dummy function since we do not actually want to capture a stack trace
|
|
|
|
// when constructing the initial Error prototytpes.
|
2015-05-26 07:24:13 +00:00
|
|
|
var captureStackTrace = function() {};
|
2009-07-27 12:01:32 +00:00
|
|
|
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2015-04-27 12:33:58 +00:00
|
|
|
// Define special error type constructors.
|
2015-05-11 08:14:54 +00:00
|
|
|
function DefineError(global, f) {
|
2015-04-27 12:33:58 +00:00
|
|
|
// Store the error function in both the global object
|
|
|
|
// and the runtime object. The function is fetched
|
|
|
|
// from the runtime object when throwing errors from
|
|
|
|
// within the runtime system to avoid strange side
|
|
|
|
// effects when overwriting the error functions from
|
|
|
|
// user code.
|
|
|
|
var name = f.name;
|
|
|
|
%AddNamedProperty(global, name, f, DONT_ENUM);
|
|
|
|
// Configure the error function.
|
|
|
|
if (name == 'Error') {
|
|
|
|
// The prototype of the Error object must itself be an error.
|
|
|
|
// However, it can't be an instance of the Error object because
|
|
|
|
// it hasn't been properly configured yet. Instead we create a
|
|
|
|
// special not-a-true-error-but-close-enough object.
|
|
|
|
var ErrorPrototype = function() {};
|
|
|
|
%FunctionSetPrototype(ErrorPrototype, GlobalObject.prototype);
|
|
|
|
%FunctionSetInstanceClassName(ErrorPrototype, 'Error');
|
|
|
|
%FunctionSetPrototype(f, new ErrorPrototype());
|
|
|
|
} else {
|
|
|
|
%FunctionSetPrototype(f, new GlobalError());
|
|
|
|
%InternalSetPrototype(f, GlobalError);
|
|
|
|
}
|
|
|
|
%FunctionSetInstanceClassName(f, 'Error');
|
|
|
|
%AddNamedProperty(f.prototype, 'constructor', f, DONT_ENUM);
|
|
|
|
%AddNamedProperty(f.prototype, 'name', name, DONT_ENUM);
|
|
|
|
%SetCode(f, function(m) {
|
|
|
|
if (%_IsConstructCall()) {
|
|
|
|
try { captureStackTrace(this, f); } catch (e) { }
|
|
|
|
// Define all the expected properties directly on the error
|
|
|
|
// object. This avoids going through getters and setters defined
|
|
|
|
// on prototype objects.
|
|
|
|
if (!IS_UNDEFINED(m)) {
|
2015-05-07 08:39:53 +00:00
|
|
|
%AddNamedProperty(this, 'message', $toString(m), DONT_ENUM);
|
2015-04-27 12:33:58 +00:00
|
|
|
}
|
2011-09-01 07:39:22 +00:00
|
|
|
} else {
|
2015-04-27 12:33:58 +00:00
|
|
|
return new f(m);
|
2011-09-01 07:39:22 +00:00
|
|
|
}
|
2015-04-27 12:33:58 +00:00
|
|
|
});
|
|
|
|
%SetNativeFlag(f);
|
|
|
|
return f;
|
|
|
|
};
|
2011-09-05 07:30:35 +00:00
|
|
|
|
2015-05-11 08:14:54 +00:00
|
|
|
GlobalError = DefineError(global, function Error() { });
|
|
|
|
GlobalEvalError = DefineError(global, function EvalError() { });
|
|
|
|
GlobalRangeError = DefineError(global, function RangeError() { });
|
|
|
|
GlobalReferenceError = DefineError(global, function ReferenceError() { });
|
|
|
|
GlobalSyntaxError = DefineError(global, function SyntaxError() { });
|
|
|
|
GlobalTypeError = DefineError(global, function TypeError() { });
|
|
|
|
GlobalURIError = DefineError(global, function URIError() { });
|
2011-06-15 13:54:40 +00:00
|
|
|
|
2015-04-27 12:33:58 +00:00
|
|
|
%AddNamedProperty(GlobalError.prototype, 'message', '', DONT_ENUM);
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2011-10-26 10:41:52 +00:00
|
|
|
function ErrorToString() {
|
2012-03-05 13:57:48 +00:00
|
|
|
if (!IS_SPEC_OBJECT(this)) {
|
2015-04-21 09:03:24 +00:00
|
|
|
throw MakeTypeError(kCalledOnNonObject, "Error.prototype.toString");
|
2011-05-05 05:21:30 +00:00
|
|
|
}
|
2011-01-21 11:44:29 +00:00
|
|
|
|
2015-08-11 09:15:27 +00:00
|
|
|
return %ErrorToStringRT(this);
|
2011-01-14 12:51:04 +00:00
|
|
|
}
|
2011-01-14 14:51:19 +00:00
|
|
|
|
2015-05-26 07:24:13 +00:00
|
|
|
utils.InstallFunctions(GlobalError.prototype, DONT_ENUM,
|
|
|
|
['toString', ErrorToString]);
|
2015-04-27 12:33:58 +00:00
|
|
|
|
|
|
|
$errorToString = ErrorToString;
|
|
|
|
$messageGetPositionInLine = GetPositionInLine;
|
|
|
|
$messageGetLineNumber = GetLineNumber;
|
|
|
|
$messageGetSourceLine = GetSourceLine;
|
2015-05-18 08:34:05 +00:00
|
|
|
$noSideEffectToString = NoSideEffectToString;
|
2015-04-27 12:33:58 +00:00
|
|
|
$toDetailString = ToDetailString;
|
|
|
|
|
|
|
|
$Error = GlobalError;
|
|
|
|
$EvalError = GlobalEvalError;
|
|
|
|
$RangeError = GlobalRangeError;
|
|
|
|
$ReferenceError = GlobalReferenceError;
|
|
|
|
$SyntaxError = GlobalSyntaxError;
|
|
|
|
$TypeError = GlobalTypeError;
|
|
|
|
$URIError = GlobalURIError;
|
|
|
|
|
|
|
|
MakeError = function(type, arg0, arg1, arg2) {
|
|
|
|
return MakeGenericError(GlobalError, type, arg0, arg1, arg2);
|
|
|
|
}
|
|
|
|
|
|
|
|
MakeEvalError = function(type, arg0, arg1, arg2) {
|
|
|
|
return MakeGenericError(GlobalEvalError, type, arg0, arg1, arg2);
|
|
|
|
}
|
|
|
|
|
|
|
|
MakeRangeError = function(type, arg0, arg1, arg2) {
|
|
|
|
return MakeGenericError(GlobalRangeError, type, arg0, arg1, arg2);
|
|
|
|
}
|
2011-02-28 13:29:05 +00:00
|
|
|
|
2015-04-27 12:33:58 +00:00
|
|
|
MakeReferenceError = function(type, arg0, arg1, arg2) {
|
|
|
|
return MakeGenericError(GlobalReferenceError, type, arg0, arg1, arg2);
|
|
|
|
}
|
2008-07-03 15:10:15 +00:00
|
|
|
|
2015-04-27 12:33:58 +00:00
|
|
|
MakeSyntaxError = function(type, arg0, arg1, arg2) {
|
|
|
|
return MakeGenericError(GlobalSyntaxError, type, arg0, arg1, arg2);
|
|
|
|
}
|
2012-11-12 14:54:29 +00:00
|
|
|
|
2015-04-27 12:33:58 +00:00
|
|
|
MakeTypeError = function(type, arg0, arg1, arg2) {
|
|
|
|
return MakeGenericError(GlobalTypeError, type, arg0, arg1, arg2);
|
|
|
|
}
|
2012-11-12 14:54:29 +00:00
|
|
|
|
2015-04-27 12:33:58 +00:00
|
|
|
MakeURIError = function() {
|
|
|
|
return MakeGenericError(GlobalURIError, kURIMalformed);
|
2012-11-12 14:54:29 +00:00
|
|
|
}
|
|
|
|
|
2015-05-26 07:24:13 +00:00
|
|
|
// Boilerplate for exceptions for stack overflows. Used from
|
|
|
|
// Isolate::StackOverflow().
|
2015-04-27 12:33:58 +00:00
|
|
|
$stackOverflowBoilerplate = MakeRangeError(kStackOverflow);
|
|
|
|
%DefineAccessorPropertyUnchecked($stackOverflowBoilerplate, 'stack',
|
2015-05-26 07:24:13 +00:00
|
|
|
StackTraceGetter, StackTraceSetter,
|
|
|
|
DONT_ENUM);
|
2015-04-27 12:33:58 +00:00
|
|
|
|
2015-05-26 07:24:13 +00:00
|
|
|
// Define actual captureStackTrace function after everything has been set up.
|
|
|
|
captureStackTrace = function captureStackTrace(obj, cons_opt) {
|
|
|
|
// Define accessors first, as this may fail and throw.
|
|
|
|
ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter,
|
|
|
|
set: StackTraceSetter,
|
|
|
|
configurable: true });
|
|
|
|
%CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace);
|
|
|
|
};
|
|
|
|
|
|
|
|
GlobalError.captureStackTrace = captureStackTrace;
|
|
|
|
|
2015-08-14 12:34:45 +00:00
|
|
|
utils.ExportToRuntime(function(to) {
|
|
|
|
to.GetStackTraceLine = GetStackTraceLine;
|
|
|
|
});
|
|
|
|
|
2015-05-26 07:24:13 +00:00
|
|
|
});
|