Hide native Date implementation in function context.

This further reduces the context size.

R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/996213003

Cr-Commit-Position: refs/heads/master@{#27138}
This commit is contained in:
yangguo 2015-03-11 08:53:24 -07:00 committed by Commit bot
parent a69cfac182
commit 9333e7e135
7 changed files with 162 additions and 155 deletions

View File

@ -1538,7 +1538,7 @@ static Handle<JSObject> ResolveBuiltinIdHolder(Handle<Context> native_context,
void Genesis::InstallNativeFunctions() { void Genesis::InstallNativeFunctions() {
HandleScope scope(isolate()); HandleScope scope(isolate());
INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun); INSTALL_NATIVE(JSFunction, "$createDate", create_date_fun);
INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun); INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
INSTALL_NATIVE(JSFunction, "ToString", to_string_fun); INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);

View File

@ -2,16 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
"use strict";
// This file relies on the fact that the following declarations have been made // This file relies on the fact that the following declarations have been made
// in v8natives.js: // in v8natives.js:
// var $isFinite = GlobalIsFinite; // var $isFinite = GlobalIsFinite;
var $Date = global.Date; var $createDate;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
(function() {
"use strict";
%CheckIsBootstrapping();
var GlobalDate = global.Date;
// This file contains date support implemented in JavaScript. // This file contains date support implemented in JavaScript.
// Helper function to throw error. // Helper function to throw error.
@ -19,7 +25,6 @@ function ThrowDateTypeError() {
throw new $TypeError('this is not a Date object.'); throw new $TypeError('this is not a Date object.');
} }
var timezone_cache_time = NAN; var timezone_cache_time = NAN;
var timezone_cache_timezone; var timezone_cache_timezone;
@ -121,7 +126,7 @@ var Date_cache = {
function DateConstructor(year, month, date, hours, minutes, seconds, ms) { function DateConstructor(year, month, date, hours, minutes, seconds, ms) {
if (!%_IsConstructCall()) { if (!%_IsConstructCall()) {
// ECMA 262 - 15.9.2 // ECMA 262 - 15.9.2
return (new $Date()).toString(); return (new GlobalDate()).toString();
} }
// ECMA 262 - 15.9.3 // ECMA 262 - 15.9.3
@ -749,79 +754,78 @@ function CheckDateCacheCurrent() {
function CreateDate(time) { function CreateDate(time) {
var date = new $Date(); var date = new GlobalDate();
date.setTime(time); date.setTime(time);
return date; return date;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
function SetUpDate() { %SetCode(GlobalDate, DateConstructor);
%CheckIsBootstrapping(); %FunctionSetPrototype(GlobalDate, new GlobalDate(NAN));
%SetCode($Date, DateConstructor); // Set up non-enumerable properties of the Date object itself.
%FunctionSetPrototype($Date, new $Date(NAN)); InstallFunctions(GlobalDate, DONT_ENUM, $Array(
"UTC", DateUTC,
"parse", DateParse,
"now", DateNow
));
// Set up non-enumerable properties of the Date object itself. // Set up non-enumerable constructor property of the Date prototype object.
InstallFunctions($Date, DONT_ENUM, $Array( %AddNamedProperty(GlobalDate.prototype, "constructor", GlobalDate, DONT_ENUM);
"UTC", DateUTC,
"parse", DateParse,
"now", DateNow
));
// Set up non-enumerable constructor property of the Date prototype object. // Set up non-enumerable functions of the Date prototype object and
%AddNamedProperty($Date.prototype, "constructor", $Date, DONT_ENUM); // set their names.
InstallFunctions(GlobalDate.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,
"toISOString", DateToISOString,
"toJSON", DateToJSON
));
// Set up non-enumerable functions of the Date prototype object and // Expose to the global scope.
// set their names. $createDate = CreateDate;
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,
"toISOString", DateToISOString,
"toJSON", DateToJSON
));
}
SetUpDate(); })();

View File

@ -2,19 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
"use strict";
// ECMAScript 402 API implementation. // ECMAScript 402 API implementation.
/** /**
* Intl object is a single object that has some named properties, * Intl object is a single object that has some named properties,
* all of which are constructors. * all of which are constructors.
*/ */
$Object.defineProperty(global, "Intl", { enumerable: false, value: (function() { (function() {
"use strict";
%CheckIsBootstrapping();
var GlobalDate = global.Date;
var undefined = global.undefined;
var Intl = {}; var Intl = {};
var undefined = global.undefined; %AddNamedProperty(global, "Intl", Intl, DONT_ENUM);
var AVAILABLE_SERVICES = ['collator', var AVAILABLE_SERVICES = ['collator',
'numberformat', 'numberformat',
@ -1658,7 +1664,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
function formatDate(formatter, dateValue) { function formatDate(formatter, dateValue) {
var dateMs; var dateMs;
if (dateValue === undefined) { if (dateValue === undefined) {
dateMs = $Date.now(); dateMs = GlobalDate.now();
} else { } else {
dateMs = $Number(dateValue); dateMs = $Number(dateValue);
} }
@ -1668,7 +1674,7 @@ function formatDate(formatter, dateValue) {
} }
return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter), return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter),
new $Date(dateMs)); new GlobalDate(dateMs));
} }
@ -1924,8 +1930,7 @@ function cachedOrNewService(service, locales, options, defaults) {
* Compares this and that, and returns less than 0, 0 or greater than 0 value. * Compares this and that, and returns less than 0, 0 or greater than 0 value.
* Overrides the built-in method. * Overrides the built-in method.
*/ */
ObjectDefineProperty($String.prototype, 'localeCompare', { OverrideFunction($String.prototype, 'localeCompare', function(that) {
value: function(that) {
if (%_IsConstructCall()) { if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
} }
@ -1938,14 +1943,8 @@ ObjectDefineProperty($String.prototype, 'localeCompare', {
var options = %_Arguments(2); var options = %_Arguments(2);
var collator = cachedOrNewService('collator', locales, options); var collator = cachedOrNewService('collator', locales, options);
return compare(collator, this, that); return compare(collator, this, that);
}, }
writable: true, );
configurable: true,
enumerable: false
});
%FunctionSetName($String.prototype.localeCompare, 'localeCompare');
%FunctionRemovePrototype($String.prototype.localeCompare);
%SetNativeFlag($String.prototype.localeCompare);
/** /**
@ -1955,8 +1954,7 @@ ObjectDefineProperty($String.prototype, 'localeCompare', {
* If the form is not one of "NFC", "NFD", "NFKC", or "NFKD", then throw * If the form is not one of "NFC", "NFD", "NFKC", or "NFKD", then throw
* a RangeError Exception. * a RangeError Exception.
*/ */
ObjectDefineProperty($String.prototype, 'normalize', { OverrideFunction($String.prototype, 'normalize', function(that) {
value: function(that) {
if (%_IsConstructCall()) { if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
} }
@ -1972,22 +1970,15 @@ ObjectDefineProperty($String.prototype, 'normalize', {
} }
return %StringNormalize(this, normalizationForm); return %StringNormalize(this, normalizationForm);
}, }
writable: true, );
configurable: true,
enumerable: false
});
%FunctionSetName($String.prototype.normalize, 'normalize');
%FunctionRemovePrototype($String.prototype.normalize);
%SetNativeFlag($String.prototype.normalize);
/** /**
* Formats a Number object (this) using locale and options values. * Formats a Number object (this) using locale and options values.
* If locale or options are omitted, defaults are used. * If locale or options are omitted, defaults are used.
*/ */
ObjectDefineProperty($Number.prototype, 'toLocaleString', { OverrideFunction($Number.prototype, 'toLocaleString', function() {
value: function() {
if (%_IsConstructCall()) { if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
} }
@ -2000,21 +1991,15 @@ ObjectDefineProperty($Number.prototype, 'toLocaleString', {
var options = %_Arguments(1); var options = %_Arguments(1);
var numberFormat = cachedOrNewService('numberformat', locales, options); var numberFormat = cachedOrNewService('numberformat', locales, options);
return formatNumber(numberFormat, this); return formatNumber(numberFormat, this);
}, }
writable: true, );
configurable: true,
enumerable: false
});
%FunctionSetName($Number.prototype.toLocaleString, 'toLocaleString');
%FunctionRemovePrototype($Number.prototype.toLocaleString);
%SetNativeFlag($Number.prototype.toLocaleString);
/** /**
* Returns actual formatted date or fails if date parameter is invalid. * Returns actual formatted date or fails if date parameter is invalid.
*/ */
function toLocaleDateTime(date, locales, options, required, defaults, service) { function toLocaleDateTime(date, locales, options, required, defaults, service) {
if (!(date instanceof $Date)) { if (!(date instanceof GlobalDate)) {
throw new $TypeError('Method invoked on an object that is not Date.'); throw new $TypeError('Method invoked on an object that is not Date.');
} }
@ -2036,8 +2021,7 @@ function toLocaleDateTime(date, locales, options, required, defaults, service) {
* If locale or options are omitted, defaults are used - both date and time are * If locale or options are omitted, defaults are used - both date and time are
* present in the output. * present in the output.
*/ */
ObjectDefineProperty($Date.prototype, 'toLocaleString', { OverrideFunction(GlobalDate.prototype, 'toLocaleString', function() {
value: function() {
if (%_IsConstructCall()) { if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
} }
@ -2046,14 +2030,8 @@ ObjectDefineProperty($Date.prototype, 'toLocaleString', {
var options = %_Arguments(1); var options = %_Arguments(1);
return toLocaleDateTime( return toLocaleDateTime(
this, locales, options, 'any', 'all', 'dateformatall'); this, locales, options, 'any', 'all', 'dateformatall');
}, }
writable: true, );
configurable: true,
enumerable: false
});
%FunctionSetName($Date.prototype.toLocaleString, 'toLocaleString');
%FunctionRemovePrototype($Date.prototype.toLocaleString);
%SetNativeFlag($Date.prototype.toLocaleString);
/** /**
@ -2061,8 +2039,7 @@ ObjectDefineProperty($Date.prototype, 'toLocaleString', {
* If locale or options are omitted, defaults are used - only date is present * If locale or options are omitted, defaults are used - only date is present
* in the output. * in the output.
*/ */
ObjectDefineProperty($Date.prototype, 'toLocaleDateString', { OverrideFunction(GlobalDate.prototype, 'toLocaleDateString', function() {
value: function() {
if (%_IsConstructCall()) { if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
} }
@ -2071,14 +2048,8 @@ ObjectDefineProperty($Date.prototype, 'toLocaleDateString', {
var options = %_Arguments(1); var options = %_Arguments(1);
return toLocaleDateTime( return toLocaleDateTime(
this, locales, options, 'date', 'date', 'dateformatdate'); this, locales, options, 'date', 'date', 'dateformatdate');
}, }
writable: true, );
configurable: true,
enumerable: false
});
%FunctionSetName($Date.prototype.toLocaleDateString, 'toLocaleDateString');
%FunctionRemovePrototype($Date.prototype.toLocaleDateString);
%SetNativeFlag($Date.prototype.toLocaleDateString);
/** /**
@ -2086,8 +2057,7 @@ ObjectDefineProperty($Date.prototype, 'toLocaleDateString', {
* If locale or options are omitted, defaults are used - only time is present * If locale or options are omitted, defaults are used - only time is present
* in the output. * in the output.
*/ */
ObjectDefineProperty($Date.prototype, 'toLocaleTimeString', { OverrideFunction(GlobalDate.prototype, 'toLocaleTimeString', function() {
value: function() {
if (%_IsConstructCall()) { if (%_IsConstructCall()) {
throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
} }
@ -2096,14 +2066,7 @@ ObjectDefineProperty($Date.prototype, 'toLocaleTimeString', {
var options = %_Arguments(1); var options = %_Arguments(1);
return toLocaleDateTime( return toLocaleDateTime(
this, locales, options, 'time', 'time', 'dateformattime'); this, locales, options, 'time', 'time', 'dateformattime');
}, }
writable: true, );
configurable: true,
enumerable: false
});
%FunctionSetName($Date.prototype.toLocaleTimeString, 'toLocaleTimeString');
%FunctionRemovePrototype($Date.prototype.toLocaleTimeString);
%SetNativeFlag($Date.prototype.toLocaleTimeString);
return Intl; })();
}())});

View File

@ -2,16 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
"use strict";
// This file relies on the fact that the following declarations have been made // This file relies on the fact that the following declarations have been made
// in runtime.js: // in runtime.js:
// var $Object = global.Object; // var $Object = global.Object;
// Instance class name can only be set on functions. That is the only // Instance class name can only be set on functions. That is the only
// purpose for MathConstructor. // purpose for MathConstructor.
function MathConstructor() {}
var $Math = new MathConstructor();
var rngstate; // Initialized to a Uint32Array during genesis. var rngstate; // Initialized to a Uint32Array during genesis.
@ -25,6 +21,8 @@ var $min;
(function() { (function() {
"use strict";
// ECMA 262 - 15.8.2.1 // ECMA 262 - 15.8.2.1
function MathAbs(x) { function MathAbs(x) {
if (%_IsSmi(x)) return x >= 0 ? x : -x; if (%_IsSmi(x)) return x >= 0 ? x : -x;
@ -297,14 +295,18 @@ function CubeRoot(x) {
%CheckIsBootstrapping(); %CheckIsBootstrapping();
%InternalSetPrototype($Math, $Object.prototype); function MathConstructor() {}
%AddNamedProperty(global, "Math", $Math, DONT_ENUM);
var Math = new MathConstructor();
%InternalSetPrototype(Math, $Object.prototype);
%AddNamedProperty(global, "Math", Math, DONT_ENUM);
%FunctionSetInstanceClassName(MathConstructor, 'Math'); %FunctionSetInstanceClassName(MathConstructor, 'Math');
%AddNamedProperty($Math, symbolToStringTag, "Math", READ_ONLY | DONT_ENUM); %AddNamedProperty(Math, symbolToStringTag, "Math", READ_ONLY | DONT_ENUM);
// Set up math constants. // Set up math constants.
InstallConstants($Math, $Array( InstallConstants(Math, $Array(
// ECMA-262, section 15.8.1.1. // ECMA-262, section 15.8.1.1.
"E", 2.7182818284590452354, "E", 2.7182818284590452354,
// ECMA-262, section 15.8.1.2. // ECMA-262, section 15.8.1.2.
@ -321,7 +323,7 @@ InstallConstants($Math, $Array(
// Set up non-enumerable functions of the Math object and // Set up non-enumerable functions of the Math object and
// set their names. // set their names.
InstallFunctions($Math, DONT_ENUM, $Array( InstallFunctions(Math, DONT_ENUM, $Array(
"random", MathRandom, "random", MathRandom,
"abs", MathAbs, "abs", MathAbs,
"acos", MathAcosJS, "acos", MathAcosJS,
@ -354,9 +356,7 @@ InstallFunctions($Math, DONT_ENUM, $Array(
%SetInlineBuiltinFlag(MathFloor); %SetInlineBuiltinFlag(MathFloor);
%SetInlineBuiltinFlag(MathRandom); %SetInlineBuiltinFlag(MathRandom);
// Keep reference to original values of some global properties. This // Expose to the global scope.
// has the added benefit that the code in this file is isolated from
// changes to these properties.
$abs = MathAbs; $abs = MathAbs;
$exp = MathExp; $exp = MathExp;
$floor = MathFloor; $floor = MathFloor;

View File

@ -98,6 +98,23 @@ void CalculateFirstPageSizes(bool is_default_snapshot,
context_snapshot.Reservations(); context_snapshot.Reservations();
int startup_index = 0; int startup_index = 0;
int context_index = 0; int context_index = 0;
if (FLAG_profile_deserialization) {
int startup_total = 0;
int context_total = 0;
for (auto& reservation : startup_reservations) {
startup_total += reservation.chunk_size();
}
for (auto& reservation : context_reservations) {
context_total += reservation.chunk_size();
}
PrintF(
"Deserialization will reserve:\n"
"%*d bytes for startup\n"
"%*d bytes per context\n",
10, startup_total, 10, context_total);
}
for (int space = 0; space < i::Serializer::kNumberOfSpaces; space++) { for (int space = 0; space < i::Serializer::kNumberOfSpaces; space++) {
bool single_chunk = true; bool single_chunk = true;
while (!startup_reservations[startup_index].is_last()) { while (!startup_reservations[startup_index].is_last()) {
@ -166,6 +183,14 @@ v8::StartupData Snapshot::CreateSnapshotBlob(
memcpy(data + kStartupDataOffset, startup_data.begin(), startup_length); memcpy(data + kStartupDataOffset, startup_data.begin(), startup_length);
memcpy(data + context_offset, context_data.begin(), context_length); memcpy(data + context_offset, context_data.begin(), context_length);
v8::StartupData result = {data, length}; v8::StartupData result = {data, length};
if (FLAG_profile_deserialization) {
PrintF(
"Snapshot blob consists of:\n"
"%*d bytes for startup\n"
"%*d bytes for context\n",
10, startup_length, 10, context_length);
}
return result; return result;
} }

View File

@ -23,13 +23,13 @@
// rempio2result is used as a container for return values of %RemPiO2. It is // rempio2result is used as a container for return values of %RemPiO2. It is
// initialized to a two-element Float64Array during genesis. // initialized to a two-element Float64Array during genesis.
"use strict";
var kMath; var kMath;
var rempio2result; var rempio2result;
(function() { (function() {
"use strict";
const INVPIO2 = kMath[0]; const INVPIO2 = kMath[0];
const PIO2_1 = kMath[1]; const PIO2_1 = kMath[1];
const PIO2_1T = kMath[2]; const PIO2_1T = kMath[2];
@ -1004,7 +1004,11 @@ function MathLog2(x) {
return t1 + t2; return t1 + t2;
} }
InstallFunctions($Math, DONT_ENUM, $Array( //-------------------------------------------------------------------
%CheckIsBootstrapping();
InstallFunctions(global.Math, DONT_ENUM, $Array(
"cos", MathCos, "cos", MathCos,
"sin", MathSin, "sin", MathSin,
"tan", MathTan, "tan", MathTan,

View File

@ -32,6 +32,17 @@ function InstallFunctions(object, attributes, functions) {
} }
function OverrideFunction(object, name, f) {
ObjectDefineProperty(object, name, { value: f,
writeable: true,
configurable: true,
enumerable: false });
%FunctionSetName(f, name);
%FunctionRemovePrototype(f);
%SetNativeFlag(f);
}
// Helper function to install a getter-only accessor property. // Helper function to install a getter-only accessor property.
function InstallGetter(object, name, getter) { function InstallGetter(object, name, getter) {
%FunctionSetName(getter, name); %FunctionSetName(getter, name);