source: webkit/trunk/JavaScriptCore/kjs/object.cpp@ 13821

Last change on this file since 13821 was 13821, checked in by darin, 19 years ago

JavaScriptCore:

Rubber-stamped by John Sullivan.

  • switched from a shell script to a makefile for generated files
  • removed lots of unneeded includes
  • added new Forward.h and HashForward.h headers that allow compiling with fewer unneeded templates
  • DerivedSources.make: Added.
  • generate-derived-sources: Removed.
  • JavaScriptCore.xcodeproj/project.pbxproj: Added new files, changed to use DerivedSources.make.
  • kxmlcore/Forward.h: Added.
  • kxmlcore/HashForward.h: Added.
  • kxmlcore/HashCountedSet.h: Include HashForward for default args.
  • kxmlcore/HashMap.h: Ditto.
  • kxmlcore/HashSet.h: Ditto.
  • kjs/object.h:
  • kjs/object.cpp: Moved KJS_MAX_STACK into the .cpp file.
  • bindings/NP_jsobject.cpp:
  • bindings/c/c_instance.h:
  • bindings/jni/jni_class.h:
  • bindings/jni/jni_runtime.h:
  • bindings/jni/jni_utility.h:
  • bindings/objc/WebScriptObject.mm:
  • bindings/objc/WebScriptObjectPrivate.h:
  • bindings/objc/objc_class.h:
  • bindings/objc/objc_class.mm:
  • bindings/objc/objc_instance.h:
  • bindings/objc/objc_instance.mm:
  • bindings/objc/objc_runtime.mm:
  • bindings/objc/objc_utility.mm:
  • bindings/runtime.h:
  • bindings/runtime_array.cpp:
  • bindings/runtime_array.h:
  • bindings/runtime_method.cpp:
  • bindings/runtime_method.h:
  • bindings/runtime_object.cpp:
  • bindings/runtime_root.h:
  • kjs/JSImmediate.cpp:
  • kjs/Parser.h:
  • kjs/array_object.cpp:
  • kjs/array_object.h:
  • kjs/bool_object.cpp:
  • kjs/bool_object.h:
  • kjs/collector.h:
  • kjs/context.h:
  • kjs/debugger.cpp:
  • kjs/error_object.h:
  • kjs/function_object.h:
  • kjs/internal.h:
  • kjs/lexer.cpp:
  • kjs/math_object.cpp:
  • kjs/math_object.h:
  • kjs/nodes.cpp:
  • kjs/nodes.h:
  • kjs/number_object.cpp:
  • kjs/number_object.h:
  • kjs/object_object.cpp:
  • kjs/operations.cpp:
  • kjs/protected_reference.h:
  • kjs/reference.h:
  • kjs/reference_list.h:
  • kjs/regexp_object.h:
  • kjs/string_object.cpp:
  • kjs/string_object.h:
  • kjs/testkjs.cpp:
  • kjs/value.cpp:
  • kjs/value.h:
  • kxmlcore/HashTable.h:
  • kxmlcore/ListRefPtr.h:
  • kxmlcore/TCPageMap.h:
  • kxmlcore/Vector.h: Removed unneeded header includes.

JavaScriptGlue:

Rubber-stamped by John Sullivan.

  • added forwarding headers for the new Forward.h and HashForward.h files
  • kxmlcore/Forward.h: Added.
  • kxmlcore/HashForward.h: Added.

WebCore:

