var date = new ORIGINAL_DATE();
date.setTime(time);
return date;
-};
+}
const kApiFunctionCache = {};
const functionCache = kApiFunctionCache;
-function Instantiate(data) {
+function Instantiate(data, name) {
if (!%IsTemplate(data)) return data;
var tag = %GetTemplateField(data, kApiTagOffset);
switch (tag) {
case kFunctionTag:
- return InstantiateFunction(data);
+ return InstantiateFunction(data, name);
case kNewObjectTag:
var Constructor = %GetTemplateField(data, kApiConstructorOffset);
var result = Constructor ? new (Instantiate(Constructor))() : {};
default:
throw 'Unknown API tag <' + tag + '>';
}
-};
+}
-function InstantiateFunction(data) {
+function InstantiateFunction(data, name) {
var serialNumber = %GetTemplateField(data, kApiSerialNumberOffset);
if (!(serialNumber in kApiFunctionCache)) {
kApiFunctionCache[serialNumber] = null;
var fun = %CreateApiFunction(data);
+ if (name) %FunctionSetName(fun, name);
kApiFunctionCache[serialNumber] = fun;
var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
fun.prototype = prototype ? Instantiate(prototype) : {};
ConfigureTemplateInstance(fun, data);
}
return kApiFunctionCache[serialNumber];
-};
+}
function ConfigureTemplateInstance(obj, data) {
var name = properties[i + 1];
var prop_data = properties[i + 2];
var attributes = properties[i + 3];
- var value = Instantiate(prop_data);
+ var value = Instantiate(prop_data, name);
%SetProperty(obj, name, value, attributes);
}
}
-};
+}
// Make sure to pop the visited array no matter what happens.
if (is_array) visited_arrays.pop();
}
-};
+}
function ConvertToString(e) {
if (e == null) return '';
else return ToString(e);
-};
+}
function ConvertToLocaleString(e) {
else
return ToString(e);
}
-};
+}
// This function implements the optimized splice implementation that can use
}
}
}
-};
+}
// This function implements the optimized splice implementation that can use
}
// Move contents of new_array into this array
%MoveArrayContents(new_array, array);
-};
+}
// This is part of the old simple-minded splice. We are using it either
if (!IS_UNDEFINED(current) || index in array)
deleted_elements[i] = current;
}
-};
+}
function SimpleMove(array, start_i, del_count, len, num_additional_args) {
}
}
}
-};
+}
// -------------------------------------------------------------------
throw new $TypeError('Array.prototype.toString is not generic');
}
return Join(this, this.length, ',', ConvertToString);
-};
+}
function ArrayToLocaleString() {
throw new $TypeError('Array.prototype.toString is not generic');
}
return Join(this, this.length, ',', ConvertToLocaleString);
-};
+}
function ArrayJoin(separator) {
if (IS_UNDEFINED(separator)) separator = ',';
else separator = ToString(separator);
return Join(this, ToUint32(this.length), separator, ConvertToString);
-};
+}
// Removes the last element from the array and returns it. See
this.length = n;
delete this[n];
return value;
-};
+}
// Appends the arguments to the end of the array and returns the new
}
this.length = n + m;
return this.length;
-};
+}
function ArrayConcat(arg1) { // length == 1
A.length = n; // may contain empty arrays
return A;
-};
+}
// For implementing reverse() on large, sparse arrays.
}
}
return this;
-};
+}
function ArrayShift() {
var len = ToUint32(this.length);
-
+
if (len === 0) {
this.length = 0;
return;
}
-
+
var first = this[0];
-
+
if (IS_ARRAY(this))
SmartMove(this, 0, 1, len, 0);
else
SimpleMove(this, 0, 1, len, 0);
-
+
this.length = len - 1;
-
+
return first;
-};
+}
function ArrayUnshift(arg1) { // length == 1
var len = ToUint32(this.length);
var num_arguments = %_ArgumentsLength();
-
+
if (IS_ARRAY(this))
SmartMove(this, 0, 0, len, num_arguments);
else
SimpleMove(this, 0, 0, len, num_arguments);
-
+
for (var i = 0; i < num_arguments; i++) {
this[i] = %_Arguments(i);
}
-
+
this.length = len + num_arguments;
-
+
return len + num_arguments;
-};
+}
function ArraySlice(start, end) {
var len = ToUint32(this.length);
var start_i = TO_INTEGER(start);
var end_i = len;
-
+
if (end !== void 0) end_i = TO_INTEGER(end);
-
+
if (start_i < 0) {
start_i += len;
if (start_i < 0) start_i = 0;
} else {
if (start_i > len) start_i = len;
}
-
+
if (end_i < 0) {
end_i += len;
if (end_i < 0) end_i = 0;
} else {
if (end_i > len) end_i = len;
}
-
+
var result = [];
-
- if (end_i < start_i)
- return result;
-
- if (IS_ARRAY(this))
+
+ if (end_i < start_i) return result;
+
+ if (IS_ARRAY(this)) {
SmartSlice(this, start_i, end_i - start_i, len, result);
- else
+ } else {
SimpleSlice(this, start_i, end_i - start_i, len, result);
-
+ }
+
result.length = end_i - start_i;
-
+
return result;
-};
+}
function ArraySplice(start, delete_count) {
var num_arguments = %_ArgumentsLength();
-
+
// SpiderMonkey and KJS return undefined in the case where no
// arguments are given instead of using the implicit undefined
// arguments. This does not follow ECMA-262, but we do the same for
// compatibility.
if (num_arguments == 0) return;
-
+
var len = ToUint32(this.length);
var start_i = TO_INTEGER(start);
-
+
if (start_i < 0) {
start_i += len;
if (start_i < 0) start_i = 0;
} else {
if (start_i > len) start_i = len;
}
-
+
// SpiderMonkey and KJS treat the case where no delete count is
// given differently from when an undefined delete count is given.
// This does not follow ECMA-262, but we do the same for
} else {
del_count = len - start_i;
}
-
+
var deleted_elements = [];
deleted_elements.length = del_count;
-
+
// Number of elements to add.
var num_additional_args = 0;
if (num_arguments > 2) {
num_additional_args = num_arguments - 2;
}
-
+
var use_simple_splice = true;
-
+
if (IS_ARRAY(this) && num_additional_args !== del_count) {
// If we are only deleting/moving a few things near the end of the
// array then the simple version is going to be faster, because it
use_simple_splice = false;
}
}
-
+
if (use_simple_splice) {
SimpleSlice(this, start_i, del_count, len, deleted_elements);
SimpleMove(this, start_i, del_count, len, num_additional_args);
SmartSlice(this, start_i, del_count, len, deleted_elements);
SmartMove(this, start_i, del_count, len, num_additional_args);
}
-
+
// Insert the arguments into the resulting array in
// place of the deleted elements.
var i = start_i;
this[i++] = %_Arguments(arguments_index++);
}
this.length = len - del_count + num_additional_args;
-
+
// Return the deleted elements.
return deleted_elements;
-};
+}
function ArraySort(comparefn) {
// For short (length <= 22) arrays, insertion sort is used for efficiency.
var custom_compare = IS_FUNCTION(comparefn);
-
+
function Compare(x,y) {
if (custom_compare) {
return comparefn.call(null, x, y);
}
return this;
-};
+}
// The following functions cannot be made efficient on sparse arrays while
// preserving the semantics, since the calls to the receiver function can add
// or delete elements from the array.
-
function ArrayFilter(f, receiver) {
if (!IS_FUNCTION(f)) {
throw MakeTypeError('called_non_callable', [ f ]);
}
}
return result;
-};
+}
function ArrayForEach(f, receiver) {
f.call(receiver, current, i, this);
}
}
-};
+}
// Executes the function once for each element present in the
}
}
return false;
-};
+}
function ArrayEvery(f, receiver) {
if (!f.call(receiver, current, i, this)) return false;
}
}
-
+
return true;
-};
+}
function ArrayMap(f, receiver) {
}
}
return result;
-};
+}
function ArrayIndexOf(element, index) {
}
}
return -1;
-};
+}
function ArrayLastIndexOf(element, index) {
}
}
return -1;
-};
+}
// -------------------------------------------------------------------
-function InstallProperties(prototype, attributes, properties) {
- for (var key in properties) {
- %AddProperty(prototype, key, properties[key], attributes);
+function InstallFunctions(prototype, attributes, functions) {
+ for (var i = 0; i < functions.length; i += 2) {
+ var key = functions[i];
+ var f = functions[i + 1];
+ %FunctionSetName(f, key);
+ %AddProperty(prototype, key, f, attributes);
}
-};
+}
function UpdateFunctionLengths(lengths) {
for (var key in lengths) {
%FunctionSetLength(this[key], lengths[key]);
}
-};
+}
// -------------------------------------------------------------------
function SetupArray() {
- // Setup non-enumerable properties of the Array.prototype object.
- InstallProperties($Array.prototype, DONT_ENUM, {
- constructor: $Array,
- toString: ArrayToString,
- toLocaleString: ArrayToLocaleString,
- join: ArrayJoin,
- pop: ArrayPop,
- push: ArrayPush,
- concat: ArrayConcat,
- reverse: ArrayReverse,
- shift: ArrayShift,
- unshift: ArrayUnshift,
- slice: ArraySlice,
- splice: ArraySplice,
- sort: ArraySort,
- filter: ArrayFilter,
- forEach: ArrayForEach,
- some: ArraySome,
- every: ArrayEvery,
- map: ArrayMap,
- indexOf: ArrayIndexOf,
- lastIndexOf: ArrayLastIndexOf
- });
+ // Setup non-enumerable constructor property on the Array.prototype
+ // object.
+ %AddProperty($Array.prototype, "constructor", $Array, DONT_ENUM);
+
+ // Setup non-enumerable functions of the Array.prototype object and
+ // set their names.
+ InstallFunctions($Array.prototype, DONT_ENUM, $Array(
+ "toString", ArrayToString,
+ "toLocaleString", ArrayToLocaleString,
+ "join", ArrayJoin,
+ "pop", ArrayPop,
+ "push", ArrayPush,
+ "concat", ArrayConcat,
+ "reverse", ArrayReverse,
+ "shift", ArrayShift,
+ "unshift", ArrayUnshift,
+ "slice", ArraySlice,
+ "splice", ArraySplice,
+ "sort", ArraySort,
+ "filter", ArrayFilter,
+ "forEach", ArrayForEach,
+ "some", ArraySome,
+ "every", ArrayEvery,
+ "map", ArrayMap,
+ "indexOf", ArrayIndexOf,
+ "lastIndexOf", ArrayLastIndexOf
+ ));
// Manipulate the length of some of the functions to meet
// expectations set by ECMA-262 or Mozilla.
ArrayLastIndexOf: 1,
ArrayPush: 1
});
-};
+}
SetupArray();
// ECMA 262 - 15.9.1.2
function Day(time) {
return $floor(time/msPerDay);
-};
+}
// ECMA 262 - 5.2
function Modulo(value, remainder) {
var mod = value % remainder;
return mod >= 0 ? mod : mod + remainder;
-};
+}
function TimeWithinDay(time) {
return Modulo(time, msPerDay);
-};
+}
// ECMA 262 - 15.9.1.3
if (year % 4 != 0) return 365;
if ((year % 100 == 0) && (year % 400 != 0)) return 365;
return 366;
-};
+}
function DayFromYear(year) {
+ $floor((year-1969)/4)
- $floor((year-1901)/100)
+ $floor((year-1601)/400);
-};
+}
function TimeFromYear(year) {
return msPerDay * DayFromYear(year);
-};
+}
function YearFromTime(time) {
return FromJulianDay(Day(time) + kDayZeroInJulianDay).year;
-};
+}
function InLeapYear(time) {
return DaysInYear(YearFromTime(time)) == 366 ? 1 : 0;
-};
+}
// ECMA 262 - 15.9.1.4
function MonthFromTime(time) {
return FromJulianDay(Day(time) + kDayZeroInJulianDay).month;
-};
+}
function DayWithinYear(time) {
return Day(time) - DayFromYear(YearFromTime(time));
-};
+}
// ECMA 262 - 15.9.1.5
function DateFromTime(time) {
return FromJulianDay(Day(time) + kDayZeroInJulianDay).date;
-};
+}
// ECMA 262 - 15.9.1.9
// - week day of first day.
var time = TimeFromYear(year);
return (InLeapYear(time) == 0 ? 1967 : 1956) + (WeekDay(time) * 12) % 28;
-};
+}
function EquivalentTime(t) {
if (t >= -2.1e12 && t <= 2.1e12) return t;
var day = MakeDay(EquivalentYear(YearFromTime(t)), MonthFromTime(t), DateFromTime(t));
return TimeClip(MakeDate(day, TimeWithinDay(t)));
-};
+}
var local_time_offset;
local_time_offset = %DateLocalTimeOffset();
}
return local_time_offset;
-};
+}
var daylight_cache_time = $NaN;
daylight_cache_time = t;
daylight_cache_offset = offset;
return offset;
-};
+}
var timezone_cache_time = $NaN;
timezone_cache_time = t;
timezone_cache_timezone = timezone;
return timezone;
-};
+}
function WeekDay(time) {
return Modulo(Day(time) + 4, 7);
-};
+}
function LocalTime(time) {
if ($isNaN(time)) return time;
return time + LocalTimeOffset() + DaylightSavingsOffset(time);
-};
+}
function UTC(time) {
if ($isNaN(time)) return time;
var tmp = time - LocalTimeOffset();
return tmp - DaylightSavingsOffset(tmp);
-};
+}
// ECMA 262 - 15.9.1.10
function HourFromTime(time) {
return Modulo($floor(time / msPerHour), HoursPerDay);
-};
+}
function MinFromTime(time) {
return Modulo($floor(time / msPerMinute), MinutesPerHour);
-};
+}
function SecFromTime(time) {
return Modulo($floor(time / msPerSecond), SecondsPerMinute);
-};
+}
function msFromTime(time) {
return Modulo(time, msPerSecond);
-};
+}
// ECMA 262 - 15.9.1.11
+ TO_INTEGER(min) * msPerMinute
+ TO_INTEGER(sec) * msPerSecond
+ TO_INTEGER(ms);
-};
+}
// ECMA 262 - 15.9.1.12
function TimeInYear(year) {
return DaysInYear(year) * msPerDay;
-};
+}
// Compute modified Julian day from year, month, date.
var jm = (month > 1) ? month + 2 : month + 14;
var ja = $floor(0.01*jy);
return $floor($floor(365.25*jy) + $floor(30.6001*jm) + date + 1720995) + 2 - ja + $floor(0.25*ja);
-};
+}
var four_year_cycle_table;
}
}
return four_year_cycle_table;
-};
+}
this.date = date;
}
+
// Compute year, month, and day from modified Julian day.
// The missing days in 1582 are ignored for JavaScript compatibility.
function FromJulianDay(julian) {
if (m > 2) { --y; --m; }
var d = jb - jd - $floor(30.6001 * je);
return new DayTriplet(y, m, d);
-};
+}
// Compute number of days given a year, month, date.
// Note that month and date can lie outside the normal range.
// Return days relative to Jan 1 1970.
return ToJulianDay(year, month, date) - kDayZeroInJulianDay;
-};
+}
// ECMA 262 - 15.9.1.13
if (!$isFinite(day)) return $NaN;
if (!$isFinite(time)) return $NaN;
return day * msPerDay + time;
-};
+}
// ECMA 262 - 15.9.1.14
if (!$isFinite(time)) return $NaN;
if ($abs(time) > 8.64E15) return $NaN;
return TO_INTEGER(time);
-};
+}
%SetCode($Date, function(year, month, date, hours, minutes, seconds, ms) {
function GetTimeFrom(aDate) {
if (IS_DATE(aDate)) return %_ValueOf(aDate);
throw new $TypeError('this is not a Date object.');
-};
+}
function GetMillisecondsFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return msFromTime(LocalTime(t));
-};
+}
function GetUTCMillisecondsFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return msFromTime(t);
-};
+}
function GetSecondsFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return SecFromTime(LocalTime(t));
-};
+}
function GetUTCSecondsFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return SecFromTime(t);
-};
+}
function GetMinutesFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return MinFromTime(LocalTime(t));
-};
+}
function GetUTCMinutesFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return MinFromTime(t);
-};
+}
function GetHoursFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return HourFromTime(LocalTime(t));
-};
+}
function GetUTCHoursFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return HourFromTime(t);
-};
+}
function GetFullYearFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return YearFromTime(LocalTime(t));
-};
+}
function GetUTCFullYearFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return YearFromTime(t);
-};
+}
function GetMonthFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return MonthFromTime(LocalTime(t));
-};
+}
function GetUTCMonthFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return MonthFromTime(t);
-};
+}
function GetDateFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return DateFromTime(LocalTime(t));
-};
+}
function GetUTCDateFrom(aDate) {
var t = GetTimeFrom(aDate);
if ($isNaN(t)) return t;
return DateFromTime(t);
-};
+}
%FunctionSetPrototype($Date, new $Date($NaN));
function TwoDigitString(value) {
return value < 10 ? "0" + value : "" + value;
-};
+}
function DateString(time) {
+ Months[YMD.month] + ' '
+ TwoDigitString(YMD.date) + ' '
+ YMD.year;
-};
+}
function TimeString(time) {
return TwoDigitString(HourFromTime(time)) + ':'
+ TwoDigitString(MinFromTime(time)) + ':'
+ TwoDigitString(SecFromTime(time));
-};
+}
function LocalTimezoneString(time) {
var min = $floor((sign * timezoneOffset)%60);
var gmt = ' GMT' + ((sign == 1) ? '+' : '-') + TwoDigitString(hours) + TwoDigitString(min);
return gmt + ' (' + LocalTimezone(time) + ')';
-};
+}
function DatePrintString(time) {
return DateString(time) + ' ' + TimeString(time);
-};
+}
// -------------------------------------------------------------------
var day = MakeDay(arr[0], arr[1], arr[2]);
var time = MakeTime(arr[3], arr[4], arr[5], 0);
var date = MakeDate(day, time);
-
+
if (IS_NULL(arr[6])) {
return TimeClip(UTC(date));
} else {
return TimeClip(date - arr[6] * 1000);
}
-};
+}
// ECMA 262 - 15.9.4.3
var day = MakeDay(year, month, date);
var time = MakeTime(hours, minutes, seconds, ms);
return %_SetValueOf(this, TimeClip(MakeDate(day, time)));
-};
+}
// Mozilla-specific extension. Returns the number of milliseconds
// elapsed since 1 January 1970 00:00:00 UTC.
function DateNow() {
return %DateCurrentTime();
-};
+}
// ECMA 262 - 15.9.5.2
var t = GetTimeFrom(this);
if ($isNaN(t)) return kInvalidDate;
return DatePrintString(LocalTime(t)) + LocalTimezoneString(t);
-};
+}
// ECMA 262 - 15.9.5.3
var t = GetTimeFrom(this);
if ($isNaN(t)) return kInvalidDate;
return DateString(LocalTime(t));
-};
+}
// ECMA 262 - 15.9.5.4
if ($isNaN(t)) return kInvalidDate;
var lt = LocalTime(t);
return TimeString(lt) + LocalTimezoneString(lt);
-};
+}
+
+
+// ECMA 262 - 15.9.5.5
+function DateToLocaleString() {
+ return DateToString.call(this);
+}
+
+
+// ECMA 262 - 15.9.5.6
+function DateToLocaleDateString() {
+ return DateToDateString.call(this);
+}
// ECMA 262 - 15.9.5.7
if ($isNaN(t)) return kInvalidDate;
var lt = LocalTime(t);
return TimeString(lt);
-};
+}
+
+
+// ECMA 262 - 15.9.5.8
+function DateValueOf() {
+ return GetTimeFrom(this);
+}
// ECMA 262 - 15.9.5.9
// ECMA 262 - 15.9.5.10
function DateGetFullYear() {
return GetFullYearFrom(this)
-};
+}
// ECMA 262 - 15.9.5.11
function DateGetUTCFullYear() {
return GetUTCFullYearFrom(this)
-};
+}
// ECMA 262 - 15.9.5.12
function DateGetMonth() {
return GetMonthFrom(this);
-};
+}
// ECMA 262 - 15.9.5.13
function DateGetUTCMonth() {
return GetUTCMonthFrom(this);
-};
+}
// ECMA 262 - 15.9.5.14
function DateGetDate() {
return GetDateFrom(this);
-};
+}
// ECMA 262 - 15.9.5.15
function DateGetUTCDate() {
return GetUTCDateFrom(this);
-};
+}
// ECMA 262 - 15.9.5.16
var t = GetTimeFrom(this);
if ($isNaN(t)) return t;
return WeekDay(LocalTime(t));
-};
+}
// ECMA 262 - 15.9.5.17
var t = GetTimeFrom(this);
if ($isNaN(t)) return t;
return WeekDay(t);
-};
+}
// ECMA 262 - 15.9.5.18
function DateGetHours() {
return GetHoursFrom(this);
-};
+}
// ECMA 262 - 15.9.5.19
function DateGetUTCHours() {
return GetUTCHoursFrom(this);
-};
+}
// ECMA 262 - 15.9.5.20
function DateGetMinutes() {
return GetMinutesFrom(this);
-};
+}
// ECMA 262 - 15.9.5.21
function DateGetUTCMinutes() {
return GetUTCMinutesFrom(this);
-};
+}
// ECMA 262 - 15.9.5.22
function DateGetSeconds() {
return GetSecondsFrom(this);
-};
+}
// ECMA 262 - 15.9.5.23
function DateGetUTCSeconds() {
return GetUTCSecondsFrom(this);
-};
+}
// ECMA 262 - 15.9.5.24
function DateGetMilliseconds() {
return GetMillisecondsFrom(this);
-};
+}
// ECMA 262 - 15.9.5.25
function DateGetUTCMilliseconds() {
return GetUTCMillisecondsFrom(this);
-};
+}
// ECMA 262 - 15.9.5.26
var t = GetTimeFrom(this);
if ($isNaN(t)) return t;
return (t - LocalTime(t)) / msPerMinute;
-};
+}
// ECMA 262 - 15.9.5.27
function DateSetTime(ms) {
if (!IS_DATE(this)) throw new $TypeError('this is not a Date object.');
return %_SetValueOf(this, TimeClip(ToNumber(ms)));
-};
+}
// ECMA 262 - 15.9.5.28
ms = ToNumber(ms);
var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms);
return %_SetValueOf(this, TimeClip(UTC(MakeDate(Day(t), time))));
-};
+}
// ECMA 262 - 15.9.5.29
ms = ToNumber(ms);
var time = MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms);
return %_SetValueOf(this, TimeClip(MakeDate(Day(t), time)));
-};
+}
// ECMA 262 - 15.9.5.30
ms = %_ArgumentsLength() < 2 ? GetMillisecondsFrom(this) : ToNumber(ms);
var time = MakeTime(HourFromTime(t), MinFromTime(t), sec, ms);
return %_SetValueOf(this, TimeClip(UTC(MakeDate(Day(t), time))));
-};
+}
// ECMA 262 - 15.9.5.31
ms = %_ArgumentsLength() < 2 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
var time = MakeTime(HourFromTime(t), MinFromTime(t), sec, ms);
return %_SetValueOf(this, TimeClip(MakeDate(Day(t), time)));
-};
+}
// ECMA 262 - 15.9.5.33
ms = argc < 3 ? GetMillisecondsFrom(this) : ToNumber(ms);
var time = MakeTime(HourFromTime(t), min, sec, ms);
return %_SetValueOf(this, TimeClip(UTC(MakeDate(Day(t), time))));
-};
+}
// ECMA 262 - 15.9.5.34
ms = argc < 3 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
var time = MakeTime(HourFromTime(t), min, sec, ms);
return %_SetValueOf(this, TimeClip(MakeDate(Day(t), time)));
-};
+}
// ECMA 262 - 15.9.5.35
ms = argc < 4 ? GetMillisecondsFrom(this) : ToNumber(ms);
var time = MakeTime(hour, min, sec, ms);
return %_SetValueOf(this, TimeClip(UTC(MakeDate(Day(t), time))));
-};
+}
// ECMA 262 - 15.9.5.34
ms = argc < 4 ? GetUTCMillisecondsFrom(this) : ToNumber(ms);
var time = MakeTime(hour, min, sec, ms);
return %_SetValueOf(this, TimeClip(MakeDate(Day(t), time)));
-};
+}
// ECMA 262 - 15.9.5.36
date = ToNumber(date);
var day = MakeDay(YearFromTime(t), MonthFromTime(t), date);
return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
-};
+}
// ECMA 262 - 15.9.5.37
date = ToNumber(date);
var day = MakeDay(YearFromTime(t), MonthFromTime(t), date);
return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
-};
+}
// ECMA 262 - 15.9.5.38
date = %_ArgumentsLength() < 2 ? GetDateFrom(this) : ToNumber(date);
var day = MakeDay(YearFromTime(t), month, date);
return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
-};
+}
// ECMA 262 - 15.9.5.39
date = %_ArgumentsLength() < 2 ? GetUTCDateFrom(this) : ToNumber(date);
var day = MakeDay(YearFromTime(t), month, date);
return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
-};
+}
// ECMA 262 - 15.9.5.40
date = argc < 3 ? DateFromTime(t) : ToNumber(date);
var day = MakeDay(year, month, date);
return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
-};
+}
// ECMA 262 - 15.9.5.41
date = argc < 3 ? DateFromTime(t) : ToNumber(date);
var day = MakeDay(year, month, date);
return %_SetValueOf(this, TimeClip(MakeDate(day, TimeWithinDay(t))));
-};
+}
// ECMA 262 - 15.9.5.42
+ Months[MonthFromTime(t)] + ' '
+ YearFromTime(t) + ' '
+ TimeString(t) + ' GMT';
-};
+}
// ECMA 262 - B.2.4
var t = GetTimeFrom(this);
if ($isNaN(t)) return $NaN;
return YearFromTime(LocalTime(t)) - 1900;
-};
+}
// ECMA 262 - B.2.5
? 1900 + TO_INTEGER(year) : year;
var day = MakeDay(year, GetMonthFrom(this), GetDateFrom(this));
return %_SetValueOf(this, TimeClip(UTC(MakeDate(day, TimeWithinDay(t)))));
-};
+}
+
+
+// ECMA 262 - B.2.6
+//
+// Notice that this does not follow ECMA 262 completely. ECMA 262
+// says that toGMTString should be the same Function object as
+// toUTCString. JSC does not do this, so for compatibility we do not
+// do that either. Instead, we create a new function whose name
+// property will return toGMTString.
+function DateToGMTString() {
+ return DateToUTCString.call(this);
+}
// -------------------------------------------------------------------
function SetupDate() {
// Setup non-enumerable properties of the Date object itself.
- InstallProperties($Date, DONT_ENUM, {
- UTC: DateUTC,
- parse: DateParse,
- now: DateNow
- });
-
- // Setup non-enumerable properties of the Date prototype object.
- InstallProperties($Date.prototype, DONT_ENUM, {
- constructor: $Date,
- toString: DateToString,
- toDateString: DateToDateString,
- toTimeString: DateToTimeString,
- toLocaleString: DateToString,
- toLocaleDateString: DateToDateString,
- toLocaleTimeString: DateToLocaleTimeString,
- valueOf: DateGetTime,
- getTime: DateGetTime,
- getFullYear: DateGetFullYear,
- getUTCFullYear: DateGetUTCFullYear,
- getMonth: DateGetMonth,
- getUTCMonth: DateGetUTCMonth,
- getDate: DateGetDate,
- getUTCDate: DateGetUTCDate,
- getDay: DateGetDay,
- getUTCDay: DateGetUTCDay,
- getHours: DateGetHours,
- getUTCHours: DateGetUTCHours,
- getMinutes: DateGetMinutes,
- getUTCMinutes: DateGetUTCMinutes,
- getSeconds: DateGetSeconds,
- getUTCSeconds: DateGetUTCSeconds,
- getMilliseconds: DateGetMilliseconds,
- getUTCMilliseconds: DateGetUTCMilliseconds,
- getTimezoneOffset: DateGetTimezoneOffset,
- setTime: DateSetTime,
- setMilliseconds: DateSetMilliseconds,
- setUTCMilliseconds: DateSetUTCMilliseconds,
- setSeconds: DateSetSeconds,
- setUTCSeconds: DateSetUTCSeconds,
- setMinutes: DateSetMinutes,
- setUTCMinutes: DateSetUTCMinutes,
- setHours: DateSetHours,
- setUTCHours: DateSetUTCHours,
- setDate: DateSetDate,
- setUTCDate: DateSetUTCDate,
- setMonth: DateSetMonth,
- setUTCMonth: DateSetUTCMonth,
- setFullYear: DateSetFullYear,
- setUTCFullYear: DateSetUTCFullYear,
- toUTCString: DateToUTCString,
- toGMTString: DateToUTCString,
- getYear: DateGetYear,
- setYear: DateSetYear
- });
-};
+ InstallFunctions($Date, DONT_ENUM, $Array(
+ "UTC", DateUTC,
+ "parse", DateParse,
+ "now", DateNow
+ ));
+
+ // Setup non-enumerable constructor property of the Date prototype object.
+ %AddProperty($Date.prototype, "constructor", $Date, DONT_ENUM);
+
+ // Setup non-enumerable functions of the Date prototype object and
+ // set their names.
+ InstallFunctions($Date.prototype, DONT_ENUM, $Array(
+ "toString", DateToString,
+ "toDateString", DateToDateString,
+ "toTimeString", DateToTimeString,
+ "toLocaleString", DateToLocaleString,
+ "toLocaleDateString", DateToLocaleDateString,
+ "toLocaleTimeString", DateToLocaleTimeString,
+ "valueOf", DateValueOf,
+ "getTime", DateGetTime,
+ "getFullYear", DateGetFullYear,
+ "getUTCFullYear", DateGetUTCFullYear,
+ "getMonth", DateGetMonth,
+ "getUTCMonth", DateGetUTCMonth,
+ "getDate", DateGetDate,
+ "getUTCDate", DateGetUTCDate,
+ "getDay", DateGetDay,
+ "getUTCDay", DateGetUTCDay,
+ "getHours", DateGetHours,
+ "getUTCHours", DateGetUTCHours,
+ "getMinutes", DateGetMinutes,
+ "getUTCMinutes", DateGetUTCMinutes,
+ "getSeconds", DateGetSeconds,
+ "getUTCSeconds", DateGetUTCSeconds,
+ "getMilliseconds", DateGetMilliseconds,
+ "getUTCMilliseconds", DateGetUTCMilliseconds,
+ "getTimezoneOffset", DateGetTimezoneOffset,
+ "setTime", DateSetTime,
+ "setMilliseconds", DateSetMilliseconds,
+ "setUTCMilliseconds", DateSetUTCMilliseconds,
+ "setSeconds", DateSetSeconds,
+ "setUTCSeconds", DateSetUTCSeconds,
+ "setMinutes", DateSetMinutes,
+ "setUTCMinutes", DateSetUTCMinutes,
+ "setHours", DateSetHours,
+ "setUTCHours", DateSetUTCHours,
+ "setDate", DateSetDate,
+ "setUTCDate", DateSetUTCDate,
+ "setMonth", DateSetMonth,
+ "setUTCMonth", DateSetUTCMonth,
+ "setFullYear", DateSetFullYear,
+ "setUTCFullYear", DateSetUTCFullYear,
+ "toGMTString", DateToGMTString,
+ "toUTCString", DateToUTCString,
+ "getYear", DateGetYear,
+ "setYear", DateSetYear
+ ));
+}
SetupDate();
var break_point = new BreakPoint(source_position, opt_line, opt_column, opt_script_break_point);
break_points.push(break_point);
return break_point;
-};
+}
// Object representing a break point.
this.active_ = true;
this.condition_ = null;
this.ignoreCount_ = 0;
-};
+}
BreakPoint.prototype.number = function() {
// the break point is triggered and supposed to break execution.
function IsBreakPointTriggered(break_id, break_point) {
return break_point.isTriggered(MakeExecutionState(break_id));
-};
+}
// Object representing a script break point. The script is referenced by its
this.active_ = true;
this.condition_ = null;
this.ignoreCount_ = 0;
-};
+}
ScriptBreakPoint.prototype.number = function() {
script_break_points[i].set(script);
}
}
-};
+}
// Function called from the runtime to handle a debug request receiced from the
function MakeExecutionState(break_id) {
return new ExecutionState(break_id);
-};
+}
function ExecutionState(break_id) {
this.break_id = break_id;
this.selected_frame = 0;
-};
+}
ExecutionState.prototype.prepareStep = function(opt_action, opt_count) {
var action = Debug.StepAction.StepIn;
function MakeBreakEvent(exec_state, break_points_hit) {
return new BreakEvent(exec_state, break_points_hit);
-};
+}
function BreakEvent(exec_state, break_points_hit) {
this.exec_state_ = exec_state;
this.break_points_hit_ = break_points_hit;
-};
+}
BreakEvent.prototype.func = function() {
function MakeExceptionEvent(exec_state, exception, uncaught) {
return new ExceptionEvent(exec_state, exception, uncaught);
-};
+}
function ExceptionEvent(exec_state, exception, uncaught) {
this.exec_state_ = exec_state;
this.exception_ = exception;
this.uncaught_ = uncaught;
-};
+}
ExceptionEvent.prototype.uncaught = function() {
return this.uncaught_;
function MakeCompileEvent(script_source, script_name, script_function) {
return new CompileEvent(script_source, script_name, script_function);
-};
+}
function CompileEvent(script_source, script_name, script_function) {
this.scriptSource = script_source;
this.scriptName = script_name;
this.scriptFunction = script_function;
-};
+}
CompileEvent.prototype.details = function() {
var result = "";
function MakeNewFunctionEvent(func) {
return new NewFunctionEvent(func);
-};
+}
function NewFunctionEvent(func) {
this.func = func;
-};
+}
NewFunctionEvent.prototype.details = function() {
var result = "";
// Return the source line text with the underline beneath.
return source_text + '\n' + underline;
-};
+}
function FrameSourceUnderline(frame) {
if (location) {
return SourceUnderline(location.sourceText(), location.position - location.start);
}
-};
+}
function RequestPacket(command) {
this.seq = 0;
this.type = 'request';
this.command = command;
-};
+}
RequestPacket.prototype.toJSONProtocol = function() {
if (request) this.command = request.command;
this.success = true;
this.running = false;
-};
+}
ResponsePacket.prototype.failed = function(message) {
// Make JSON object representation.
return '{' + content.join(',') + '}';
-};
+}
/**
* Convert an array to its JSON representation. This is a VERY simple
}
json += ']';
return json;
-};
+}
// has the added benefit that the code in this file is isolated from
// changes to these properties.
const $Infinity = global.Infinity;
-const $floor = $Math_floor;
-const $random = $Math_random;
-const $abs = $Math_abs;
+const $floor = MathFloor;
+const $random = MathRandom;
+const $abs = MathAbs;
// Instance class name can only be set on functions. That is the only
// purpose for MathConstructor.
-function MathConstructor() {};
-%FunctionSetInstanceClassName(MathConstructor, 'Math');
+function MathConstructor() {}
+%FunctionSetInstanceClassName(MathConstructor, 'Math');
const $Math = new MathConstructor();
$Math.__proto__ = global.Object.prototype;
%AddProperty(global, "Math", $Math, DONT_ENUM);
-
-function $Math_random() { return %Math_random(); }
-%AddProperty($Math, "random", $Math_random, DONT_ENUM);
-
-function $Math_abs(x) {
+// ECMA 262 - 15.8.2.1
+function MathAbs(x) {
if (%_IsSmi(x)) {
return x >= 0 ? x : -x;
} else {
return %Math_abs(ToNumber(x));
}
}
-%AddProperty($Math, "abs", $Math_abs, DONT_ENUM);
-
-function $Math_acos(x) { return %Math_acos(ToNumber(x)); }
-%AddProperty($Math, "acos", $Math_acos, DONT_ENUM);
-
-function $Math_asin(x) { return %Math_asin(ToNumber(x)); }
-%AddProperty($Math, "asin", $Math_asin, DONT_ENUM);
-
-function $Math_atan(x) { return %Math_atan(ToNumber(x)); }
-%AddProperty($Math, "atan", $Math_atan, DONT_ENUM);
-
-function $Math_ceil(x) { return %Math_ceil(ToNumber(x)); }
-%AddProperty($Math, "ceil", $Math_ceil, DONT_ENUM);
-function $Math_cos(x) { return %Math_cos(ToNumber(x)); }
-%AddProperty($Math, "cos", $Math_cos, DONT_ENUM);
+// ECMA 262 - 15.8.2.2
+function MathAcos(x) { return %Math_acos(ToNumber(x)); }
-function $Math_exp(x) { return %Math_exp(ToNumber(x)); }
-%AddProperty($Math, "exp", $Math_exp, DONT_ENUM);
+// ECMA 262 - 15.8.2.3
+function MathAsin(x) { return %Math_asin(ToNumber(x)); }
-function $Math_floor(x) { return %Math_floor(ToNumber(x)); }
-%AddProperty($Math, "floor", $Math_floor, DONT_ENUM);
+// ECMA 262 - 15.8.2.4
+function MathAtan(x) { return %Math_atan(ToNumber(x)); }
-function $Math_log(x) { return %Math_log(ToNumber(x)); }
-%AddProperty($Math, "log", $Math_log, DONT_ENUM);
+// ECMA 262 - 15.8.2.5
+function MathAtan2(x, y) { return %Math_atan2(ToNumber(x), ToNumber(y)); }
-function $Math_round(x) { return %Math_round(ToNumber(x)); }
-%AddProperty($Math, "round", $Math_round, DONT_ENUM);
+// ECMA 262 - 15.8.2.6
+function MathCeil(x) { return %Math_ceil(ToNumber(x)); }
-function $Math_sin(x) { return %Math_sin(ToNumber(x)); }
-%AddProperty($Math, "sin", $Math_sin, DONT_ENUM);
+// ECMA 262 - 15.8.2.7
+function MathCos(x) { return %Math_cos(ToNumber(x)); }
-function $Math_sqrt(x) { return %Math_sqrt(ToNumber(x)); }
-%AddProperty($Math, "sqrt", $Math_sqrt, DONT_ENUM);
+// ECMA 262 - 15.8.2.8
+function MathExp(x) { return %Math_exp(ToNumber(x)); }
-function $Math_tan(x) { return %Math_tan(ToNumber(x)); }
-%AddProperty($Math, "tan", $Math_tan, DONT_ENUM);
+// ECMA 262 - 15.8.2.9
+function MathFloor(x) { return %Math_floor(ToNumber(x)); }
-function $Math_atan2(x, y) { return %Math_atan2(ToNumber(x), ToNumber(y)); }
-%AddProperty($Math, "atan2", $Math_atan2, DONT_ENUM);
+// ECMA 262 - 15.8.2.10
+function MathLog(x) { return %Math_log(ToNumber(x)); }
-function $Math_pow(x, y) { return %Math_pow(ToNumber(x), ToNumber(y)); }
-%AddProperty($Math, "pow", $Math_pow, DONT_ENUM);
-
-function $Math_max(arg1, arg2) { // length == 2
+// ECMA 262 - 15.8.2.11
+function MathMax(arg1, arg2) { // length == 2
var r = -$Infinity;
for (var i = %_ArgumentsLength() - 1; i >= 0; --i) {
var n = ToNumber(%_Arguments(i));
}
return r;
}
-%AddProperty($Math, "max", $Math_max, DONT_ENUM);
-function $Math_min(arg1, arg2) { // length == 2
+// ECMA 262 - 15.8.2.12
+function MathMin(arg1, arg2) { // length == 2
var r = $Infinity;
for (var i = %_ArgumentsLength() - 1; i >= 0; --i) {
var n = ToNumber(%_Arguments(i));
}
return r;
}
-%AddProperty($Math, "min", $Math_min, DONT_ENUM);
-
-
-// ECMA-262, section 15.8.1.1.
-%AddProperty($Math, "E", 2.7182818284590452354, DONT_ENUM | DONT_DELETE | READ_ONLY);
-
-// ECMA-262, section 15.8.1.2.
-%AddProperty($Math, "LN10", 2.302585092994046, DONT_ENUM | DONT_DELETE | READ_ONLY);
-
-// ECMA-262, section 15.8.1.3.
-%AddProperty($Math, "LN2", 0.6931471805599453, DONT_ENUM | DONT_DELETE | READ_ONLY);
-// ECMA-262, section 15.8.1.4.
-%AddProperty($Math, "LOG2E", 1.4426950408889634, DONT_ENUM | DONT_DELETE | READ_ONLY);
-%AddProperty($Math, "LOG10E", 0.43429448190325176, DONT_ENUM | DONT_DELETE | READ_ONLY);
-%AddProperty($Math, "PI", 3.1415926535897932, DONT_ENUM | DONT_DELETE | READ_ONLY);
-%AddProperty($Math, "SQRT1_2", 0.7071067811865476, DONT_ENUM | DONT_DELETE | READ_ONLY);
-%AddProperty($Math, "SQRT2", 1.4142135623730951, DONT_ENUM | DONT_DELETE | READ_ONLY);
+// ECMA 262 - 15.8.2.13
+function MathPow(x, y) { return %Math_pow(ToNumber(x), ToNumber(y)); }
+
+// ECMA 262 - 15.8.2.14
+function MathRandom() { return %Math_random(); }
+
+// ECMA 262 - 15.8.2.15
+function MathRound(x) { return %Math_round(ToNumber(x)); }
+
+// ECMA 262 - 15.8.2.16
+function MathSin(x) { return %Math_sin(ToNumber(x)); }
+
+// ECMA 262 - 15.8.2.17
+function MathSqrt(x) { return %Math_sqrt(ToNumber(x)); }
+
+// ECMA 262 - 15.8.2.18
+function MathTan(x) { return %Math_tan(ToNumber(x)); }
+
+
+// -------------------------------------------------------------------
+
+function SetupMath() {
+ // Setup math constants.
+ // ECMA-262, section 15.8.1.1.
+ %AddProperty($Math, "E", 2.7182818284590452354, DONT_ENUM | DONT_DELETE | READ_ONLY);
+ // ECMA-262, section 15.8.1.2.
+ %AddProperty($Math, "LN10", 2.302585092994046, DONT_ENUM | DONT_DELETE | READ_ONLY);
+ // ECMA-262, section 15.8.1.3.
+ %AddProperty($Math, "LN2", 0.6931471805599453, DONT_ENUM | DONT_DELETE | READ_ONLY);
+ // ECMA-262, section 15.8.1.4.
+ %AddProperty($Math, "LOG2E", 1.4426950408889634, DONT_ENUM | DONT_DELETE | READ_ONLY);
+ %AddProperty($Math, "LOG10E", 0.43429448190325176, DONT_ENUM | DONT_DELETE | READ_ONLY);
+ %AddProperty($Math, "PI", 3.1415926535897932, DONT_ENUM | DONT_DELETE | READ_ONLY);
+ %AddProperty($Math, "SQRT1_2", 0.7071067811865476, DONT_ENUM | DONT_DELETE | READ_ONLY);
+ %AddProperty($Math, "SQRT2", 1.4142135623730951, DONT_ENUM | DONT_DELETE | READ_ONLY);
+
+ // Setup non-enumerable functions of the Math object and
+ // set their names.
+ InstallFunctions($Math, DONT_ENUM, $Array(
+ "random", MathRandom,
+ "abs", MathAbs,
+ "acos", MathAcos,
+ "asin", MathAsin,
+ "atan", MathAtan,
+ "ceil", MathCeil,
+ "cos", MathCos,
+ "exp", MathExp,
+ "floor", MathFloor,
+ "log", MathLog,
+ "round", MathRound,
+ "sin", MathSin,
+ "sqrt", MathSqrt,
+ "tan", MathTan,
+ "atan2", MathAtan2,
+ "pow", MathPow,
+ "max", MathMax,
+ "min", MathMin
+ ));
+};
+
+
+SetupMath();
}
var s = mapping[first] ? "an " : "a ";
return s + cons;
-};
+}
const kMessages = {
result = result.split("%" + i).join(str);
}
return result;
-};
+}
function ToDetailString(obj) {
} else {
return ToString(obj);
}
-};
+}
function MakeGenericError(constructor, type, args) {
e.type = type;
e.arguments = args;
return e;
-};
+}
/**
var format = kMessages[message.type];
if (!format) return "<unknown message " + message.type + ">";
return FormatString(format, message.args);
-};
+}
function GetLineNumber(message) {
var location = message.script.locationFromPosition(message.startPos);
if (location == null) return -1;
return location.line + 1;
-};
+}
// Returns the source code line containing the given source
if (location == null) return "";
location.restrict();
return location.sourceText();
-};
+}
function MakeTypeError(type, args) {
return MakeGenericError($TypeError, type, args);
-};
+}
function MakeRangeError(type, args) {
return MakeGenericError($RangeError, type, args);
-};
+}
function MakeSyntaxError(type, args) {
return MakeGenericError($SyntaxError, type, args);
-};
+}
function MakeReferenceError(type, args) {
return MakeGenericError($ReferenceError, type, args);
-};
+}
function MakeEvalError(type, args) {
return MakeGenericError($EvalError, type, args);
-};
+}
function MakeError(type, args) {
return MakeGenericError($Error, type, args);
-};
+}
/**
this.column = column;
this.start = start;
this.end = end;
-};
+}
const kLineLengthLimit = 78;
// If no before is specified center for small limits and perfer more source
// before the the position that after for longer limits.
if (limit <= 20) {
- before = $Math_floor(limit / 2);
+ before = $floor(limit / 2);
} else {
before = limit - 10;
}
if (location == null) return -1;
location.restrict();
return message.startPos - location.start;
-};
+}
function ErrorMessage(type, args, startPos, endPos, script, stackTrace) {
this.args = args;
this.script = script;
this.stackTrace = stackTrace;
-};
+}
function MakeMessage(type, args, startPos, endPos, script, stackTrace) {
return new ErrorMessage(type, args, startPos, endPos, script, stackTrace);
-};
+}
function GetStackTraceLine(recv, fun, pos, isGlobal) {
} catch (e) {
return "<error: " + e + ">";
}
-};
+}
function GetFunctionName(fun, recv) {
return prop;
}
return "[anonymous]";
-};
+}
function UnsafeGetStackTraceLine(recv, fun, pos, isTopLevel) {
}
}
return (result) ? " at " + result : result;
-};
+}
// ----------------------------------------------------------------------------
// Error implementation
-function DefineError(name) {
- var f = function(msg) {};
+function DefineError(f) {
// 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;
%AddProperty(global, name, f, DONT_ENUM);
this['$' + name] = f;
// Configure the error function.
return new f(m);
}
});
-};
+}
$Math.__proto__ = global.Object.prototype;
-DefineError('Error');
-DefineError('TypeError');
-DefineError('RangeError');
-DefineError('SyntaxError');
-DefineError('ReferenceError');
-DefineError('EvalError');
-DefineError('URIError');
+DefineError(function Error() { });
+DefineError(function TypeError() { });
+DefineError(function RangeError() { });
+DefineError(function SyntaxError() { });
+DefineError(function ReferenceError() { });
+DefineError(function EvalError() { });
+DefineError(function URIError() { });
// Setup extra properties of the Error.prototype object.
$Error.prototype.message = '';
-%AddProperty($Error.prototype, 'toString', function() {
+%AddProperty($Error.prototype, 'toString', function toString() {
var type = this.type;
if (type && !this.hasOwnProperty("message")) {
return this.name + ": " + FormatMessage({ type: type, args: this.arguments });
function ValueMirror(type, value) {
Mirror.call(this, type);
this.value_ = value;
-};
+}
inherits(ValueMirror, Mirror);
*/
function UndefinedMirror() {
ValueMirror.call(this, UNDEFINED_TYPE, void 0);
-};
+}
inherits(UndefinedMirror, ValueMirror);
*/
function NullMirror() {
ValueMirror.call(this, NULL_TYPE, null);
-};
+}
inherits(NullMirror, ValueMirror);
*/
function BooleanMirror(value) {
ValueMirror.call(this, BOOLEAN_TYPE, value);
-};
+}
inherits(BooleanMirror, ValueMirror);
*/
function NumberMirror(value) {
ValueMirror.call(this, NUMBER_TYPE, value);
-};
+}
inherits(NumberMirror, ValueMirror);
*/
function StringMirror(value) {
ValueMirror.call(this, STRING_TYPE, value);
-};
+}
inherits(StringMirror, ValueMirror);
*/
function ObjectMirror(value, type) {
ValueMirror.call(this, type || OBJECT_TYPE, value);
-};
+}
inherits(ObjectMirror, ValueMirror);
var names = new Array(limit);
var index = 0;
-
+
// Copy names for named properties.
if (kind & PropertyKind.Named) {
for (var i = 0; index < limit && i < propertyNames.length; i++) {
names[index++] = propertyNames[i];
}
}
-
+
// Copy names for indexed properties.
if (kind & PropertyKind.Indexed) {
for (var i = 0; index < limit && i < elementNames.length; i++) {
if (this.hasNamedInterceptor() && kind & PropertyKind.Named) {
namedInterceptorNames = %DebugNamedInterceptorPropertyNames(this.value_);
}
-
+
// Get names for indexed interceptor properties.
if (this.hasIndexedInterceptor() && kind & PropertyKind.Indexed) {
indexedInterceptorNames = %DebugIndexedInterceptorElementNames(this.value_);
var kind = opt_kind || PropertyKind.Named | PropertyKind.Indexed;
var namedInterceptorProperties;
var indexedInterceptorProperties;
-
+
// Get values for named interceptor properties.
if (kind & PropertyKind.Named) {
var names = opt_names || this.interceptorPropertyNames(PropertyKind.Named);
namedInterceptorProperties[i] = new InterceptorPropertyMirror(this, names[i], value);
}
}
-
+
// Get values for indexed interceptor properties.
if (kind & PropertyKind.Indexed) {
var names = opt_names || this.interceptorPropertyNames(PropertyKind.Indexed);
function FunctionMirror(value) {
ObjectMirror.call(this, value, FUNCTION_TYPE);
this.resolved_ = true;
-};
+}
inherits(FunctionMirror, ObjectMirror);
if (this.resolved()) {
// Find all objects constructed from this function.
var result = %DebugConstructedBy(this.value_, opt_max_instances || 0);
-
+
// Make mirrors for all the instances found.
for (var i = 0; i < result.length; i++) {
result[i] = MakeMirror(result[i]);
}
-
+
return result;
} else {
return [];
this.propertyCount_ = 0;
this.elementCount_ = 0;
this.resolved_ = false;
-};
+}
inherits(UnresolvedFunctionMirror, FunctionMirror);
*/
function ArrayMirror(value) {
ObjectMirror.call(this, value);
-};
+}
inherits(ArrayMirror, ObjectMirror);
*/
function DateMirror(value) {
ObjectMirror.call(this, value);
-};
+}
inherits(DateMirror, ObjectMirror);
*/
function RegExpMirror(value) {
ObjectMirror.call(this, value, REGEXP_TYPE);
-};
+}
inherits(RegExpMirror, ObjectMirror);
*/
function ErrorMirror(value) {
ObjectMirror.call(this, value, ERROR_TYPE);
-};
+}
inherits(ErrorMirror, ObjectMirror);
this.name_ = name;
this.value_ = value;
this.details_ = details;
-};
+}
inherits(PropertyMirror, Mirror);
*/
function InterceptorPropertyMirror(mirror, name, value) {
PropertyMirror.call(this, mirror, name, value, PropertyType.Interceptor);
-};
+}
inherits(InterceptorPropertyMirror, PropertyMirror);
Mirror.call(this, ACCESSOR_TYPE);
this.getter_ = getter;
this.setter_ = setter;
-};
+}
inherits(AccessorMirror, Mirror);
function FrameDetails(break_id, index) {
this.break_id_ = break_id;
this.details_ = %GetFrameDetails(break_id, index);
-};
+}
FrameDetails.prototype.frameId = function() {
this.break_id_ = break_id;
this.index_ = index;
this.details_ = new FrameDetails(break_id, index);
-};
+}
inherits(FrameMirror, Mirror);
// under which it was looked up.
if (func.name() && func.name() != property.name()) {
result += '(aka ' + func.name() + ')';
- }
+ }
} else {
// The function invoked was not found on the receiver. Use the function
// name if available for the backtrace.
}
result += ')';
}
-
+
return result;
}
function ScriptMirror(script) {
Mirror.call(this, SCRIPT_TYPE);
this.script_ = script;
-};
+}
inherits(ScriptMirror, Mirror);
content.push(MakeJSONPair_('lineCount', NumberToJSON_(this.lineCount())));
content.push(MakeJSONPair_('scriptType', NumberToJSON_(this.scriptType())));
}
-
-
+
+
ScriptMirror.prototype.toText = function() {
var result = '';
result += this.name();
function MakeJSONPair_(name, value) {
return '"' + name + '":' + value;
-};
+}
function ArrayToJSONObject_(content) {
return '{' + content.join(',') + '}';
-};
+}
function ArrayToJSONArray_(content) {
return '[' + content.join(',') + ']';
-};
+}
function BooleanToJSON_(value) {
return String(value);
-};
+}
function NumberToJSON_(value) {
return String(value);
-};
+}
// Mapping of some control characters to avoid the \uXXXX syntax for most
// Simple string with no special characters.
return '"' + value + '"';
-};
+}
/**
f(builtins.GetUTCMinutesFrom(value)) + ':' +
f(builtins.GetUTCSecondsFrom(value)) + '.' +
g(builtins.GetUTCMillisecondsFrom(value)) + 'Z';
-};
+}
/**
* Convert a Date to ISO 8601 format. To avoid depending on the Date object
*/
function DateToJSON_(value) {
return '"' + DateToISO8601_(value) + '"';
-};
+}
// Call internal function to compile the pattern.
%RegExpCompile(object, pattern, flags);
-};
+}
function RegExpConstructor(pattern, flags) {
}
return new $RegExp(pattern, flags);
}
-};
+}
// Deprecated RegExp.prototype.compile method. We behave like the constructor
var matchIndices = %RegExpExec(regexp, string, index);
if (!IS_NULL(matchIndices)) {
regExpCaptures = matchIndices;
- regExpSubject = regexp_input = string;
+ regExpSubject = regExpInput = string;
}
return matchIndices;
-};
+}
+
function DoRegExpExecGlobal(regexp, string) {
// Here, matchIndices is an array of arrays of substring indices.
var matchIndices = %RegExpExecGlobal(regexp, string);
if (matchIndices.length != 0) {
regExpCaptures = matchIndices[matchIndices.length - 1];
- regExpSubject = regexp_input = string;
+ regExpSubject = regExpInput = string;
}
return matchIndices;
-};
+}
function RegExpExec(string) {
if (%_ArgumentsLength() == 0) {
- string = regexp_input;
+ string = regExpInput;
}
var s = ToString(string);
var length = s.length;
result.index = matchIndices[0];
result.input = s;
return result;
-};
+}
function RegExpTest(string) {
var result = (%_ArgumentsLength() == 0) ? this.exec() : this.exec(string);
return result != null;
-};
+}
function RegExpToString() {
if (this.multiline)
result += 'm';
return result;
-};
+}
// Getters for the static properties lastMatch, lastParen, leftContext, and
// of the last successful match.
function RegExpGetLastMatch() {
return regExpSubject.slice(regExpCaptures[0], regExpCaptures[1]);
-};
+}
+
function RegExpGetLastParen() {
var length = regExpCaptures.length;
// it is empty.
return regExpSubject.slice(regExpCaptures[length - 2],
regExpCaptures[length - 1]);
-};
+}
+
function RegExpGetLeftContext() {
return regExpSubject.slice(0, regExpCaptures[0]);
-};
+}
+
function RegExpGetRightContext() {
return regExpSubject.slice(regExpCaptures[1], regExpSubject.length);
-};
+}
// The properties $1..$9 are the first nine capturing substrings of the last
if (matchStart == -1 || matchEnd == -1) return '';
return regExpSubject.slice(matchStart, matchEnd);
};
-};
+}
// Properties of the builtins object for recording the result of the last
// the last successful match.
var regExpCaptures = [0, 0];
var regExpSubject = '';
+var regExpInput = "";
+
+// -------------------------------------------------------------------
+
+function SetupRegExp() {
+ %FunctionSetInstanceClassName($RegExp, 'RegExp');
+ %FunctionSetPrototype($RegExp, new $Object());
+ %AddProperty($RegExp.prototype, 'constructor', $RegExp, DONT_ENUM);
+ %SetCode($RegExp, RegExpConstructor);
+
+ InstallFunctions($RegExp.prototype, DONT_ENUM, $Array(
+ "exec", RegExpExec,
+ "test", RegExpTest,
+ "toString", RegExpToString,
+ "compile", CompileRegExp
+ ));
+
+ // The spec says nothing about the length of exec and test, but
+ // SpiderMonkey and KJS have length equal to 0.
+ %FunctionSetLength($RegExp.prototype.exec, 0);
+ %FunctionSetLength($RegExp.prototype.test, 0);
+ // The length of compile is 1 in SpiderMonkey.
+ %FunctionSetLength($RegExp.prototype.compile, 1);
+
+ // The properties input, $input, and $_ are aliases for each other. When this
+ // value is set in SpiderMonkey, the value it is set to is coerced to a
+ // string. We mimic that behavior with a slight difference: in SpiderMonkey
+ // the value of the expression 'RegExp.input = null' (for instance) is the
+ // string "null" (ie, the value after coercion), while in V8 it is the value
+ // null (ie, the value before coercion).
+ // Getter and setter for the input.
+ function RegExpGetInput() { return regExpInput; }
+ function RegExpSetInput(string) { regExpInput = ToString(string); }
+
+ %DefineAccessor($RegExp, 'input', GETTER, RegExpGetInput, DONT_DELETE);
+ %DefineAccessor($RegExp, 'input', SETTER, RegExpSetInput, DONT_DELETE);
+ %DefineAccessor($RegExp, '$_', GETTER, RegExpGetInput, DONT_ENUM | DONT_DELETE);
+ %DefineAccessor($RegExp, '$_', SETTER, RegExpSetInput, DONT_ENUM | DONT_DELETE);
+ %DefineAccessor($RegExp, '$input', GETTER, RegExpGetInput, DONT_ENUM | DONT_DELETE);
+ %DefineAccessor($RegExp, '$input', SETTER, RegExpSetInput, DONT_ENUM | DONT_DELETE);
+
+ // The properties multiline and $* are aliases for each other. When this
+ // value is set in SpiderMonkey, the value it is set to is coerced to a
+ // boolean. We mimic that behavior with a slight difference: in SpiderMonkey
+ // the value of the expression 'RegExp.multiline = null' (for instance) is the
+ // boolean false (ie, the value after coercion), while in V8 it is the value
+ // null (ie, the value before coercion).
-
-%FunctionSetInstanceClassName($RegExp, 'RegExp');
-%FunctionSetPrototype($RegExp, new $Object());
-%AddProperty($RegExp.prototype, 'constructor', $RegExp, DONT_ENUM);
-%SetCode($RegExp, RegExpConstructor);
-
-%AddProperty($RegExp.prototype, 'exec', RegExpExec, DONT_ENUM);
-%AddProperty($RegExp.prototype, 'test', RegExpTest, DONT_ENUM);
-%AddProperty($RegExp.prototype, 'toString', RegExpToString, DONT_ENUM);
-%AddProperty($RegExp.prototype, 'compile', CompileRegExp, DONT_ENUM);
-
-// The spec says nothing about the length of exec and test, but
-// SpiderMonkey and KJS have length equal to 0.
-%FunctionSetLength($RegExp.prototype.exec, 0);
-%FunctionSetLength($RegExp.prototype.test, 0);
-// The length of compile is 1 in SpiderMonkey.
-%FunctionSetLength($RegExp.prototype.compile, 1);
-
-// The properties input, $input, and $_ are aliases for each other. When this
-// value is set in SpiderMonkey, the value it is set to is coerced to a
-// string. We mimic that behavior with a slight difference: in SpiderMonkey
-// the value of the expression 'RegExp.input = null' (for instance) is the
-// string "null" (ie, the value after coercion), while in V8 it is the value
-// null (ie, the value before coercion).
-// Getter and setter for the input.
-var regexp_input = "";
-function RegExpGetInput() { return regexp_input; };
-function RegExpSetInput(string) { regexp_input = ToString(string); };
-
-%DefineAccessor($RegExp, 'input', GETTER, RegExpGetInput, DONT_DELETE);
-%DefineAccessor($RegExp, 'input', SETTER, RegExpSetInput, DONT_DELETE);
-%DefineAccessor($RegExp, '$_', GETTER, RegExpGetInput, DONT_ENUM | DONT_DELETE);
-%DefineAccessor($RegExp, '$_', SETTER, RegExpSetInput, DONT_ENUM | DONT_DELETE);
-%DefineAccessor($RegExp, '$input', GETTER, RegExpGetInput, DONT_ENUM | DONT_DELETE);
-%DefineAccessor($RegExp, '$input', SETTER, RegExpSetInput, DONT_ENUM | DONT_DELETE);
-
-// The properties multiline and $* are aliases for each other. When this
-// value is set in SpiderMonkey, the value it is set to is coerced to a
-// boolean. We mimic that behavior with a slight difference: in SpiderMonkey
-// the value of the expression 'RegExp.multiline = null' (for instance) is the
-// boolean false (ie, the value after coercion), while in V8 it is the value
-// null (ie, the value before coercion).
-(function () {
// Getter and setter for multiline.
var multiline = false;
function RegExpGetMultiline() { return multiline; };
%DefineAccessor($RegExp, 'multiline', SETTER, RegExpSetMultiline, DONT_DELETE);
%DefineAccessor($RegExp, '$*', GETTER, RegExpGetMultiline, DONT_ENUM | DONT_DELETE);
%DefineAccessor($RegExp, '$*', SETTER, RegExpSetMultiline, DONT_ENUM | DONT_DELETE);
-})();
-
-
-function NoOpSetter(ignored) {};
-
-
-// Static properties set by a successful match.
-%DefineAccessor($RegExp, 'lastMatch', GETTER, RegExpGetLastMatch, DONT_DELETE);
-%DefineAccessor($RegExp, 'lastMatch', SETTER, NoOpSetter, DONT_DELETE);
-%DefineAccessor($RegExp, '$&', GETTER, RegExpGetLastMatch, DONT_ENUM | DONT_DELETE);
-%DefineAccessor($RegExp, '$&', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
-%DefineAccessor($RegExp, 'lastParen', GETTER, RegExpGetLastParen, DONT_DELETE);
-%DefineAccessor($RegExp, 'lastParen', SETTER, NoOpSetter, DONT_DELETE);
-%DefineAccessor($RegExp, '$+', GETTER, RegExpGetLastParen, DONT_ENUM | DONT_DELETE);
-%DefineAccessor($RegExp, '$+', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
-%DefineAccessor($RegExp, 'leftContext', GETTER, RegExpGetLeftContext, DONT_DELETE);
-%DefineAccessor($RegExp, 'leftContext', SETTER, NoOpSetter, DONT_DELETE);
-%DefineAccessor($RegExp, '$`', GETTER, RegExpGetLeftContext, DONT_ENUM | DONT_DELETE);
-%DefineAccessor($RegExp, '$`', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
-%DefineAccessor($RegExp, 'rightContext', GETTER, RegExpGetRightContext, DONT_DELETE);
-%DefineAccessor($RegExp, 'rightContext', SETTER, NoOpSetter, DONT_DELETE);
-%DefineAccessor($RegExp, "$'", GETTER, RegExpGetRightContext, DONT_ENUM | DONT_DELETE);
-%DefineAccessor($RegExp, "$'", SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
-
-// A local scope to hide the loop index i.
-(function() {
+
+
+ function NoOpSetter(ignored) {}
+
+
+ // Static properties set by a successful match.
+ %DefineAccessor($RegExp, 'lastMatch', GETTER, RegExpGetLastMatch, DONT_DELETE);
+ %DefineAccessor($RegExp, 'lastMatch', SETTER, NoOpSetter, DONT_DELETE);
+ %DefineAccessor($RegExp, '$&', GETTER, RegExpGetLastMatch, DONT_ENUM | DONT_DELETE);
+ %DefineAccessor($RegExp, '$&', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
+ %DefineAccessor($RegExp, 'lastParen', GETTER, RegExpGetLastParen, DONT_DELETE);
+ %DefineAccessor($RegExp, 'lastParen', SETTER, NoOpSetter, DONT_DELETE);
+ %DefineAccessor($RegExp, '$+', GETTER, RegExpGetLastParen, DONT_ENUM | DONT_DELETE);
+ %DefineAccessor($RegExp, '$+', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
+ %DefineAccessor($RegExp, 'leftContext', GETTER, RegExpGetLeftContext, DONT_DELETE);
+ %DefineAccessor($RegExp, 'leftContext', SETTER, NoOpSetter, DONT_DELETE);
+ %DefineAccessor($RegExp, '$`', GETTER, RegExpGetLeftContext, DONT_ENUM | DONT_DELETE);
+ %DefineAccessor($RegExp, '$`', SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
+ %DefineAccessor($RegExp, 'rightContext', GETTER, RegExpGetRightContext, DONT_DELETE);
+ %DefineAccessor($RegExp, 'rightContext', SETTER, NoOpSetter, DONT_DELETE);
+ %DefineAccessor($RegExp, "$'", GETTER, RegExpGetRightContext, DONT_ENUM | DONT_DELETE);
+ %DefineAccessor($RegExp, "$'", SETTER, NoOpSetter, DONT_ENUM | DONT_DELETE);
+
for (var i = 1; i < 10; ++i) {
%DefineAccessor($RegExp, '$' + i, GETTER, RegExpMakeCaptureGetter(i), DONT_DELETE);
%DefineAccessor($RegExp, '$' + i, SETTER, NoOpSetter, DONT_DELETE);
}
-})();
+}
+
+
+SetupRegExp();
Handle<FixedArray> literals = args.at<FixedArray>(0);
int literals_index = Smi::cast(args[1])->value();
Handle<FixedArray> constant_properties = args.at<FixedArray>(2);
+
+ // Get the global context from the literals array. This is the
+ // context in which the function was created and we use the object
+ // function from this context to create the object literal. We do
+ // not use the object function from the current global context
+ // because this might be the object function from another context
+ // which we should not have access to.
Handle<Context> context =
Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals));
constant_properties,
is_result_from_cache);
- // Get the object function from the literals array. This is the
- // object function from the context in which the function was
- // created. We do not use the object function from the current
- // global context because this might be the object function from
- // another context which we should not have access to.
Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map);
{ // Add the constant propeties to the boilerplate.
int length = constant_properties->length();
// Takes a FixedArray of elements containing the literal elements of
// the array literal and produces JSArray with those elements.
// Additionally takes the literals array of the surrounding function
- // which contains the Array function to use for creating the array
- // literal.
+ // which contains the context from which to get the Array function
+ // to use for creating the array literal.
ASSERT(args.length() == 2);
CONVERT_CHECKED(FixedArray, elements, args[0]);
CONVERT_CHECKED(FixedArray, literals, args[1]);
Handle<String> pattern = args.at<String>(2);
Handle<String> flags = args.at<String>(3);
- // Get the RegExp function from the literals array. This is the
- // RegExp function from the context in which the function was
- // created. We do not use the RegExp function from the current
- // global context because this might be the RegExp function from
- // another context which we should not have access to.
+ // Get the RegExp function from the context in the literals array.
+ // This is the RegExp function from the context in which the
+ // function was created. We do not use the RegExp function from the
+ // current global context because this might be the RegExp function
+ // from another context which we should not have access to.
Handle<JSFunction> constructor =
Handle<JSFunction>(
JSFunction::GlobalContextFromLiterals(*literals)->regexp_function());
target->set_code(fun->code());
target->shared()->set_length(fun->shared()->length());
target->shared()->set_formal_parameter_count(
- fun->shared()->formal_parameter_count());
+ fun->shared()->formal_parameter_count());
// Set the source code of the target function.
target->shared()->set_script(fun->shared()->script());
target->shared()->set_start_position(fun->shared()->start_position());
}
}
-};
+}
// ECMA-262, section 11.9.4, page 56.
}
return %_ObjectEquals(this, x) ? 0 : 1;
-};
+}
// ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as
} else {
return %NumberCompare(%ToNumber(a), %ToNumber(b), ncr);
}
-};
+}
if (IS_NUMBER(this) && IS_NUMBER(x)) {
return %NumberAdd(this, x);
}
-
+
var a = %ToPrimitive(this, NO_HINT);
var b = %ToPrimitive(x, NO_HINT);
} else {
return %NumberAdd(%ToNumber(a), %ToNumber(b));
}
-};
+}
// ECMA-262, section 11.6.2, page 50.
function SUB(x) {
return %NumberSub(%ToNumber(this), %ToNumber(x));
-};
+}
// ECMA-262, section 11.5.1, page 48.
function MUL(x) {
return %NumberMul(%ToNumber(this), %ToNumber(x));
-};
+}
// ECMA-262, section 11.5.2, page 49.
function DIV(x) {
return %NumberDiv(%ToNumber(this), %ToNumber(x));
-};
+}
// ECMA-262, section 11.5.3, page 49.
function MOD(x) {
return %NumberMod(%ToNumber(this), %ToNumber(x));
-};
+}
// ECMA-262, section 11.4.4, page 47.
function INC() {
return %NumberAdd(%ToNumber(this), 1);
-};
+}
// ECMA-262, section 11.4.5, page 48.
function DEC() {
return %NumberSub(%ToNumber(this), 1);
-};
+}
// ECMA-262, section 11.10, page 57.
function BIT_OR(x) {
return %NumberOr(%ToNumber(this), %ToNumber(x));
-};
+}
// ECMA-262, section 11.10, page 57.
function BIT_AND(x) {
return %NumberAnd(%ToNumber(this), %ToNumber(x));
-};
+}
// ECMA-262, section 11.10, page 57.
function BIT_XOR(x) {
return %NumberXor(%ToNumber(this), %ToNumber(x));
-};
+}
// ECMA-262, section 11.4.7, page 47.
function UNARY_MINUS() {
return %NumberUnaryMinus(%ToNumber(this));
-};
+}
// ECMA-262, section 11.4.8, page 48.
function BIT_NOT() {
return %NumberNot(%ToNumber(this));
-};
+}
// ECMA-262, section 11.7.1, page 51.
function SHL(x) {
return %NumberShl(%ToNumber(this), %ToNumber(x));
-};
+}
// ECMA-262, section 11.7.2, page 51.
function SAR(x) {
return %NumberSar(%ToNumber(this), %ToNumber(x));
-};
+}
// ECMA-262, section 11.7.3, page 52.
function SHR(x) {
return %NumberShr(%ToNumber(this), %ToNumber(x));
-};
+}
// ECMA-262, section 11.4.1, page 46.
function DELETE(key) {
return %DeleteProperty(%ToObject(this), %ToString(key));
-};
+}
// ECMA-262, section 11.8.7, page 54.
throw %MakeTypeError('invalid_in_operator_use', [this, x]);
}
return %_IsNonNegativeSmi(this) ? %HasElement(x, this) : %HasProperty(x, %ToString(this));
-};
+}
// ECMA-262, section 11.8.6, page 54.
// Return whether or not O is in the prototype chain of V.
return %IsInPrototypeChain(O, V);
-};
+}
// Get an array of property keys for the given object. Used in
// for-in statements.
function GET_KEYS() {
return %GetPropertyNames(this);
-};
+}
// Filter a given key against an object by checking if the object
var string = %ToString(key);
if (%HasProperty(this, string)) return string;
return null;
-};
+}
function CALL_NON_FUNCTION() {
var parameters = %NewArguments(delegate);
return delegate.apply(callee, parameters);
-};
+}
function APPLY_PREPARE(args) {
// Return the length which is the number of arguments to copy to the
// stack. It is guaranteed to be a small integer at this point.
return length;
-};
+}
function APPLY_OVERFLOW(length) {
throw %MakeRangeError('apply_overflow', [length]);
-};
+}
// Convert the receiver to an object - forward to ToObject.
function TO_OBJECT() {
return %ToObject(this);
-};
+}
// Convert the receiver to a number - forward to ToNumber.
function TO_NUMBER() {
return %ToNumber(this);
-};
+}
// Convert the receiver to a string - forward to ToString.
function TO_STRING() {
return %ToString(this);
-};
+}
/* -------------------------------------
if (x == null) return x; // check for null, undefined
if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT;
return (hint == NUMBER_HINT) ? %DefaultNumber(x) : %DefaultString(x);
-};
+}
// ECMA-262, section 9.3, page 31.
if (IS_BOOLEAN(x)) return x ? 1 : 0;
if (IS_UNDEFINED(x)) return $NaN;
return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x));
-};
+}
// ECMA-262, section 9.8, page 35.
if (IS_BOOLEAN(x)) return x ? 'true' : 'false';
if (IS_UNDEFINED(x)) return 'undefined';
return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x));
-};
+}
// ... where did this come from?
if (x == null) return false;
if (IS_NUMBER(x)) return !((x == 0) || NUMBER_IS_NAN(x));
return true;
-};
+}
// ECMA-262, section 9.9, page 36.
if (IS_BOOLEAN(x)) return new $Boolean(x);
if (x == null) throw %MakeTypeError('null_to_object', []);
return x;
-};
+}
// ECMA-262, section 9.4, page 34.
function ToInteger(x) {
if (%_IsSmi(x)) return x;
return %NumberToInteger(ToNumber(x));
-};
+}
// ECMA-262, section 9.6, page 34.
function ToUint32(x) {
if (%_IsSmi(x) && x >= 0) return x;
return %NumberToJSUint32(ToNumber(x));
-};
+}
// ECMA-262, section 9.5, page 34
function ToInt32(x) {
if (%_IsSmi(x)) return x;
return %NumberToJSInt32(ToNumber(x));
-};
+}
// considered a primitive value.
return IS_NULL(x);
}
-};
+}
// ECMA-262, section 8.6.2.6, page 28.
}
throw %MakeTypeError('cannot_convert_to_primitive', []);
-};
+}
// ECMA-262, section 8.6.2.6, page 28.
}
throw %MakeTypeError('cannot_convert_to_primitive', []);
-};
+}
// NOTE: Setting the prototype for Array must take place as early as
%AddProperty($String.prototype, "constructor", $String, DONT_ENUM);
-%AddProperty($String.prototype, "valueOf", function() {
+%AddProperty($String.prototype, "valueOf", function valueOf() {
if (!IS_STRING(this) && %ClassOf(this) !== 'String')
throw new $TypeError('String.prototype.valueOf is not generic');
return %_ValueOf(this);
}, DONT_ENUM);
-
-%AddProperty($String.prototype, "toString", $String.prototype.valueOf, DONT_ENUM);
+%AddProperty($String.prototype, "toString", function toString() {
+ if (!IS_STRING(this) && %ClassOf(this) !== 'String')
+ throw new $TypeError('String.prototype.toString is not generic');
+ return %_ValueOf(this);
+}, DONT_ENUM);
// ECMA-262 section 15.5.4.5
-%AddProperty($String.prototype, "charCodeAt", function(pos) {
+%AddProperty($String.prototype, "charCodeAt", function charCodeAt(pos) {
var fast_answer = %_FastCharCodeAt(this, pos);
if (%_IsSmi(fast_answer)) {
return fast_answer;
// ECMA-262, section 15.5.4.6
-%AddProperty($String.prototype, "concat", function() {
+%AddProperty($String.prototype, "concat", function concat() {
var len = %_ArgumentsLength();
var parts = new $Array(len + 1);
parts[0] = ToString(this);
// ECMA-262, section 15.5.4.11
-%AddProperty($String.prototype, "replace", function (search, replace) {
+%AddProperty($String.prototype, "replace", function replace(search, replace) {
var subject = ToString(this);
// Delegate to one of the regular expression variants if necessary.
// ECMA-262 section 15.5.4.7
-%AddProperty($String.prototype, "indexOf", function(searchString /* position */) { // length == 1
+%AddProperty($String.prototype, "indexOf", function indexOf(searchString /* position */) { // length == 1
var subject_str = ToString(this);
var pattern_str = ToString(searchString);
var subject_str_len = subject_str.length;
// ECMA-262 section 15.5.4.8
-%AddProperty($String.prototype, "lastIndexOf", function(searchString /* position */) { // length == 1
+%AddProperty($String.prototype, "lastIndexOf", function lastIndexOf(searchString /* position */) { // length == 1
var sub = ToString(this);
var pat = ToString(searchString);
var index = (%_ArgumentsLength() > 1)
//
// This function is implementation specific. For now, we do not
// do anything locale specific.
-%AddProperty($String.prototype, "localeCompare", function(other) {
+%AddProperty($String.prototype, "localeCompare", function localeCompare(other) {
if (%_ArgumentsLength() === 0) return 0;
var this_str = ToString(this);
// ECMA-262 section 15.5.4.10
-%AddProperty($String.prototype, "match", function(regexp) {
+%AddProperty($String.prototype, "match", function match(regexp) {
if (!IS_REGEXP(regexp)) regexp = new ORIGINAL_REGEXP(regexp);
var subject = ToString(this);
// ECMA-262 section 15.5.4.12
-%AddProperty($String.prototype, "search", function(re) {
+%AddProperty($String.prototype, "search", function search(re) {
var regexp = new ORIGINAL_REGEXP(re);
var s = ToString(this);
var last_idx = regexp.lastIndex; // keep old lastIndex
// ECMA-262 section 15.5.4.13
-%AddProperty($String.prototype, "slice", function(start, end) {
+%AddProperty($String.prototype, "slice", function slice(start, end) {
var s = ToString(this);
var s_len = s.length;
var start_i = TO_INTEGER(start);
// ECMA-262 section 15.5.4.14
-%AddProperty($String.prototype, "split", function(separator, limit) {
+%AddProperty($String.prototype, "split", function split(separator, limit) {
var subject = ToString(this);
var result = [];
var lim = (limit === void 0) ? 0xffffffff : ToUint32(limit);
-
+
if (lim === 0) return result;
-
+
// ECMA-262 says that if separator is undefined, the result should
// be an array of size 1 containing the entire string. SpiderMonkey
// and KJS have this behaviour only when no separator is given. If
result[result.length] = subject;
return result;
}
-
+
var length = subject.length;
var currentIndex = 0;
var startIndex = 0;
-
+
var sep = IS_REGEXP(separator) ? separator : ToString(separator);
-
+
if (length === 0) {
if (splitMatch(sep, subject, 0, 0) != null) return result;
result[result.length] = subject;
return result;
}
-
+
while (true) {
if (startIndex === length) {
result[result.length] = subject.slice(currentIndex, length);
return result;
}
-
+
var match = splitMatch(sep, subject, currentIndex, startIndex);
-
+
if (IS_NULL(match)) {
result[result.length] = subject.slice(currentIndex, length);
return result;
}
-
+
var endIndex = match[0];
// We ignore a zero-length match at the currentIndex.
result[result.length] = match[1];
if (result.length === lim) return result;
-
+
for (var i = 2; i < match.length; i++) {
result[result.length] = match[i];
if (result.length === lim) return result;
}
-
+
startIndex = currentIndex = endIndex;
}
}, DONT_ENUM);
}
return result;
}
-
+
var separatorIndex = subject.indexOf(separator, start_index);
if (separatorIndex === -1) return null;
-
+
return [ separatorIndex + separator.length, subject.slice(current_index, separatorIndex) ];
};
// ECMA-262 section 15.5.4.15
-%AddProperty($String.prototype, "substring", function(start, end) {
+%AddProperty($String.prototype, "substring", function substring(start, end) {
var s = ToString(this);
var s_len = s.length;
var start_i = TO_INTEGER(start);
// This is not a part of ECMA-262.
-%AddProperty($String.prototype, "substr", function(start, n) {
+%AddProperty($String.prototype, "substr", function substr(start, n) {
var s = ToString(this);
var len;
// ECMA-262, 15.5.4.16
-%AddProperty($String.prototype, "toLowerCase", function() {
+%AddProperty($String.prototype, "toLowerCase", function toLowerCase() {
return %StringToLowerCase(ToString(this));
}, DONT_ENUM);
// ECMA-262, 15.5.4.17
-%AddProperty($String.prototype, "toLocaleLowerCase", $String.prototype.toLowerCase, DONT_ENUM);
+%AddProperty($String.prototype, "toLocaleLowerCase", function toLocaleLowerCase() {
+ return %StringToLowerCase(ToString(this));
+}, DONT_ENUM);
// ECMA-262, 15.5.4.18
-%AddProperty($String.prototype, "toUpperCase", function() {
+%AddProperty($String.prototype, "toUpperCase", function toUpperCase() {
return %StringToUpperCase(ToString(this));
}, DONT_ENUM);
// ECMA-262, 15.5.4.19
-%AddProperty($String.prototype, "toLocaleUpperCase", $String.prototype.toUpperCase, DONT_ENUM);
+%AddProperty($String.prototype, "toLocaleUpperCase", function toLocaleUpperCase() {
+ return %StringToUpperCase(ToString(this));
+}, DONT_ENUM);
// ECMA-262, section 15.5.3.2
-%AddProperty($String, "fromCharCode", function(code) {
+%AddProperty($String, "fromCharCode", function fromCharCode(code) {
var n = %_ArgumentsLength();
if (n == 1) return %CharFromCode(ToNumber(code) & 0xffff)
// ECMA-262, section 15.5.4.4
-function CharAt(pos) {
+function charAt(pos) {
var subject = ToString(this);
var index = TO_INTEGER(pos);
if (index >= subject.length || index < 0) return "";
return %CharFromCode(%StringCharCodeAt(subject, index));
};
-%AddProperty($String.prototype, "charAt", CharAt, DONT_ENUM);
+%AddProperty($String.prototype, "charAt", charAt, DONT_ENUM);
// Helper function for very basic XSS protection.
// Compatibility support for KJS.
// Tested by mozilla/js/tests/js1_5/Regress/regress-276103.js.
-%AddProperty($String.prototype, "link", function(link) {
- return "<a href=\"" + HtmlEscape(link) + "\">" + this + "</a>";
+%AddProperty($String.prototype, "link", function link(s) {
+ return "<a href=\"" + HtmlEscape(s) + "\">" + this + "</a>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "anchor", function(name) {
+%AddProperty($String.prototype, "anchor", function anchor(name) {
return "<a name=\"" + HtmlEscape(name) + "\">" + this + "</a>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "fontcolor", function(color) {
+%AddProperty($String.prototype, "fontcolor", function fontcolor(color) {
return "<font color=\"" + HtmlEscape(color) + "\">" + this + "</font>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "fontsize", function(size) {
+%AddProperty($String.prototype, "fontsize", function fontsize(size) {
return "<font size=\"" + HtmlEscape(size) + "\">" + this + "</font>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "big", function() {
+%AddProperty($String.prototype, "big", function big() {
return "<big>" + this + "</big>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "blink", function() {
+%AddProperty($String.prototype, "blink", function blink() {
return "<blink>" + this + "</blink>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "bold", function() {
+%AddProperty($String.prototype, "bold", function bold() {
return "<b>" + this + "</b>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "fixed", function() {
+%AddProperty($String.prototype, "fixed", function fixed() {
return "<tt>" + this + "</tt>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "italics", function() {
+%AddProperty($String.prototype, "italics", function italics() {
return "<i>" + this + "</i>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "small", function() {
+%AddProperty($String.prototype, "small", function small() {
return "<small>" + this + "</small>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "strike", function() {
+%AddProperty($String.prototype, "strike", function strike() {
return "<strike>" + this + "</strike>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "sub", function() {
+%AddProperty($String.prototype, "sub", function sub() {
return "<sub>" + this + "</sub>";
}, DONT_ENUM);
-%AddProperty($String.prototype, "sup", function() {
+%AddProperty($String.prototype, "sup", function sup() {
return "<sup>" + this + "</sup>";
}, DONT_ENUM);
result[index++] = hexCharCodeArray[octet >> 4];
result[index++] = hexCharCodeArray[octet & 0x0F];
return index;
-};
+}
function URIEncodeOctets(octets, result, index) {
if (octets[2]) index = URIAddEncodedOctetToBuffer(octets[2], result, index);
if (octets[3]) index = URIAddEncodedOctetToBuffer(octets[3], result, index);
return index;
-};
+}
function URIEncodeSingle(cc, result, index) {
octets[2] = z + 128;
}
return URIEncodeOctets(octets, result, index);
-};
+}
function URIEncodePair(cc1 , cc2, result, index) {
octets[2] = ((x << 4) | y) + 128;
octets[3] = z + 128;
return URIEncodeOctets(octets, result, index);
-};
+}
function URIHexCharsToCharCode(ch1, ch2) {
throw new $URIError("URI malformed");
}
return HexStrToCharCode(ch1 + ch2);
-};
+}
function URIDecodeOctets(octets, result, index) {
var y = octets[0] & 31;
result[index++] = (y << 6) | z;
return index;
-};
+}
// ECMA-262, section 15.1.3
}
}
return %StringFromCharCodeArray(result);
-};
+}
// ECMA-262, section 15.1.3
}
result.length = index;
return %StringFromCharCodeArray(result);
-};
+}
// ECMA-262 - 15.1.3.1.
};
var string = ToString(uri);
return Decode(string, reservedPredicate);
-};
+}
// ECMA-262 - 15.1.3.2.
function reservedPredicate(cc) { return false; };
var string = ToString(component);
return Decode(string, reservedPredicate);
-};
+}
// Does the char code correspond to an alpha-numeric char.
if (48 <= cc && cc <= 57) return true;
return false;
-};
+}
// ECMA-262 - 15.1.3.3.
var string = ToString(uri);
return Encode(string, unescapePredicate);
-};
+}
// ECMA-262 - 15.1.3.4
var string = ToString(component);
return Encode(string, unescapePredicate);
-};
+}
const hexCharArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
if (code >= 97 && code <= 102) return code - 87;
return -1;
-};
+}
// Convert a character code to 4-digit hex string representation
cc = cc >>> 4;
}
return r;
-};
+}
// Converts hex string to char code. Not efficient.
m = m + 4;
}
return r;
-};
+}
// Returns true if all digits in string s are valid hex numbers
}
}
return true;
-};
+}
// ECMA-262 - B.2.1.
function URIEscape(str) {
var s = ToString(str);
return %URIEscape(s);
-};
+}
// ECMA-262 - B.2.2.
// -------------------------------------------------------------------
function SetupURI() {
- // Setup non-enumerable URI properties of the global object.
- InstallProperties(global, DONT_ENUM, {
- escape: URIEscape,
- unescape: URIUnescape,
- decodeURI: URIDecode,
- decodeURIComponent: URIDecodeComponent,
- encodeURI: URIEncode,
- encodeURIComponent: URIEncodeComponent
- });
-};
+ // Setup non-enumerable URI functions on the global object and set
+ // their names.
+ InstallFunctions(global, DONT_ENUM, $Array(
+ "escape", URIEscape,
+ "unescape", URIUnescape,
+ "decodeURI", URIDecode,
+ "decodeURIComponent", URIDecodeComponent,
+ "encodeURI", URIEncode,
+ "encodeURIComponent", URIEncodeComponent
+ ));
+}
SetupURI();
// This file relies on the fact that the following declarations have been made
+//
// in runtime.js:
// const $Object = global.Object;
// const $Boolean = global.Boolean;
// const $Function = global.Function;
// const $Array = global.Array;
// const $NaN = 0/0;
+//
+// in math.js:
+// const $floor = MathFloor
// ECMA 262 - 15.1.1.1.
function $isNaN(number) {
var n = ToNumber(number);
return NUMBER_IS_NAN(n);
-};
+}
%AddProperty(global, "isNaN", $isNaN, DONT_ENUM);
// ECMA 262 - 15.1.5
function $isFinite(number) {
return %NumberIsFinite(ToNumber(number));
-};
+}
%AddProperty(global, "isFinite", $isFinite, DONT_ENUM);
if (%_IsSmi(string)) return string;
if (IS_NUMBER(string)) {
if (string >= 0.01 && string < 1e9)
- return $Math_floor(string);
+ return $floor(string);
if (string <= -0.01 && string > -1e9)
- return - $Math_floor(-string);
+ return - $floor(-string);
}
} else {
radix = TO_INT32(radix);
if (source.match(regexp)) source = source.replace(regexp, "$1");
var name = %FunctionGetName(func);
return 'function ' + name + source;
-};
+}
%AddProperty($Function.prototype, "toString", function() {
var f = %CompileString(source, -1, false)();
%FunctionSetName(f, "anonymous");
return %SetNewFunctionAttributes(f);
-};
+}
%SetCode($Function, NewFunction);
CHECK_EQ(1234, script1->Run()->Int32Value());
CHECK_EQ(1234, script2->Run()->Int32Value());
}
+
+
+static v8::Handle<Value> FunctionNameCallback(const v8::Arguments& args) {
+ ApiTestFuzzer::Fuzz();
+ return v8_num(42);
+}
+
+
+THREADED_TEST(CallbackFunctionName) {
+ v8::HandleScope scope;
+ LocalContext context;
+ Local<ObjectTemplate> t = ObjectTemplate::New();
+ t->Set(v8_str("asdf"), v8::FunctionTemplate::New(FunctionNameCallback));
+ context->Global()->Set(v8_str("obj"), t->NewInstance());
+ v8::Handle<v8::Value> value = CompileRun("obj.asdf.name");
+ CHECK(value->IsString());
+ v8::String::AsciiValue name(value);
+ CHECK_EQ("asdf", *name);
+}
--- /dev/null
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+function TestFunctionNames(object, names) {
+ for (var i = 0; i < names.length; i++) {
+ assertEquals(names[i], object[names[i]].name);
+ }
+}
+
+
+// Array.prototype functions.
+var arrayPrototypeFunctions = [
+ "toString", "toLocaleString", "join", "pop", "push", "concat", "reverse",
+ "shift", "unshift", "slice", "splice", "sort", "filter", "forEach",
+ "some", "every", "map", "indexOf", "lastIndexOf"];
+
+TestFunctionNames(Array.prototype, arrayPrototypeFunctions);
+
+
+// Date functions.
+var dateFunctions = ["UTC", "parse", "now"];
+
+TestFunctionNames(Date, dateFunctions);
+
+
+// Date.prototype functions.
+var datePrototypeFunctions = [
+ "toString", "toDateString", "toTimeString", "toLocaleString",
+ "toLocaleDateString", "toLocaleTimeString", "valueOf", "getTime",
+ "getFullYear", "getUTCFullYear", "getMonth", "getUTCMonth",
+ "getDate", "getUTCDate", "getDay", "getUTCDay", "getHours",
+ "getUTCHours", "getMinutes", "getUTCMinutes", "getSeconds",
+ "getUTCSeconds", "getMilliseconds", "getUTCMilliseconds",
+ "getTimezoneOffset", "setTime", "setMilliseconds",
+ "setUTCMilliseconds", "setSeconds", "setUTCSeconds", "setMinutes",
+ "setUTCMinutes", "setHours", "setUTCHours", "setDate", "setUTCDate",
+ "setMonth", "setUTCMonth", "setFullYear", "setUTCFullYear", "toGMTString",
+ "toUTCString", "getYear", "setYear"];
+
+TestFunctionNames(Date.prototype, datePrototypeFunctions);
+
+
+// Math functions.
+var mathFunctions = [
+ "random", "abs", "acos", "asin", "atan", "ceil", "cos", "exp", "floor",
+ "log", "round", "sin", "sqrt", "tan", "atan2", "pow", "max", "min"];
+
+TestFunctionNames(Math, mathFunctions);
+
+
+// RegExp.prototype functions.
+var regExpPrototypeFunctions = ["exec", "test", "toString", "compile"];
+
+TestFunctionNames(RegExp.prototype, regExpPrototypeFunctions);
+
+// String functions.
+var stringFunctions = ["fromCharCode"];
+
+TestFunctionNames(String, stringFunctions);
+
+
+// String.prototype functions.
+var stringPrototypeFunctions = [
+ "toString", "valueOf", "charAt", "charCodeAt", "concat", "indexOf",
+ "lastIndexOf", "localeCompare", "match", "replace", "search", "slice",
+ "split", "substring", "substr", "toLowerCase", "toLocaleLowerCase",
+ "toUpperCase", "toLocaleUpperCase", "link", "anchor", "fontcolor",
+ "fontsize", "big", "blink", "bold", "fixed", "italics", "small",
+ "strike", "sub", "sup"];
+
+TestFunctionNames(String.prototype, stringPrototypeFunctions);
+
+
+// Global functions.
+var globalFunctions = [
+ "escape", "unescape", "decodeURI", "decodeURIComponent",
+ "encodeURI", "encodeURIComponent", "Error", "TypeError",
+ "RangeError", "SyntaxError", "ReferenceError", "EvalError",
+ "URIError"];
+
+TestFunctionNames(this, globalFunctions);