source: webkit/trunk/JavaScriptCore/kjs/internal.cpp@ 10634

Last change on this file since 10634 was 10634, checked in by mjs, 20 years ago

JavaScriptCore:

Reviewed by John.

I also moved SharedPtr and the assertion code from WebCore into a
new kxmlcore directory.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • kjs/collector.cpp: (KJS::Collector::allocate): (KJS::Collector::collect):
  • kjs/config.h:
  • kjs/fast_malloc.cpp: Removed.
  • kjs/fast_malloc.h: Removed.
  • kjs/function.cpp:
  • kjs/function.h:
  • kjs/function_object.cpp:
  • kjs/identifier.cpp: (KJS::Identifier::add):
  • kjs/internal.cpp:
  • kjs/internal.h:
  • kjs/nodes.h:
  • kjs/nodes2string.cpp:
  • kjs/property_map.cpp: (KJS::PropertyMap::~PropertyMap): (KJS::PropertyMap::rehash):
  • kjs/scope_chain.h:
  • kjs/shared_ptr.h: Removed.
  • kjs/string_object.cpp: (StringObjectFuncImp::callAsFunction):
  • kjs/ustring.cpp: (KJS::UString::Rep::createCopying): (KJS::UString::Rep::destroy): (KJS::UString::expandCapacity): (KJS::UString::expandPreCapacity): (KJS::UString::UString): (KJS::UString::spliceSubstringsWithSeparators): (KJS::UString::append): (KJS::UString::operator=): (KJS::UString::detach):
  • kjs/ustring.h:
  • kxmlcore/Assertions.h: Added.
  • kxmlcore/Assertions.mm: Added.
  • kxmlcore/FastMalloc.cpp: Added. (KXMLCore::LgFloor): (KXMLCore::SizeClass): (KXMLCore::ByteSizeForClass): (KXMLCore::InitSizeClasses): (KXMLCore::MetaDataAlloc): (KXMLCore::PageHeapAllocator::Init): (KXMLCore::PageHeapAllocator::New): (KXMLCore::PageHeapAllocator::Delete): (KXMLCore::PageHeapAllocator::inuse): (KXMLCore::pages): (KXMLCore::AllocationSize): (KXMLCore::Event): (KXMLCore::NewSpan): (KXMLCore::DeleteSpan): (KXMLCore::DLL_Init): (KXMLCore::DLL_Remove): (KXMLCore::DLL_IsEmpty): (KXMLCore::DLL_Length): (KXMLCore::DLL_Print): (KXMLCore::DLL_Prepend): (KXMLCore::DLL_InsertOrdered): (KXMLCore::): (KXMLCore::TCMalloc_PageHeap::GetDescriptor): (KXMLCore::TCMalloc_PageHeap::SystemBytes): (KXMLCore::TCMalloc_PageHeap::FreeBytes): (KXMLCore::TCMalloc_PageHeap::RecordSpan): (KXMLCore::TCMalloc_PageHeap::TCMalloc_PageHeap): (KXMLCore::TCMalloc_PageHeap::New): (KXMLCore::TCMalloc_PageHeap::Split): (KXMLCore::TCMalloc_PageHeap::Carve): (KXMLCore::TCMalloc_PageHeap::Delete): (KXMLCore::TCMalloc_PageHeap::RegisterSizeClass): (KXMLCore::TCMalloc_PageHeap::Dump): (KXMLCore::TCMalloc_PageHeap::GrowHeap): (KXMLCore::TCMalloc_PageHeap::Check): (KXMLCore::TCMalloc_PageHeap::CheckList): (KXMLCore::TCMalloc_ThreadCache_FreeList::Init): (KXMLCore::TCMalloc_ThreadCache_FreeList::length): (KXMLCore::TCMalloc_ThreadCache_FreeList::empty): (KXMLCore::TCMalloc_ThreadCache_FreeList::lowwatermark): (KXMLCore::TCMalloc_ThreadCache_FreeList::clear_lowwatermark): (KXMLCore::TCMalloc_ThreadCache_FreeList::Push): (KXMLCore::TCMalloc_ThreadCache_FreeList::Pop): (KXMLCore::TCMalloc_ThreadCache::freelist_length): (KXMLCore::TCMalloc_ThreadCache::Size): (KXMLCore::TCMalloc_Central_FreeList::length): (KXMLCore::TCMalloc_Central_FreeList::Init): (KXMLCore::TCMalloc_Central_FreeList::Insert): (KXMLCore::TCMalloc_Central_FreeList::Remove): (KXMLCore::TCMalloc_Central_FreeList::Populate): (KXMLCore::TCMalloc_ThreadCache::SampleAllocation): (KXMLCore::TCMalloc_ThreadCache::Init): (KXMLCore::TCMalloc_ThreadCache::Cleanup): (KXMLCore::TCMalloc_ThreadCache::Allocate): (KXMLCore::TCMalloc_ThreadCache::Deallocate): (KXMLCore::TCMalloc_ThreadCache::FetchFromCentralCache): (KXMLCore::TCMalloc_ThreadCache::ReleaseToCentralCache): (KXMLCore::TCMalloc_ThreadCache::Scavenge): (KXMLCore::TCMalloc_ThreadCache::GetCache): (KXMLCore::TCMalloc_ThreadCache::GetCacheIfPresent): (KXMLCore::TCMalloc_ThreadCache::PickNextSample): (KXMLCore::TCMalloc_ThreadCache::InitModule): (KXMLCore::TCMalloc_ThreadCache::InitTSD): (KXMLCore::TCMalloc_ThreadCache::CreateCacheIfNecessary): (KXMLCore::TCMalloc_ThreadCache::DeleteCache): (KXMLCore::TCMalloc_ThreadCache::RecomputeThreadCacheSize): (KXMLCore::TCMalloc_ThreadCache::Print): (KXMLCore::ExtractStats): (KXMLCore::DumpStats): (KXMLCore::PrintStats): (KXMLCore::DumpStackTraces): (KXMLCore::TCMallocImplementation::GetStats): (KXMLCore::TCMallocImplementation::ReadStackTraces): (KXMLCore::TCMallocImplementation::GetNumericProperty): (KXMLCore::TCMallocImplementation::SetNumericProperty): (KXMLCore::DoSampledAllocation): (KXMLCore::do_malloc): (KXMLCore::do_free): (KXMLCore::do_memalign): (KXMLCore::TCMallocGuard::TCMallocGuard): (KXMLCore::TCMallocGuard::~TCMallocGuard): (KXMLCore::malloc): (KXMLCore::free): (KXMLCore::calloc): (KXMLCore::cfree): (KXMLCore::realloc): (KXMLCore::memalign): (KXMLCore::posix_memalign): (KXMLCore::valloc): (KXMLCore::pvalloc): (KXMLCore::malloc_stats): (KXMLCore::mallopt): (KXMLCore::mallinfo):
  • kxmlcore/FastMalloc.h: Added. (KXMLCore::FastAllocated::operator new): (KXMLCore::FastAllocated::operator delete): (KXMLCore::FastAllocated::operator new[]): (KXMLCore::FastAllocated::operator delete[]):
  • kxmlcore/SharedPtr.h: Added. (KXMLCore::SharedPtr::SharedPtr): (KXMLCore::SharedPtr::~SharedPtr): (KXMLCore::SharedPtr::isNull): (KXMLCore::SharedPtr::notNull): (KXMLCore::SharedPtr::reset): (KXMLCore::SharedPtr::get): (KXMLCore::SharedPtr::operator*): (KXMLCore::SharedPtr::operator->): (KXMLCore::SharedPtr::operator!): (KXMLCore::SharedPtr::operator bool): (KXMLCore::::operator): (KXMLCore::operator==): (KXMLCore::operator!=): (KXMLCore::static_pointer_cast): (KXMLCore::const_pointer_cast):
  • kxmlcore/TCPageMap.h: Added. (TCMalloc_PageMap1::TCMalloc_PageMap1): (TCMalloc_PageMap1::Ensure): (TCMalloc_PageMap1::get): (TCMalloc_PageMap1::set): (TCMalloc_PageMap2::TCMalloc_PageMap2): (TCMalloc_PageMap2::get): (TCMalloc_PageMap2::set): (TCMalloc_PageMap2::Ensure): (TCMalloc_PageMap3::NewNode): (TCMalloc_PageMap3::TCMalloc_PageMap3): (TCMalloc_PageMap3::get): (TCMalloc_PageMap3::set): (TCMalloc_PageMap3::Ensure):
  • kxmlcore/TCSpinLock.h: Added. (TCMalloc_SpinLock::Init): (TCMalloc_SpinLock::Finalize): (TCMalloc_SpinLock::Lock): (TCMalloc_SpinLock::Unlock): (TCMalloc_SlowLock): (TCMalloc_SpinLockHolder::TCMalloc_SpinLockHolder): (TCMalloc_SpinLockHolder::~TCMalloc_SpinLockHolder):
  • kxmlcore/TCSystemAlloc.cpp: Added. (TrySbrk): (TryMmap): (TryDevMem): (TCMalloc_SystemAlloc):
  • kxmlcore/TCSystemAlloc.h: Added.

