]> git.saurik.com Git - apple/javascriptcore.git/blob - kjs/internal.cpp
JavaScriptCore-461.tar.gz
[apple/javascriptcore.git] / kjs / internal.cpp
1 /*
2 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "config.h"
24 #include "internal.h"
25
26 #include "ExecState.h"
27 #include "array_object.h"
28 #include "bool_object.h"
29 #include "collector.h"
30 #include "date_object.h"
31 #include "debugger.h"
32 #include "error_object.h"
33 #include "function_object.h"
34 #include "lexer.h"
35 #include "math_object.h"
36 #include "nodes.h"
37 #include "number_object.h"
38 #include "object.h"
39 #include "object_object.h"
40 #include "operations.h"
41 #include "regexp_object.h"
42 #include "string_object.h"
43 #include <math.h>
44 #include <stdio.h>
45 #include <wtf/Assertions.h>
46 #include <wtf/HashMap.h>
47 #include <wtf/HashSet.h>
48 #include <wtf/Vector.h>
49
50 namespace KJS {
51
52 // ------------------------------ StringImp ------------------------------------
53
54 JSValue* StringImp::toPrimitive(ExecState*, JSType) const
55 {
56 return const_cast<StringImp*>(this);
57 }
58
59 bool StringImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
60 {
61 value = this;
62 number = val.toDouble();
63 return false;
64 }
65
66 bool StringImp::toBoolean(ExecState *) const
67 {
68 return (val.size() > 0);
69 }
70
71 double StringImp::toNumber(ExecState *) const
72 {
73 return val.toDouble();
74 }
75
76 UString StringImp::toString(ExecState *) const
77 {
78 return val;
79 }
80
81 JSObject* StringImp::toObject(ExecState *exec) const
82 {
83 return new StringInstance(exec->lexicalGlobalObject()->stringPrototype(), const_cast<StringImp*>(this));
84 }
85
86 // ------------------------------ NumberImp ------------------------------------
87
88 JSValue* NumberImp::toPrimitive(ExecState*, JSType) const
89 {
90 return const_cast<NumberImp*>(this);
91 }
92
93 bool NumberImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
94 {
95 number = val;
96 value = this;
97 return true;
98 }
99
100 bool NumberImp::toBoolean(ExecState *) const
101 {
102 return val < 0.0 || val > 0.0; // false for NaN
103 }
104
105 double NumberImp::toNumber(ExecState *) const
106 {
107 return val;
108 }
109
110 UString NumberImp::toString(ExecState *) const
111 {
112 if (val == 0.0) // +0.0 or -0.0
113 return "0";
114 return UString::from(val);
115 }
116
117 JSObject *NumberImp::toObject(ExecState *exec) const
118 {
119 List args;
120 args.append(const_cast<NumberImp*>(this));
121 return static_cast<JSObject *>(exec->lexicalGlobalObject()->numberConstructor()->construct(exec,args));
122 }
123
124 bool NumberImp::getUInt32(uint32_t& uint32) const
125 {
126 uint32 = static_cast<uint32_t>(val);
127 return uint32 == val;
128 }
129
130 bool NumberImp::getTruncatedInt32(int32_t& int32) const
131 {
132 if (!(val >= -2147483648.0 && val < 2147483648.0))
133 return false;
134 int32 = static_cast<int32_t>(val);
135 return true;
136 }
137
138 bool NumberImp::getTruncatedUInt32(uint32_t& uint32) const
139 {
140 if (!(val >= 0.0 && val < 4294967296.0))
141 return false;
142 uint32 = static_cast<uint32_t>(val);
143 return true;
144 }
145
146 // --------------------------- GetterSetterImp ---------------------------------
147 void GetterSetterImp::mark()
148 {
149 JSCell::mark();
150
151 if (getter && !getter->marked())
152 getter->mark();
153 if (setter && !setter->marked())
154 setter->mark();
155 }
156
157 JSValue* GetterSetterImp::toPrimitive(ExecState*, JSType) const
158 {
159 ASSERT(false);
160 return jsNull();
161 }
162
163 bool GetterSetterImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
164 {
165 ASSERT_NOT_REACHED();
166 number = 0;
167 value = 0;
168 return true;
169 }
170
171 bool GetterSetterImp::toBoolean(ExecState*) const
172 {
173 ASSERT(false);
174 return false;
175 }
176
177 double GetterSetterImp::toNumber(ExecState *) const
178 {
179 ASSERT(false);
180 return 0.0;
181 }
182
183 UString GetterSetterImp::toString(ExecState *) const
184 {
185 ASSERT(false);
186 return UString::null();
187 }
188
189 JSObject *GetterSetterImp::toObject(ExecState *exec) const
190 {
191 ASSERT(false);
192 return jsNull()->toObject(exec);
193 }
194
195 // ------------------------------ LabelStack -----------------------------------
196
197 bool LabelStack::push(const Identifier &id)
198 {
199 if (contains(id))
200 return false;
201
202 StackElem *newtos = new StackElem;
203 newtos->id = id;
204 newtos->prev = tos;
205 tos = newtos;
206 return true;
207 }
208
209 bool LabelStack::contains(const Identifier &id) const
210 {
211 if (id.isEmpty())
212 return true;
213
214 for (StackElem *curr = tos; curr; curr = curr->prev)
215 if (curr->id == id)
216 return true;
217
218 return false;
219 }
220
221 // ------------------------------ InternalFunctionImp --------------------------
222
223 const ClassInfo InternalFunctionImp::info = { "Function", 0, 0 };
224
225 InternalFunctionImp::InternalFunctionImp()
226 {
227 }
228
229 InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto, const Identifier& name)
230 : JSObject(funcProto)
231 , m_name(name)
232 {
233 }
234
235 bool InternalFunctionImp::implementsCall() const
236 {
237 return true;
238 }
239
240 bool InternalFunctionImp::implementsHasInstance() const
241 {
242 return true;
243 }
244
245 // ------------------------------ global functions -----------------------------
246
247 #ifndef NDEBUG
248 #include <stdio.h>
249 void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno)
250 {
251 if (!o)
252 fprintf(stderr, "KJS: %s: (null)", s);
253 else {
254 JSValue *v = o;
255
256 UString name;
257 switch (v->type()) {
258 case UnspecifiedType:
259 name = "Unspecified";
260 break;
261 case UndefinedType:
262 name = "Undefined";
263 break;
264 case NullType:
265 name = "Null";
266 break;
267 case BooleanType:
268 name = "Boolean";
269 break;
270 case StringType:
271 name = "String";
272 break;
273 case NumberType:
274 name = "Number";
275 break;
276 case ObjectType:
277 name = static_cast<JSObject *>(v)->className();
278 if (name.isNull())
279 name = "(unknown class)";
280 break;
281 case GetterSetterType:
282 name = "GetterSetter";
283 break;
284 }
285 UString vString = v->toString(exec);
286 if ( vString.size() > 50 )
287 vString = vString.substr( 0, 50 ) + "...";
288 // Can't use two UString::ascii() in the same fprintf call
289 CString tempString( vString.cstring() );
290
291 fprintf(stderr, "KJS: %s: %s : %s (%p)",
292 s, tempString.c_str(), name.ascii(), (void*)v);
293
294 if (lineno >= 0)
295 fprintf(stderr, ", line %d\n",lineno);
296 else
297 fprintf(stderr, "\n");
298 }
299 }
300 #endif
301
302 }