Rubber-stamped by John Sullivan (except for pbxproj change).

  • updated to use the new Forward.h and HashForward.h headers
  • moved the showTree debugging functions out of the WebCore namespace so they are easier to call from gdb, and renamed the showTree member functions so they don't get in the way; now you can do "call showTree(x)" in gdb and it just works
  • removed a lot of unneeded includes
  • WebCore.xcodeproj/project.pbxproj: Fixed a lot of paths that were not relative to the enclosing group.
  • ForwardingHeaders/kxmlcore/Forward.h: Added.
  • ForwardingHeaders/kxmlcore/HashForward.h: Added.
  • bindings/js/JSCanvasRenderingContext2DBase.cpp:
  • bindings/js/JSXMLHttpRequest.cpp:
  • bindings/js/JSXMLHttpRequest.h:
  • bindings/js/JSXSLTProcessor.h:
  • bindings/js/kjs_binding.h:
  • bindings/js/kjs_dom.cpp:
  • bindings/js/kjs_dom.h:
  • bindings/js/kjs_events.cpp:
  • bindings/js/kjs_events.h:
  • bindings/js/kjs_html.cpp:
  • bindings/js/kjs_navigator.cpp:
  • bindings/js/kjs_navigator.h:
  • bindings/js/kjs_proxy.cpp:
  • bindings/js/kjs_traversal.h:
  • bindings/js/kjs_window.cpp:
  • bindings/js/kjs_window.h:
  • bindings/objc/DOM.mm:
  • bindings/objc/DOMCSS.mm:
  • bindings/objc/DOMCore.h:
  • bindings/objc/DOMEvents.mm:
  • bindings/objc/DOMHTML.mm:
  • bindings/objc/DOMImplementationFront.h:
  • bindings/objc/DOMInternal.mm:
  • bindings/objc/DOMUtility.mm:
  • bindings/objc/DOMViews.mm:
  • bridge/BrowserExtension.h:
  • bridge/mac/BrowserExtensionMac.mm:
  • bridge/mac/FrameMac.h:
  • bridge/mac/FrameMac.mm:
  • bridge/mac/WebCoreFrameBridge.mm:
  • bridge/mac/WebCoreFrameNamespaces.mm:
  • bridge/mac/WebCoreJavaScript.mm:
  • bridge/win/PageWin.cpp:
  • css/CSSComputedStyleDeclaration.cpp:
  • css/css_base.h:
  • css/css_ruleimpl.h:
  • css/css_valueimpl.cpp:
  • css/cssparser.cpp:
  • css/cssparser.h:
  • css/cssstyleselector.cpp:
  • css/cssstyleselector.h:
  • dom/AbstractView.h:
  • dom/AtomicStringList.h:
  • dom/Attribute.cpp:
  • dom/Attribute.h:
  • dom/Comment.cpp:
  • dom/ContainerNode.cpp:
  • dom/DOMImplementation.cpp:
  • dom/DOMImplementation.h:
  • dom/Document.cpp:
  • dom/Document.h:
  • dom/Element.h:
  • dom/EventTargetNode.cpp: (WebCore::EventTargetNode::dump): (WebCore::forbidEventDispatch): (WebCore::allowEventDispatch): (WebCore::eventDispatchForbidden):
  • dom/EventTargetNode.h: (WebCore::EventTargetNode::postDispatchEventHandler):
  • dom/NamedAttrMap.h:
  • dom/Node.cpp: (WebCore::Node::showNode): (WebCore::Node::showTree): (WebCore::Node::showTreeAndMark): (showTree):
  • dom/Node.h:
  • dom/NodeList.cpp:
  • dom/NodeList.h:
  • dom/Position.cpp: (showTree):
  • dom/Position.h:
  • dom/Range.cpp:
  • dom/Range.h:
  • dom/StyledElement.cpp:
  • dom/StyledElement.h:
  • dom/dom2_eventsimpl.cpp:
  • dom/dom2_eventsimpl.h:
  • dom/dom2_traversalimpl.h:
  • dom/dom_xmlimpl.cpp:
  • dom/xml_tokenizer.cpp:
  • dom/xml_tokenizer.h:
  • editing/AppendNodeCommand.cpp:
  • editing/ApplyStyleCommand.cpp:
  • editing/ApplyStyleCommand.h:
  • editing/BreakBlockquoteCommand.cpp:
  • editing/CompositeEditCommand.cpp:
  • editing/CreateLinkCommand.cpp:
  • editing/DeleteFromTextNodeCommand.cpp:
  • editing/DeleteFromTextNodeCommand.h:
  • editing/DeleteSelectionCommand.cpp:
  • editing/EditCommand.cpp:
  • editing/EditCommand.h:
  • editing/HTMLInterchange.cpp:
  • editing/InsertIntoTextNodeCommand.cpp:
  • editing/InsertIntoTextNodeCommand.h:
  • editing/InsertLineBreakCommand.cpp:
  • editing/InsertNodeBeforeCommand.cpp:
  • editing/InsertParagraphSeparatorCommand.cpp:
  • editing/InsertTextCommand.cpp:
  • editing/JSEditor.cpp:
  • editing/JoinTextNodesCommand.cpp:
  • editing/MergeIdenticalElementsCommand.cpp:
  • editing/ModifySelectionListLevelCommand.cpp:
  • editing/MoveSelectionCommand.cpp:
  • editing/RebalanceWhitespaceCommand.h:
  • editing/RemoveCSSPropertyCommand.h:
  • editing/ReplaceSelectionCommand.cpp:
  • editing/ReplaceSelectionCommand.h:
  • editing/Selection.cpp: (WebCore::Selection::formatForDebugger): (WebCore::Selection::showTree): (showTree):
  • editing/Selection.h:
  • editing/SelectionController.cpp: (WebCore::SelectionController::formatForDebugger): (WebCore::SelectionController::showTree): (showTree):
  • editing/SelectionController.h:
  • editing/TextIterator.cpp:
  • editing/TextIterator.h:
  • editing/TypingCommand.cpp:
  • editing/TypingCommand.h:
  • editing/UnlinkCommand.cpp:
  • editing/VisiblePosition.cpp: (WebCore::isEqualIgnoringAffinity): (WebCore::VisiblePosition::formatForDebugger): (WebCore::VisiblePosition::showTree): (showTree):
  • editing/VisiblePosition.h: (WebCore::VisiblePosition::VisiblePosition): (WebCore::operator==):
  • editing/WrapContentsInDummySpanCommand.cpp:
  • editing/htmlediting.h:
  • editing/markup.cpp:
  • editing/markup.h: (WebCore::):
  • editing/visible_units.cpp:
  • html/CanvasGradient.cpp:
  • html/CanvasRenderingContext2D.h:
  • html/CanvasStyle.cpp:
  • html/CanvasStyle.h:
  • html/FormDataList.cpp:
  • html/FormDataList.h:
  • html/HTMLCollection.cpp:
  • html/HTMLCollection.h:
  • html/HTMLDocument.cpp:
  • html/HTMLDocument.h:
  • html/HTMLElement.cpp:
  • html/HTMLElementFactory.cpp:
  • html/HTMLElementFactory.h:
  • html/HTMLFormCollection.cpp:
  • html/HTMLFormElement.cpp:
  • html/HTMLFormElement.h:
  • html/HTMLInputElement.cpp:
  • html/HTMLParser.cpp:
  • html/HTMLSelectElement.cpp:
  • html/HTMLSelectElement.h:
  • html/HTMLTokenizer.cpp:
  • html/HTMLTokenizer.h:
  • html/html_baseimpl.cpp:
  • html/html_headimpl.h:
  • kcanvas/KCanvasCreator.cpp:
  • kcanvas/KCanvasFilters.h:
  • kcanvas/KCanvasPath.h:
  • kcanvas/KCanvasResources.h:
  • kcanvas/KCanvasTreeDebug.cpp:
  • kcanvas/RenderPath.cpp:
  • kcanvas/RenderPath.h:
  • kcanvas/device/KRenderingDevice.h:
  • kcanvas/device/KRenderingPaintServerGradient.h:
  • kcanvas/device/KRenderingPaintServerPattern.h:
  • kcanvas/device/KRenderingPaintServerSolid.h:
  • kcanvas/device/quartz/KCanvasFilterQuartz.mm:
  • kcanvas/device/quartz/KCanvasMaskerQuartz.h:
  • kcanvas/device/quartz/KCanvasResourcesQuartz.h:
  • kcanvas/device/quartz/KCanvasResourcesQuartz.mm:
  • kcanvas/device/quartz/KRenderingPaintServerQuartz.h:
  • khtml/misc/decoder.cpp:
  • khtml/misc/decoder.h:
  • khtml/xsl/XSLStyleSheet.cpp:
  • khtml/xsl/XSLTProcessor.cpp:
  • khtml/xsl/XSLTProcessor.h:
  • ksvg2/css/SVGRenderStyle.h:
  • ksvg2/ecma/GlobalObject.cpp:
  • ksvg2/misc/KCanvasRenderingStyle.h:
  • ksvg2/misc/SVGDocumentExtensions.h:
  • ksvg2/svg/SVGAngle.h:
  • ksvg2/svg/SVGAnimateColorElement.h:
  • ksvg2/svg/SVGAnimatedColor.h:
  • ksvg2/svg/SVGAnimatedLengthList.h:
  • ksvg2/svg/SVGAnimatedNumberList.h:
  • ksvg2/svg/SVGAnimatedString.h:
  • ksvg2/svg/SVGAnimatedTransformList.h:
  • ksvg2/svg/SVGAnimationElement.h:
  • ksvg2/svg/SVGColor.h:
  • ksvg2/svg/SVGCursorElement.h:
  • ksvg2/svg/SVGHelper.h:
  • ksvg2/svg/SVGLength.h:
  • ksvg2/svg/SVGList.h:
  • ksvg2/svg/SVGPaint.h:
  • ksvg2/svg/SVGPathSeg.h:
  • ksvg2/svg/SVGPatternElement.h:
  • ksvg2/svg/SVGSVGElement.cpp:
  • ksvg2/svg/SVGSVGElement.h:
  • ksvg2/svg/SVGStringList.h:
  • ksvg2/svg/SVGTransform.h:
  • kwq/AccessibilityObjectCache.mm:
  • kwq/ClipboardMac.mm:
  • kwq/JavaAppletWidget.mm:
  • kwq/KWQComboBox.mm:
  • kwq/KWQEditCommand.mm:
  • kwq/KWQFileButton.mm:
  • kwq/KWQKHTMLSettings.h:
  • kwq/KWQKSSLKeyGen.mm:
  • kwq/KWQLoader.mm:
  • kwq/KWQPageState.mm:
  • kwq/KWQTextEdit.mm:
  • kwq/RegularExpression.h:
  • kwq/RenderTreeAsText.cpp:
  • kwq/RenderTreeAsText.h:
  • kwq/WebCoreAXObject.mm:
  • loader/Cache.cpp:
  • loader/Cache.h:
  • loader/CachedCSSStyleSheet.cpp:
  • loader/CachedObject.h:
  • loader/CachedScript.cpp:
  • loader/CachedXBLDocument.cpp:
  • loader/CachedXBLDocument.h:
  • loader/CachedXSLStyleSheet.cpp:
  • loader/CachedXSLStyleSheet.h:
  • loader/DocLoader.cpp:
  • page/Frame.cpp:
  • page/Frame.h:
  • page/FramePrivate.h:
  • page/FrameTree.cpp:
  • page/FrameTree.h:
  • page/FrameView.cpp:
  • page/FrameView.h:
  • page/Page.cpp:
  • page/Page.h:
  • page/Plugin.h: (WebCore::Plugin::Plugin): (WebCore::Plugin::view):
  • platform/Color.cpp:
  • platform/FloatRect.h:
  • platform/Font.cpp:
  • platform/Font.h:
  • platform/FontFamily.cpp:
  • platform/GraphicsContext.cpp:
  • platform/Image.cpp:
  • platform/Image.h:
  • platform/IntRect.h:
  • platform/KURL.cpp:
  • platform/KURL.h:
  • platform/SegmentedString.h:
  • platform/Shared.h:
  • platform/StreamingTextDecoder.cpp:
  • platform/StringImpl.cpp:
  • platform/StringImpl.h:
  • platform/TextEncoding.h:
  • platform/Timer.cpp:
  • platform/Timer.h:
  • platform/TransferJob.cpp:
  • platform/TransferJob.h:
  • platform/TransferJobInternal.h:
  • platform/cairo/GraphicsContextCairo.cpp:
  • platform/cairo/ImageCairo.cpp:
  • platform/cairo/ImageSourceCairo.cpp:
  • platform/image-decoders/gif/GIFImageReader.cpp:
  • platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
  • platform/mac/FontFamilyMac.mm:
  • platform/mac/FontMac.mm:
  • platform/mac/ImageMac.mm:
  • platform/mac/TextEncodingMac.cpp:
  • platform/mac/TransferJobMac.mm:
  • platform/win/FontPlatformDataWin.cpp:
  • platform/win/TransferJobWin.cpp:
  • rendering/RenderBlock.cpp:
  • rendering/RenderBlock.h:
  • rendering/RenderBox.cpp:
  • rendering/RenderBox.h:
  • rendering/RenderCanvas.cpp:
  • rendering/RenderCanvas.h:
  • rendering/RenderContainer.cpp:
  • rendering/RenderFlexibleBox.h:
  • rendering/RenderFlow.cpp:
  • rendering/RenderFlow.h:
  • rendering/RenderImage.cpp:
  • rendering/RenderImage.h:
  • rendering/RenderLayer.cpp:
  • rendering/RenderLayer.h:
  • rendering/RenderObject.cpp: (showTree):
  • rendering/RenderObject.h:
  • rendering/RenderTableCell.h:
  • rendering/RenderTableSection.h:
  • rendering/RenderText.cpp:
  • rendering/RenderText.h:
  • rendering/RenderTextField.cpp:
  • rendering/RenderTextFragment.h:
  • rendering/RenderTheme.h:
  • rendering/RenderThemeMac.mm:
  • rendering/RenderThemeWin.cpp:
  • rendering/bidi.cpp:
  • rendering/render_form.h:
  • rendering/render_line.cpp: (showTree):
  • rendering/render_line.h:
  • rendering/render_list.cpp:
  • rendering/render_replaced.cpp:
  • rendering/render_replaced.h:
  • rendering/render_style.cpp:
  • rendering/render_style.h:
  • xml/xmlhttprequest.h:
  • Property svn:eol-style set to native