WebCore:

Reviewed by John.

I also moved SharedPtr and the assertion code from WebCore into a
new kxmlcore directory.

  • ForwardingHeaders/kjs/shared_ptr.h: Removed.
  • ForwardingHeaders/kxmlcore/Assertions.h: Added.
  • ForwardingHeaders/kxmlcore/FastMalloc.h: Added.
  • ForwardingHeaders/kxmlcore/SharedPtr.h: Added.
  • ForwardingHeaders/misc/main_thread_malloc.h: Removed.
  • WebCore.xcodeproj/project.pbxproj:
  • khtml/css/css_base.h:
  • khtml/css/css_computedstyle.cpp:
  • khtml/css/css_ruleimpl.h:
  • khtml/css/css_valueimpl.h:
  • khtml/css/cssstyleselector.h:
  • khtml/ecma/domparser.h:
  • khtml/ecma/kjs_css.h:
  • khtml/ecma/kjs_dom.cpp:
  • khtml/ecma/kjs_dom.h:
  • khtml/ecma/kjs_events.h:
  • khtml/ecma/kjs_html.cpp:
  • khtml/ecma/kjs_html.h:
  • khtml/ecma/kjs_range.h:
  • khtml/ecma/kjs_traversal.h:
  • khtml/ecma/kjs_views.cpp:
  • khtml/ecma/kjs_views.h:
  • khtml/ecma/kjs_window.cpp:
  • khtml/ecma/xmlhttprequest.h:
  • khtml/editing/SelectionController.cpp:
  • khtml/editing/append_node_command.cpp:
  • khtml/editing/apply_style_command.cpp:
  • khtml/editing/break_blockquote_command.cpp:
  • khtml/editing/composite_edit_command.cpp:
  • khtml/editing/delete_from_text_node_command.cpp:
  • khtml/editing/delete_selection_command.cpp:
  • khtml/editing/edit_command.cpp:
  • khtml/editing/htmlediting.cpp:
  • khtml/editing/insert_into_text_node_command.cpp:
  • khtml/editing/insert_line_break_command.cpp:
  • khtml/editing/insert_node_before_command.cpp:
  • khtml/editing/insert_paragraph_separator_command.cpp:
  • khtml/editing/insert_text_command.cpp:
  • khtml/editing/join_text_nodes_command.cpp:
  • khtml/editing/markup.cpp:
  • khtml/editing/merge_identical_elements_command.cpp:
  • khtml/editing/move_selection_command.cpp:
  • khtml/editing/rebalance_whitespace_command.cpp:
  • khtml/editing/remove_css_property_command.cpp:
  • khtml/editing/remove_node_attribute_command.cpp:
  • khtml/editing/remove_node_command.cpp:
  • khtml/editing/remove_node_preserving_children_command.cpp:
  • khtml/editing/replace_selection_command.cpp:
  • khtml/editing/set_node_attribute_command.cpp:
  • khtml/editing/split_element_command.cpp:
  • khtml/editing/split_text_node_command.cpp:
  • khtml/editing/split_text_node_containing_element.cpp:
  • khtml/editing/typing_command.cpp:
  • khtml/editing/visible_position.cpp:
  • khtml/editing/visible_position.h:
  • khtml/editing/wrap_contents_in_dummy_span_command.cpp:
  • khtml/html/html_imageimpl.h:
  • khtml/html/html_tableimpl.h:
  • khtml/html/htmlparser.cpp:
  • khtml/khtmlpart_p.h:
  • khtml/misc/arena.cpp: (ArenaAllocate): (FreeArenaList): (ArenaFinish):
  • khtml/misc/hashtable.h: (khtml::HashTable::~HashTable): (khtml::::allocateTable): (khtml::::rehash): (khtml::::clear): (khtml::::HashTable):
  • khtml/misc/loader.cpp:
  • khtml/misc/main_thread_malloc.cpp: Removed.
  • khtml/misc/main_thread_malloc.h: Removed.
  • khtml/misc/shared.h:
  • khtml/rendering/render_style.h:
  • khtml/xml/dom2_eventsimpl.h:
  • khtml/xml/dom2_rangeimpl.h:
  • khtml/xml/dom2_traversalimpl.h:
  • khtml/xml/dom2_viewsimpl.h:
  • khtml/xml/dom_docimpl.h:
  • khtml/xml/dom_elementimpl.cpp: (NamedAttrMapImpl::clearAttributes): (NamedAttrMapImpl::operator=): (NamedAttrMapImpl::addAttribute): (NamedAttrMapImpl::removeAttribute):
  • khtml/xml/dom_elementimpl.h:
  • khtml/xml/dom_nodeimpl.cpp:
  • khtml/xml/dom_nodeimpl.h:
  • khtml/xml/dom_position.cpp:
  • khtml/xml/dom_stringimpl.h:
  • kwq/DOM-CSS.mm:
  • kwq/DOM.mm:
  • kwq/DOMEvents.mm:
  • kwq/DOMHTML.mm:
  • kwq/DOMInternal.mm:
  • kwq/DOMViews.mm:
  • kwq/KWQAccObject.mm:
  • kwq/KWQAccObjectCache.mm:
  • kwq/KWQArrayImpl.h:
  • kwq/KWQArrayImpl.mm: (KWQArrayImpl::KWQArrayPrivate::KWQArrayPrivate): (KWQArrayImpl::KWQArrayPrivate::~KWQArrayPrivate): (KWQArrayImpl::resize):
  • kwq/KWQAssertions.h: Removed.
  • kwq/KWQAssertions.m: Removed.
  • kwq/KWQButton.mm:
  • kwq/KWQCString.mm:
  • kwq/KWQClipboard.h:
  • kwq/KWQClipboard.mm:
  • kwq/KWQColor.mm:
  • kwq/KWQComboBox.mm:
  • kwq/KWQEditCommand.mm:
  • kwq/KWQExceptions.h:
  • kwq/KWQFileButton.mm:
  • kwq/KWQFontFamily.h:
  • kwq/KWQFormData.mm:
  • kwq/KWQKHTMLPart.h:
  • kwq/KWQKHTMLPart.mm:
  • kwq/KWQKPartsBrowserInterface.mm:
  • kwq/KWQKURL.mm:
  • kwq/KWQListBox.mm:
  • kwq/KWQListImpl.mm:
  • kwq/KWQLogging.h:
  • kwq/KWQLogging.m:
  • kwq/KWQMapImpl.h:
  • kwq/KWQMapImpl.mm:
  • kwq/KWQObject.mm:
  • kwq/KWQPageState.mm:
  • kwq/KWQPainter.mm:
  • kwq/KWQResourceLoader.mm:
  • kwq/KWQSignal.mm:
  • kwq/KWQSlot.mm:
  • kwq/KWQString.h:
  • kwq/KWQString.mm: (ALLOC_QCHAR): (QString::setBufferFromCFString): (allocatePageNode):
  • kwq/KWQTextArea.mm:
  • kwq/KWQTextCodec.mm:
  • kwq/KWQTextEdit.mm:
  • kwq/KWQTextField.mm:
  • kwq/KWQTimer.mm:
  • kwq/KWQValueListImpl.h:
  • kwq/KWQValueListImpl.mm:
  • kwq/WebCoreBridge.mm:
  • kwq/WebCoreCookieAdapter.m:
  • kwq/WebCoreGraphicsBridge.m:
  • kwq/WebCoreImageRendererFactory.m:
  • kwq/WebCoreKeyGenerator.m:
  • kwq/WebCoreTextRendererFactory.mm:
  • kwq/WebCoreViewFactory.m:
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.5 KB
Line 
1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 1999-2002 Harri Porten ([email protected])
4 * Copyright (C) 2001 Peter Kelly ([email protected])
5 * Copyright (C) 2004 Apple Computer, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include <stdio.h>
25#include <math.h>
26#include <assert.h>
27
28#include "array_object.h"
29#include "bool_object.h"
30#include "collector.h"
31#include "context.h"
32#include "date_object.h"
33#include "debugger.h"
34#include "error_object.h"
35#include "function_object.h"
36#include "internal.h"
37#include "interpreter_map.h"
38#include "lexer.h"
39#include "math_object.h"
40#include "nodes.h"
41#include "number_object.h"
42#include "object.h"
43#include "object_object.h"
44#include "operations.h"
45#include "regexp_object.h"
46#include "string_object.h"
47
48#if WIN32
49#include <float.h>
50#define copysign(a, b) _copysign(a, b)
51#endif
52
53extern int kjsyyparse();
54
55namespace KJS {
56
57#if !APPLE_CHANGES
58
59#ifdef WORDS_BIGENDIAN
60 const unsigned char NaN_Bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
61 const unsigned char Inf_Bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
62#elif defined(arm)
63 const unsigned char NaN_Bytes[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 };
64 const unsigned char Inf_Bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };
65#else
66 const unsigned char NaN_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
67 const unsigned char Inf_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
68#endif
69
70 const double NaN = *(const double*) NaN_Bytes;
71 const double Inf = *(const double*) Inf_Bytes;
72
73#endif // APPLE_CHANGES
74
75#if !KJS_MULTIPLE_THREADS
76
77static inline void initializeInterpreterLock() { }
78static inline void lockInterpreter() { }
79static inline void unlockInterpreter() { }
80
81const int interpreterLockCount = 1;
82
83#else
84
85static pthread_once_t interpreterLockOnce = PTHREAD_ONCE_INIT;
86static pthread_mutex_t interpreterLock;
87static int interpreterLockCount = 0;
88
89static void initializeInterpreterLock()
90{
91 pthread_mutexattr_t attr;
92
93 pthread_mutexattr_init(&attr);
94 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
95
96 pthread_mutex_init(&interpreterLock, &attr);
97}
98
99static inline void lockInterpreter()
100{
101 pthread_once(&interpreterLockOnce, initializeInterpreterLock);
102 pthread_mutex_lock(&interpreterLock);
103 interpreterLockCount++;
104 Collector::registerThread();
105}
106
107static inline void unlockInterpreter()
108{
109 interpreterLockCount--;
110 pthread_mutex_unlock(&interpreterLock);
111}
112
113#endif
114
115// ------------------------------ UndefinedImp ---------------------------------
116
117ValueImp *UndefinedImp::toPrimitive(ExecState */*exec*/, Type) const
118{
119 return const_cast<UndefinedImp *>(this);
120}
121
122bool UndefinedImp::toBoolean(ExecState */*exec*/) const
123{
124 return false;
125}
126
127double UndefinedImp::toNumber(ExecState */*exec*/) const
128{
129 return NaN;
130}
131
132UString UndefinedImp::toString(ExecState */*exec*/) const
133{
134 return "undefined";
135}
136
137ObjectImp *UndefinedImp::toObject(ExecState *exec) const
138{
139 return throwError(exec, TypeError, "Undefined value");
140}
141
142// ------------------------------ NullImp --------------------------------------
143
144ValueImp *NullImp::toPrimitive(ExecState */*exec*/, Type) const
145{
146 return const_cast<NullImp *>(this);
147}
148
149bool NullImp::toBoolean(ExecState */*exec*/) const
150{
151 return false;
152}
153
154double NullImp::toNumber(ExecState */*exec*/) const
155{
156 return 0.0;
157}
158
159UString NullImp::toString(ExecState */*exec*/) const
160{
161 return "null";
162}
163
164ObjectImp *NullImp::toObject(ExecState *exec) const
165{
166 return throwError(exec, TypeError, "Null value");
167}
168
169// ------------------------------ BooleanImp -----------------------------------
170
171ValueImp *BooleanImp::toPrimitive(ExecState */*exec*/, Type) const
172{
173 return const_cast<BooleanImp *>(this);
174}
175
176bool BooleanImp::toBoolean(ExecState */*exec*/) const
177{
178 return val;
179}
180
181double BooleanImp::toNumber(ExecState */*exec*/) const
182{
183 return val ? 1.0 : 0.0;
184}
185
186UString BooleanImp::toString(ExecState */*exec*/) const
187{
188 return val ? "true" : "false";
189}
190
191ObjectImp *BooleanImp::toObject(ExecState *exec) const
192{
193 List args;
194 args.append(const_cast<BooleanImp*>(this));
195 return static_cast<ObjectImp *>(exec->lexicalInterpreter()->builtinBoolean()->construct(exec,args));
196}
197
198// ------------------------------ StringImp ------------------------------------
199
200ValueImp *StringImp::toPrimitive(ExecState */*exec*/, Type) const
201{
202 return const_cast<StringImp *>(this);
203}
204
205bool StringImp::toBoolean(ExecState */*exec*/) const
206{
207 return (val.size() > 0);
208}
209
210double StringImp::toNumber(ExecState */*exec*/) const
211{
212 return val.toDouble();
213}
214
215UString StringImp::toString(ExecState */*exec*/) const
216{
217 return val;
218}
219
220ObjectImp *StringImp::toObject(ExecState *exec) const
221{
222 List args;
223 args.append(const_cast<StringImp*>(this));
224 return static_cast<ObjectImp *>(exec->lexicalInterpreter()->builtinString()->construct(exec, args));
225}
226
227// ------------------------------ NumberImp ------------------------------------
228
229ValueImp *NumberImp::toPrimitive(ExecState *, Type) const
230{
231 return const_cast<NumberImp *>(this);
232}
233
234bool NumberImp::toBoolean(ExecState *) const
235{
236 return !((val == 0) /* || (iVal() == N0) */ || isNaN(val));
237}
238
239double NumberImp::toNumber(ExecState *) const
240{
241 return val;
242}
243
244UString NumberImp::toString(ExecState *) const
245{
246 if (val == 0.0) // +0.0 or -0.0
247 return "0";
248 return UString::from(val);
249}
250
251ObjectImp *NumberImp::toObject(ExecState *exec) const
252{
253 List args;
254 args.append(const_cast<NumberImp*>(this));
255 return static_cast<ObjectImp *>(exec->lexicalInterpreter()->builtinNumber()->construct(exec,args));
256}
257
258bool NumberImp::getUInt32(uint32_t& uint32) const
259{
260 uint32 = (uint32_t)val;
261 return (double)uint32 == val;
262}
263
264// ------------------------------ LabelStack -----------------------------------
265
266bool LabelStack::push(const Identifier &id)
267{
268 if (contains(id))
269 return false;
270
271 StackElem *newtos = new StackElem;
272 newtos->id = id;
273 newtos->prev = tos;
274 tos = newtos;
275 return true;
276}
277
278bool LabelStack::contains(const Identifier &id) const
279{
280 if (id.isEmpty())
281 return true;
282
283 for (StackElem *curr = tos; curr; curr = curr->prev)
284 if (curr->id == id)
285 return true;
286
287 return false;
288}
289
290// ------------------------------ ContextImp -----------------------------------
291
292// ECMA 10.2
293ContextImp::ContextImp(ObjectImp *glob, InterpreterImp *interpreter, ObjectImp *thisV, CodeType type,
294 ContextImp *callingCon, FunctionImp *func, const List *args)
295 : _interpreter(interpreter), _function(func), _arguments(args)
296{
297 m_codeType = type;
298 _callingContext = callingCon;
299
300 // create and initialize activation object (ECMA 10.1.6)
301 if (type == FunctionCode || type == AnonymousCode ) {
302 activation = new ActivationImp(func, *args);
303 variable = activation;
304 } else {
305 activation = NULL;
306 variable = glob;
307 }
308
309 // ECMA 10.2
310 switch(type) {
311 case EvalCode:
312 if (_callingContext) {
313 scope = _callingContext->scopeChain();
314 variable = _callingContext->variableObject();
315 thisVal = _callingContext->thisValue();
316 break;
317 } // else same as GlobalCode
318 case GlobalCode:
319 scope.clear();
320 scope.push(glob);
321 thisVal = static_cast<ObjectImp*>(glob);
322 break;
323 case FunctionCode:
324 case AnonymousCode:
325 if (type == FunctionCode) {
326 scope = func->scope();
327 scope.push(activation);
328 } else {
329 scope.clear();
330 scope.push(glob);
331 scope.push(activation);
332 }
333 variable = activation; // TODO: DontDelete ? (ECMA 10.2.3)
334 thisVal = thisV;
335 break;
336 }
337
338 _interpreter->setContext(this);
339}
340
341ContextImp::~ContextImp()
342{
343 _interpreter->setContext(_callingContext);
344}
345
346void ContextImp::mark()
347{
348 for (ContextImp *context = this; context; context = context->_callingContext) {
349 context->scope.mark();
350 }
351}
352
353// ------------------------------ Parser ---------------------------------------
354
355static SharedPtr<ProgramNode> *progNode;
356int Parser::sid = 0;
357
358const int initialCapacity = 64;
359const int growthFactor = 2;
360
361static int numNewNodes;
362static int newNodesCapacity;
363static Node **newNodes;
364
365void Parser::saveNewNode(Node *node)
366{
367 if (numNewNodes == newNodesCapacity) {
368 newNodesCapacity = (newNodesCapacity == 0) ? initialCapacity : newNodesCapacity * growthFactor;
369 newNodes = (Node **)realloc(newNodes, sizeof(Node *) * newNodesCapacity);
370 }
371
372 newNodes[numNewNodes++] = node;
373}
374
375static void clearNewNodes()
376{
377 for (int i = 0; i < numNewNodes; i++) {
378 if (newNodes[i]->refcount() == 0)
379 delete newNodes[i];
380 }
381 delete newNodes;
382 newNodes = 0;
383 numNewNodes = 0;
384 newNodesCapacity = 0;
385}
386
387SharedPtr<ProgramNode> Parser::parse(const UString &sourceURL, int startingLineNumber,
388 const UChar *code, unsigned int length, int *sourceId,
389 int *errLine, UString *errMsg)
390{
391 if (errLine)
392 *errLine = -1;
393 if (errMsg)
394 *errMsg = 0;
395 if (!progNode)
396 progNode = new SharedPtr<ProgramNode>;
397
398 Lexer::curr()->setCode(sourceURL, startingLineNumber, code, length);
399 *progNode = 0;
400 sid++;
401 if (sourceId)
402 *sourceId = sid;
403 // Enable this (and the #define YYDEBUG in grammar.y) to debug a parse error
404 //extern int kjsyydebug;
405 //kjsyydebug=1;
406 int parseError = kjsyyparse();
407 bool lexError = Lexer::curr()->sawError();
408 Lexer::curr()->doneParsing();
409 SharedPtr<ProgramNode> prog = *progNode;
410 *progNode = 0;
411
412 clearNewNodes();
413
414 if (parseError || lexError) {
415 int eline = Lexer::curr()->lineNo();
416 if (errLine)
417 *errLine = eline;
418 if (errMsg)
419 *errMsg = "Parse error";
420 return SharedPtr<ProgramNode>();
421 }
422
423 return prog;
424}
425
426void Parser::accept(ProgramNode *prog)
427{
428 *progNode = prog;
429}
430
431// ------------------------------ InterpreterImp -------------------------------
432
433InterpreterImp* InterpreterImp::s_hook = 0L;
434
435void InterpreterImp::globalInit()
436{
437 ConstantValues::init();
438}
439
440void InterpreterImp::globalClear()
441{
442 ConstantValues::clear();
443}
444
445InterpreterImp::InterpreterImp(Interpreter *interp, ObjectImp *glob)
446 : globExec(interp, 0)
447 , _context(0)
448{
449 // add this interpreter to the global chain
450 // as a root set for garbage collection
451 InterpreterLock lock;
452
453 m_interpreter = interp;
454 if (s_hook) {
455 prev = s_hook;
456 next = s_hook->next;
457 s_hook->next->prev = this;
458 s_hook->next = this;
459 } else {
460 // This is the first interpreter
461 s_hook = next = prev = this;
462 globalInit();
463 }
464
465 InterpreterMap::setInterpreterForGlobalObject(this, glob);
466
467 global = glob;
468 dbg = 0;
469 m_compatMode = Interpreter::NativeMode;
470
471 // initialize properties of the global object
472 initGlobalObject();
473
474 recursion = 0;
475}
476
477void InterpreterImp::lock()
478{
479 lockInterpreter();
480}
481
482int InterpreterImp::lockCount()
483{
484 return interpreterLockCount;
485}
486
487void InterpreterImp::unlock()
488{
489 unlockInterpreter();
490}
491
492 void InterpreterImp::initGlobalObject()
493{
494 Identifier::init();
495
496 // Contructor prototype objects (Object.prototype, Array.prototype etc)
497
498 FunctionPrototypeImp *funcProto = new FunctionPrototypeImp(&globExec);
499 b_FunctionPrototype = funcProto;
500 ObjectPrototypeImp *objProto = new ObjectPrototypeImp(&globExec, funcProto);
501 b_ObjectPrototype = objProto;
502 funcProto->setPrototype(b_ObjectPrototype);
503
504 ArrayPrototypeImp *arrayProto = new ArrayPrototypeImp(&globExec, objProto);
505 b_ArrayPrototype = arrayProto;
506 StringPrototypeImp *stringProto = new StringPrototypeImp(&globExec, objProto);
507 b_StringPrototype = stringProto;
508 BooleanPrototypeImp *booleanProto = new BooleanPrototypeImp(&globExec, objProto, funcProto);
509 b_BooleanPrototype = booleanProto;
510 NumberPrototypeImp *numberProto = new NumberPrototypeImp(&globExec, objProto, funcProto);
511 b_NumberPrototype = numberProto;
512 DatePrototypeImp *dateProto = new DatePrototypeImp(&globExec, objProto);
513 b_DatePrototype = dateProto;
514 RegExpPrototypeImp *regexpProto = new RegExpPrototypeImp(&globExec, objProto, funcProto);
515 b_RegExpPrototype = regexpProto;
516 ErrorPrototypeImp *errorProto = new ErrorPrototypeImp(&globExec, objProto, funcProto);
517 b_ErrorPrototype = errorProto;
518
519 static_cast<ObjectImp*>(global)->setPrototype(b_ObjectPrototype);
520
521 // Constructors (Object, Array, etc.)
522 b_Object = new ObjectObjectImp(&globExec, objProto, funcProto);
523 b_Function = new FunctionObjectImp(&globExec, funcProto);
524 b_Array = new ArrayObjectImp(&globExec, funcProto, arrayProto);
525 b_String = new StringObjectImp(&globExec, funcProto, stringProto);
526 b_Boolean = new BooleanObjectImp(&globExec, funcProto, booleanProto);
527 b_Number = new NumberObjectImp(&globExec, funcProto, numberProto);
528 b_Date = new DateObjectImp(&globExec, funcProto, dateProto);
529 b_RegExp = new RegExpObjectImp(&globExec, funcProto, regexpProto);
530 b_Error = new ErrorObjectImp(&globExec, funcProto, errorProto);
531
532 // Error object prototypes
533 b_evalErrorPrototype = new NativeErrorPrototypeImp(&globExec, errorProto, EvalError, "EvalError", "EvalError");
534 b_rangeErrorPrototype = new NativeErrorPrototypeImp(&globExec, errorProto, RangeError, "RangeError", "RangeError");
535 b_referenceErrorPrototype = new NativeErrorPrototypeImp(&globExec, errorProto, ReferenceError, "ReferenceError", "ReferenceError");
536 b_syntaxErrorPrototype = new NativeErrorPrototypeImp(&globExec, errorProto, SyntaxError, "SyntaxError", "SyntaxError");
537 b_typeErrorPrototype = new NativeErrorPrototypeImp(&globExec, errorProto, TypeError, "TypeError", "TypeError");
538 b_uriErrorPrototype = new NativeErrorPrototypeImp(&globExec, errorProto, URIError, "URIError", "URIError");
539
540 // Error objects
541 b_evalError = new NativeErrorImp(&globExec, funcProto, b_evalErrorPrototype);
542 b_rangeError = new NativeErrorImp(&globExec, funcProto, b_rangeErrorPrototype);
543 b_referenceError = new NativeErrorImp(&globExec, funcProto, b_referenceErrorPrototype);
544 b_syntaxError = new NativeErrorImp(&globExec, funcProto, b_syntaxErrorPrototype);
545 b_typeError = new NativeErrorImp(&globExec, funcProto, b_typeErrorPrototype);
546 b_uriError = new NativeErrorImp(&globExec, funcProto, b_uriErrorPrototype);
547
548 // ECMA 15.3.4.1
549 funcProto->put(&globExec, "constructor", b_Function, DontEnum);
550
551 global->put(&globExec, "Object", b_Object, DontEnum);
552 global->put(&globExec, "Function", b_Function, DontEnum);
553 global->put(&globExec, "Array", b_Array, DontEnum);
554 global->put(&globExec, "Boolean", b_Boolean, DontEnum);
555 global->put(&globExec, "String", b_String, DontEnum);
556 global->put(&globExec, "Number", b_Number, DontEnum);
557 global->put(&globExec, "Date", b_Date, DontEnum);
558 global->put(&globExec, "RegExp", b_RegExp, DontEnum);
559 global->put(&globExec, "Error", b_Error, DontEnum);
560 // Using Internal for those to have something != 0
561 // (see kjs_window). Maybe DontEnum would be ok too ?
562 global->put(&globExec, "EvalError",b_evalError, Internal);
563 global->put(&globExec, "RangeError",b_rangeError, Internal);
564 global->put(&globExec, "ReferenceError",b_referenceError, Internal);
565 global->put(&globExec, "SyntaxError",b_syntaxError, Internal);
566 global->put(&globExec, "TypeError",b_typeError, Internal);
567 global->put(&globExec, "URIError",b_uriError, Internal);
568
569 // Set the "constructor" property of all builtin constructors
570 objProto->put(&globExec, "constructor", b_Object, DontEnum | DontDelete | ReadOnly);
571 funcProto->put(&globExec, "constructor", b_Function, DontEnum | DontDelete | ReadOnly);
572 arrayProto->put(&globExec, "constructor", b_Array, DontEnum | DontDelete | ReadOnly);
573 booleanProto->put(&globExec, "constructor", b_Boolean, DontEnum | DontDelete | ReadOnly);
574 stringProto->put(&globExec, "constructor", b_String, DontEnum | DontDelete | ReadOnly);
575 numberProto->put(&globExec, "constructor", b_Number, DontEnum | DontDelete | ReadOnly);
576 dateProto->put(&globExec, "constructor", b_Date, DontEnum | DontDelete | ReadOnly);
577 regexpProto->put(&globExec, "constructor", b_RegExp, DontEnum | DontDelete | ReadOnly);
578 errorProto->put(&globExec, "constructor", b_Error, DontEnum | DontDelete | ReadOnly);
579 b_evalErrorPrototype->put(&globExec, "constructor", b_evalError, DontEnum | DontDelete | ReadOnly);
580 b_rangeErrorPrototype->put(&globExec, "constructor", b_rangeError, DontEnum | DontDelete | ReadOnly);
581 b_referenceErrorPrototype->put(&globExec, "constructor", b_referenceError, DontEnum | DontDelete | ReadOnly);
582 b_syntaxErrorPrototype->put(&globExec, "constructor", b_syntaxError, DontEnum | DontDelete | ReadOnly);
583 b_typeErrorPrototype->put(&globExec, "constructor", b_typeError, DontEnum | DontDelete | ReadOnly);
584 b_uriErrorPrototype->put(&globExec, "constructor", b_uriError, DontEnum | DontDelete | ReadOnly);
585
586 // built-in values
587 global->put(&globExec, "NaN", jsNaN(), DontEnum|DontDelete);
588 global->put(&globExec, "Infinity", Number(Inf), DontEnum|DontDelete);
589 global->put(&globExec, "undefined", Undefined(), DontEnum|DontDelete);
590
591 // built-in functions
592 global->put(&globExec, "eval", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Eval, 1), DontEnum);
593 global->put(&globExec, "parseInt", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseInt, 2), DontEnum);
594 global->put(&globExec, "parseFloat", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::ParseFloat, 1), DontEnum);
595 global->put(&globExec, "isNaN", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsNaN, 1), DontEnum);
596 global->put(&globExec, "isFinite", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::IsFinite, 1), DontEnum);
597 global->put(&globExec, "escape", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::Escape, 1), DontEnum);
598 global->put(&globExec, "unescape", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::UnEscape, 1), DontEnum);
599 global->put(&globExec, "decodeURI", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURI, 1), DontEnum);
600 global->put(&globExec, "decodeURIComponent", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::DecodeURIComponent, 1), DontEnum);
601 global->put(&globExec, "encodeURI", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURI, 1), DontEnum);
602 global->put(&globExec, "encodeURIComponent", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::EncodeURIComponent, 1), DontEnum);
603#ifndef NDEBUG
604 global->put(&globExec, "kjsprint", new GlobalFuncImp(&globExec, funcProto, GlobalFuncImp::KJSPrint, 1), DontEnum);
605#endif
606
607 // built-in objects
608 global->put(&globExec, "Math", new MathObjectImp(&globExec, objProto), DontEnum);
609}
610
611InterpreterImp::~InterpreterImp()
612{
613 if (dbg)
614 dbg->detach(m_interpreter);
615 clear();
616}
617
618void InterpreterImp::clear()
619{
620 //fprintf(stderr,"InterpreterImp::clear\n");
621 // remove from global chain (see init())
622 InterpreterLock lock;
623
624 next->prev = prev;
625 prev->next = next;
626 s_hook = next;
627 if (s_hook == this)
628 {
629 // This was the last interpreter
630 s_hook = 0L;
631 globalClear();
632 }
633 InterpreterMap::removeInterpreterForGlobalObject(global);
634}
635
636void InterpreterImp::mark()
637{
638 ConstantValues::mark();
639 if (m_interpreter)
640 m_interpreter->mark();
641 if (_context)
642 _context->mark();
643 if (global)
644 global->mark();
645 if (globExec._exception)
646 globExec._exception->mark();
647}
648
649bool InterpreterImp::checkSyntax(const UString &code)
650{
651 InterpreterLock lock;
652
653 // Parser::parse() returns 0 in a syntax error occurs, so we just check for that
654 SharedPtr<ProgramNode> progNode = Parser::parse(UString(), 0, code.data(),code.size(),0,0,0);
655 return progNode;
656}
657
658Completion InterpreterImp::evaluate(const UString &code, ValueImp *thisV, const UString &sourceURL, int startingLineNumber)
659{
660 InterpreterLock lock;
661
662 // prevent against infinite recursion
663 if (recursion >= 20) {
664#if APPLE_CHANGES
665 Completion result = Completion(Throw, Error::create(&globExec, GeneralError, "Recursion too deep"));
666 return result;
667#else
668 return Completion(Throw,Error::create(&globExec, GeneralError, "Recursion too deep"));
669#endif
670 }
671
672 // parse the source code
673 int sid;
674 int errLine;
675 UString errMsg;
676 SharedPtr<ProgramNode> progNode = Parser::parse(sourceURL, startingLineNumber, code.data(),code.size(),&sid,&errLine,&errMsg);
677
678 // notify debugger that source has been parsed
679 if (dbg) {
680 bool cont = dbg->sourceParsed(&globExec, sid, sourceURL, code, errLine);
681 if (!cont)
682 return Completion(Break);
683 }
684
685 // no program node means a syntax error occurred
686 if (!progNode) {
687 ObjectImp *err = Error::create(&globExec, SyntaxError, errMsg, errLine, sid, &sourceURL);
688 return Completion(Throw,err);
689 }
690
691 globExec.clearException();
692
693 recursion++;
694
695 ObjectImp *globalObj = globalObject();
696 ObjectImp *thisObj = globalObject();
697
698 if (thisV) {
699 // "this" must be an object... use same rules as Function.prototype.apply()
700 if (thisV->isUndefinedOrNull())
701 thisObj = globalObject();
702 else {
703 thisObj = thisV->toObject(&globExec);
704 }
705 }
706
707 Completion res;
708 if (globExec.hadException()) {
709 // the thisArg->toObject() conversion above might have thrown an exception - if so,
710 // propagate it back
711 res = Completion(Throw, globExec.exception());
712 }
713 else {
714 // execute the code
715 ContextImp ctx(globalObj, this, thisObj);
716 ExecState newExec(m_interpreter, &ctx);
717 progNode->processVarDecls(&newExec);
718 res = progNode->execute(&newExec);
719 }
720
721 recursion--;
722
723 return res;
724}
725
726void InterpreterImp::saveBuiltins (SavedBuiltins &builtins) const
727{
728 if (!builtins._internal) {
729 builtins._internal = new SavedBuiltinsInternal;
730 }
731
732 builtins._internal->b_Object = b_Object;
733 builtins._internal->b_Function = b_Function;
734 builtins._internal->b_Array = b_Array;
735 builtins._internal->b_Boolean = b_Boolean;
736 builtins._internal->b_String = b_String;
737 builtins._internal->b_Number = b_Number;
738 builtins._internal->b_Date = b_Date;
739 builtins._internal->b_RegExp = b_RegExp;
740 builtins._internal->b_Error = b_Error;
741
742 builtins._internal->b_ObjectPrototype = b_ObjectPrototype;
743 builtins._internal->b_FunctionPrototype = b_FunctionPrototype;
744 builtins._internal->b_ArrayPrototype = b_ArrayPrototype;
745 builtins._internal->b_BooleanPrototype = b_BooleanPrototype;
746 builtins._internal->b_StringPrototype = b_StringPrototype;
747 builtins._internal->b_NumberPrototype = b_NumberPrototype;
748 builtins._internal->b_DatePrototype = b_DatePrototype;
749 builtins._internal->b_RegExpPrototype = b_RegExpPrototype;
750 builtins._internal->b_ErrorPrototype = b_ErrorPrototype;
751
752 builtins._internal->b_evalError = b_evalError;
753 builtins._internal->b_rangeError = b_rangeError;
754 builtins._internal->b_referenceError = b_referenceError;
755 builtins._internal->b_syntaxError = b_syntaxError;
756 builtins._internal->b_typeError = b_typeError;
757 builtins._internal->b_uriError = b_uriError;
758
759 builtins._internal->b_evalErrorPrototype = b_evalErrorPrototype;
760 builtins._internal->b_rangeErrorPrototype = b_rangeErrorPrototype;
761 builtins._internal->b_referenceErrorPrototype = b_referenceErrorPrototype;
762 builtins._internal->b_syntaxErrorPrototype = b_syntaxErrorPrototype;
763 builtins._internal->b_typeErrorPrototype = b_typeErrorPrototype;
764 builtins._internal->b_uriErrorPrototype = b_uriErrorPrototype;
765}
766
767void InterpreterImp::restoreBuiltins (const SavedBuiltins &builtins)
768{
769 if (!builtins._internal) {
770 return;
771 }
772
773 b_Object = builtins._internal->b_Object;
774 b_Function = builtins._internal->b_Function;
775 b_Array = builtins._internal->b_Array;
776 b_Boolean = builtins._internal->b_Boolean;
777 b_String = builtins._internal->b_String;
778 b_Number = builtins._internal->b_Number;
779 b_Date = builtins._internal->b_Date;
780 b_RegExp = builtins._internal->b_RegExp;
781 b_Error = builtins._internal->b_Error;
782
783 b_ObjectPrototype = builtins._internal->b_ObjectPrototype;
784 b_FunctionPrototype = builtins._internal->b_FunctionPrototype;
785 b_ArrayPrototype = builtins._internal->b_ArrayPrototype;
786 b_BooleanPrototype = builtins._internal->b_BooleanPrototype;
787 b_StringPrototype = builtins._internal->b_StringPrototype;
788 b_NumberPrototype = builtins._internal->b_NumberPrototype;
789 b_DatePrototype = builtins._internal->b_DatePrototype;
790 b_RegExpPrototype = builtins._internal->b_RegExpPrototype;
791 b_ErrorPrototype = builtins._internal->b_ErrorPrototype;
792
793 b_evalError = builtins._internal->b_evalError;
794 b_rangeError = builtins._internal->b_rangeError;
795 b_referenceError = builtins._internal->b_referenceError;
796 b_syntaxError = builtins._internal->b_syntaxError;
797 b_typeError = builtins._internal->b_typeError;
798 b_uriError = builtins._internal->b_uriError;
799
800 b_evalErrorPrototype = builtins._internal->b_evalErrorPrototype;
801 b_rangeErrorPrototype = builtins._internal->b_rangeErrorPrototype;
802 b_referenceErrorPrototype = builtins._internal->b_referenceErrorPrototype;
803 b_syntaxErrorPrototype = builtins._internal->b_syntaxErrorPrototype;
804 b_typeErrorPrototype = builtins._internal->b_typeErrorPrototype;
805 b_uriErrorPrototype = builtins._internal->b_uriErrorPrototype;
806}
807
808InterpreterImp *InterpreterImp::interpreterWithGlobalObject(ObjectImp *global)
809{
810 return InterpreterMap::getInterpreterForGlobalObject(global);
811}
812
813
814// ------------------------------ InternalFunctionImp --------------------------
815
816const ClassInfo InternalFunctionImp::info = {"Function", 0, 0, 0};
817
818InternalFunctionImp::InternalFunctionImp()
819{
820}
821
822InternalFunctionImp::InternalFunctionImp(FunctionPrototypeImp *funcProto)
823 : ObjectImp(funcProto)
824{
825}
826
827bool InternalFunctionImp::implementsHasInstance() const
828{
829 return true;
830}
831
832bool InternalFunctionImp::hasInstance(ExecState *exec, ValueImp *value)
833{
834 if (!value->isObject())
835 return false;
836
837 ValueImp *prot = get(exec,prototypePropertyName);
838 if (!prot->isObject() && !prot->isNull()) {
839 throwError(exec, TypeError, "Invalid prototype encountered in instanceof operation.");
840 return false;
841 }
842
843 ObjectImp *v = static_cast<ObjectImp *>(value);
844 while ((v = v->prototype()->getObject())) {
845 if (v == prot)
846 return true;
847 }
848 return false;
849}
850
851// ------------------------------ global functions -----------------------------
852
853double roundValue(ExecState *exec, ValueImp *v)
854{
855 double d = v->toNumber(exec);
856 double ad = fabs(d);
857 if (ad == 0 || isNaN(d) || isInf(d))
858 return d;
859 return copysign(floor(ad), d);
860}
861
862#ifndef NDEBUG
863#include <stdio.h>
864void printInfo(ExecState *exec, const char *s, ValueImp *o, int lineno)
865{
866 if (!o)
867 fprintf(stderr, "KJS: %s: (null)", s);
868 else {
869 ValueImp *v = o;
870
871 UString name;
872 switch (v->type()) {
873 case UnspecifiedType:
874 name = "Unspecified";
875 break;
876 case UndefinedType:
877 name = "Undefined";
878 break;
879 case NullType:
880 name = "Null";
881 break;
882 case BooleanType:
883 name = "Boolean";
884 break;
885 case StringType:
886 name = "String";
887 break;
888 case NumberType:
889 name = "Number";
890 break;
891 case ObjectType:
892 name = static_cast<ObjectImp *>(v)->className();
893 if (name.isNull())
894 name = "(unknown class)";
895 break;
896 }
897 UString vString = v->toString(exec);
898 if ( vString.size() > 50 )
899 vString = vString.substr( 0, 50 ) + "...";
900 // Can't use two UString::ascii() in the same fprintf call
901 CString tempString( vString.cstring() );
902
903 fprintf(stderr, "KJS: %s: %s : %s (%p)",
904 s, tempString.c_str(), name.ascii(), (void*)v);
905
906 if (lineno >= 0)
907 fprintf(stderr, ", line %d\n",lineno);
908 else
909 fprintf(stderr, "\n");
910 }
911}
912#endif
913
914}
Note: See TracBrowser for help on using the repository browser.