1 /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
\r
3 * The contents of this file are subject to the Netscape Public
\r
4 * License Version 1.1 (the "License"); you may not use this file
\r
5 * except in compliance with the License. You may obtain a copy of
\r
6 * the License at http://www.mozilla.org/NPL/
\r
8 * Software distributed under the License is distributed on an "AS
\r
9 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
\r
10 * implied. See the License for the specific language governing
\r
11 * rights and limitations under the License.
\r
13 * The Original Code is Rhino code, released
\r
16 * The Initial Developer of the Original Code is Netscape
\r
17 * Communications Corporation. Portions created by Netscape are
\r
18 * Copyright (C) 1997-1999 Netscape Communications Corporation. All
\r
26 * Alternatively, the contents of this file may be used under the
\r
27 * terms of the GNU Public License (the "GPL"), in which case the
\r
28 * provisions of the GPL are applicable instead of those above.
\r
29 * If you wish to allow use of your version of this file only
\r
30 * under the terms of the GPL and not to allow others to use your
\r
31 * version of this file under the NPL, indicate your decision by
\r
32 * deleting the provisions above and replace them with the notice
\r
33 * and other provisions required by the GPL. If you do not delete
\r
34 * the provisions above, a recipient may use your version of this
\r
35 * file under either the NPL or the GPL.
\r
38 package org.mozilla.javascript;
\r
41 * This class implements the Number native object.
\r
45 * @author Norris Boyd
\r
47 public class NativeNumber extends IdScriptable {
\r
49 private static final int MAX_PRECISION = 100;
\r
51 public static void init(Context cx, Scriptable scope, boolean sealed) {
\r
52 NativeNumber obj = new NativeNumber();
\r
53 obj.prototypeFlag = true;
\r
54 obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
\r
58 * Zero-parameter constructor: just used to create Number.prototype
\r
60 public NativeNumber() {
\r
61 doubleValue = defaultValue;
\r
64 public NativeNumber(double number) {
\r
65 doubleValue = number;
\r
68 public String getClassName() {
\r
72 protected void fillConstructorProperties
\r
73 (Context cx, IdFunction ctor, boolean sealed)
\r
75 final int attr = ScriptableObject.DONTENUM |
\r
76 ScriptableObject.PERMANENT |
\r
77 ScriptableObject.READONLY;
\r
79 ctor.defineProperty("NaN", wrap_double(ScriptRuntime.NaN), attr);
\r
80 ctor.defineProperty("POSITIVE_INFINITY",
\r
81 wrap_double(Double.POSITIVE_INFINITY), attr);
\r
82 ctor.defineProperty("NEGATIVE_INFINITY",
\r
83 wrap_double(Double.NEGATIVE_INFINITY), attr);
\r
84 ctor.defineProperty("MAX_VALUE", wrap_double(Double.MAX_VALUE), attr);
\r
85 ctor.defineProperty("MIN_VALUE", wrap_double(Double.MIN_VALUE), attr);
\r
87 super.fillConstructorProperties(cx, ctor, sealed);
\r
90 public int methodArity(int methodId) {
\r
91 if (prototypeFlag) {
\r
93 case Id_constructor: return 1;
\r
94 case Id_toString: return 1;
\r
95 case Id_valueOf: return 0;
\r
96 case Id_toLocaleString: return 1;
\r
97 case Id_toFixed: return 1;
\r
98 case Id_toExponential: return 1;
\r
99 case Id_toPrecision: return 1;
\r
102 return super.methodArity(methodId);
\r
105 public Object execMethod
\r
106 (int methodId, IdFunction f,
\r
107 Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
\r
108 throws JavaScriptException
\r
110 if (prototypeFlag) {
\r
111 switch (methodId) {
\r
112 case Id_constructor:
\r
113 return jsConstructor(args, thisObj == null);
\r
115 case Id_toString: return realThis(thisObj, f).
\r
116 jsFunction_toString(toBase(args, 0));
\r
118 case Id_valueOf: return wrap_double(realThis(thisObj, f).
\r
119 jsFunction_valueOf());
\r
121 case Id_toLocaleString: return realThis(thisObj, f).
\r
122 jsFunction_toLocaleString(toBase(args, 0));
\r
124 case Id_toFixed: return realThis(thisObj, f).
\r
125 jsFunction_toFixed(cx, args);
\r
127 case Id_toExponential: return realThis(thisObj, f).
\r
128 jsFunction_toExponential(cx, args);
\r
130 case Id_toPrecision:return realThis(thisObj, f).
\r
131 jsFunction_toPrecision(cx, args);
\r
134 return super.execMethod(methodId, f, cx, scope, thisObj, args);
\r
137 private NativeNumber realThis(Scriptable thisObj, IdFunction f) {
\r
138 while (!(thisObj instanceof NativeNumber)) {
\r
139 thisObj = nextInstanceCheck(thisObj, f, true);
\r
141 return (NativeNumber)thisObj;
\r
144 private static int toBase(Object[] args, int index) {
\r
145 return (index < args.length) ? ScriptRuntime.toInt32(args[index]) : 10;
\r
148 private Object jsConstructor(Object[] args, boolean inNewExpr) {
\r
149 double d = args.length >= 1
\r
150 ? ScriptRuntime.toNumber(args[0])
\r
153 // new Number(val) creates a new Number object.
\r
154 return new NativeNumber(d);
\r
156 // Number(val) converts val to a number value.
\r
157 return wrap_double(d);
\r
160 public String toString() {
\r
161 return jsFunction_toString(10);
\r
164 private String jsFunction_toString(int base) {
\r
165 return ScriptRuntime.numberToString(doubleValue, base);
\r
168 private double jsFunction_valueOf() {
\r
169 return doubleValue;
\r
172 private String jsFunction_toLocaleString(int base) {
\r
173 return jsFunction_toString(base);
\r
176 private String jsFunction_toFixed(Context cx, Object[] args) {
\r
177 /* We allow a larger range of precision than
\r
178 ECMA requires; this is permitted by ECMA. */
\r
179 return num_to(cx, args, DToA.DTOSTR_FIXED, DToA.DTOSTR_FIXED,
\r
180 -20, MAX_PRECISION, 0);
\r
183 private String jsFunction_toExponential(Context cx, Object[] args) {
\r
184 /* We allow a larger range of precision than
\r
185 ECMA requires; this is permitted by ECMA. */
\r
186 return num_to(cx, args,
\r
187 DToA.DTOSTR_STANDARD_EXPONENTIAL,
\r
188 DToA.DTOSTR_EXPONENTIAL,
\r
189 0, MAX_PRECISION, 1);
\r
192 private String jsFunction_toPrecision(Context cx, Object[] args) {
\r
193 /* We allow a larger range of precision than
\r
194 ECMA requires; this is permitted by ECMA. */
\r
195 return num_to(cx, args, DToA.DTOSTR_STANDARD, DToA.DTOSTR_PRECISION,
\r
196 1, MAX_PRECISION, 0);
\r
199 private String num_to(Context cx, Object[] args,
\r
200 int zeroArgMode, int oneArgMode,
\r
201 int precisionMin, int precisionMax,
\r
202 int precisionOffset)
\r
206 if (args.length == 0) {
\r
208 oneArgMode = zeroArgMode;
\r
210 precision = ScriptRuntime.toInt32(args[0]);
\r
211 if (precision < precisionMin || precision > precisionMax) {
\r
212 String msg = ScriptRuntime.getMessage1(
\r
213 "msg.bad.precision", ScriptRuntime.toString(args[0]));
\r
214 throw NativeGlobal.constructError(cx, "RangeError", msg, this);
\r
217 StringBuffer result = new StringBuffer();
\r
218 DToA.JS_dtostr(result, oneArgMode, precision + precisionOffset,
\r
220 return result.toString();
\r
223 protected String getIdName(int id) {
\r
224 if (prototypeFlag) {
\r
226 case Id_constructor: return "constructor";
\r
227 case Id_toString: return "toString";
\r
228 case Id_valueOf: return "valueOf";
\r
229 case Id_toLocaleString: return "toLocaleString";
\r
230 case Id_toFixed: return "toFixed";
\r
231 case Id_toExponential: return "toExponential";
\r
232 case Id_toPrecision: return "toPrecision";
\r
240 protected int mapNameToId(String s) {
\r
241 if (!prototypeFlag) { return 0; }
\r
243 // #generated# Last update: 2001-04-23 10:40:45 CEST
\r
244 L0: { id = 0; String X = null; int c;
\r
245 L: switch (s.length()) {
\r
246 case 7: c=s.charAt(0);
\r
247 if (c=='t') { X="toFixed";id=Id_toFixed; }
\r
248 else if (c=='v') { X="valueOf";id=Id_valueOf; }
\r
250 case 8: X="toString";id=Id_toString; break L;
\r
251 case 11: c=s.charAt(0);
\r
252 if (c=='c') { X="constructor";id=Id_constructor; }
\r
253 else if (c=='t') { X="toPrecision";id=Id_toPrecision; }
\r
255 case 13: X="toExponential";id=Id_toExponential; break L;
\r
256 case 14: X="toLocaleString";id=Id_toLocaleString; break L;
\r
258 if (X!=null && X!=s && !X.equals(s)) id = 0;
\r
264 private static final int
\r
265 Id_constructor = 1,
\r
268 Id_toLocaleString = 4,
\r
270 Id_toExponential = 6,
\r
271 Id_toPrecision = 7,
\r
272 MAX_PROTOTYPE_ID = 7;
\r
274 // #/string_id_map#
\r
276 private static final double defaultValue = +0.0;
\r
277 private double doubleValue;
\r
279 private boolean prototypeFlag;
\r