File size: 17.3 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2001 Harri Porten ([email protected])
5 * Copyright (C) 2001 Peter Kelly ([email protected])
6 * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#include "config.h"
26#include "object.h"
27
28#include "error_object.h"
29#include "lookup.h"
30#include "nodes.h"
31#include "operations.h"
32#include "reference_list.h"
33#include <math.h>
34
35// maximum global call stack size. Protects against accidental or
36// malicious infinite recursions. Define to -1 if you want no limit.
37#if PLATFORM(DARWIN)
38// Given OS X stack sizes we run out of stack at about 350 levels.
39// If we improve our stack usage, we can bump this number.
40#define KJS_MAX_STACK 100
41#else
42#define KJS_MAX_STACK 1000
43#endif
44
45#define JAVASCRIPT_CALL_TRACING 0
46
47#if JAVASCRIPT_CALL_TRACING
48static bool _traceJavaScript = false;
49
50extern "C" {
51 void setTraceJavaScript(bool f)
52 {
53 _traceJavaScript = f;
54 }
55
56 static bool traceJavaScript()
57 {
58 return _traceJavaScript;
59 }
60}
61#endif
62
63namespace KJS {
64
65// ------------------------------ Object ---------------------------------------
66
67JSValue *JSObject::call(ExecState *exec, JSObject *thisObj, const List &args)
68{
69 assert(implementsCall());
70
71#if KJS_MAX_STACK > 0
72 static int depth = 0; // sum of all concurrent interpreters
73
74#if JAVASCRIPT_CALL_TRACING
75 static bool tracing = false;
76 if (traceJavaScript() && !tracing) {
77 tracing = true;
78 for (int i = 0; i < depth; i++)
79 putchar (' ');
80 printf ("*** calling: %s\n", toString(exec).ascii());
81 for (int j = 0; j < args.size(); j++) {
82 for (int i = 0; i < depth; i++)
83 putchar (' ');
84 printf ("*** arg[%d] = %s\n", j, args[j]->toString(exec).ascii());
85 }
86 tracing = false;
87 }
88#endif
89
90 if (++depth > KJS_MAX_STACK) {
91 --depth;
92 return throwError(exec, RangeError, "Maximum call stack size exceeded.");
93 }
94#endif
95
96 JSValue *ret = callAsFunction(exec,thisObj,args);
97
98#if KJS_MAX_STACK > 0
99 --depth;
100#endif
101
102#if JAVASCRIPT_CALL_TRACING
103 if (traceJavaScript() && !tracing) {
104 tracing = true;
105 for (int i = 0; i < depth; i++)
106 putchar (' ');
107 printf ("*** returning: %s\n", ret->toString(exec).ascii());
108 tracing = false;
109 }
110#endif
111
112 return ret;
113}
114
115// ------------------------------ JSObject ------------------------------------
116
117void JSObject::mark()
118{
119 JSCell::mark();
120
121 JSValue *proto = _proto;
122 if (!proto->marked())
123 proto->mark();
124
125 _prop.mark();
126
127 if (_internalValue && !_internalValue->marked())
128 _internalValue->mark();
129
130 _scope.mark();
131}
132
133JSType JSObject::type() const
134{
135 return ObjectType;
136}
137
138const ClassInfo *JSObject::classInfo() const
139{
140 return 0;
141}
142
143UString JSObject::className() const
144{
145 const ClassInfo *ci = classInfo();
146 if ( ci )
147 return ci->className;
148 return "Object";
149}
150
151JSValue *JSObject::get(ExecState *exec, const Identifier &propertyName) const
152{
153 PropertySlot slot;
154
155 if (const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot))
156 return slot.getValue(exec, const_cast<JSObject *>(this), propertyName);
157
158 return jsUndefined();
159}
160
161JSValue *JSObject::get(ExecState *exec, unsigned propertyName) const
162{
163 PropertySlot slot;
164 if (const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot))
165 return slot.getValue(exec, const_cast<JSObject *>(this), propertyName);
166
167 return jsUndefined();
168}
169
170bool JSObject::getPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot)
171{
172 JSObject *imp = this;
173
174 while (true) {
175 if (imp->getOwnPropertySlot(exec, propertyName, slot))
176 return true;
177
178 JSValue *proto = imp->_proto;
179 if (!proto->isObject())
180 break;
181
182 imp = static_cast<JSObject *>(proto);
183 }
184
185 return false;
186}
187
188bool JSObject::getOwnPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot)
189{
190 return getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
191}
192
193static void throwSetterError(ExecState *exec)
194{
195 throwError(exec, TypeError, "setting a property that has only a getter");
196}
197
198// ECMA 8.6.2.2
199void JSObject::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr)
200{
201 assert(value);
202
203 // non-standard netscape extension
204 if (propertyName == exec->dynamicInterpreter()->specialPrototypeIdentifier()) {
205 setPrototype(value);
206 return;
207 }
208
209 /* TODO: check for write permissions directly w/o this call */
210 /* Doesn't look very easy with the PropertyMap API - David */
211 // putValue() is used for JS assignemnts. It passes no attribute.
212 // Assume that a C++ implementation knows what it is doing
213 // and let it override the canPut() check.
214 if ((attr == None || attr == DontDelete) && !canPut(exec,propertyName)) {
215#ifdef KJS_VERBOSE
216 fprintf( stderr, "WARNING: canPut %s said NO\n", propertyName.ascii() );
217#endif
218 return;
219 }
220
221 // Check if there are any setters or getters in the prototype chain
222 JSObject *obj = this;
223 bool hasGettersOrSetters = false;
224 while (true) {
225 if (obj->_prop.hasGetterSetterProperties()) {
226 hasGettersOrSetters = true;
227 break;
228 }
229
230 if (!obj->_proto->isObject())
231 break;
232
233 obj = static_cast<JSObject *>(obj->_proto);
234 }
235
236 if (hasGettersOrSetters) {
237 obj = this;
238 while (true) {
239 int attributes;
240 if (JSValue *gs = obj->_prop.get(propertyName, attributes)) {
241 if (attributes & GetterSetter) {
242 JSObject *setterFunc = static_cast<GetterSetterImp *>(gs)->getSetter();
243
244 if (!setterFunc) {
245 throwSetterError(exec);
246 return;
247 }
248
249 List args;
250 args.append(value);
251
252 setterFunc->call(exec, this, args);
253 return;
254 } else {
255 // If there's an existing property on the object or one of its
256 // prototype it should be replaced, so we just break here.
257 break;
258 }
259 }
260
261 if (!obj->_proto->isObject())
262 break;
263
264 obj = static_cast<JSObject *>(obj->_proto);
265 }
266 }
267
268 _prop.put(propertyName,value,attr);
269}
270
271void JSObject::put(ExecState *exec, unsigned propertyName,
272 JSValue *value, int attr)
273{
274 put(exec, Identifier::from(propertyName), value, attr);
275}
276
277// ECMA 8.6.2.3
278bool JSObject::canPut(ExecState *, const Identifier &propertyName) const
279{
280 int attributes;
281
282 // Don't look in the prototype here. We can always put an override
283 // in the object, even if the prototype has a ReadOnly property.
284
285 if (!getPropertyAttributes(propertyName, attributes))
286 return true;
287 else
288 return !(attributes & ReadOnly);
289}
290
291// ECMA 8.6.2.4
292bool JSObject::hasProperty(ExecState *exec, const Identifier &propertyName) const
293{
294 PropertySlot slot;
295 return const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot);
296}
297
298bool JSObject::hasProperty(ExecState *exec, unsigned propertyName) const
299{
300 PropertySlot slot;
301 return const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot);
302}
303
304// ECMA 8.6.2.5
305bool JSObject::deleteProperty(ExecState */*exec*/, const Identifier &propertyName)
306{
307 int attributes;
308 JSValue *v = _prop.get(propertyName, attributes);
309 if (v) {
310 if ((attributes & DontDelete))
311 return false;
312 _prop.remove(propertyName);
313 if (attributes & GetterSetter)
314 _prop.setHasGetterSetterProperties(_prop.containsGettersOrSetters());
315 return true;
316 }
317
318 // Look in the static hashtable of properties
319 const HashEntry* entry = findPropertyHashEntry(propertyName);
320 if (entry && entry->attr & DontDelete)
321 return false; // this builtin property can't be deleted
322 return true;
323}
324
325bool JSObject::deleteProperty(ExecState *exec, unsigned propertyName)
326{
327 return deleteProperty(exec, Identifier::from(propertyName));
328}
329
330static ALWAYS_INLINE JSValue *tryGetAndCallProperty(ExecState *exec, const JSObject *object, const Identifier &propertyName) {
331 JSValue *v = object->get(exec, propertyName);
332 if (v->isObject()) {
333 JSObject *o = static_cast<JSObject*>(v);
334 if (o->implementsCall()) { // spec says "not primitive type" but ...
335 JSObject *thisObj = const_cast<JSObject*>(object);
336 JSValue *def = o->call(exec, thisObj, List::empty());
337 JSType defType = def->type();
338 ASSERT(defType != GetterSetterType);
339 if (defType != ObjectType)
340 return def;
341 }
342 }
343 return NULL;
344}
345
346// ECMA 8.6.2.6
347JSValue *JSObject::defaultValue(ExecState *exec, JSType hint) const
348{
349 Identifier firstPropertyName;
350 Identifier secondPropertyName;
351 /* Prefer String for Date objects */
352 if ((hint == StringType) || (hint != StringType) && (hint != NumberType) && (_proto == exec->lexicalInterpreter()->builtinDatePrototype())) {
353 firstPropertyName = toStringPropertyName;
354 secondPropertyName = valueOfPropertyName;
355 } else {
356 firstPropertyName = valueOfPropertyName;
357 secondPropertyName = toStringPropertyName;
358 }
359
360 JSValue *v;
361 if ((v = tryGetAndCallProperty(exec, this, firstPropertyName)))
362 return v;
363 if ((v = tryGetAndCallProperty(exec, this, secondPropertyName)))
364 return v;
365
366 if (exec->hadException())
367 return exec->exception();
368
369 return throwError(exec, TypeError, "No default value");
370}
371
372const HashEntry* JSObject::findPropertyHashEntry(const Identifier& propertyName) const
373{
374 for (const ClassInfo *info = classInfo(); info; info = info->parentClass) {
375 if (const HashTable *propHashTable = info->propHashTable) {
376 if (const HashEntry *e = Lookup::findEntry(propHashTable, propertyName))
377 return e;
378 }
379 }
380 return 0;
381}
382
383void JSObject::defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc)
384{
385 JSValue *o = getDirect(propertyName);
386 GetterSetterImp *gs;
387
388 if (o && o->type() == GetterSetterType) {
389 gs = static_cast<GetterSetterImp *>(o);
390 } else {
391 gs = new GetterSetterImp;
392 putDirect(propertyName, gs, GetterSetter);
393 }
394
395 _prop.setHasGetterSetterProperties(true);
396 gs->setGetter(getterFunc);
397}
398
399void JSObject::defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc)
400{
401 JSValue *o = getDirect(propertyName);
402 GetterSetterImp *gs;
403
404 if (o && o->type() == GetterSetterType) {
405 gs = static_cast<GetterSetterImp *>(o);
406 } else {
407 gs = new GetterSetterImp;
408 putDirect(propertyName, gs, GetterSetter);
409 }
410
411 _prop.setHasGetterSetterProperties(true);
412 gs->setSetter(setterFunc);
413}
414
415bool JSObject::implementsConstruct() const
416{
417 return false;
418}
419
420JSObject* JSObject::construct(ExecState*, const List& /*args*/)
421{
422 assert(false);
423 return NULL;
424}
425
426JSObject* JSObject::construct(ExecState* exec, const List& args, const Identifier& /*functionName*/, const UString& /*sourceURL*/, int /*lineNumber*/)
427{
428 return construct(exec, args);
429}
430
431bool JSObject::implementsCall() const
432{
433 return false;
434}
435
436JSValue *JSObject::callAsFunction(ExecState */*exec*/, JSObject */*thisObj*/, const List &/*args*/)
437{
438 assert(false);
439 return NULL;
440}
441
442bool JSObject::implementsHasInstance() const
443{
444 return false;
445}
446
447bool JSObject::hasInstance(ExecState *, JSValue *)
448{
449 assert(false);
450 return false;
451}
452
453bool JSObject::propertyIsEnumerable(ExecState*, const Identifier& propertyName) const
454{
455 int attributes;
456
457 if (!getPropertyAttributes(propertyName, attributes))
458 return false;
459 else
460 return !(attributes & DontEnum);
461}
462
463bool JSObject::getPropertyAttributes(const Identifier& propertyName, int& attributes) const
464{
465 if (_prop.get(propertyName, attributes))
466 return true;
467
468 // Look in the static hashtable of properties
469 const HashEntry* e = findPropertyHashEntry(propertyName);
470 if (e) {
471 attributes = e->attr;
472 return true;
473 }
474
475 return false;
476}
477
478ReferenceList JSObject::propList(ExecState *exec, bool recursive)
479{
480 ReferenceList list;
481 if (_proto->isObject() && recursive)
482 list = static_cast<JSObject*>(_proto)->propList(exec,recursive);
483
484 _prop.addEnumerablesToReferenceList(list, this);
485
486 // Add properties from the static hashtable of properties
487 const ClassInfo *info = classInfo();
488 while (info) {
489 if (info->propHashTable) {
490 int size = info->propHashTable->size;
491 const HashEntry *e = info->propHashTable->entries;
492 for (int i = 0; i < size; ++i, ++e) {
493 if ( e->s && !(e->attr & DontEnum) )
494 list.append(Reference(this, e->s)); /// ######### check for duplicates with the propertymap
495 }
496 }
497 info = info->parentClass;
498 }
499
500 return list;
501}
502
503bool JSObject::toBoolean(ExecState */*exec*/) const
504{
505 return true;
506}
507
508double JSObject::toNumber(ExecState *exec) const
509{
510 JSValue *prim = toPrimitive(exec,NumberType);
511 if (exec->hadException()) // should be picked up soon in nodes.cpp
512 return 0.0;
513 return prim->toNumber(exec);
514}
515
516UString JSObject::toString(ExecState *exec) const
517{
518 JSValue *prim = toPrimitive(exec,StringType);
519 if (exec->hadException()) // should be picked up soon in nodes.cpp
520 return "";
521 return prim->toString(exec);
522}
523
524JSObject *JSObject::toObject(ExecState */*exec*/) const
525{
526 return const_cast<JSObject*>(this);
527}
528
529void JSObject::putDirect(const Identifier &propertyName, JSValue *value, int attr)
530{
531 _prop.put(propertyName, value, attr);
532}
533
534void JSObject::putDirect(const Identifier &propertyName, int value, int attr)
535{
536 _prop.put(propertyName, jsNumber(value), attr);
537}
538
539void JSObject::putDirectFunction(InternalFunctionImp* func, int attr)
540{
541 putDirect(func->functionName(), func, attr);
542}
543
544void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue **location)
545{
546 GetterSetterImp *gs = static_cast<GetterSetterImp *>(*location);
547 JSObject *getterFunc = gs->getGetter();
548 if (getterFunc)
549 slot.setGetterSlot(this, getterFunc);
550 else
551 slot.setUndefined(this);
552}
553
554// ------------------------------ Error ----------------------------------------
555
556const char * const errorNamesArr[] = {
557 I18N_NOOP("Error"), // GeneralError
558 I18N_NOOP("Evaluation error"), // EvalError
559 I18N_NOOP("Range error"), // RangeError
560 I18N_NOOP("Reference error"), // ReferenceError
561 I18N_NOOP("Syntax error"), // SyntaxError
562 I18N_NOOP("Type error"), // TypeError
563 I18N_NOOP("URI error"), // URIError
564};
565
566const char * const * const Error::errorNames = errorNamesArr;
567
568JSObject *Error::create(ExecState *exec, ErrorType errtype, const UString &message,
569 int lineno, int sourceId, const UString *sourceURL)
570{
571 JSObject *cons;
572 switch (errtype) {
573 case EvalError:
574 cons = exec->lexicalInterpreter()->builtinEvalError();
575 break;
576 case RangeError:
577 cons = exec->lexicalInterpreter()->builtinRangeError();
578 break;
579 case ReferenceError:
580 cons = exec->lexicalInterpreter()->builtinReferenceError();
581 break;
582 case SyntaxError:
583 cons = exec->lexicalInterpreter()->builtinSyntaxError();
584 break;
585 case TypeError:
586 cons = exec->lexicalInterpreter()->builtinTypeError();
587 break;
588 case URIError:
589 cons = exec->lexicalInterpreter()->builtinURIError();
590 break;
591 default:
592 cons = exec->lexicalInterpreter()->builtinError();
593 break;
594 }
595
596 List args;
597 if (message.isEmpty())
598 args.append(jsString(errorNames[errtype]));
599 else
600 args.append(jsString(message));
601 JSObject *err = static_cast<JSObject *>(cons->construct(exec,args));
602
603 if (lineno != -1)
604 err->put(exec, "line", jsNumber(lineno));
605 if (sourceId != -1)
606 err->put(exec, "sourceId", jsNumber(sourceId));
607
608 if(sourceURL)
609 err->put(exec,"sourceURL", jsString(*sourceURL));
610
611 return err;
612
613/*
614#ifndef NDEBUG
615 const char *msg = err->get(messagePropertyName)->toString().value().ascii();
616 if (l >= 0)
617 fprintf(stderr, "KJS: %s at line %d. %s\n", estr, l, msg);
618 else
619 fprintf(stderr, "KJS: %s. %s\n", estr, msg);
620#endif
621
622 return err;
623*/
624}
625
626JSObject *Error::create(ExecState *exec, ErrorType type, const char *message)
627{
628 return create(exec, type, message, -1, -1, NULL);
629}
630
631JSObject *throwError(ExecState *exec, ErrorType type)
632{
633 JSObject *error = Error::create(exec, type, UString(), -1, -1, NULL);
634 exec->setException(error);
635 return error;
636}
637
638JSObject *throwError(ExecState *exec, ErrorType type, const UString &message)
639{
640 JSObject *error = Error::create(exec, type, message, -1, -1, NULL);
641 exec->setException(error);
642 return error;
643}
644
645JSObject *throwError(ExecState *exec, ErrorType type, const char *message)
646{
647 JSObject *error = Error::create(exec, type, message, -1, -1, NULL);
648 exec->setException(error);
649 return error;
650}
651
652JSObject *throwError(ExecState *exec, ErrorType type, const UString &message, int line, int sourceId, const UString *sourceURL)
653{
654 JSObject *error = Error::create(exec, type, message, line, sourceId, sourceURL);
655 exec->setException(error);
656 return error;
657}
658
659} // namespace KJS
Note: See TracBrowser for help on using the repository browser.