Merged changes from LABYRINTH_KDE_3_MERGE branch.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Mar 2002 00:31:57 +0000 (00:31 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Mar 2002 00:31:57 +0000 (00:31 +0000)
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@798 268f45cc-cd09-0410-ab3c-d52691b4dbfc

829 files changed:
JavaScriptCore/kjs/Makefile.am
JavaScriptCore/kjs/array_object.cpp
JavaScriptCore/kjs/array_object.h
JavaScriptCore/kjs/bool_object.cpp
JavaScriptCore/kjs/bool_object.h
JavaScriptCore/kjs/collector.cpp
JavaScriptCore/kjs/collector.h
JavaScriptCore/kjs/create_hash_table [new file with mode: 0755]
JavaScriptCore/kjs/date_object.cpp
JavaScriptCore/kjs/date_object.h
JavaScriptCore/kjs/debugger.cpp
JavaScriptCore/kjs/debugger.h
JavaScriptCore/kjs/error_object.cpp
JavaScriptCore/kjs/error_object.h
JavaScriptCore/kjs/function.cpp
JavaScriptCore/kjs/function.h
JavaScriptCore/kjs/function_object.cpp
JavaScriptCore/kjs/function_object.h
JavaScriptCore/kjs/global_object.cpp [deleted file]
JavaScriptCore/kjs/grammar.y
JavaScriptCore/kjs/internal.cpp
JavaScriptCore/kjs/internal.h
JavaScriptCore/kjs/interpreter.cpp [new file with mode: 0644]
JavaScriptCore/kjs/interpreter.h [new file with mode: 0644]
JavaScriptCore/kjs/keywords.table [new file with mode: 0644]
JavaScriptCore/kjs/kjs.cpp [deleted file]
JavaScriptCore/kjs/kjs.h [deleted file]
JavaScriptCore/kjs/lexer.cpp
JavaScriptCore/kjs/lexer.h
JavaScriptCore/kjs/lexer.lut.h
JavaScriptCore/kjs/lookup.cpp
JavaScriptCore/kjs/lookup.h
JavaScriptCore/kjs/math_object.cpp
JavaScriptCore/kjs/math_object.h
JavaScriptCore/kjs/math_object.lut.h
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/nodes.h
JavaScriptCore/kjs/number_object.cpp
JavaScriptCore/kjs/number_object.h
JavaScriptCore/kjs/object.cpp
JavaScriptCore/kjs/object.h
JavaScriptCore/kjs/object_object.cpp
JavaScriptCore/kjs/object_object.h
JavaScriptCore/kjs/operations.cpp
JavaScriptCore/kjs/operations.h
JavaScriptCore/kjs/property_map.cpp [new file with mode: 0644]
JavaScriptCore/kjs/property_map.h [new file with mode: 0644]
JavaScriptCore/kjs/regexp.cpp
JavaScriptCore/kjs/regexp.h
JavaScriptCore/kjs/regexp_object.cpp
JavaScriptCore/kjs/regexp_object.h
JavaScriptCore/kjs/string_object.cpp
JavaScriptCore/kjs/string_object.h
JavaScriptCore/kjs/testkjs.cpp
JavaScriptCore/kjs/types.cpp
JavaScriptCore/kjs/types.h
JavaScriptCore/kjs/ustring.cpp
JavaScriptCore/kjs/ustring.h
JavaScriptCore/kjs/value.cpp [new file with mode: 0644]
JavaScriptCore/kjs/value.h [new file with mode: 0644]
WebCore/ChangeLog-2002-12-03
WebCore/ChangeLog-2003-10-25
WebCore/ChangeLog-2005-08-23
WebCore/khtml/css/css_ruleimpl.cpp
WebCore/khtml/css/css_ruleimpl.h
WebCore/khtml/css/css_stylesheetimpl.cpp
WebCore/khtml/css/css_stylesheetimpl.h
WebCore/khtml/css/css_valueimpl.cpp
WebCore/khtml/css/css_valueimpl.h
WebCore/khtml/css/csshelper.cpp
WebCore/khtml/css/cssparser.cpp
WebCore/khtml/css/cssparser.h
WebCore/khtml/css/cssproperties.in
WebCore/khtml/css/cssstyleselector.cpp
WebCore/khtml/css/cssstyleselector.h
WebCore/khtml/css/cssvalues.in
WebCore/khtml/css/html4.css
WebCore/khtml/dom/css_rule.cpp
WebCore/khtml/dom/css_rule.h
WebCore/khtml/dom/css_stylesheet.cpp
WebCore/khtml/dom/css_stylesheet.h
WebCore/khtml/dom/css_value.cpp
WebCore/khtml/dom/css_value.h
WebCore/khtml/dom/dom2_events.cpp
WebCore/khtml/dom/dom2_events.h
WebCore/khtml/dom/dom2_range.cpp
WebCore/khtml/dom/dom2_range.h
WebCore/khtml/dom/dom2_traversal.cpp
WebCore/khtml/dom/dom2_traversal.h
WebCore/khtml/dom/dom2_views.cpp
WebCore/khtml/dom/dom2_views.h
WebCore/khtml/dom/dom_doc.cpp
WebCore/khtml/dom/dom_doc.h
WebCore/khtml/dom/dom_element.cpp
WebCore/khtml/dom/dom_element.h
WebCore/khtml/dom/dom_misc.cpp
WebCore/khtml/dom/dom_misc.h
WebCore/khtml/dom/dom_node.cpp
WebCore/khtml/dom/dom_node.h
WebCore/khtml/dom/dom_string.cpp
WebCore/khtml/dom/dom_string.h
WebCore/khtml/dom/dom_text.cpp
WebCore/khtml/dom/dom_xml.cpp
WebCore/khtml/dom/html_base.cpp
WebCore/khtml/dom/html_base.h
WebCore/khtml/dom/html_block.cpp
WebCore/khtml/dom/html_document.cpp
WebCore/khtml/dom/html_document.h
WebCore/khtml/dom/html_element.cpp
WebCore/khtml/dom/html_element.h
WebCore/khtml/dom/html_form.cpp
WebCore/khtml/dom/html_form.h
WebCore/khtml/dom/html_head.cpp
WebCore/khtml/dom/html_image.cpp
WebCore/khtml/dom/html_image.h
WebCore/khtml/dom/html_inline.cpp
WebCore/khtml/dom/html_inline.h
WebCore/khtml/dom/html_list.cpp
WebCore/khtml/dom/html_misc.cpp
WebCore/khtml/dom/html_misc.h
WebCore/khtml/dom/html_object.cpp
WebCore/khtml/dom/html_object.h
WebCore/khtml/dom/html_table.cpp
WebCore/khtml/ecma/.cvsignore
WebCore/khtml/ecma/Makefile.am
WebCore/khtml/ecma/kjs_binding.cpp
WebCore/khtml/ecma/kjs_binding.h
WebCore/khtml/ecma/kjs_css.cpp
WebCore/khtml/ecma/kjs_css.h
WebCore/khtml/ecma/kjs_debugwin.cpp
WebCore/khtml/ecma/kjs_debugwin.h
WebCore/khtml/ecma/kjs_dom.cpp
WebCore/khtml/ecma/kjs_dom.h
WebCore/khtml/ecma/kjs_events.cpp
WebCore/khtml/ecma/kjs_events.h
WebCore/khtml/ecma/kjs_html.cpp
WebCore/khtml/ecma/kjs_html.h
WebCore/khtml/ecma/kjs_navigator.cpp
WebCore/khtml/ecma/kjs_navigator.h
WebCore/khtml/ecma/kjs_proxy.cpp
WebCore/khtml/ecma/kjs_proxy.h
WebCore/khtml/ecma/kjs_range.cpp
WebCore/khtml/ecma/kjs_range.h
WebCore/khtml/ecma/kjs_text.cpp [deleted file]
WebCore/khtml/ecma/kjs_text.h [deleted file]
WebCore/khtml/ecma/kjs_traversal.cpp
WebCore/khtml/ecma/kjs_traversal.h
WebCore/khtml/ecma/kjs_views.cpp
WebCore/khtml/ecma/kjs_views.h
WebCore/khtml/ecma/kjs_window.cpp
WebCore/khtml/ecma/kjs_window.h
WebCore/khtml/html/dtd.cpp
WebCore/khtml/html/dtd.h
WebCore/khtml/html/html_baseimpl.cpp
WebCore/khtml/html/html_baseimpl.h
WebCore/khtml/html/html_blockimpl.cpp
WebCore/khtml/html/html_blockimpl.h
WebCore/khtml/html/html_documentimpl.cpp
WebCore/khtml/html/html_documentimpl.h
WebCore/khtml/html/html_elementimpl.cpp
WebCore/khtml/html/html_elementimpl.h
WebCore/khtml/html/html_formimpl.cpp
WebCore/khtml/html/html_formimpl.h
WebCore/khtml/html/html_headimpl.cpp
WebCore/khtml/html/html_headimpl.h
WebCore/khtml/html/html_imageimpl.cpp
WebCore/khtml/html/html_imageimpl.h
WebCore/khtml/html/html_inlineimpl.cpp
WebCore/khtml/html/html_inlineimpl.h
WebCore/khtml/html/html_listimpl.cpp
WebCore/khtml/html/html_listimpl.h
WebCore/khtml/html/html_miscimpl.cpp
WebCore/khtml/html/html_miscimpl.h
WebCore/khtml/html/html_objectimpl.cpp
WebCore/khtml/html/html_objectimpl.h
WebCore/khtml/html/html_tableimpl.cpp
WebCore/khtml/html/html_tableimpl.h
WebCore/khtml/html/htmlparser.cpp
WebCore/khtml/html/htmltokenizer.cpp
WebCore/khtml/html/htmltokenizer.h
WebCore/khtml/java/javaembed.h
WebCore/khtml/java/kjavaappletcontext.cpp
WebCore/khtml/java/kjavaappletserver.cpp
WebCore/khtml/java/kjavaappletwidget.h
WebCore/khtml/java/kjavaprocess.cpp
WebCore/khtml/java/org/kde/kjas/server/.cvsignore [deleted file]
WebCore/khtml/khtml_events.cpp
WebCore/khtml/khtml_events.h
WebCore/khtml/khtml_ext.h
WebCore/khtml/khtml_factory.h
WebCore/khtml/khtml_part.h
WebCore/khtml/khtmlview.cpp
WebCore/khtml/khtmlview.h
WebCore/khtml/misc/Makefile.am
WebCore/khtml/misc/font.cpp [deleted file]
WebCore/khtml/misc/font.h [deleted file]
WebCore/khtml/misc/helper.cpp
WebCore/khtml/misc/helper.h
WebCore/khtml/misc/htmlattrs.in
WebCore/khtml/misc/htmltags.in
WebCore/khtml/misc/khtmllayout.h
WebCore/khtml/misc/loader.h
WebCore/khtml/misc/loader_client.h
WebCore/khtml/misc/makeattrs
WebCore/khtml/misc/maketags
WebCore/khtml/misc/stringit.h
WebCore/khtml/pics/.cvsignore [deleted file]
WebCore/khtml/rendering/Makefile.am
WebCore/khtml/rendering/bidi.cpp
WebCore/khtml/rendering/bidi.h
WebCore/khtml/rendering/break_lines.cpp
WebCore/khtml/rendering/render_applet.cpp
WebCore/khtml/rendering/render_applet.h
WebCore/khtml/rendering/render_body.cpp
WebCore/khtml/rendering/render_body.h
WebCore/khtml/rendering/render_box.cpp
WebCore/khtml/rendering/render_box.h
WebCore/khtml/rendering/render_br.cpp
WebCore/khtml/rendering/render_br.h
WebCore/khtml/rendering/render_container.cpp
WebCore/khtml/rendering/render_container.h
WebCore/khtml/rendering/render_flow.cpp
WebCore/khtml/rendering/render_flow.h
WebCore/khtml/rendering/render_form.cpp
WebCore/khtml/rendering/render_form.h
WebCore/khtml/rendering/render_frames.cpp
WebCore/khtml/rendering/render_frames.h
WebCore/khtml/rendering/render_hr.cpp [deleted file]
WebCore/khtml/rendering/render_hr.h [deleted file]
WebCore/khtml/rendering/render_html.cpp
WebCore/khtml/rendering/render_html.h
WebCore/khtml/rendering/render_image.cpp
WebCore/khtml/rendering/render_image.h
WebCore/khtml/rendering/render_list.cpp
WebCore/khtml/rendering/render_list.h
WebCore/khtml/rendering/render_object.cpp
WebCore/khtml/rendering/render_object.h
WebCore/khtml/rendering/render_replaced.cpp
WebCore/khtml/rendering/render_replaced.h
WebCore/khtml/rendering/render_root.cpp
WebCore/khtml/rendering/render_root.h
WebCore/khtml/rendering/render_style.cpp
WebCore/khtml/rendering/render_style.h
WebCore/khtml/rendering/render_table.cpp
WebCore/khtml/rendering/render_table.h
WebCore/khtml/rendering/render_text.cpp
WebCore/khtml/rendering/render_text.h
WebCore/khtml/test/.cvsignore [deleted file]
WebCore/khtml/xml/dom2_eventsimpl.cpp
WebCore/khtml/xml/dom2_eventsimpl.h
WebCore/khtml/xml/dom2_rangeimpl.cpp
WebCore/khtml/xml/dom2_rangeimpl.h
WebCore/khtml/xml/dom2_traversalimpl.cpp
WebCore/khtml/xml/dom2_traversalimpl.h
WebCore/khtml/xml/dom2_viewsimpl.cpp
WebCore/khtml/xml/dom2_viewsimpl.h
WebCore/khtml/xml/dom_docimpl.cpp
WebCore/khtml/xml/dom_docimpl.h
WebCore/khtml/xml/dom_elementimpl.cpp
WebCore/khtml/xml/dom_elementimpl.h
WebCore/khtml/xml/dom_nodeimpl.cpp
WebCore/khtml/xml/dom_nodeimpl.h
WebCore/khtml/xml/dom_stringimpl.cpp
WebCore/khtml/xml/dom_stringimpl.h
WebCore/khtml/xml/dom_textimpl.cpp
WebCore/khtml/xml/dom_textimpl.h
WebCore/khtml/xml/dom_xmlimpl.cpp
WebCore/khtml/xml/dom_xmlimpl.h
WebCore/khtml/xml/xml_tokenizer.cpp
WebCore/khtml/xml/xml_tokenizer.h
WebCore/kwq/KWQApplication.h
WebCore/kwq/KWQApplication.mm
WebCore/kwq/KWQCString.h
WebCore/kwq/KWQCollection.h
WebCore/kwq/KWQCollection.mm
WebCore/kwq/KWQColorGroup.mm
WebCore/kwq/KWQComboBox.h
WebCore/kwq/KWQComboBox.mm
WebCore/kwq/KWQCursor.h
WebCore/kwq/KWQCursor.mm
WebCore/kwq/KWQDef.h
WebCore/kwq/KWQDict.h
WebCore/kwq/KWQEvent.h
WebCore/kwq/KWQEvent.mm
WebCore/kwq/KWQFontMetrics.h
WebCore/kwq/KWQFontMetrics.mm
WebCore/kwq/KWQIcon.h
WebCore/kwq/KWQInputDialog.mm
WebCore/kwq/KWQKApplication.h [new file with mode: 0644]
WebCore/kwq/KWQKConfigBase.h
WebCore/kwq/KWQKConfigBase.mm
WebCore/kwq/KWQKCursor.h
WebCore/kwq/KWQKCursor.mm
WebCore/kwq/KWQKDebug.h
WebCore/kwq/KWQKDebug.mm
WebCore/kwq/KWQKHTMLFactory.h
WebCore/kwq/KWQKHTMLFactory.mm
WebCore/kwq/KWQKHTMLPart.mm
WebCore/kwq/KWQKHTMLPartImpl.mm
WebCore/kwq/KWQKHTMLSettings.h
WebCore/kwq/KWQKHTMLSettings.mm
WebCore/kwq/KWQKIOGlobal.h [new file with mode: 0644]
WebCore/kwq/KWQKIconLoader.h
WebCore/kwq/KWQKKAction.h
WebCore/kwq/KWQKMimeType.h
WebCore/kwq/KWQKMimeType.mm
WebCore/kwq/KWQKPartsBrowserExtension.h
WebCore/kwq/KWQKPrinter.mm
WebCore/kwq/KWQKProcess.mm
WebCore/kwq/KWQKProtocolManager.mm
WebCore/kwq/KWQKSSLKeyGen.h [new file with mode: 0644]
WebCore/kwq/KWQKStandardDirs.mm
WebCore/kwq/KWQKStaticDeleter.h
WebCore/kwq/KWQKloader.mm
WebCore/kwq/KWQKstddirs.mm
WebCore/kwq/KWQLineEdit.h
WebCore/kwq/KWQLineEdit.mm
WebCore/kwq/KWQListImpl.h
WebCore/kwq/KWQListImpl.mm
WebCore/kwq/KWQLoader.mm
WebCore/kwq/KWQLoaderImpl.mm
WebCore/kwq/KWQMap.h
WebCore/kwq/KWQMapImpl.h
WebCore/kwq/KWQMapImpl.mm
WebCore/kwq/KWQMemArray.h
WebCore/kwq/KWQMovie.h
WebCore/kwq/KWQNSTextField.h
WebCore/kwq/KWQNSTextField.mm
WebCore/kwq/KWQNamespace.h
WebCore/kwq/KWQObject.h
WebCore/kwq/KWQObject.mm
WebCore/kwq/KWQPainter.h
WebCore/kwq/KWQPainter.mm
WebCore/kwq/KWQPalette.h
WebCore/kwq/KWQPalette.mm
WebCore/kwq/KWQPointArray.h
WebCore/kwq/KWQPointArray.mm
WebCore/kwq/KWQPrinter.h [new file with mode: 0644]
WebCore/kwq/KWQPtrDict.h
WebCore/kwq/KWQPtrList.h
WebCore/kwq/KWQPtrQueue.h [new file with mode: 0644]
WebCore/kwq/KWQPtrStack.h
WebCore/kwq/KWQPtrVector.h
WebCore/kwq/KWQRadioButton.h
WebCore/kwq/KWQRadioButton.mm
WebCore/kwq/KWQRect.h
WebCore/kwq/KWQRect.mm
WebCore/kwq/KWQRegion.h
WebCore/kwq/KWQRegion.mm
WebCore/kwq/KWQScrollView.h
WebCore/kwq/KWQScrollView.mm
WebCore/kwq/KWQSignalStubs.mm
WebCore/kwq/KWQSortedList.h
WebCore/kwq/KWQStrList.h
WebCore/kwq/KWQString.h
WebCore/kwq/KWQStyle.h [new file with mode: 0644]
WebCore/kwq/KWQStyleSheet.h [new file with mode: 0644]
WebCore/kwq/KWQStyleSheet.mm [new file with mode: 0644]
WebCore/kwq/KWQTextArea.h
WebCore/kwq/KWQTextArea.mm
WebCore/kwq/KWQTextEdit.h [new file with mode: 0644]
WebCore/kwq/KWQTextEdit.mm
WebCore/kwq/KWQTextField.h
WebCore/kwq/KWQTextField.mm
WebCore/kwq/KWQTextStream.h
WebCore/kwq/KWQTextStream.mm
WebCore/kwq/KWQValueList.h
WebCore/kwq/KWQValueListImpl.h
WebCore/kwq/KWQValueListImpl.mm
WebCore/kwq/KWQVectorImpl.h
WebCore/kwq/KWQVectorImpl.mm
WebCore/kwq/KWQView.mm
WebCore/kwq/KWQWidget.h
WebCore/kwq/KWQWidget.mm
WebCore/kwq/KWQXml.h
WebCore/kwq/KWQXml.mm
WebCore/kwq/KWQbrowserextension.mm
WebCore/kwq/KWQsignals.mm
WebCore/kwq/Makefile.am
WebCore/kwq/kdecore/kapplication.h [new file with mode: 0644]
WebCore/kwq/kdecore/kconfig.h
WebCore/kwq/kdecore/kdebug.h
WebCore/kwq/kdecore/kiconloader.h
WebCore/kwq/kdecore/kprocess.h
WebCore/kwq/kdecore/kstandarddirs.h [new file with mode: 0644]
WebCore/kwq/kdecore/kstaticdeleter.h
WebCore/kwq/kdeui/kaction.h
WebCore/kwq/kdeui/kcursor.h
WebCore/kwq/kdeui/keditcl.h
WebCore/kwq/khtml/khtml_factory.h
WebCore/kwq/khtml/khtml_settings.h
WebCore/kwq/kio/global.h [new file with mode: 0644]
WebCore/kwq/kio/kmimetype.h
WebCore/kwq/kio/kprinter.h
WebCore/kwq/kio/kprotocolmanager.h
WebCore/kwq/kio/kssl/ksslkeygen.h [new file with mode: 0644]
WebCore/kwq/kparts/browserextension.h
WebCore/kwq/loader.moc [new file with mode: 0644]
WebCore/kwq/qt/qapplication.h
WebCore/kwq/qt/qarray.h
WebCore/kwq/qt/qcollection.h
WebCore/kwq/qt/qcombobox.h
WebCore/kwq/qt/qcstring.h
WebCore/kwq/qt/qcursor.h
WebCore/kwq/qt/qdict.h
WebCore/kwq/qt/qevent.h
WebCore/kwq/qt/qfontmetrics.h
WebCore/kwq/qt/qglobal.h [new file with mode: 0644]
WebCore/kwq/qt/qinputdialog.h
WebCore/kwq/qt/qlineedit.h
WebCore/kwq/qt/qlist.h
WebCore/kwq/qt/qmap.h
WebCore/kwq/qt/qmemarray.h [new file with mode: 0644]
WebCore/kwq/qt/qmovie.h
WebCore/kwq/qt/qnamespace.h
WebCore/kwq/qt/qobject.h
WebCore/kwq/qt/qpainter.h
WebCore/kwq/qt/qpalette.h
WebCore/kwq/qt/qpoint.h
WebCore/kwq/qt/qpointarray.h [new file with mode: 0644]
WebCore/kwq/qt/qprinter.h [new file with mode: 0644]
WebCore/kwq/qt/qptrdict.h
WebCore/kwq/qt/qptrlist.h [new file with mode: 0644]
WebCore/kwq/qt/qptrqueue.h [new file with mode: 0644]
WebCore/kwq/qt/qptrstack.h [new file with mode: 0644]
WebCore/kwq/qt/qptrvector.h [new file with mode: 0644]
WebCore/kwq/qt/qradiobutton.h
WebCore/kwq/qt/qrect.h
WebCore/kwq/qt/qregion.h
WebCore/kwq/qt/qscrollview.h
WebCore/kwq/qt/qsortedlist.h
WebCore/kwq/qt/qstack.h
WebCore/kwq/qt/qstring.h
WebCore/kwq/qt/qstyle.h [new file with mode: 0644]
WebCore/kwq/qt/qstylesheet.h [new file with mode: 0644]
WebCore/kwq/qt/qtextedit.h [new file with mode: 0644]
WebCore/kwq/qt/qtextstream.h
WebCore/kwq/qt/qvaluelist.h
WebCore/kwq/qt/qvector.h
WebCore/kwq/qt/qwidget.h
WebCore/kwq/qt/qxml.h
WebCore/src/kdelibs/khtml/css/css_ruleimpl.cpp
WebCore/src/kdelibs/khtml/css/css_ruleimpl.h
WebCore/src/kdelibs/khtml/css/css_stylesheetimpl.cpp
WebCore/src/kdelibs/khtml/css/css_stylesheetimpl.h
WebCore/src/kdelibs/khtml/css/css_valueimpl.cpp
WebCore/src/kdelibs/khtml/css/css_valueimpl.h
WebCore/src/kdelibs/khtml/css/csshelper.cpp
WebCore/src/kdelibs/khtml/css/cssparser.cpp
WebCore/src/kdelibs/khtml/css/cssparser.h
WebCore/src/kdelibs/khtml/css/cssproperties.in
WebCore/src/kdelibs/khtml/css/cssstyleselector.cpp
WebCore/src/kdelibs/khtml/css/cssstyleselector.h
WebCore/src/kdelibs/khtml/css/cssvalues.in
WebCore/src/kdelibs/khtml/css/html4.css
WebCore/src/kdelibs/khtml/dom/css_rule.cpp
WebCore/src/kdelibs/khtml/dom/css_rule.h
WebCore/src/kdelibs/khtml/dom/css_stylesheet.cpp
WebCore/src/kdelibs/khtml/dom/css_stylesheet.h
WebCore/src/kdelibs/khtml/dom/css_value.cpp
WebCore/src/kdelibs/khtml/dom/css_value.h
WebCore/src/kdelibs/khtml/dom/dom2_events.cpp
WebCore/src/kdelibs/khtml/dom/dom2_events.h
WebCore/src/kdelibs/khtml/dom/dom2_range.cpp
WebCore/src/kdelibs/khtml/dom/dom2_range.h
WebCore/src/kdelibs/khtml/dom/dom2_traversal.cpp
WebCore/src/kdelibs/khtml/dom/dom2_traversal.h
WebCore/src/kdelibs/khtml/dom/dom2_views.cpp
WebCore/src/kdelibs/khtml/dom/dom2_views.h
WebCore/src/kdelibs/khtml/dom/dom_doc.cpp
WebCore/src/kdelibs/khtml/dom/dom_doc.h
WebCore/src/kdelibs/khtml/dom/dom_element.cpp
WebCore/src/kdelibs/khtml/dom/dom_element.h
WebCore/src/kdelibs/khtml/dom/dom_misc.cpp
WebCore/src/kdelibs/khtml/dom/dom_misc.h
WebCore/src/kdelibs/khtml/dom/dom_node.cpp
WebCore/src/kdelibs/khtml/dom/dom_node.h
WebCore/src/kdelibs/khtml/dom/dom_string.cpp
WebCore/src/kdelibs/khtml/dom/dom_string.h
WebCore/src/kdelibs/khtml/dom/dom_text.cpp
WebCore/src/kdelibs/khtml/dom/dom_xml.cpp
WebCore/src/kdelibs/khtml/dom/html_base.cpp
WebCore/src/kdelibs/khtml/dom/html_base.h
WebCore/src/kdelibs/khtml/dom/html_block.cpp
WebCore/src/kdelibs/khtml/dom/html_document.cpp
WebCore/src/kdelibs/khtml/dom/html_document.h
WebCore/src/kdelibs/khtml/dom/html_element.cpp
WebCore/src/kdelibs/khtml/dom/html_element.h
WebCore/src/kdelibs/khtml/dom/html_form.cpp
WebCore/src/kdelibs/khtml/dom/html_form.h
WebCore/src/kdelibs/khtml/dom/html_head.cpp
WebCore/src/kdelibs/khtml/dom/html_image.cpp
WebCore/src/kdelibs/khtml/dom/html_image.h
WebCore/src/kdelibs/khtml/dom/html_inline.cpp
WebCore/src/kdelibs/khtml/dom/html_inline.h
WebCore/src/kdelibs/khtml/dom/html_list.cpp
WebCore/src/kdelibs/khtml/dom/html_misc.cpp
WebCore/src/kdelibs/khtml/dom/html_misc.h
WebCore/src/kdelibs/khtml/dom/html_object.cpp
WebCore/src/kdelibs/khtml/dom/html_object.h
WebCore/src/kdelibs/khtml/dom/html_table.cpp
WebCore/src/kdelibs/khtml/ecma/.cvsignore
WebCore/src/kdelibs/khtml/ecma/Makefile.am
WebCore/src/kdelibs/khtml/ecma/kjs_binding.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_binding.h
WebCore/src/kdelibs/khtml/ecma/kjs_css.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_css.h
WebCore/src/kdelibs/khtml/ecma/kjs_debugwin.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_debugwin.h
WebCore/src/kdelibs/khtml/ecma/kjs_dom.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_dom.h
WebCore/src/kdelibs/khtml/ecma/kjs_events.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_events.h
WebCore/src/kdelibs/khtml/ecma/kjs_html.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_html.h
WebCore/src/kdelibs/khtml/ecma/kjs_navigator.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_navigator.h
WebCore/src/kdelibs/khtml/ecma/kjs_proxy.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_proxy.h
WebCore/src/kdelibs/khtml/ecma/kjs_range.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_range.h
WebCore/src/kdelibs/khtml/ecma/kjs_text.cpp [deleted file]
WebCore/src/kdelibs/khtml/ecma/kjs_text.h [deleted file]
WebCore/src/kdelibs/khtml/ecma/kjs_traversal.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_traversal.h
WebCore/src/kdelibs/khtml/ecma/kjs_views.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_views.h
WebCore/src/kdelibs/khtml/ecma/kjs_window.cpp
WebCore/src/kdelibs/khtml/ecma/kjs_window.h
WebCore/src/kdelibs/khtml/html/dtd.cpp
WebCore/src/kdelibs/khtml/html/dtd.h
WebCore/src/kdelibs/khtml/html/html_baseimpl.cpp
WebCore/src/kdelibs/khtml/html/html_baseimpl.h
WebCore/src/kdelibs/khtml/html/html_blockimpl.cpp
WebCore/src/kdelibs/khtml/html/html_blockimpl.h
WebCore/src/kdelibs/khtml/html/html_documentimpl.cpp
WebCore/src/kdelibs/khtml/html/html_documentimpl.h
WebCore/src/kdelibs/khtml/html/html_elementimpl.cpp
WebCore/src/kdelibs/khtml/html/html_elementimpl.h
WebCore/src/kdelibs/khtml/html/html_formimpl.cpp
WebCore/src/kdelibs/khtml/html/html_formimpl.h
WebCore/src/kdelibs/khtml/html/html_headimpl.cpp
WebCore/src/kdelibs/khtml/html/html_headimpl.h
WebCore/src/kdelibs/khtml/html/html_imageimpl.cpp
WebCore/src/kdelibs/khtml/html/html_imageimpl.h
WebCore/src/kdelibs/khtml/html/html_inlineimpl.cpp
WebCore/src/kdelibs/khtml/html/html_inlineimpl.h
WebCore/src/kdelibs/khtml/html/html_listimpl.cpp
WebCore/src/kdelibs/khtml/html/html_listimpl.h
WebCore/src/kdelibs/khtml/html/html_miscimpl.cpp
WebCore/src/kdelibs/khtml/html/html_miscimpl.h
WebCore/src/kdelibs/khtml/html/html_objectimpl.cpp
WebCore/src/kdelibs/khtml/html/html_objectimpl.h
WebCore/src/kdelibs/khtml/html/html_tableimpl.cpp
WebCore/src/kdelibs/khtml/html/html_tableimpl.h
WebCore/src/kdelibs/khtml/html/htmlparser.cpp
WebCore/src/kdelibs/khtml/html/htmltokenizer.cpp
WebCore/src/kdelibs/khtml/html/htmltokenizer.h
WebCore/src/kdelibs/khtml/java/javaembed.h
WebCore/src/kdelibs/khtml/java/kjavaappletcontext.cpp
WebCore/src/kdelibs/khtml/java/kjavaappletserver.cpp
WebCore/src/kdelibs/khtml/java/kjavaappletwidget.h
WebCore/src/kdelibs/khtml/java/kjavaprocess.cpp
WebCore/src/kdelibs/khtml/java/org/kde/kjas/server/.cvsignore [deleted file]
WebCore/src/kdelibs/khtml/khtml_events.cpp
WebCore/src/kdelibs/khtml/khtml_events.h
WebCore/src/kdelibs/khtml/khtml_ext.h
WebCore/src/kdelibs/khtml/khtml_factory.h
WebCore/src/kdelibs/khtml/khtml_part.h
WebCore/src/kdelibs/khtml/khtmlview.cpp
WebCore/src/kdelibs/khtml/khtmlview.h
WebCore/src/kdelibs/khtml/misc/Makefile.am
WebCore/src/kdelibs/khtml/misc/font.cpp [deleted file]
WebCore/src/kdelibs/khtml/misc/font.h [deleted file]
WebCore/src/kdelibs/khtml/misc/helper.cpp
WebCore/src/kdelibs/khtml/misc/helper.h
WebCore/src/kdelibs/khtml/misc/htmlattrs.in
WebCore/src/kdelibs/khtml/misc/htmltags.in
WebCore/src/kdelibs/khtml/misc/khtmllayout.h
WebCore/src/kdelibs/khtml/misc/loader.h
WebCore/src/kdelibs/khtml/misc/loader_client.h
WebCore/src/kdelibs/khtml/misc/makeattrs
WebCore/src/kdelibs/khtml/misc/maketags
WebCore/src/kdelibs/khtml/misc/stringit.h
WebCore/src/kdelibs/khtml/pics/.cvsignore [deleted file]
WebCore/src/kdelibs/khtml/rendering/Makefile.am
WebCore/src/kdelibs/khtml/rendering/bidi.cpp
WebCore/src/kdelibs/khtml/rendering/bidi.h
WebCore/src/kdelibs/khtml/rendering/break_lines.cpp
WebCore/src/kdelibs/khtml/rendering/render_applet.cpp
WebCore/src/kdelibs/khtml/rendering/render_applet.h
WebCore/src/kdelibs/khtml/rendering/render_body.cpp
WebCore/src/kdelibs/khtml/rendering/render_body.h
WebCore/src/kdelibs/khtml/rendering/render_box.cpp
WebCore/src/kdelibs/khtml/rendering/render_box.h
WebCore/src/kdelibs/khtml/rendering/render_br.cpp
WebCore/src/kdelibs/khtml/rendering/render_br.h
WebCore/src/kdelibs/khtml/rendering/render_container.cpp
WebCore/src/kdelibs/khtml/rendering/render_container.h
WebCore/src/kdelibs/khtml/rendering/render_flow.cpp
WebCore/src/kdelibs/khtml/rendering/render_flow.h
WebCore/src/kdelibs/khtml/rendering/render_form.cpp
WebCore/src/kdelibs/khtml/rendering/render_form.h
WebCore/src/kdelibs/khtml/rendering/render_frames.cpp
WebCore/src/kdelibs/khtml/rendering/render_frames.h
WebCore/src/kdelibs/khtml/rendering/render_hr.cpp [deleted file]
WebCore/src/kdelibs/khtml/rendering/render_hr.h [deleted file]
WebCore/src/kdelibs/khtml/rendering/render_html.cpp
WebCore/src/kdelibs/khtml/rendering/render_html.h
WebCore/src/kdelibs/khtml/rendering/render_image.cpp
WebCore/src/kdelibs/khtml/rendering/render_image.h
WebCore/src/kdelibs/khtml/rendering/render_list.cpp
WebCore/src/kdelibs/khtml/rendering/render_list.h
WebCore/src/kdelibs/khtml/rendering/render_object.cpp
WebCore/src/kdelibs/khtml/rendering/render_object.h
WebCore/src/kdelibs/khtml/rendering/render_replaced.cpp
WebCore/src/kdelibs/khtml/rendering/render_replaced.h
WebCore/src/kdelibs/khtml/rendering/render_root.cpp
WebCore/src/kdelibs/khtml/rendering/render_root.h
WebCore/src/kdelibs/khtml/rendering/render_style.cpp
WebCore/src/kdelibs/khtml/rendering/render_style.h
WebCore/src/kdelibs/khtml/rendering/render_table.cpp
WebCore/src/kdelibs/khtml/rendering/render_table.h
WebCore/src/kdelibs/khtml/rendering/render_text.cpp
WebCore/src/kdelibs/khtml/rendering/render_text.h
WebCore/src/kdelibs/khtml/test/.cvsignore [deleted file]
WebCore/src/kdelibs/khtml/xml/dom2_eventsimpl.cpp
WebCore/src/kdelibs/khtml/xml/dom2_eventsimpl.h
WebCore/src/kdelibs/khtml/xml/dom2_rangeimpl.cpp
WebCore/src/kdelibs/khtml/xml/dom2_rangeimpl.h
WebCore/src/kdelibs/khtml/xml/dom2_traversalimpl.cpp
WebCore/src/kdelibs/khtml/xml/dom2_traversalimpl.h
WebCore/src/kdelibs/khtml/xml/dom2_viewsimpl.cpp
WebCore/src/kdelibs/khtml/xml/dom2_viewsimpl.h
WebCore/src/kdelibs/khtml/xml/dom_docimpl.cpp
WebCore/src/kdelibs/khtml/xml/dom_docimpl.h
WebCore/src/kdelibs/khtml/xml/dom_elementimpl.cpp
WebCore/src/kdelibs/khtml/xml/dom_elementimpl.h
WebCore/src/kdelibs/khtml/xml/dom_nodeimpl.cpp
WebCore/src/kdelibs/khtml/xml/dom_nodeimpl.h
WebCore/src/kdelibs/khtml/xml/dom_stringimpl.cpp
WebCore/src/kdelibs/khtml/xml/dom_stringimpl.h
WebCore/src/kdelibs/khtml/xml/dom_textimpl.cpp
WebCore/src/kdelibs/khtml/xml/dom_textimpl.h
WebCore/src/kdelibs/khtml/xml/dom_xmlimpl.cpp
WebCore/src/kdelibs/khtml/xml/dom_xmlimpl.h
WebCore/src/kdelibs/khtml/xml/xml_tokenizer.cpp
WebCore/src/kdelibs/khtml/xml/xml_tokenizer.h
WebCore/src/kdelibs/kjs/.cvsignore
WebCore/src/kdelibs/kjs/Makefile.am
WebCore/src/kdelibs/kjs/array_object.cpp
WebCore/src/kdelibs/kjs/array_object.h
WebCore/src/kdelibs/kjs/bool_object.cpp
WebCore/src/kdelibs/kjs/bool_object.h
WebCore/src/kdelibs/kjs/collector.cpp
WebCore/src/kdelibs/kjs/collector.h
WebCore/src/kdelibs/kjs/create_hash_table [new file with mode: 0755]
WebCore/src/kdelibs/kjs/date_object.cpp
WebCore/src/kdelibs/kjs/date_object.h
WebCore/src/kdelibs/kjs/debugger.cpp
WebCore/src/kdelibs/kjs/debugger.h
WebCore/src/kdelibs/kjs/error_object.cpp
WebCore/src/kdelibs/kjs/error_object.h
WebCore/src/kdelibs/kjs/function.cpp
WebCore/src/kdelibs/kjs/function.h
WebCore/src/kdelibs/kjs/function_object.cpp
WebCore/src/kdelibs/kjs/function_object.h
WebCore/src/kdelibs/kjs/global_object.cpp [deleted file]
WebCore/src/kdelibs/kjs/grammar.y
WebCore/src/kdelibs/kjs/internal.cpp
WebCore/src/kdelibs/kjs/internal.h
WebCore/src/kdelibs/kjs/interpreter.cpp [new file with mode: 0644]
WebCore/src/kdelibs/kjs/interpreter.h [new file with mode: 0644]
WebCore/src/kdelibs/kjs/keywords.table [new file with mode: 0644]
WebCore/src/kdelibs/kjs/kjs.cpp [deleted file]
WebCore/src/kdelibs/kjs/kjs.h [deleted file]
WebCore/src/kdelibs/kjs/lexer.cpp
WebCore/src/kdelibs/kjs/lexer.h
WebCore/src/kdelibs/kjs/lexer.lut.h
WebCore/src/kdelibs/kjs/lookup.cpp
WebCore/src/kdelibs/kjs/lookup.h
WebCore/src/kdelibs/kjs/math_object.cpp
WebCore/src/kdelibs/kjs/math_object.h
WebCore/src/kdelibs/kjs/math_object.lut.h
WebCore/src/kdelibs/kjs/nodes.cpp
WebCore/src/kdelibs/kjs/nodes.h
WebCore/src/kdelibs/kjs/number_object.cpp
WebCore/src/kdelibs/kjs/number_object.h
WebCore/src/kdelibs/kjs/object.cpp
WebCore/src/kdelibs/kjs/object.h
WebCore/src/kdelibs/kjs/object_object.cpp
WebCore/src/kdelibs/kjs/object_object.h
WebCore/src/kdelibs/kjs/operations.cpp
WebCore/src/kdelibs/kjs/operations.h
WebCore/src/kdelibs/kjs/property_map.cpp [new file with mode: 0644]
WebCore/src/kdelibs/kjs/property_map.h [new file with mode: 0644]
WebCore/src/kdelibs/kjs/regexp.cpp
WebCore/src/kdelibs/kjs/regexp.h
WebCore/src/kdelibs/kjs/regexp_object.cpp
WebCore/src/kdelibs/kjs/regexp_object.h
WebCore/src/kdelibs/kjs/string_object.cpp
WebCore/src/kdelibs/kjs/string_object.h
WebCore/src/kdelibs/kjs/testkjs.cpp
WebCore/src/kdelibs/kjs/types.cpp
WebCore/src/kdelibs/kjs/types.h
WebCore/src/kdelibs/kjs/ustring.cpp
WebCore/src/kdelibs/kjs/ustring.h
WebCore/src/kdelibs/kjs/value.cpp [new file with mode: 0644]
WebCore/src/kdelibs/kjs/value.h [new file with mode: 0644]
WebCore/src/kwq/KWQApplication.mm
WebCore/src/kwq/KWQCollection.mm
WebCore/src/kwq/KWQColorGroup.mm
WebCore/src/kwq/KWQComboBox.mm
WebCore/src/kwq/KWQCursor.mm
WebCore/src/kwq/KWQDef.h
WebCore/src/kwq/KWQEvent.mm
WebCore/src/kwq/KWQFontMetrics.mm
WebCore/src/kwq/KWQIcon.h
WebCore/src/kwq/KWQInputDialog.mm
WebCore/src/kwq/KWQKConfigBase.mm
WebCore/src/kwq/KWQKCursor.mm
WebCore/src/kwq/KWQKDebug.mm
WebCore/src/kwq/KWQKHTMLFactory.mm
WebCore/src/kwq/KWQKHTMLPart.h
WebCore/src/kwq/KWQKHTMLPart.mm
WebCore/src/kwq/KWQKHTMLSettings.mm
WebCore/src/kwq/KWQKMimeType.mm
WebCore/src/kwq/KWQKPrinter.mm
WebCore/src/kwq/KWQKProcess.mm
WebCore/src/kwq/KWQKProtocolManager.mm
WebCore/src/kwq/KWQKloader.mm
WebCore/src/kwq/KWQKstddirs.mm
WebCore/src/kwq/KWQLineEdit.mm
WebCore/src/kwq/KWQListImpl.h
WebCore/src/kwq/KWQListImpl.mm
WebCore/src/kwq/KWQMapImpl.h
WebCore/src/kwq/KWQMapImpl.mm
WebCore/src/kwq/KWQNSTextField.h
WebCore/src/kwq/KWQNSTextField.mm
WebCore/src/kwq/KWQObject.mm
WebCore/src/kwq/KWQPainter.mm
WebCore/src/kwq/KWQPalette.mm
WebCore/src/kwq/KWQPointArray.mm
WebCore/src/kwq/KWQRadioButton.mm
WebCore/src/kwq/KWQRect.mm
WebCore/src/kwq/KWQRegion.mm
WebCore/src/kwq/KWQScrollView.mm
WebCore/src/kwq/KWQStrList.h
WebCore/src/kwq/KWQStyle.h
WebCore/src/kwq/KWQStyleSheet.mm [new file with mode: 0644]
WebCore/src/kwq/KWQTextArea.h
WebCore/src/kwq/KWQTextArea.mm
WebCore/src/kwq/KWQTextEdit.mm
WebCore/src/kwq/KWQValueListImpl.h
WebCore/src/kwq/KWQValueListImpl.mm
WebCore/src/kwq/KWQVectorImpl.h
WebCore/src/kwq/KWQVectorImpl.mm
WebCore/src/kwq/KWQView.mm
WebCore/src/kwq/KWQWidget.mm
WebCore/src/kwq/KWQbrowserextension.mm
WebCore/src/kwq/KWQsignals.mm
WebCore/src/kwq/KWQxml.mm
WebCore/src/kwq/Makefile.am
WebCore/src/kwq/kdecore/kapplication.h [new file with mode: 0644]
WebCore/src/kwq/kdecore/kconfig.h
WebCore/src/kwq/kdecore/kdebug.h
WebCore/src/kwq/kdecore/kiconloader.h
WebCore/src/kwq/kdecore/kprocess.h
WebCore/src/kwq/kdecore/kstandarddirs.h [new file with mode: 0644]
WebCore/src/kwq/kdecore/kstaticdeleter.h
WebCore/src/kwq/kdeui/kaction.h
WebCore/src/kwq/kdeui/kcursor.h
WebCore/src/kwq/kdeui/keditcl.h
WebCore/src/kwq/khtml/khtml_factory.h
WebCore/src/kwq/khtml/khtml_settings.h
WebCore/src/kwq/kio/global.h [new file with mode: 0644]
WebCore/src/kwq/kio/kmimetype.h
WebCore/src/kwq/kio/kprinter.h
WebCore/src/kwq/kio/kprotocolmanager.h
WebCore/src/kwq/kio/kssl/ksslkeygen.h [new file with mode: 0644]
WebCore/src/kwq/kparts/browserextension.h
WebCore/src/kwq/loader.moc [new file with mode: 0644]
WebCore/src/kwq/qt/qapplication.h
WebCore/src/kwq/qt/qarray.h
WebCore/src/kwq/qt/qcollection.h
WebCore/src/kwq/qt/qcombobox.h
WebCore/src/kwq/qt/qcstring.h
WebCore/src/kwq/qt/qcursor.h
WebCore/src/kwq/qt/qdict.h
WebCore/src/kwq/qt/qevent.h
WebCore/src/kwq/qt/qfontmetrics.h
WebCore/src/kwq/qt/qglobal.h [new file with mode: 0644]
WebCore/src/kwq/qt/qinputdialog.h
WebCore/src/kwq/qt/qlineedit.h
WebCore/src/kwq/qt/qlist.h
WebCore/src/kwq/qt/qmap.h
WebCore/src/kwq/qt/qmemarray.h [new file with mode: 0644]
WebCore/src/kwq/qt/qmovie.h
WebCore/src/kwq/qt/qnamespace.h
WebCore/src/kwq/qt/qobject.h
WebCore/src/kwq/qt/qpainter.h
WebCore/src/kwq/qt/qpalette.h
WebCore/src/kwq/qt/qpoint.h
WebCore/src/kwq/qt/qpointarray.h [new file with mode: 0644]
WebCore/src/kwq/qt/qprinter.h [new file with mode: 0644]
WebCore/src/kwq/qt/qptrdict.h
WebCore/src/kwq/qt/qptrlist.h [new file with mode: 0644]
WebCore/src/kwq/qt/qptrqueue.h [new file with mode: 0644]
WebCore/src/kwq/qt/qptrstack.h [new file with mode: 0644]
WebCore/src/kwq/qt/qptrvector.h [new file with mode: 0644]
WebCore/src/kwq/qt/qradiobutton.h
WebCore/src/kwq/qt/qrect.h
WebCore/src/kwq/qt/qregion.h
WebCore/src/kwq/qt/qscrollview.h
WebCore/src/kwq/qt/qsortedlist.h
WebCore/src/kwq/qt/qstack.h
WebCore/src/kwq/qt/qstring.h
WebCore/src/kwq/qt/qstyle.h [new file with mode: 0644]
WebCore/src/kwq/qt/qstylesheet.h [new file with mode: 0644]
WebCore/src/kwq/qt/qtextedit.h [new file with mode: 0644]
WebCore/src/kwq/qt/qtextstream.h
WebCore/src/kwq/qt/qvaluelist.h
WebCore/src/kwq/qt/qvector.h
WebCore/src/kwq/qt/qwidget.h
WebCore/src/kwq/qt/qxml.h
WebKit/ChangeLog
WebKit/ChangeLog-2002-12-03
WebKit/WebView.subproj/IFWebView.mm
WebKit/WebView.subproj/WebFrameView.m

index 300612220b89f2e6009ad571db3d4fa5b81da673..5d99c48482e183ad9067d9b03befbe85769f0f62 100644 (file)
@@ -4,6 +4,8 @@ noinst_LIBRARIES = libkjs.o
 libkjs_o_LDFLAGS = -Wl,-r -nostdlib
 libkjs_o_AR = $(OBJCXXLD) $(AM_OBJCXXFLAGS) $(OBJCXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) $(libkjs_o_LDFLAGS) -o
 
+INCLUDES = $(KWQ_INCLUDES)
+
 libkjs_o_SOURCES = \
        array_object.cpp \
        array_object.h \
@@ -21,13 +23,12 @@ libkjs_o_SOURCES = \
        function.h \
        function_object.cpp \
        function_object.h \
-       global_object.cpp \
        grammar.cpp \
        grammar.h \
        internal.cpp \
        internal.h \
-       kjs.cpp \
-       kjs.h \
+       interpreter.cpp \
+       interpreter.h \
        lexer.cpp \
        lexer.h \
        lexer.lut.h \
@@ -46,6 +47,8 @@ libkjs_o_SOURCES = \
        object_object.h \
        operations.cpp \
        operations.h \
+       property_map.cpp \
+       property_map.h \
        regexp.cpp \
        regexp.h \
        regexp_object.cpp \
@@ -56,6 +59,8 @@ libkjs_o_SOURCES = \
        types.h \
        ustring.cpp \
        ustring.h \
+       value.cpp \
+       value.h \
        $(NULL)
 
 noinst_PROGRAMS = testkjs
@@ -75,7 +80,29 @@ grammar-stamp: grammar.y
        ln -sf grammar.cpp.h grammar.h
        touch ./grammar-stamp
 
-BUILT_SOURCES = $(GRAMMAR_FILES) grammar-stamp
+LUT_FILES = math_object.lut.h lexer.lut.h array_object.lut.h date_object.lut.h string_object.lut.h number_object.lut.h
+
+lexer.lut.h: keywords.table
+       ./create_hash_table keywords.table -i > lexer.lut.h;
+
+array_object.lut.h: array_object.cpp
+       ./create_hash_table array_object.cpp -i > array_object.lut.h
+
+math_object.lut.h: math_object.cpp
+       ./create_hash_table math_object.cpp -i > math_object.lut.h
+
+date_object.lut.h: date_object.cpp
+       ./create_hash_table date_object.cpp -i > date_object.lut.h
+
+number_object.lut.h: number_object.cpp
+       ./create_hash_table number_object.cpp -i > number_object.lut.h
+
+string_object.lut.h: string_object.cpp
+       ./create_hash_table string_object.cpp -i > string_object.lut.h
+
+
+
+BUILT_SOURCES = $(GRAMMAR_FILES) $(LUT_FILES) grammar-stamp
 
 CLEANFILES = $(BUILT_SOURCES)
 
index cc97dff163e77a07ff3888a46d3d3ce971e11c12..a8aa622fcbe459303679d9120a95c4e7bb17bf52 100644 (file)
@@ -1,3 +1,4 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
  */
 
-#include "kjs.h"
-#include "operations.h"
+#include "value.h"
+#include "object.h"
 #include "types.h"
+#include "interpreter.h"
+#include "operations.h"
 #include "array_object.h"
+#include "internal.h"
+#include "error_object.h"
+
+#include "array_object.lut.h"
+
 #include <stdio.h>
+#include <assert.h>
 
 using namespace KJS;
 
-ArrayObject::ArrayObject(const Object &funcProto,
-                        const Object &arrayProto)
-    : ConstructorImp(funcProto, 1)
+// ------------------------------ ArrayInstanceImp -----------------------------
+
+const ClassInfo ArrayInstanceImp::info = {"Array", 0, 0, 0};
+
+ArrayInstanceImp::ArrayInstanceImp(const Object &proto)
+  : ObjectImp(proto)
 {
-  // ECMA 15.4.3.1 Array.prototype
-  setPrototypeProperty(arrayProto);
 }
 
-// ECMA 15.6.1
-Completion ArrayObject::execute(const List &args)
+// Special implementation of [[Put]] - see ECMA 15.4.5.1
+void ArrayInstanceImp::put(ExecState *exec, const UString &propertyName, const Value &value, int attr)
 {
-  // equivalent to 'new Array(....)'
-  KJSO result = construct(args);
+  if ((attr == None || attr == DontDelete) && !canPut(exec,propertyName))
+    return;
+
+  if (hasProperty(exec,propertyName)) {
+    if (propertyName == "length") {
+      Value len = get(exec,"length");
+      unsigned int oldLen = len.toUInt32(exec);
+      unsigned int newLen = value.toUInt32(exec);
+      // shrink array
+      for (unsigned int u = newLen; u < oldLen; u++) {
+       UString p = UString::from(u);
+       if (hasProperty(exec, p, false))
+         deleteProperty(exec, p);
+      }
+      ObjectImp::put(exec, "length", Number(newLen), DontEnum | DontDelete);
+      return;
+    }
+    //    put(p, v);
+  } //  } else
+    ObjectImp::put(exec, propertyName, value, attr);
+
+  // array index ?
+  unsigned int idx;
+  if (!sscanf(propertyName.cstring().c_str(), "%u", &idx)) /* TODO */
+    return;
 
-  return Completion(ReturnValue, result);
+  // do we need to update/create the length property ?
+  if (hasProperty(exec, "length", false)) {
+    Value len = get(exec, "length");
+    if (idx < len.toUInt32(exec))
+      return;
+  }
+
+  ObjectImp::put(exec, "length", Number(idx+1), DontDelete | DontEnum);
 }
 
-// ECMA 15.6.2
-Object ArrayObject::construct(const List &args)
+void ArrayInstanceImp::putDirect(ExecState *exec, const UString &propertyName, const Value &value, int attr)
 {
-  Object result = Object::create(ArrayClass);
+  ObjectImp::put(exec,propertyName,value,attr);
+}
+// ------------------------------ ArrayPrototypeImp ----------------------------
 
-  unsigned int len;
-  ListIterator it = args.begin();
-  // a single argument might denote the array size
-  if (args.size() == 1 && it->isA(NumberType))
-    len = it->toUInt32();
-  else {
-    // initialize array
-    len = args.size();
-    for (unsigned int u = 0; it != args.end(); it++, u++)
-      result.put(UString::from(u), *it);
-  }
+const ClassInfo ArrayPrototypeImp::info = {"Array", &ArrayInstanceImp::info, &arrayTable, 0};
 
-  // array size
-  result.put("length", len, DontEnum | DontDelete);
+/* Source for array_object.lut.h
+@begin arrayTable 13
+  toString       ArrayProtoFuncImp::ToString       DontEnum|Function 0
+  toLocaleString ArrayProtoFuncImp::ToLocaleString DontEnum|Function 0
+  concat         ArrayProtoFuncImp::Concat         DontEnum|Function 1
+  join           ArrayProtoFuncImp::Join           DontEnum|Function 1
+  pop            ArrayProtoFuncImp::Pop            DontEnum|Function 0
+  push           ArrayProtoFuncImp::Push           DontEnum|Function 1
+  reverse        ArrayProtoFuncImp::Reverse        DontEnum|Function 0
+  shift          ArrayProtoFuncImp::Shift          DontEnum|Function 0
+  slice          ArrayProtoFuncImp::Slice          DontEnum|Function 2
+  sort           ArrayProtoFuncImp::Sort           DontEnum|Function 1
+  splice         ArrayProtoFuncImp::Splice         DontEnum|Function 2
+  unshift        ArrayProtoFuncImp::UnShift        DontEnum|Function 1
+@end
+*/
 
-  return result;
+// ECMA 15.4.4
+ArrayPrototypeImp::ArrayPrototypeImp(ExecState *exec,
+                                     ObjectPrototypeImp *objProto)
+  : ArrayInstanceImp(Object(objProto))
+{
+  Value protect(this);
+  setInternalValue(Null());
+
+  // The constructor will be added later, by InterpreterImp, once ArrayObjectImp has been constructed.
+  put(exec,"length", Number(0), DontEnum | DontDelete);
 }
 
-// ECMA 15.6.4
-ArrayPrototype::ArrayPrototype(const Object& proto)
-  : ObjectImp(ArrayClass, Null(), proto)
+Value ArrayPrototypeImp::get(ExecState *exec, const UString &propertyName) const
 {
-  // The constructor will be added later in ArrayObject's constructor
+  //fprintf( stderr, "ArrayPrototypeImp::get(%s)\n", propertyName.ascii() );
+  return lookupGetFunction<ArrayProtoFuncImp, ArrayInstanceImp>( exec, propertyName, &arrayTable, this );
+}
+
+// ------------------------------ ArrayProtoFuncImp ----------------------------
 
-  put("length", 0u, DontEnum | DontDelete);
+ArrayProtoFuncImp::ArrayProtoFuncImp(ExecState *exec, int i, int len)
+  : InternalFunctionImp(
+    static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
+    ), id(i)
+{
+  Value protect(this);
+  put(exec,"length",Number(len),DontDelete|ReadOnly|DontEnum);
 }
 
-KJSO ArrayPrototype::get(const UString &p) const
+bool ArrayProtoFuncImp::implementsCall() const
 {
-  int id;
-  if(p == "toString")
-    id = ArrayProtoFunc::ToString;
-  else if(p == "toLocaleString")
-    id = ArrayProtoFunc::ToLocaleString;
-  else if(p == "concat")
-    id = ArrayProtoFunc::Concat;
-  else if (p == "join")
-    id = ArrayProtoFunc::Join;
-  else if(p == "pop")
-    id = ArrayProtoFunc::Pop;
-  else if(p == "push")
-    id = ArrayProtoFunc::Push;
-  else if(p == "reverse")
-    id = ArrayProtoFunc::Reverse;
-  else if(p == "shift")
-    id = ArrayProtoFunc::Shift;
-  else if(p == "slice")
-    id = ArrayProtoFunc::Slice;
-  else if(p == "sort")
-    id = ArrayProtoFunc::Sort;
-  else if(p == "splice")
-    id = ArrayProtoFunc::Splice;
-  else if(p == "unshift")
-    id = ArrayProtoFunc::UnShift;
-  else
-    return Imp::get(p);
-
-  return Function(new ArrayProtoFunc(id));
+  return true;
 }
 
 // ECMA 15.4.4
-Completion ArrayProtoFunc::execute(const List &args)
+Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
 {
-  KJSO result, obj, obj2;
-  Object thisObj = Object::dynamicCast(thisValue());
-  unsigned int length = thisObj.get("length").toUInt32();
-  unsigned int middle;
-  UString str = "", str2;
-  UString separator = ",";
+  unsigned int length = thisObj.get(exec,"length").toUInt32(exec);
 
+  Value result;
   switch (id) {
   case ToLocaleString:
-    /* TODO */
-    // fall trough
+    // TODO  - see 15.4.4.3
+    // fall through
   case ToString:
-    if (!thisObj.getClass() == ArrayClass) {
-      result = Error::create(TypeError);
-      break;
+
+    if (!thisObj.inherits(&ArrayInstanceImp::info)) {
+      Object err = Error::create(exec,TypeError);
+      exec->setException(err);
+      return err;
     }
-    // fall trough
-  case Join:
-    {
-      if (!args[0].isA(UndefinedType))
-       separator = args[0].toString().value();
-      for (unsigned int k = 0; k < length; k++) {
-       if (k >= 1)
-         str += separator;
-       obj = thisObj.get(UString::from(k));
-       if (!obj.isA(UndefinedType) && !obj.isA(NullType))
-         str += obj.toString().value();
-      }
+
+    // fall through
+
+  case Join: {
+    UString separator = ",";
+    UString str = "";
+
+    if (args.size() > 0)
+      separator = args[0].toString(exec);
+    for (unsigned int k = 0; k < length; k++) {
+      if (k >= 1)
+        str += separator;
+      Value element = thisObj.get(exec,UString::from(k));
+      if (element.type() != UndefinedType && element.type() != NullType)
+        str += element.toString(exec);
     }
     result = String(str);
     break;
+  }
   case Concat: {
-    result = Object::create(ArrayClass);
+    Object arr = Object::dynamicCast(exec->interpreter()->builtinArray().construct(exec,List::empty()));
     int n = 0;
-    obj = thisObj;
+    Value curArg = thisObj;
+    Object curObj = Object::dynamicCast(thisObj);
     ListIterator it = args.begin();
     for (;;) {
-      if (obj.isA(ObjectType) &&
-         static_cast<Object&>(obj).getClass() == ArrayClass) {
-       unsigned int k = 0;
-       if (n > 0)
-         length = obj.get("length").toUInt32();
-       while (k < length) {
-         UString p = UString::from(k);
-         if (obj.hasProperty(p))
-           result.put(UString::from(n), obj.get(p));
-         n++;
-         k++;
-       }
+      if (curArg.type() == ObjectType &&
+          curObj.inherits(&ArrayInstanceImp::info)) {
+        unsigned int k = 0;
+        if (n > 0)
+          length = curObj.get(exec,"length").toUInt32(exec);
+        while (k < length) {
+          UString p = UString::from(k);
+          if (curObj.hasProperty(exec,p))
+            arr.put(exec,UString::from(n), curObj.get(exec,p));
+          n++;
+          k++;
+        }
       } else {
-       result.put(UString::from(n), obj);
-       n++;      
+        arr.put(exec,UString::from(n), curArg);
+        n++;
       }
       if (it == args.end())
-       break;
-      obj = it++;
+        break;
+      curArg = *it;
+      curObj = Object::dynamicCast(it++); // may be 0
     }
-    result.put("length", Number(n), DontEnum | DontDelete);
-  }
+    arr.put(exec,"length", Number(n), DontEnum | DontDelete);
+
+    result = arr;
     break;
-  case Pop:
+  }
+  case Pop:{
+
     if (length == 0) {
-      thisObj.put("length", Number(length), DontEnum | DontDelete);
+      thisObj.put(exec, "length", Number(length), DontEnum | DontDelete);
       result = Undefined();
     } else {
-      str = UString::from(length - 1);
-      result = thisObj.get(str);
-      thisObj.deleteProperty(str);
-      thisObj.put("length", length - 1, DontEnum | DontDelete);
+      UString str = UString::from(length - 1);
+      result = thisObj.get(exec,str);
+      thisObj.deleteProperty(exec, str);
+      thisObj.put(exec, "length", Number(length - 1), DontEnum | DontDelete);
     }
     break;
-  case Push:
-    {
-      for (int n = 0; n < args.size(); n++)
-       thisObj.put(UString::from(length + n), args[n]);
-      length += args.size();
-      thisObj.put("length", length, DontEnum | DontDelete);
-      result = Number(length);
-    }
+  }
+  case Push: {
+    for (int n = 0; n < args.size(); n++)
+      thisObj.put(exec,UString::from(length + n), args[n]);
+    length += args.size();
+    thisObj.put(exec,"length", Number(length), DontEnum | DontDelete);
+    result = Number(length);
     break;
-  case Reverse:
-    {
-      middle = length / 2;
-      for (unsigned int k = 0; k < middle; k++) {
-       str = UString::from(k);
-       str2 = UString::from(length - k - 1);
-       obj = thisObj.get(str);
-       obj2 = thisObj.get(str2);
-       if (thisObj.hasProperty(str2)) {
-         if (thisObj.hasProperty(str)) {
-           thisObj.put(str, obj2);
-           thisObj.put(str2, obj);
-         } else {
-           thisObj.put(str, obj2);
-           thisObj.deleteProperty(str2);
-         }
-       } else {
-         if (thisObj.hasProperty(str)) {
-           thisObj.deleteProperty(str);
-           thisObj.put(str2, obj);
-         } else {
-           // why delete something that's not there ? Strange.
-           thisObj.deleteProperty(str);
-           thisObj.deleteProperty(str2);
-         }
-       }
+  }
+  case Reverse: {
+
+    unsigned int middle = length / 2;
+
+    for (unsigned int k = 0; k < middle; k++) {
+      UString str = UString::from(k);
+      UString str2 = UString::from(length - k - 1);
+      Value obj = thisObj.get(exec,str);
+      Value obj2 = thisObj.get(exec,str2);
+      if (thisObj.hasProperty(exec,str2)) {
+        if (thisObj.hasProperty(exec,str)) {
+          thisObj.put(exec, str, obj2);
+          thisObj.put(exec, str2, obj);
+        } else {
+          thisObj.put(exec, str, obj2);
+          thisObj.deleteProperty(exec, str2);
+        }
+      } else {
+        if (thisObj.hasProperty(exec, str)) {
+          thisObj.deleteProperty(exec, str);
+          thisObj.put(exec, str2, obj);
+        } else {
+          // why delete something that's not there ? Strange.
+          thisObj.deleteProperty(exec, str);
+          thisObj.deleteProperty(exec, str2);
+        }
       }
     }
     result = thisObj;
     break;
-  case Shift:
+  }
+  case Shift: {
     if (length == 0) {
-      thisObj.put("length", Number(length), DontEnum | DontDelete);
+      thisObj.put(exec, "length", Number(length), DontEnum | DontDelete);
       result = Undefined();
     } else {
-      result = thisObj.get("0");
+      result = thisObj.get(exec, "0");
       for(unsigned int k = 1; k < length; k++) {
-       str = UString::from(k);
-       str2 = UString::from(k-1);
-       if (thisObj.hasProperty(str)) {
-         obj = thisObj.get(str);
-         thisObj.put(str2, obj);
-       } else
-         thisObj.deleteProperty(str2);
+        UString str = UString::from(k);
+        UString str2 = UString::from(k-1);
+        if (thisObj.hasProperty(exec, str)) {
+          Value obj = thisObj.get(exec, str);
+          thisObj.put(exec, str2, obj);
+        } else
+          thisObj.deleteProperty(exec, str2);
       }
-      thisObj.deleteProperty(UString::from(length - 1));
-      thisObj.put("length", length - 1, DontEnum | DontDelete);
+      thisObj.deleteProperty(exec, UString::from(length - 1));
+      thisObj.put(exec, "length", Number(length - 1), DontEnum | DontDelete);
     }
     break;
-  case Slice: // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713
+  }
+  case Slice: {
+    // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10
+
+    // We return a new array
+    Object resObj = Object::dynamicCast(exec->interpreter()->builtinArray().construct(exec,List::empty()));
+    result = resObj;
+    int begin = args[0].toUInt32(exec);
+    if ( begin < 0 )
+      begin = maxInt( begin + length, 0 );
+    else
+      begin = minInt( begin, length );
+    int end = length;
+    if (args[1].type() != UndefinedType)
     {
-        result = Object::create(ArrayClass); // We return a new array
-        int begin = args[0].toUInt32();
-        int end = length;
-        if (!args[1].isA(UndefinedType))
-        {
-          end = args[1].toUInt32();
-          if ( end < 0 )
-            end += length;
-        }
-        // safety tests
-        if ( begin < 0 || end < 0 || begin >= end ) {
-            result.put("length", Number(0), DontEnum | DontDelete);
-            break;
-        }
-        //printf( "Slicing from %d to %d \n", begin, end );
-        for(unsigned int k = 0; k < (unsigned int) end-begin; k++) {
-            str = UString::from(k+begin);
-            str2 = UString::from(k);
-            if (thisObj.hasProperty(str)) {
-                obj = thisObj.get(str);
-                result.put(str2, obj);
-            }
-        }
-        result.put("length", end - begin, DontEnum | DontDelete);
-        break;
+      end = args[1].toUInt32(exec);
+      if ( end < 0 )
+        end = maxInt( end + length, 0 );
+      else
+        end = minInt( end, length );
     }
-  case Sort:
-    {
+
+    //printf( "Slicing from %d to %d \n", begin, end );
+    for(unsigned int k = 0; k < (unsigned int) end-begin; k++) {
+      UString str = UString::from(k+begin);
+      if (thisObj.hasProperty(exec,str)) {
+        UString str2 = UString::from(k);
+        Value obj = thisObj.get(exec, str);
+        resObj.put(exec, str2, obj);
+      }
+    }
+    resObj.put(exec, "length", Number(end - begin), DontEnum | DontDelete);
+    break;
+  }
+  case Sort:{
 #if 0
-        printf("KJS Array::Sort length=%d\n", length);
-        for ( unsigned int i = 0 ; i<length ; ++i )
-            printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(UString::from(i)).toString().value().ascii() );
+    printf("KJS Array::Sort length=%d\n", length);
+    for ( unsigned int i = 0 ; i<length ; ++i )
+      printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(UString::from(i)).toString().value().ascii() );
 #endif
-        Object sortFunction;
-        bool useSortFunction = !args[0].isA(UndefinedType);
-        if (useSortFunction)
-        {
-            sortFunction = args[0].toObject();
-            if (!sortFunction.implementsCall())
-                useSortFunction = false;
-        }
+    Object sortFunction;
+    bool useSortFunction = (args[0].type() != UndefinedType);
+    if (useSortFunction)
+      {
+        sortFunction = args[0].toObject(exec);
+        if (!sortFunction.implementsCall())
+          useSortFunction = false;
+      }
 
-        if (length == 0) {
-            thisObj.put("length", Number(0), DontEnum | DontDelete);
-            result = Undefined();
-            break;
-        }
+    if (length == 0) {
+      thisObj.put(exec, "length", Number(0), DontEnum | DontDelete);
+      result = Undefined();
+      break;
+    }
 
-        // "Min" sort. Not the fastest, but definitely less code than heapsort
-        // or quicksort, and much less swapping than bubblesort/insertionsort.
-        for ( unsigned int i = 0 ; i<length-1 ; ++i )
-        {
-            KJSO iObj = thisObj.get(UString::from(i));
-            unsigned int themin = i;
-            KJSO minObj = iObj;
-            for ( unsigned int j = i+1 ; j<length ; ++j )
-            {
-                KJSO jObj = thisObj.get(UString::from(j));
-                int cmp;
-                if ( useSortFunction )
-                {
-                    List l;
-                    l.append(jObj);
-                    l.append(minObj);
-                    cmp = sortFunction.executeCall( Global::current(), &l ).toInt32();
-                }
-                else
-                    cmp = ( jObj.toString().value() < minObj.toString().value() ) ? -1 : 1;
-                if ( cmp < 0 )
-                {
-                    themin = j;
-                    minObj = jObj;
-                }
-            }
-            // Swap themin and i
-            if ( themin > i )
-            {
-                //printf("KJS Array::Sort: swapping %d and %d\n", i, themin );
-                thisObj.put( UString::from(i), minObj );
-                thisObj.put( UString::from(themin), iObj );
-            }
-        }
+    // "Min" sort. Not the fastest, but definitely less code than heapsort
+    // or quicksort, and much less swapping than bubblesort/insertionsort.
+    for ( unsigned int i = 0 ; i<length-1 ; ++i )
+      {
+        Value iObj = thisObj.get(exec,UString::from(i));
+        unsigned int themin = i;
+        Value minObj = iObj;
+        for ( unsigned int j = i+1 ; j<length ; ++j )
+          {
+            Value jObj = thisObj.get(exec,UString::from(j));
+            int cmp;
+            if ( useSortFunction )
+              {
+                List l;
+                l.append(jObj);
+                l.append(minObj);
+                Object thisObj = exec->interpreter()->globalObject();
+                cmp = sortFunction.call(exec,thisObj, l ).toInt32(exec);
+              }
+            else
+              cmp = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1;
+            if ( cmp < 0 )
+              {
+                themin = j;
+                minObj = jObj;
+              }
+          }
+        // Swap themin and i
+        if ( themin > i )
+          {
+            //printf("KJS Array::Sort: swapping %d and %d\n", i, themin );
+            thisObj.put( exec, UString::from(i), minObj );
+            thisObj.put( exec, UString::from(themin), iObj );
+          }
+      }
 #if 0
-        printf("KJS Array::Sort -- Resulting array:\n");
-        for ( unsigned int i = 0 ; i<length ; ++i )
-            printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(UString::from(i)).toString().value().ascii() );
+    printf("KJS Array::Sort -- Resulting array:\n");
+    for ( unsigned int i = 0 ; i<length ; ++i )
+      printf("KJS Array::Sort: %d: %s\n", i, thisObj.get(UString::from(i)).toString().value().ascii() );
 #endif
-        result = thisObj;
-        break;
+    result = thisObj;
+    break;
+  }
+  case Splice: {
+    // 15.4.4.12 - oh boy this is huge
+    Object resObj = Object::dynamicCast(exec->interpreter()->builtinArray().construct(exec,List::empty()));
+    result = resObj;
+    int begin = args[0].toUInt32(exec);
+    if ( begin < 0 )
+      begin = maxInt( begin + length, 0 );
+    else
+      begin = minInt( begin, length );
+    unsigned int deleteCount = minInt( maxInt( args[1].toUInt32(exec), 0 ), length - begin );
+
+    //printf( "Splicing from %d, deleteCount=%d \n", begin, deleteCount );
+    for(unsigned int k = 0; k < deleteCount; k++) {
+      UString str = UString::from(k+begin);
+      if (thisObj.hasProperty(exec,str)) {
+        UString str2 = UString::from(k);
+        Value obj = thisObj.get(exec, str);
+        resObj.put(exec, str2, obj);
+      }
+    }
+    resObj.put(exec, "length", Number(deleteCount), DontEnum | DontDelete);
+
+    unsigned int additionalArgs = maxInt( args.size() - 2, 0 );
+    if ( additionalArgs != deleteCount )
+    {
+      if ( additionalArgs < deleteCount )
+      {
+        for ( unsigned int k = begin; k < length - deleteCount; ++k )
+        {
+          UString str = UString::from(k+deleteCount);
+          UString str2 = UString::from(k+additionalArgs);
+          if (thisObj.hasProperty(exec,str)) {
+            Value obj = thisObj.get(exec, str);
+            thisObj.put(exec, str2, obj);
+          }
+          else
+            thisObj.deleteProperty(exec, str2);
+        }
+        for ( unsigned int k = length ; k > length - deleteCount + additionalArgs; --k )
+          thisObj.deleteProperty(exec, UString::from(k-1));
+      }
+      else
+      {
+        for ( unsigned int k = length - deleteCount; (int)k > begin; --k )
+        {
+          UString str = UString::from(k+deleteCount-1);
+          UString str2 = UString::from(k+additionalArgs-1);
+          if (thisObj.hasProperty(exec,str)) {
+            Value obj = thisObj.get(exec, str);
+            thisObj.put(exec, str2, obj);
+          }
+          else
+            thisObj.deleteProperty(exec, str2);
+        }
+      }
+    }
+    for ( unsigned int k = 0; k < additionalArgs; ++k )
+    {
+      thisObj.put(exec, UString::from(k+begin), args[k+2]);
     }
-  // TODO Splice
-  // TODO Unshift
+    thisObj.put(exec, "length", Number(length - deleteCount + additionalArgs), DontEnum | DontDelete);
+    break;
+  }
+  case UnShift: { // 15.4.4.13
+    unsigned int nrArgs = args.size();
+    for ( unsigned int k = length; k > 0; --k )
+    {
+      UString str = UString::from(k-1);
+      UString str2 = UString::from(k+nrArgs-1);
+      if (thisObj.hasProperty(exec,str)) {
+        Value obj = thisObj.get(exec, str);
+        thisObj.put(exec, str2, obj);
+      } else {
+        thisObj.deleteProperty(exec, str2);
+      }
+    }
+    for ( unsigned int k = 0; k < nrArgs; ++k )
+      thisObj.put(exec, UString::from(k), args[k]);
+    result = Number(length + nrArgs);
+    thisObj.put(exec, "length", result, DontEnum | DontDelete);
+    break;
+  }
   default:
-    result = Undefined();
+    assert(0);
+    break;
   }
+  return result;
+}
+
+// ------------------------------ ArrayObjectImp -------------------------------
+
+ArrayObjectImp::ArrayObjectImp(ExecState *exec,
+                               FunctionPrototypeImp *funcProto,
+                               ArrayPrototypeImp *arrayProto)
+  : InternalFunctionImp(funcProto)
+{
+  Value protect(this);
+  // ECMA 15.4.3.1 Array.prototype
+  put(exec,"prototype", Object(arrayProto), DontEnum|DontDelete|ReadOnly);
+
+  // no. of arguments for constructor
+  put(exec,"length", Number(1), ReadOnly|DontDelete|DontEnum);
+}
 
-  return Completion(ReturnValue, result);
+bool ArrayObjectImp::implementsConstruct() const
+{
+  return true;
 }
+
+// ECMA 15.4.2
+Object ArrayObjectImp::construct(ExecState *exec, const List &args)
+{
+  Object result(new ArrayInstanceImp(exec->interpreter()->builtinArrayPrototype()));
+
+  unsigned int len;
+  ListIterator it = args.begin();
+  // a single argument might denote the array size
+  if (args.size() == 1 && it->type() == NumberType)
+    len = it->toUInt32(exec);
+  else {
+    // initialize array
+    len = args.size();
+    for (unsigned int u = 0; it != args.end(); it++, u++)
+      result.put(exec, UString::from(u), *it);
+  }
+
+  // array size
+  result.put(exec, "length", Number(len), DontEnum | DontDelete);
+  static_cast<ArrayInstanceImp*>(result.imp())->putDirect(exec, "length", Number(len), DontEnum | DontDelete);
+
+  return result;
+}
+
+bool ArrayObjectImp::implementsCall() const
+{
+  return true;
+}
+
+// ECMA 15.6.1
+Value ArrayObjectImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
+{
+  // equivalent to 'new Array(....)'
+  return construct(exec,args);
+}
+
index f4d56e4e8806c627b22d0ce56fa96f00697699ad..17641d104c7c945e46d9729e52c100d1f3af4b57 100644 (file)
@@ -1,3 +1,4 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id$
  */
 
 #ifndef _ARRAY_OBJECT_H_
 #define _ARRAY_OBJECT_H_
 
-#include "object.h"
-#include "function.h"
+#include "internal.h"
+#include "function_object.h"
 
 namespace KJS {
 
-  class ArrayObject : public ConstructorImp {
+  class ArrayInstanceImp : public ObjectImp {
   public:
-    ArrayObject(const Object &funcProto, const Object &arrayProto);
-    Completion execute(const List &);
-    Object construct(const List &);
+    ArrayInstanceImp(const Object &proto);
+
+    virtual void put(ExecState *exec, const UString &propertyName, const Value &value, int attr = None);
+    virtual void putDirect(ExecState *exec, const UString &propertyName, const Value &value, int attr = None);
+
+    virtual const ClassInfo *classInfo() const { return &info; }
+    static const ClassInfo info;
   };
 
 class ArrayPrototype : public ObjectImp {
class ArrayPrototypeImp : public ArrayInstanceImp {
   public:
-    ArrayPrototype(const Object& proto);
-    virtual KJSO get(const UString &p) const;
+    ArrayPrototypeImp(ExecState *exec,
+                      ObjectPrototypeImp *objProto);
+    Value get(ExecState *exec, const UString &p) const;
+    virtual const ClassInfo *classInfo() const { return &info; }
+    static const ClassInfo info;
   };
 
-  class ArrayProtoFunc : public InternalFunctionImp {
+  class ArrayProtoFuncImp : public InternalFunctionImp {
   public:
-    ArrayProtoFunc(int i) : id(i) { }
-    Completion execute(const List &);
+    ArrayProtoFuncImp(ExecState *exec, int i, int len);
+
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+
     enum { ToString, ToLocaleString, Concat, Join, Pop, Push,
           Reverse, Shift, Slice, Sort, Splice, UnShift };
   private:
     int id;
   };
 
+  class ArrayObjectImp : public InternalFunctionImp {
+  public:
+    ArrayObjectImp(ExecState *exec,
+                   FunctionPrototypeImp *funcProto,
+                   ArrayPrototypeImp *arrayProto);
+
+    virtual bool implementsConstruct() const;
+    virtual Object construct(ExecState *exec, const List &args);
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+
+  };
+
 }; // namespace
 
 #endif
index 08fcc5c82a17597f823f7f088f66c5b533112748..7e10643c8ece8fa93ed8601e7fba311deb60e550 100644 (file)
@@ -1,3 +1,4 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
  */
 
-#include "kjs.h"
-#include "operations.h"
+#include "value.h"
+#include "object.h"
 #include "types.h"
+#include "interpreter.h"
+#include "operations.h"
 #include "bool_object.h"
 #include "error_object.h"
 
+#include <assert.h>
+
 using namespace KJS;
 
-BooleanObject::BooleanObject(const KJSO& funcProto, const KJSO &booleanProto)
-  : ConstructorImp(funcProto, 1)
+// ------------------------------ BooleanInstanceImp ---------------------------
+
+const ClassInfo BooleanInstanceImp::info = {"Boolean", 0, 0, 0};
+
+BooleanInstanceImp::BooleanInstanceImp(const Object &proto)
+  : ObjectImp(proto)
 {
-  // Boolean.prototype
-  setPrototypeProperty(booleanProto);
 }
 
-// ECMA 15.6.1
-Completion BooleanObject::execute(const List &args)
-{
-  Boolean b;
+// ------------------------------ BooleanPrototypeImp --------------------------
 
-  if (args.isEmpty())
-    b = Boolean(false);
-  else
-    b = args[0].toBoolean();
+// ECMA 15.6.4
+
+BooleanPrototypeImp::BooleanPrototypeImp(ExecState *exec,
+                                         ObjectPrototypeImp *objectProto,
+                                         FunctionPrototypeImp *funcProto)
+  : BooleanInstanceImp(Object(objectProto))
+{
+  Value protect(this);
+  // The constructor will be added later by InterpreterImp::InterpreterImp()
 
-  return Completion(ReturnValue, b);
+  put(exec,"toString", Object(new BooleanProtoFuncImp(exec,funcProto,BooleanProtoFuncImp::ToString,0)), DontEnum);
+  put(exec,"valueOf",  Object(new BooleanProtoFuncImp(exec,funcProto,BooleanProtoFuncImp::ValueOf,0)),  DontEnum);
+  setInternalValue(Boolean(false));
 }
 
-// ECMA 15.6.2
-Object BooleanObject::construct(const List &args)
-{
-  Boolean b;
-  if (args.size() > 0)
-    b = args.begin()->toBoolean();
-  else
-    b = Boolean(false);
 
-  return Object::create(BooleanClass, b);
+// ------------------------------ BooleanProtoFuncImp --------------------------
+
+BooleanProtoFuncImp::BooleanProtoFuncImp(ExecState *exec,
+                                         FunctionPrototypeImp *funcProto, int i, int len)
+  : InternalFunctionImp(funcProto), id(i)
+{
+  Value protect(this);
+  put(exec,"length",Number(len),DontDelete|ReadOnly|DontEnum);
 }
 
-// ECMA 15.6.4
-BooleanPrototype::BooleanPrototype(const Object& proto)
-  : ObjectImp(BooleanClass, Boolean(false), proto)
+
+bool BooleanProtoFuncImp::implementsCall() const
 {
-  // The constructor will be added later in BooleanObject's constructor
+  return true;
 }
 
-KJSO BooleanPrototype::get(const UString &p) const
+
+// ECMA 15.6.4.2 + 15.6.4.3
+Value BooleanProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &/*args*/)
 {
-  if (p == "toString")
-    return Function(new BooleanProtoFunc(ToString));
-  else if (p == "valueOf")
-    return Function(new BooleanProtoFunc(ValueOf));
+  // no generic function. "this" has to be a Boolean object
+  if (!thisObj.inherits(&BooleanInstanceImp::info)) {
+    Object err = Error::create(exec,TypeError);
+    exec->setException(err);
+    return err;
+  }
+
+  // execute "toString()" or "valueOf()", respectively
+
+  Value v = thisObj.internalValue();
+  assert(!v.isNull());
+
+  if (id == ToString)
+    return String(v.toString(exec));
   else
-    return Imp::get(p);
+    return Boolean(v.toBoolean(exec)); /* TODO: optimize for bool case */
 }
 
-BooleanProtoFunc::BooleanProtoFunc(int i)
-  : id(i)
+// ------------------------------ BooleanObjectImp -----------------------------
+
+
+BooleanObjectImp::BooleanObjectImp(ExecState *exec, FunctionPrototypeImp *funcProto,
+                                   BooleanPrototypeImp *booleanProto)
+  : InternalFunctionImp(funcProto)
 {
+  Value protect(this);
+  put(exec,"prototype", Object(booleanProto),DontEnum|DontDelete|ReadOnly);
+
+  // no. of arguments for constructor
+  put(exec,"length", Number(1), ReadOnly|DontDelete|DontEnum);
 }
 
-// ECMA 15.6.4.2 + 15.6.4.3
-Completion BooleanProtoFunc::execute(const List &)
-{
-  KJSO result;
 
-  Object thisObj = Object::dynamicCast(thisValue());
+bool BooleanObjectImp::implementsConstruct() const
+{
+  return true;
+}
 
-  // no generic function. "this" has to be a Boolean object
-  if (thisObj.isNull() || thisObj.getClass() != BooleanClass) {
-    result = Error::create(TypeError);
-    return Completion(ReturnValue, result);
-  }
+// ECMA 15.6.2
+Object BooleanObjectImp::construct(ExecState *exec, const List &args)
+{
+  Object proto = exec->interpreter()->builtinBooleanPrototype();
+  Object obj(new BooleanInstanceImp(proto));
 
-  // execute "toString()" or "valueOf()", respectively
-  KJSO v = thisObj.internalValue();
-  if (id == BooleanPrototype::ToString)
-    result = v.toString();
+  Boolean b;
+  if (args.size() > 0)
+    b = args.begin()->toBoolean(exec);
   else
-    result = v.toBoolean();
+    b = Boolean(false);
+
+  obj.setInternalValue(b);
+
+  return obj;
+}
+
+bool BooleanObjectImp::implementsCall() const
+{
+  return true;
+}
 
-  return Completion(ReturnValue, result);
+// ECMA 15.6.1
+Value BooleanObjectImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
+{
+  if (args.isEmpty())
+    return Boolean(false);
+  else
+    return Boolean(args[0].toBoolean(exec)); /* TODO: optimize for bool case */
 }
+
index 89dc4518cb25ed62e1cfe6365f033a8748366a4e..c395179c4c6c0541890d8e2f2c842e593df02671 100644 (file)
@@ -1,3 +1,4 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id$
  */
 
 #ifndef _BOOL_OBJECT_H_
 #define _BOOL_OBJECT_H_
 
-#include "object.h"
-#include "function.h"
+#include "internal.h"
+#include "function_object.h"
 
 namespace KJS {
 
-  class BooleanObject : public ConstructorImp {
+  class BooleanInstanceImp : public ObjectImp {
   public:
-    BooleanObject(const KJSO& funcProto, const KJSO &booleanProto);
-    Completion execute(const List &);
-    Object construct(const List &);
+    BooleanInstanceImp(const Object &proto);
+
+    virtual const ClassInfo *classInfo() const { return &info; }
+    static const ClassInfo info;
   };
 
-  class BooleanPrototype : public ObjectImp {
+  /**
+   * @internal
+   *
+   * The initial value of Boolean.prototype (and thus all objects created
+   * with the Boolean constructor
+   */
+  class BooleanPrototypeImp : public BooleanInstanceImp {
   public:
-    BooleanPrototype(const Object& proto);
-    virtual KJSO get(const UString &p) const;
-    enum { ToString, ValueOf };
+    BooleanPrototypeImp(ExecState *exec,
+                        ObjectPrototypeImp *objectProto,
+                        FunctionPrototypeImp *funcProto);
   };
 
-  class BooleanProtoFunc : public InternalFunctionImp {
+  /**
+   * @internal
+   *
+   * Class to implement all methods that are properties of the
+   * Boolean.prototype object
+   */
+  class BooleanProtoFuncImp : public InternalFunctionImp {
   public:
-    BooleanProtoFunc(int i);
-    Completion execute(const List &);
+    BooleanProtoFuncImp(ExecState *exec,
+                        FunctionPrototypeImp *funcProto, int i, int len);
+
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+
+    enum { ToString, ValueOf };
   private:
     int id;
   };
 
+  /**
+   * @internal
+   *
+   * The initial value of the the global variable's "Boolean" property
+   */
+  class BooleanObjectImp : public InternalFunctionImp {
+    friend class BooleanProtoFuncImp;
+  public:
+    BooleanObjectImp(ExecState *exec, FunctionPrototypeImp *funcProto,
+                     BooleanPrototypeImp *booleanProto);
+
+    virtual bool implementsConstruct() const;
+    virtual Object construct(ExecState *exec, const List &args);
+
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+  };
+
 }; // namespace
 
 #endif
index df79038e13f09e5ab818f7f451a4b6d49b70a974..2bed7e1eafb4abfc436f991bf1345db6a180c09d 100644 (file)
@@ -1,6 +1,8 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id$
  */
 
 #include "collector.h"
-#include "object.h"
 #include "internal.h"
 
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
+#ifdef KJS_DEBUG_MEM
+#include <typeinfo>
+#endif
 
 namespace KJS {
 
@@ -61,6 +67,12 @@ CollectorBlock* Collector::root = 0L;
 CollectorBlock* Collector::currentBlock = 0L;
 unsigned long Collector::filled = 0;
 unsigned long Collector::softLimit = KJS_MEM_INCREMENT;
+
+unsigned long Collector::timesFilled = 0;
+unsigned long Collector::increaseLimitAt = 1;
+
+bool Collector::memLimitReached = false;
+
 #ifdef KJS_DEBUG_MEM
 bool Collector::collecting = false;
 #endif
@@ -70,18 +82,35 @@ void* Collector::allocate(size_t s)
   if (s == 0)
     return 0L;
 
+  // Try and deal with memory requirements in a scalable way. Simple scripts
+  // should only require small amounts of memory, but for complex scripts we don't
+  // want to end up running the garbage collector hundreds of times a second.
   if (filled >= softLimit) {
+    timesFilled++;
     collect();
-    if (filled >= softLimit && softLimit < KJS_MEM_LIMIT) // we are actually using all this memory
+
+    if (filled >= softLimit && softLimit < KJS_MEM_LIMIT) {
+      // Even after collection we are still using more than the limit, so increase
+      // the limit
       softLimit *= 2;
+    }
+    else if (timesFilled == increaseLimitAt && increaseLimitAt < 128) {
+      // The allowed memory limit keeps getting reached (lots of objects created
+      // and deleted). Increase it a bit so GC gets run less often.
+      timesFilled = 0;
+      softLimit *= 2;
+      increaseLimitAt *= 2;
+    }
   }
 
   void *m = malloc(s);
+#ifdef KJS_DEBUG_MEM
+  //fprintf( stderr, "allocate: size=%d valueimp=%p\n",s,m);
+#endif
 
-  // hack to ensure obj is protected from GC before any constructors are run
-  // (prev = marked, next = gcallowed)
-  static_cast<Imp*>(m)->prev = 0;
-  static_cast<Imp*>(m)->next = 0;
+  // VI_CREATED and VI_GCALLOWED being unset ensure that value
+  // is protected from GC before any constructors are run
+  static_cast<ValueImp*>(m)->_flags = 0;
 
   if (!root) {
     root = new CollectorBlock(BlockSize);
@@ -98,7 +127,7 @@ void* Collector::allocate(size_t s)
 
   if (block->filled >= block->size) {
 #ifdef KJS_DEBUG_MEM
-    printf("allocating new block of size %d\n", block->size);
+    //fprintf( stderr, "allocating new block of size %d\n", block->size);
 #endif
     CollectorBlock *tmp = new CollectorBlock(BlockSize);
     block->next = tmp;
@@ -115,7 +144,8 @@ void* Collector::allocate(size_t s)
   block->filled++;
 
   if (softLimit >= KJS_MEM_LIMIT) {
-      KJScriptImp::setException("Out of memory");
+    memLimitReached = true;
+    fprintf(stderr,"Out of memory");
   }
 
   return m;
@@ -124,88 +154,125 @@ void* Collector::allocate(size_t s)
 /**
  * Mark-sweep garbage collection.
  */
-void Collector::collect()
+bool Collector::collect()
 {
 #ifdef KJS_DEBUG_MEM
-  printf("collecting %d objects total\n", Imp::count);
-  collecting = true;
+  fprintf(stderr,"Collector::collect()\n");
 #endif
-
-  // MARK: first set all ref counts to 0 ....
+  bool deleted = false;
+  // MARK: first unmark everything
   CollectorBlock *block = root;
   while (block) {
-#ifdef KJS_DEBUG_MEM
-    printf("cleaning block filled %d out of %d\n", block->filled, block->size);
-#endif
-    Imp **r = (Imp**)block->mem;
+    ValueImp **r = (ValueImp**)block->mem;
     assert(r);
     for (int i = 0; i < block->size; i++, r++)
       if (*r) {
-        (*r)->setMarked(false);
+        (*r)->_flags &= ~ValueImp::VI_MARKED;
       }
     block = block->next;
   }
 
-  // ... increase counter for all referenced objects recursively
+  // mark all referenced objects recursively
   // starting out from the set of root objects
-  if (KJScriptImp::hook) {
-    KJScriptImp *scr = KJScriptImp::hook;
+  if (InterpreterImp::s_hook) {
+    InterpreterImp *scr = InterpreterImp::s_hook;
     do {
+      //fprintf( stderr, "Collector marking interpreter %p\n",(void*)scr);
       scr->mark();
       scr = scr->next;
-    } while (scr != KJScriptImp::hook);
+    } while (scr != InterpreterImp::s_hook);
   }
 
   // mark any other objects that we wouldn't delete anyway
   block = root;
   while (block) {
-    Imp **r = (Imp**)block->mem;
+    ValueImp **r = (ValueImp**)block->mem;
     assert(r);
     for (int i = 0; i < block->size; i++, r++)
-      if (*r && (*r)->created() && ((*r)->refcount || !(*r)->gcAllowed()) && !(*r)->marked())
-        (*r)->mark();
+    {
+      ValueImp *imp = (*r);
+      // Check for created=true, marked=false and (gcallowed=false or refcount>0)
+      if (imp &&
+          (imp->_flags & (ValueImp::VI_CREATED|ValueImp::VI_MARKED)) == ValueImp::VI_CREATED &&
+          ( (imp->_flags & ValueImp::VI_GCALLOWED) == 0 || imp->refcount ) ) {
+        //fprintf( stderr, "Collector marking imp=%p\n",(void*)imp);
+        imp->mark();
+      }
+    }
     block = block->next;
   }
 
   // SWEEP: delete everything with a zero refcount (garbage)
   block = root;
   while (block) {
-    Imp **r = (Imp**)block->mem;
+    ValueImp **r = (ValueImp**)block->mem;
     int del = 0;
     for (int i = 0; i < block->size; i++, r++) {
-      if (*r && ((*r)->refcount == 0) && !(*r)->marked() && (*r)->gcAllowed()) {
-       // emulate destructing part of 'operator delete()'
-       (*r)->~Imp();
-       free(*r);
-       *r = 0L;
-       del++;
+      ValueImp *imp = (*r);
+      // Can delete if refcount==0, created==true, gcAllowed==true, and marked==false
+      // Make sure to update the test if you add more bits to _flags.
+      if (imp &&
+          !imp->refcount && imp->_flags == (ValueImp::VI_GCALLOWED | ValueImp::VI_CREATED)) {
+        // emulate destructing part of 'operator delete()'
+        //fprintf( stderr, "Collector::deleting ValueImp %p (%s)\n", (void*)imp, typeid(*imp).name());
+        imp->~ValueImp();
+        free(imp);
+        *r = 0L;
+        del++;
       }
     }
     filled -= del;
     block->filled -= del;
     block = block->next;
+    if (del)
+      deleted = true;
   }
 
-  // delete the emtpy containers
+  // delete the empty containers
   block = root;
   while (block) {
     CollectorBlock *next = block->next;
     if (block->filled == 0) {
       if (block->prev)
-       block->prev->next = next;
+        block->prev->next = next;
       if (block == root)
-       root = next;
+        root = next;
       if (next)
-       next->prev = block->prev;
+        next->prev = block->prev;
       if (block == currentBlock) // we don't want a dangling pointer
-       currentBlock = 0L;
+        currentBlock = 0L;
       assert(block != root);
       delete block;
     }
     block = next;
   }
+#if 0
+  // This is useful to track down memory leaks
+  static int s_count = 0;
+  fprintf(stderr, "Collector done (was run %d)\n",s_count);
+  if (s_count++ % 50 == 2)
+    finalCheck();
+#endif
+  return deleted;
+}
 
 #ifdef KJS_DEBUG_MEM
-  collecting = false;
-#endif
+void Collector::finalCheck()
+{
+  CollectorBlock *block = root;
+  while (block) {
+    ValueImp **r = (ValueImp**)block->mem;
+    for (int i = 0; i < block->size; i++, r++) {
+      if (*r ) {
+        fprintf( stderr, "Collector::finalCheck() still having ValueImp %p (%s)  [marked:%d gcAllowed:%d created:%d refcount:%d]\n",
+                 (void*)(*r), typeid( **r ).name(),
+                 (bool)((*r)->_flags & ValueImp::VI_MARKED),
+                 (bool)((*r)->_flags & ValueImp::VI_GCALLOWED),
+                 (bool)((*r)->_flags & ValueImp::VI_CREATED),
+                 (*r)->refcount);
+      }
+    }
+    block = block->next;
+  }
 }
+#endif
index 7e88e7fe1b3b635cbfa108774b3713f928de693b..86cc2100988793d279318f51c000e02c1f86d083 100644 (file)
@@ -1,6 +1,8 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -15,6 +17,8 @@
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id$
  */
 
 #ifndef _KJSCOLLECTOR_H_
 
 #include <stdlib.h>
 
+// for DEBUG_*
+#include "value.h"
+#include "object.h"
+#include "types.h"
+#include "interpreter.h"
+
 namespace KJS {
 
-  class Imp;
   class CollectorBlock;
 
   /**
@@ -65,14 +74,14 @@ namespace KJS {
     /**
      * Run the garbage collection. This involves calling the delete operator
      * on each object and freeing the used memory.
-     * In the current implemenation this will basically free all registered
-     * object regardless whether they are still references by others or not.
-     * 
      */
-    static void collect();
+    static bool collect();
     static int size() { return filled; }
+    static bool outOfMemory() { return memLimitReached; }
 
 #ifdef KJS_DEBUG_MEM
+    /** Check that nothing is left when the last interpreter gets deleted */
+    static void finalCheck();
     /**
      * @internal
      */
@@ -83,6 +92,9 @@ namespace KJS {
     static CollectorBlock* currentBlock;
     static unsigned long filled;
     static unsigned long softLimit;
+    static unsigned long timesFilled;
+    static unsigned long increaseLimitAt;
+    static bool memLimitReached;
     enum { BlockSize = 100 };
   };
 
diff --git a/JavaScriptCore/kjs/create_hash_table b/JavaScriptCore/kjs/create_hash_table
new file mode 100755 (executable)
index 0000000..689e777
--- /dev/null
@@ -0,0 +1,161 @@
+#! /usr/bin/perl -w
+#
+# Static Hashtable Generator
+#
+# (c) 2000-2002 by Harri Porten <porten@kde.org> and
+#                  David Faure <faure@kde.org>
+
+$file = $ARGV[0];
+shift;
+my $findSize = 0;
+my $includelookup = 0;
+# Use -s as second argument to make it try many hash sizes
+$findSize = 1 if (defined($ARGV[0]) && $ARGV[0] eq "-s");
+# Use -i as second argument to make it include "lookup.h"
+$includelookup = 1 if (defined($ARGV[0]) && $ARGV[0] eq "-i");
+print STDERR "Creating hashtable for $file\n";
+open(IN, $file) or die "No such file $file";
+
+@keys = ();
+@values = ();
+@attrs = ();
+@params = ();
+
+my $inside = 0;
+my $name;
+my $size;
+my $hashsize;
+my $banner = 0;
+sub calcTable();
+sub output();
+sub hashValue($);
+
+while (<IN>) {
+  chop;
+  s/^\s*//g;
+  if (/^\#|^$/) {
+      # comment. do nothing
+    } elsif (/^\@begin\s*(\w+)\s*(\d+)\s*$/ && !$inside) {
+      $inside = 1;
+      $name = $1;
+      $hashsize = $2;
+    } elsif (/^\@end\s*$/ && $inside) {
+
+      if($findSize) {
+       my $entriesnum=@keys;
+        print STDERR "Table: $name   $entriesnum entries\n";
+       for( $i=3 ; $i<79 ; ++$i) { $hashsize=$i ; calcTable(); }
+      } else {
+        calcTable();
+      }
+
+      output();
+      @keys = ();
+      @values = ();
+      @attrs = ();
+      @params = ();
+      $inside = 0;
+    } elsif (/^([\w\[\=\]]+)\s*([\w\:-]+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) {
+      my $key = $1;
+      my $val = $2;
+      my $att = $3;
+      my $param = $4;
+      push(@keys, $key);
+      push(@values, $val);
+      printf STDERR "WARNING: Number of arguments missing for $key/$val\n"
+        if ( $att =~ m/Function/ && length($param) == 0);
+      push(@attrs, length($att) > 0 ? $att : "0");
+      push(@params, length($param) > 0 ? $param : "0");
+    } elsif ($inside) {
+      die "invalid data";
+    }
+}
+
+die "missing closing \@end" if ($inside);
+
+sub calcTable() {
+  @table = ();
+  @links = ();
+  $size = $hashsize;
+  my $collisions = 0;
+  my $maxdepth = 0;
+  my $i = 0;
+  foreach $key (@keys) {
+    my $depth = 0;
+    my $h = hashValue($key) % $hashsize;
+    while (defined($table[$h])) {
+      if (defined($links[$h])) {
+       $h = $links[$h];
+       $depth++;
+      } else {
+       $collisions++;
+       $links[$h] = $size;
+       $h = $size;
+       $size++;
+      }
+    }
+    $table[$h] = $i;
+    $i++;
+    $maxdepth = $depth if ( $depth > $maxdepth);
+  }
+
+  if ($findSize) {
+    my $emptycount = 0;
+    foreach $entry (@table) {
+      $emptycount++ if (!defined($entry));
+    }
+    print STDERR "Hashsize: $hashsize  Total Size: $size Empty: $emptycount MaxDepth: $maxdepth Collisions: $collisions\n";
+  }
+#  my $i = 0;
+#  foreach $entry (@table) {
+#    print "$i " . $entry;
+#    print " -> " . $links[$i] if (defined($links[$i]));
+#    print "\n";
+#    $i++;
+#  }
+}
+
+sub hashValue($) {
+  @chars = split(/ */, $_[0]);
+  my $val = 0;
+  foreach $c (@chars) {
+    $val += ord($c);
+  }
+  return $val;
+}
+
+sub output() {
+  if (!$banner) {
+    $banner = 1;
+    print "/* Automatically generated from $file using $0. DO NOT EDIT ! */\n";
+  }
+
+  print "\n#include \"lookup.h\"\n" if ($includelookup);
+  print "\nnamespace KJS {\n";
+  print "\nconst struct HashEntry ${name}Entries[] = {\n";
+  my $i = 0;
+  foreach $entry (@table) {
+    if (defined($entry)) {
+      my $key = $keys[$entry];
+      print "   \{ \"" . $key . "\"";
+      print ", " . $values[$entry];
+      print ", " . $attrs[$entry];
+      print ", " . $params[$entry];
+      print ", ";
+      if (defined($links[$i])) {
+       print "&${name}Entries[$links[$i]]" . " \}";
+      } else {
+       print "0 \}"
+      }
+    } else {
+      print "   \{ 0, 0, 0, 0, 0 \}";
+    }
+    print "," unless ($i == $size - 1);
+    print "\n";
+    $i++;
+  }
+  print "};\n";
+  print "\nconst struct HashTable $name = ";
+  print "\{ 2, $size, ${name}Entries, $hashsize \};\n\n";
+  print "}; // namespace\n";
+}
index ab8150497d372dd4c67072d27a1a09830993ebd1..c3f757884ae565d535027a7a3cf8788d3f8baa10 100644 (file)
@@ -1,3 +1,4 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
@@ -15,6 +16,8 @@
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id$
  */
 
 #ifdef HAVE_CONFIG_H
 #include <math.h>
 #include <string.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <locale.h>
+#include <ctype.h>
 
-#include "kjs.h"
 #include "date_object.h"
+#include "error_object.h"
+#include "operations.h"
 
-namespace KJS {
-
-  class DateObjectFunc : public InternalFunctionImp {
-  public:
-    DateObjectFunc(int i) : id(i) { };
-    Completion execute(const List &);
-    enum { Parse, UTC };
-  private:
-    int id;
-  };
-
-  class DateProtoFunc : public InternalFunctionImp {
-  public:
-    DateProtoFunc(int i, bool u);
-    Completion execute(const List &);
-    enum { ToString, ToDateString, ToTimeString, ToLocaleString,
-          ToLocaleDateString, ToLocaleTimeString, ValueOf, GetTime,
-          GetFullYear, GetMonth, GetDate, GetDay, GetHours, GetMinutes,
-          GetSeconds, GetMilliSeconds, GetTimezoneOffset, SetTime,
-          SetMilliSeconds, SetSeconds, SetMinutes, SetHours, SetDate,
-          SetMonth, SetFullYear, ToUTCString,
-          // non-normative properties (Appendix B)
-          GetYear, SetYear, ToGMTString };
-  private:
-    int id;
-    bool utc;
-  };
-
-  // helper functions
-  KJSO parseDate(const String &s);
-  KJSO timeClip(const KJSO &t);
-};
+#include "date_object.lut.h"
 
 using namespace KJS;
 
-KJSO KJS::parseDate(const String &s)
-{
-  UString u = s.value();
-  int firstSlash = u.find('/');
-  if ( firstSlash == -1 )
-  {
-    /* TODO parse dates like "December 25, 1995 23:15:00"*/
-    fprintf(stderr,"KJS::parseDate parsing for this format isn't implemented\n%s", u.ascii());
-    return Number(0);
-  }
-  else
-  {
-    // Found 12/31/2099 on some website -> obviously MM/DD/YYYY
-    int month = u.substr(0,firstSlash).toULong();
-    int secondSlash = u.find('/',firstSlash+1);
-    //fprintf(stdout,"KJS::parseDate firstSlash=%d, secondSlash=%d\n", firstSlash, secondSlash);
-    if ( secondSlash == -1 )
-    {
-      fprintf(stderr,"KJS::parseDate parsing for this format isn't implemented\n%s", u.ascii());
-      return Number(0);
-    }
-    int day = u.substr(firstSlash+1,secondSlash-firstSlash-1).toULong();
-    int year = u.substr(secondSlash+1).toULong();
-    //fprintf(stdout,"KJS::parseDate day=%d, month=%d, year=%d\n", day, month, year);
-    struct tm t;
-    memset( &t, 0, sizeof(t) );
-    year = (year > 2037) ? 2037 : year; // mktime is limited to 2037 !!!
-    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
-    t.tm_mon = month-1; // mktime wants 0-11 for some reason
-    t.tm_mday = day;
-    time_t seconds = mktime(&t);
-    if ( seconds == -1 )
-    {
-      fprintf(stderr,"KJS::parseDate mktime returned -1.\n%s", u.ascii());
-      return Undefined();
-    }
-    else
-      return Number(seconds * 1000.0);
-  }
-}
+// ------------------------------ DateInstanceImp ------------------------------
 
-KJSO KJS::timeClip(const KJSO &t)
-{
-  /* TODO */
-  return t;
-}
+const ClassInfo DateInstanceImp::info = {"Date", 0, 0, 0};
 
-DateObject::DateObject(const Object& funcProto, const Object &dateProto)
-    : ConstructorImp(funcProto, 7)
+DateInstanceImp::DateInstanceImp(const Object &proto)
+  : ObjectImp(proto)
 {
-  // ECMA 15.9.4.1 Date.prototype
-  setPrototypeProperty(dateProto);
 }
 
-// ECMA 15.9.2
-Completion DateObject::execute(const List &)
-{
-  time_t t = time(0L);
-  UString s(ctime(&t));
-
-  // return formatted string minus trailing \n
-  return Completion(ReturnValue, String(s.substr(0, s.size() - 1)));
-}
+// ------------------------------ DatePrototypeImp -----------------------------
+
+const ClassInfo DatePrototypeImp::info = {"Date", 0, &dateTable, 0};
+
+/* Source for date_object.lut.h
+   We use a negative ID to denote the "UTC" variant.
+@begin dateTable 61
+  toString             DateProtoFuncImp::ToString              DontEnum|Function       0
+  toUTCString          -DateProtoFuncImp::ToString             DontEnum|Function       0
+  toDateString         DateProtoFuncImp::ToDateString          DontEnum|Function       0
+  toTimeString         DateProtoFuncImp::ToTimeString          DontEnum|Function       0
+  toLocaleString       DateProtoFuncImp::ToLocaleString        DontEnum|Function       0
+  toLocaleDateString   DateProtoFuncImp::ToLocaleDateString    DontEnum|Function       0
+  toLocaleTimeString   DateProtoFuncImp::ToLocaleTimeString    DontEnum|Function       0
+  valueOf              DateProtoFuncImp::ValueOf               DontEnum|Function       0
+  getTime              DateProtoFuncImp::GetTime               DontEnum|Function       0
+  getFullYear          DateProtoFuncImp::GetFullYear           DontEnum|Function       0
+  getUTCFullYear       -DateProtoFuncImp::GetFullYear          DontEnum|Function       0
+  toGMTString          DateProtoFuncImp::ToGMTString           DontEnum|Function       0
+  getMonth             DateProtoFuncImp::GetMonth              DontEnum|Function       0
+  getUTCMonth          -DateProtoFuncImp::GetMonth             DontEnum|Function       0
+  getDate              DateProtoFuncImp::GetDate               DontEnum|Function       0
+  getUTCDate           -DateProtoFuncImp::GetDate              DontEnum|Function       0
+  getDay               DateProtoFuncImp::GetDay                DontEnum|Function       0
+  getUTCDay            -DateProtoFuncImp::GetDay               DontEnum|Function       0
+  getHours             DateProtoFuncImp::GetHours              DontEnum|Function       0
+  getUTCHours          -DateProtoFuncImp::GetHours             DontEnum|Function       0
+  getMinutes           DateProtoFuncImp::GetMinutes            DontEnum|Function       0
+  getUTCMinutes                -DateProtoFuncImp::GetMinutes           DontEnum|Function       0
+  getSeconds           DateProtoFuncImp::GetSeconds            DontEnum|Function       0
+  getUTCSeconds                -DateProtoFuncImp::GetSeconds           DontEnum|Function       0
+  getMilliseconds      DateProtoFuncImp::GetMilliSeconds       DontEnum|Function       0
+  getUTCMilliseconds   -DateProtoFuncImp::GetMilliSeconds      DontEnum|Function       0
+  getTimezoneOffset    DateProtoFuncImp::GetTimezoneOffset     DontEnum|Function       0
+  setTime              DateProtoFuncImp::SetTime               DontEnum|Function       1
+  setMilliseconds      DateProtoFuncImp::SetMilliSeconds       DontEnum|Function       1
+  setUTCMilliseconds   -DateProtoFuncImp::SetMilliSeconds      DontEnum|Function       1
+  setSeconds           DateProtoFuncImp::SetSeconds            DontEnum|Function       2
+  setUTCSeconds                -DateProtoFuncImp::SetSeconds           DontEnum|Function       2
+  setMinutes           DateProtoFuncImp::SetMinutes            DontEnum|Function       3
+  setUTCMinutes                -DateProtoFuncImp::SetMinutes           DontEnum|Function       3
+  setHours             DateProtoFuncImp::SetHours              DontEnum|Function       4
+  setUTCHours          -DateProtoFuncImp::SetHours             DontEnum|Function       4
+  setDate              DateProtoFuncImp::SetDate               DontEnum|Function       1
+  setUTCDate           -DateProtoFuncImp::SetDate              DontEnum|Function       1
+  setMonth             DateProtoFuncImp::SetMonth              DontEnum|Function       2
+  setUTCMonth          -DateProtoFuncImp::SetMonth             DontEnum|Function       2
+  setFullYear          DateProtoFuncImp::SetFullYear           DontEnum|Function       3
+  setUTCFullYear       -DateProtoFuncImp::SetFullYear          DontEnum|Function       3
+  setYear              DateProtoFuncImp::SetYear               DontEnum|Function       1
+  getYear              DateProtoFuncImp::GetYear               DontEnum|Function       0
+  toGMTString          DateProtoFuncImp::ToGMTString           DontEnum|Function       0
+@end
+*/
+// ECMA 15.9.4
 
-// ECMA 15.9.3
-Object DateObject::construct(const List &args)
+DatePrototypeImp::DatePrototypeImp(ExecState *,
+                                   ObjectPrototypeImp *objectProto)
+  : DateInstanceImp(Object(objectProto))
 {
-  KJSO value;
-
-  int numArgs = args.size();
-
-  if (numArgs == 0) { // new Date() ECMA 15.9.3.3
-#if HAVE_SYS_TIMEB_H
-#  if defined(__BORLANDC__)
-    struct timeb timebuffer;
-    ftime(&timebuffer);
-#  else
-    struct _timeb timebuffer;
-    _ftime(&timebuffer);
-#  endif
-    double utc = floor((double)timebuffer.time * 1000.0 + (double)timebuffer.millitm);
-#else
-    struct timeval tv;
-    gettimeofday(&tv, 0L);
-    double utc = floor((double)tv.tv_sec * 1000.0 + (double)tv.tv_usec / 1000.0);
-#endif
-    value = Number(utc);
-  } else if (numArgs == 1) {
-    KJSO p = args[0].toPrimitive();
-    if (p.isA(StringType))
-      value = parseDate(p.toString());
-    else
-      value = p.toNumber();
-  } else {
-    struct tm t;
-    memset(&t, 0, sizeof(t));
-    Number y = args[0].toNumber();
-    /* TODO: check for NaN */
-    int year = y.toInt32();
-    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
-    t.tm_mon = args[1].toInt32();
-    t.tm_mday = (numArgs >= 3) ? args[2].toInt32() : 1;
-    t.tm_hour = (numArgs >= 4) ? args[3].toInt32() : 0;
-    t.tm_min = (numArgs >= 5) ? args[4].toInt32() : 0;
-    t.tm_sec = (numArgs >= 6) ? args[5].toInt32() : 0;
-    t.tm_isdst = -1;
-    int ms = (numArgs >= 7) ? args[6].toInt32() : 0;
-    value = Number(mktime(&t) * 1000.0 + ms);
-  }
-
-  return Object::create(DateClass, timeClip(value));
+  Value protect(this);
+  setInternalValue(Number(NaN));
+  // The constructor will be added later, after DateObjectImp has been built
 }
 
-KJSO DateObject::get(const UString &p) const
+Value DatePrototypeImp::get(ExecState *exec, const UString &propertyName) const
 {
-  int id;
-
-  if (p == "parse")
-    id = DateObjectFunc::Parse;
-  else if (p == "UTC")
-    id = DateObjectFunc::UTC;
-  else
-    return Imp::get(p);
-
-  return Function(new DateObjectFunc(id));
+  return lookupGetFunction<DateProtoFuncImp, ObjectImp>( exec, propertyName, &dateTable, this );
 }
 
-// ECMA 15.9.4.2 - 3
-Completion DateObjectFunc::execute(const List &args)
-{
-  KJSO result;
-
-  if (id == Parse)
-    if (args[0].isA(StringType))
-      result = parseDate(args[0].toString());
-    else
-      result = Undefined();
-  else {
-    struct tm t;
-    memset(&t, 0, sizeof(t));
-    int n = args.size();
-    Number y = args[0].toNumber();
-    /* TODO: check for NaN */
-    int year = y.toInt32();
-    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
-    t.tm_mon = args[1].toInt32();
-    t.tm_mday = (n >= 3) ? args[2].toInt32() : 1;
-    t.tm_hour = (n >= 4) ? args[3].toInt32() : 0;
-    t.tm_min = (n >= 5) ? args[4].toInt32() : 0;
-    t.tm_sec = (n >= 6) ? args[5].toInt32() : 0;
-    int ms = (n >= 7) ? args[6].toInt32() : 0;
-    result = Number(mktime(&t) * 1000.0 + ms);
-  }
-
-  return Completion(ReturnValue, result);
-}
+// ------------------------------ DateProtoFuncImp -----------------------------
 
-// ECMA 15.9.4
-DatePrototype::DatePrototype(const Object& proto)
-  : ObjectImp(DateClass, Number(NaN), proto)
+DateProtoFuncImp::DateProtoFuncImp(ExecState *exec, int i, int len)
+  : InternalFunctionImp(
+    static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
+    ), id(abs(i)), utc(i<0)
+  // We use a negative ID to denote the "UTC" variant.
 {
-  // The constructor will be added later in DateObject's constructor
+  Value protect(this);
+  put(exec,"length",Number(len),DontDelete|ReadOnly|DontEnum);
 }
 
-KJSO DatePrototype::get(const UString &p) const
+bool DateProtoFuncImp::implementsCall() const
 {
-  int id;
-
-  if (p == "toString" || p == "toUTCString")
-    id = DateProtoFunc::ToString;
-  else if (p == "toDateString")
-    id = DateProtoFunc::ToDateString;
-  else if (p == "toTimeString")
-    id = DateProtoFunc::ToTimeString;
-  else if (p == "toLocaleString")
-    id = DateProtoFunc::ToLocaleString;
-  else if (p == "toLocaleDateString")
-    id = DateProtoFunc::ToLocaleDateString;
-  else if (p == "toLocaleTimeString")
-    id = DateProtoFunc::ToLocaleTimeString;
-  else if (p == "valueOf")
-    id = DateProtoFunc::ValueOf;
-  else if (p == "getTime")
-    id = DateProtoFunc::GetTime;
-  else if (p == "getFullYear" || p == "getUTCFullYear")
-    id = DateProtoFunc::GetFullYear;
-  else if (p == "toGMTString")
-    id = DateProtoFunc::ToGMTString;
-  else if (p == "getMonth" || p == "getUTCMonth")
-    id = DateProtoFunc::GetMonth;
-  else if (p == "getDate" || p == "getUTCDate")
-    id = DateProtoFunc::GetDate;
-  else if (p == "getDay" || p == "getUTCDay")
-    id = DateProtoFunc::GetDay;
-  else if (p == "getHours" || p == "getUTCHours")
-    id = DateProtoFunc::GetHours;
-  else if (p == "getMinutes" || p == "getUTCMinutes")
-    id = DateProtoFunc::GetMinutes;
-  else if (p == "getSeconds" || p == "getUTCSeconds")
-    id = DateProtoFunc::GetSeconds;
-  else if (p == "getMilliseconds" || p == "getUTCMilliseconds")
-    id = DateProtoFunc::GetMilliSeconds;
-  else if (p == "getTimezoneOffset")
-    id = DateProtoFunc::GetTimezoneOffset;
-  else if (p == "setTime")
-    id = DateProtoFunc::SetTime;
-  else if (p == "setMilliseconds" || p == "setUTCMilliseconds")
-    id = DateProtoFunc::SetMilliSeconds;
-  else if (p == "setSeconds" || p == "setUTCSeconds")
-    id = DateProtoFunc::SetSeconds;
-  else if (p == "setMinutes" || p == "setUTCMinutes")
-    id = DateProtoFunc::SetMinutes;
-  else if (p == "setHours" || p == "setUTCHours")
-    id = DateProtoFunc::SetHours;
-  else if (p == "setDate" || p == "setUTCDate")
-    id = DateProtoFunc::SetDate;
-  else if (p == "setMonth" || p == "setUTCMonth")
-    id = DateProtoFunc::SetMonth;
-  else if (p == "setFullYear" || p == "setUTCFullYear")
-    id = DateProtoFunc::SetFullYear;
-  else if (p == "setYear" )
-    id = DateProtoFunc::SetYear;
-  // non-normative
-  else if (p == "getYear")
-    id = DateProtoFunc::GetYear;
-  else if (p == "toGMTString")
-    id = DateProtoFunc::ToGMTString;
-  else
-    return Undefined();
-
-  bool utc = (p.find("UTC") >= 0) ? true : false;
-  return Function(new DateProtoFunc(id, utc));
+  return true;
 }
 
-DateProtoFunc::DateProtoFunc(int i, bool u) : id(i), utc(u)
+Value DateProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
 {
-}
+  if ((id == ToString || id == ValueOf || id == GetTime || id == SetTime) &&
+      !thisObj.inherits(&DateInstanceImp::info)) {
+    // non-generic function called on non-date object
+
+    // ToString and ValueOf are generic according to the spec, but the mozilla
+    // tests suggest otherwise...
+    Object err = Error::create(exec,TypeError);
+    exec->setException(err);
+    return err;
+  }
 
-Completion DateProtoFunc::execute(const List &args)
-{
-  KJSO result;
+
+  Value result;
   UString s;
   const int bufsize=100;
   char timebuffer[bufsize];
   char *oldlocale = setlocale(LC_TIME,NULL);
   if (!oldlocale)
     oldlocale = setlocale(LC_ALL, NULL);
-  Object thisObj = Object::dynamicCast(thisValue());
-  KJSO v = thisObj.internalValue();
-  double milli = v.toNumber().value();
+  Value v = thisObj.internalValue();
+  double milli = v.toNumber(exec);
   time_t tv = (time_t) floor(milli / 1000.0);
   int ms = int(milli - tv * 1000.0);
 
@@ -353,9 +197,9 @@ Completion DateProtoFunc::execute(const List &args)
   case ToTimeString:
   case ToGMTString:
     setlocale(LC_TIME,"C");
-    if (id == DateProtoFunc::ToDateString) {
+    if (id == DateProtoFuncImp::ToDateString) {
       strftime(timebuffer, bufsize, "%x",t);
-    } else if (id == DateProtoFunc::ToTimeString) {
+    } else if (id == DateProtoFuncImp::ToTimeString) {
       strftime(timebuffer, bufsize, "%X",t);
     } else {
       t = gmtime(&tv);
@@ -380,13 +224,14 @@ Completion DateProtoFunc::execute(const List &args)
     result = Number(milli);
     break;
   case GetTime:
-    if (thisObj.getClass() == DateClass)
-      result = Number(milli);
-    else
-      result = Error::create(TypeError);
+    result = Number(milli);
     break;
   case GetYear:
-    result = Number(t->tm_year);
+    // IE returns the full year even in getYear.
+    if ( exec->interpreter()->compatMode() == Interpreter::IECompat )
+      result = Number(1900 + t->tm_year);
+    else
+      result = Number(t->tm_year);
     break;
   case GetFullYear:
     result = Number(1900 + t->tm_year);
@@ -410,7 +255,7 @@ Completion DateProtoFunc::execute(const List &args)
     result = Number(t->tm_sec);
     break;
   case GetMilliSeconds:
-    result = Undefined();
+    result = Number(ms);
     break;
   case GetTimezoneOffset:
 #if defined BSD || defined(__APPLE__)
@@ -425,33 +270,33 @@ Completion DateProtoFunc::execute(const List &args)
 #endif
     break;
   case SetTime:
-    milli = args[0].round();
+    milli = roundValue(exec,args[0]);
     result = Number(milli);
     thisObj.setInternalValue(result);
     break;
   case SetMilliSeconds:
-    ms = args[0].toInt32();
+    ms = args[0].toInt32(exec);
     break;
   case SetSeconds:
-    t->tm_sec = args[0].toInt32();
+    t->tm_sec = args[0].toInt32(exec);
     break;
   case SetMinutes:
-    t->tm_min = args[0].toInt32();
+    t->tm_min = args[0].toInt32(exec);
     break;
   case SetHours:
-    t->tm_hour = args[0].toInt32();
+    t->tm_hour = args[0].toInt32(exec);
     break;
   case SetDate:
-    t->tm_mday = args[0].toInt32();
+    t->tm_mday = args[0].toInt32(exec);
     break;
   case SetMonth:
-    t->tm_mon = args[0].toInt32();
+    t->tm_mon = args[0].toInt32(exec);
     break;
   case SetFullYear:
-    t->tm_year = args[0].toInt32() - 1900;
+    t->tm_year = args[0].toInt32(exec) - 1900;
     break;
   case SetYear:
-    t->tm_year = args[0].toInt32() >= 1900 ? args[0].toInt32() - 1900 : args[0].toInt32();
+    t->tm_year = args[0].toInt32(exec) >= 1900 ? args[0].toInt32(exec) - 1900 : args[0].toInt32(exec);
     break;
   }
 
@@ -462,5 +307,482 @@ Completion DateProtoFunc::execute(const List &args)
     thisObj.setInternalValue(result);
   }
 
-  return Completion(ReturnValue, result);
+  return result;
+}
+
+// ------------------------------ DateObjectImp --------------------------------
+
+// TODO: MakeTime (15.9.11.1) etc. ?
+
+DateObjectImp::DateObjectImp(ExecState *exec,
+                             FunctionPrototypeImp *funcProto,
+                             DatePrototypeImp *dateProto)
+  : InternalFunctionImp(funcProto)
+{
+  Value protect(this);
+  // ECMA 15.9.4.1 Date.prototype
+  put(exec,"prototype", Object(dateProto), DontEnum|DontDelete|ReadOnly);
+
+  put(exec,"parse", Object(new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::Parse, 1)), DontEnum);
+  put(exec,"UTC",   Object(new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::UTC,   7)),   DontEnum);
+
+  // no. of arguments for constructor
+  put(exec,"length", Number(7), ReadOnly|DontDelete|DontEnum);
+}
+
+bool DateObjectImp::implementsConstruct() const
+{
+  return true;
+}
+
+// ECMA 15.9.3
+Object DateObjectImp::construct(ExecState *exec, const List &args)
+{
+  int numArgs = args.size();
+
+#ifdef KJS_VERBOSE
+  fprintf(stderr,"DateObjectImp::construct - %d args\n", numArgs);
+#endif
+  Value value;
+
+  if (numArgs == 0) { // new Date() ECMA 15.9.3.3
+#if HAVE_SYS_TIMEB_H
+#  if defined(__BORLANDC__)
+    struct timeb timebuffer;
+    ftime(&timebuffer);
+#  else
+    struct _timeb timebuffer;
+    _ftime(&timebuffer);
+#  endif
+    double utc = floor((double)timebuffer.time * 1000.0 + (double)timebuffer.millitm);
+#else
+    struct timeval tv;
+    gettimeofday(&tv, 0L);
+    double utc = floor((double)tv.tv_sec * 1000.0 + (double)tv.tv_usec / 1000.0);
+#endif
+    value = Number(utc);
+  } else if (numArgs == 1) {
+    UString s = args[0].toString(exec);
+    double d = s.toDouble();
+    if (isNaN(d))
+      value = parseDate(s);
+    else
+      value = Number(d);
+  } else {
+    struct tm t;
+    memset(&t, 0, sizeof(t));
+    Number y = args[0].toNumber(exec);
+    // TODO: check for NaN
+    int year = y.toInt32(exec);
+    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
+    t.tm_mon = args[1].toInt32(exec);
+    t.tm_mday = (numArgs >= 3) ? args[2].toInt32(exec) : 1;
+    t.tm_hour = (numArgs >= 4) ? args[3].toInt32(exec) : 0;
+    t.tm_min = (numArgs >= 5) ? args[4].toInt32(exec) : 0;
+    t.tm_sec = (numArgs >= 6) ? args[5].toInt32(exec) : 0;
+    t.tm_isdst = -1;
+    int ms = (numArgs >= 7) ? args[6].toInt32(exec) : 0;
+    value = Number(mktime(&t) * 1000.0 + ms);
+  }
+
+  Object proto = exec->interpreter()->builtinDatePrototype();
+  Object ret(new DateInstanceImp(proto));
+  ret.setInternalValue(timeClip(value));
+  return ret;
 }
+
+bool DateObjectImp::implementsCall() const
+{
+  return true;
+}
+
+// ECMA 15.9.2
+Value DateObjectImp::call(ExecState */*exec*/, Object &/*thisObj*/, const List &/*args*/)
+{
+#ifdef KJS_VERBOSE
+  fprintf(stderr,"DateObjectImp::call - current time\n");
+#endif
+  time_t t = time(0L);
+  UString s(ctime(&t));
+
+  // return formatted string minus trailing \n
+  return String(s.substr(0, s.size() - 1));
+}
+
+// ------------------------------ DateObjectFuncImp ----------------------------
+
+DateObjectFuncImp::DateObjectFuncImp(ExecState *exec, FunctionPrototypeImp *funcProto,
+                                     int i, int len)
+  : InternalFunctionImp(funcProto), id(i)
+{
+  Value protect(this);
+  put(exec,"length",Number(len),DontDelete|ReadOnly|DontEnum);
+}
+
+bool DateObjectFuncImp::implementsCall() const
+{
+  return true;
+}
+
+// ECMA 15.9.4.2 - 3
+Value DateObjectFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
+{
+  if (id == Parse) {
+    if (args[0].type() == StringType)
+      return parseDate(args[0].toString(exec));
+    else
+      return Undefined();
+  }
+  else { // UTC
+    struct tm t;
+    memset(&t, 0, sizeof(t));
+    int n = args.size();
+    Number y = args[0].toNumber(exec);
+    // TODO: check for NaN
+    int year = y.toInt32(exec);
+    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
+    t.tm_mon = args[1].toInt32(exec);
+    t.tm_mday = (n >= 3) ? args[2].toInt32(exec) : 1;
+    t.tm_hour = (n >= 4) ? args[3].toInt32(exec) : 0;
+    t.tm_min = (n >= 5) ? args[4].toInt32(exec) : 0;
+    t.tm_sec = (n >= 6) ? args[5].toInt32(exec) : 0;
+    int ms = (n >= 7) ? args[6].toInt32(exec) : 0;
+    return Number(mktime(&t) * 1000.0 + ms);
+  }
+}
+
+// -----------------------------------------------------------------------------
+
+
+Value KJS::parseDate(const String &s)
+{
+  UString u = s.value();
+#ifdef KJS_VERBOSE
+  fprintf(stderr,"KJS::parseDate %s\n",u.ascii());
+#endif
+  int firstSlash = u.find('/');
+  if ( firstSlash == -1 )
+  {
+    time_t seconds = KRFCDate_parseDate( u );
+#ifdef KJS_VERBOSE
+    fprintf(stderr,"KRFCDate_parseDate returned seconds=%d\n",seconds);
+#endif
+    if ( seconds == -1 )
+      return Undefined();
+    else
+      return Number(seconds * 1000.0);
+  }
+  else
+  {
+    // Found 12/31/2099 on some website -> obviously MM/DD/YYYY
+    int month = u.substr(0,firstSlash).toULong();
+    int secondSlash = u.find('/',firstSlash+1);
+    //fprintf(stdout,"KJS::parseDate firstSlash=%d, secondSlash=%d\n", firstSlash, secondSlash);
+    if ( secondSlash == -1 )
+    {
+      fprintf(stderr,"KJS::parseDate parsing for this format isn't implemented\n%s", u.ascii());
+      return Number(0);
+    }
+    int day = u.substr(firstSlash+1,secondSlash-firstSlash-1).toULong();
+    int year = u.substr(secondSlash+1).toULong();
+    //fprintf(stdout,"KJS::parseDate day=%d, month=%d, year=%d\n", day, month, year);
+    struct tm t;
+    memset( &t, 0, sizeof(t) );
+    year = (year > 2037) ? 2037 : year; // mktime is limited to 2037 !!!
+    t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
+    t.tm_mon = month-1; // mktime wants 0-11 for some reason
+    t.tm_mday = day;
+    time_t seconds = mktime(&t);
+    if ( seconds == -1 )
+    {
+      fprintf(stderr,"KJS::parseDate mktime returned -1.\n%s", u.ascii());
+      return Undefined();
+    }
+    else
+      return Number(seconds * 1000.0);
+  }
+}
+
+///// Awful duplication from krfcdate.cpp - we don't link to kdecore
+
+static unsigned int ymdhms_to_seconds(int year, int mon, int day, int hour, int minute, int second)
+{
+    unsigned int ret = (day - 32075)       /* days */
+            + 1461L * (year + 4800L + (mon - 14) / 12) / 4
+            + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12
+            - 3 * ((year + 4900L + (mon - 14) / 12) / 100) / 4
+            - 2440588;
+    ret = 24*ret + hour;     /* hours   */
+    ret = 60*ret + minute;   /* minutes */
+    ret = 60*ret + second;   /* seconds */
+
+    return ret;
+}
+
+static const char haystack[37]="janfebmaraprmayjunjulaugsepoctnovdec";
+
+// we follow the recommendation of rfc2822 to consider all
+// obsolete time zones not listed here equivalent to "-0000"
+static const struct {
+    const char *tzName;
+    int tzOffset;
+} known_zones[] = {
+    { "UT", 0 },
+    { "GMT", 0 },
+    { "EST", -300 },
+    { "EDT", -240 },
+    { "CST", -360 },
+    { "CDT", -300 },
+    { "MST", -420 },
+    { "MDT", -360 },
+    { "PST", -480 },
+    { "PDT", -420 },
+    { 0, 0 }
+};
+
+time_t KJS::KRFCDate_parseDate(const UString &_date)
+{
+     // This parse a date in the form:
+     //     Wednesday, 09-Nov-99 23:12:40 GMT
+     // or
+     //     Sat, 01-Jan-2000 08:00:00 GMT
+     // or
+     //     Sat, 01 Jan 2000 08:00:00 GMT
+     // or
+     //     01 Jan 99 22:00 +0100    (exceptions in rfc822/rfc2822)
+     // ### non RFC format, added for Javascript:
+     //     [Wednesday] January 09 1999 23:12:40 GMT
+     //
+     // We ignore the weekday
+     //
+     time_t result = 0;
+     int offset = 0;
+     char *newPosStr;
+     const char *dateString = _date.ascii();
+     int day = 0;
+     char monthStr[4];
+     int month = -1; // not set yet
+     int year = 0;
+     int hour = 0;
+     int minute = 0;
+     int second = 0;
+
+     // Skip leading space
+     while(*dateString && isspace(*dateString))
+       dateString++;
+
+     const char *wordStart = dateString;
+     // Check contents of first words if not number
+     while(*dateString && !isdigit(*dateString))
+     {
+        if ( isspace(*dateString) && dateString - wordStart >= 3 )
+        {
+          monthStr[0] = tolower(*wordStart++);
+          monthStr[1] = tolower(*wordStart++);
+          monthStr[2] = tolower(*wordStart++);
+          monthStr[3] = '\0';
+          //fprintf(stderr,"KJS::parseDate found word starting with '%s'\n", monthStr);
+          const char *str = strstr(haystack, monthStr);
+          if (str)
+            month = (str-haystack)/3; // Jan=00, Feb=01, Mar=02, ..
+          while(*dateString && isspace(*dateString))
+             dateString++;
+          wordStart = dateString;
+        }
+        else
+           dateString++;
+     }
+
+     while(*dateString && isspace(*dateString))
+       dateString++;
+
+     if (!*dateString)
+       return result;  // Invalid date
+
+     // ' 09-Nov-99 23:12:40 GMT'
+     day = strtol(dateString, &newPosStr, 10);
+     dateString = newPosStr;
+
+     if ((day < 1) || (day > 31))
+       return result; // Invalid date;
+     if (!*dateString)
+       return result;  // Invalid date
+
+     if (*dateString == '-')
+       dateString++;
+
+     while(*dateString && isspace(*dateString))
+       dateString++;
+
+     if ( month == -1 ) // not found yet
+     {
+        for(int i=0; i < 3;i++)
+        {
+           if (!*dateString || (*dateString == '-') || isspace(*dateString))
+              return result;  // Invalid date
+           monthStr[i] = tolower(*dateString++);
+        }
+        monthStr[3] = '\0';
+
+        newPosStr = (char*)strstr(haystack, monthStr);
+
+        if (!newPosStr)
+           return result;  // Invalid date
+
+        month = (newPosStr-haystack)/3; // Jan=00, Feb=01, Mar=02, ..
+
+        if ((month < 0) || (month > 11))
+           return result;  // Invalid date
+
+        while(*dateString && (*dateString != '-') && !isspace(*dateString))
+           dateString++;
+
+        if (!*dateString)
+           return result;  // Invalid date
+
+        // '-99 23:12:40 GMT'
+        if ((*dateString != '-') && !isspace(*dateString))
+           return result;  // Invalid date
+        dateString++;
+     }
+
+     if ((month < 0) || (month > 11))
+       return result;  // Invalid date
+
+     // '99 23:12:40 GMT'
+     year = strtol(dateString, &newPosStr, 10);
+     dateString = newPosStr;
+
+     // Y2K: Solve 2 digit years
+     if ((year >= 0) && (year < 50))
+         year += 2000;
+
+     if ((year >= 50) && (year < 100))
+         year += 1900;  // Y2K
+
+     if ((year < 1900) || (year > 2500))
+       return result; // Invalid date
+
+     // Don't fail if the time is missing.
+     if (*dateString)
+     {
+        // ' 23:12:40 GMT'
+        if (!isspace(*dateString++))
+           return result;  // Invalid date
+
+        hour = strtol(dateString, &newPosStr, 10);
+        dateString = newPosStr;
+
+        if ((hour < 0) || (hour > 23))
+           return result; // Invalid date
+
+        if (!*dateString)
+           return result;  // Invalid date
+
+        // ':12:40 GMT'
+        if (*dateString++ != ':')
+           return result;  // Invalid date
+
+        minute = strtol(dateString, &newPosStr, 10);
+        dateString = newPosStr;
+
+        if ((minute < 0) || (minute > 59))
+           return result; // Invalid date
+
+        if (!*dateString)
+           return result;  // Invalid date
+
+        // ':40 GMT'
+        if (*dateString != ':' && !isspace(*dateString))
+           return result;  // Invalid date
+
+        // seconds are optional in rfc822 + rfc2822
+        if (*dateString ==':') {
+           dateString++;
+
+           second = strtol(dateString, &newPosStr, 10);
+           dateString = newPosStr;
+
+           if ((second < 0) || (second > 59))
+              return result; // Invalid date
+        } else {
+           dateString++;
+        }
+
+        while(*dateString && isspace(*dateString))
+           dateString++;
+     }
+
+     // don't fail if the time zone is missing, some
+     // broken mail-/news-clients omit the time zone
+     if (*dateString) {
+
+        if ((*dateString == '+') || (*dateString == '-')) {
+           offset = strtol(dateString, &newPosStr, 10);
+
+           if ((offset < -9959) || (offset > 9959))
+              return result; // Invalid date
+
+           int sgn = (offset < 0)? -1:1;
+           offset = abs(offset);
+           offset = ((offset / 100)*60 + (offset % 100))*sgn;
+        } else {
+           for (int i=0; known_zones[i].tzName != 0; i++) {
+              if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {
+                 offset = known_zones[i].tzOffset;
+                 break;
+              }
+           }
+        }
+     }
+     if (sizeof(time_t) == 4)
+     {
+         if ((time_t)-1 < 0)
+         {
+            if (year >= 2038)
+            {
+               year = 2038;
+               month = 0;
+               day = 1;
+               hour = 0;
+               minute = 0;
+               second = 0;
+            }
+         }
+         else
+         {
+            if (year >= 2115)
+            {
+               year = 2115;
+               month = 0;
+               day = 1;
+               hour = 0;
+               minute = 0;
+               second = 0;
+            }
+         }
+     }
+
+     result = ymdhms_to_seconds(year, month+1, day, hour, minute, second);
+
+     // avoid negative time values
+     if ((offset > 0) && (offset > result))
+        offset = 0;
+
+     result -= offset*60;
+
+     // If epoch 0 return epoch +1 which is Thu, 01-Jan-70 00:00:01 GMT
+     // This is so that parse error and valid epoch 0 return values won't
+     // be the same for sensitive applications...
+     if (result < 1) result = 1;
+
+     return result;
+}
+
+
+Value KJS::timeClip(const Value &t)
+{
+  /* TODO */
+  return t;
+}
+
index 5eed675292dfb53b97bbc8c75b9261b6b58cbfe3..e20a4215a912146af1a61bc43d36fb7391eae386 100644 (file)
@@ -1,3 +1,4 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id$
  */
 
 #ifndef _DATE_OBJECT_H_
 #define _DATE_OBJECT_H_
 
-#include "object.h"
-#include "function.h"
+#include "internal.h"
+#include "function_object.h"
 
 namespace KJS {
 
-  class DateObject : public ConstructorImp {
+  class DateInstanceImp : public ObjectImp {
+  public:
+    DateInstanceImp(const Object &proto);
+
+    virtual const ClassInfo *classInfo() const { return &info; }
+    static const ClassInfo info;
+  };
+
+  /**
+   * @internal
+   *
+   * The initial value of Date.prototype (and thus all objects created
+   * with the Date constructor
+   */
+  class DatePrototypeImp : public DateInstanceImp {
+  public:
+    DatePrototypeImp(ExecState *exec, ObjectPrototypeImp *objectProto);
+    Value get(ExecState *exec, const UString &p) const;
+    virtual const ClassInfo *classInfo() const { return &info; }
+    static const ClassInfo info;
+  };
+
+  /**
+   * @internal
+   *
+   * Class to implement all methods that are properties of the
+   * Date.prototype object
+   */
+  class DateProtoFuncImp : public InternalFunctionImp {
+  public:
+    DateProtoFuncImp(ExecState *exec, int i, int len);
+
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+
+
+    Completion execute(const List &);
+    enum { ToString, ToDateString, ToTimeString, ToLocaleString,
+          ToLocaleDateString, ToLocaleTimeString, ValueOf, GetTime,
+          GetFullYear, GetMonth, GetDate, GetDay, GetHours, GetMinutes,
+          GetSeconds, GetMilliSeconds, GetTimezoneOffset, SetTime,
+          SetMilliSeconds, SetSeconds, SetMinutes, SetHours, SetDate,
+          SetMonth, SetFullYear, ToUTCString,
+          // non-normative properties (Appendix B)
+          GetYear, SetYear, ToGMTString };
+  private:
+    int id;
+    bool utc;
+  };
+
+  /**
+   * @internal
+   *
+   * The initial value of the the global variable's "Date" property
+   */
+  class DateObjectImp : public InternalFunctionImp {
   public:
-    DateObject(const Object& funcProto, const Object &dateProto);
+    DateObjectImp(ExecState *exec,
+                  FunctionPrototypeImp *funcProto,
+                  DatePrototypeImp *dateProto);
+
+    virtual bool implementsConstruct() const;
+    virtual Object construct(ExecState *exec, const List &args);
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+
     Completion execute(const List &);
     Object construct(const List &);
-    KJSO get(const UString &p) const;
   };
 
-  class DatePrototype : public ObjectImp {
+  /**
+   * @internal
+   *
+   * Class to implement all methods that are properties of the
+   * Date object
+   */
+  class DateObjectFuncImp : public InternalFunctionImp {
   public:
-    DatePrototype(const Object& proto);
-    virtual KJSO get(const UString &p) const;
+    DateObjectFuncImp(ExecState *exec, FunctionPrototypeImp *funcProto,
+                      int i, int len);
+
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+
+    enum { Parse, UTC };
+  private:
+    int id;
   };
 
+  // helper functions
+  Value parseDate(const String &s);
+  time_t KRFCDate_parseDate(const UString &_date);
+  Value timeClip(const Value &t);
+
 }; // namespace
 
 #endif
index e0f3859319785b4ffd22c1b930619def7c1b91a2..8ce7d810f5484fb15fcfa61a6610cfdbc8dc098f 100644 (file)
@@ -1,6 +1,8 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id$
  */
 
-#ifdef KJS_DEBUGGER
-
 #include "debugger.h"
-#include "kjs.h"
+#include "value.h"
+#include "object.h"
+#include "types.h"
+#include "interpreter.h"
 #include "internal.h"
 #include "ustring.h"
 
 using namespace KJS;
 
-Debugger::Debugger(KJScript *engine)
-  : eng(0L),
-    sid(-1)
-{
-  attach(engine);
-}
-
-Debugger::~Debugger()
-{
-  detach();
-}
-
-void Debugger::attach(KJScript *e)
-{
-  dmode = Disabled;
-  if (e) {
-    if (!eng || e->rep != eng->rep) {
-      eng = e;
-      eng->rep->attachDebugger(this);
-    }
-  } else {
-    eng = 0L;
-  }
-  reset();
-}
+// ------------------------------ Debugger -------------------------------------
 
-KJScript *Debugger::engine() const
-{
-  return eng;
-}
+namespace KJS {
+  struct AttachedInterpreter
+  {
+  public:
+    AttachedInterpreter(Interpreter *i) : interp(i) {}
+    Interpreter *interp;
+    AttachedInterpreter *next;
+  };
 
-void Debugger::detach()
-{
-  reset();
-  if (!eng)
-    return;
-  eng->rep->attachDebugger(0L);
-  eng = 0L;
 }
 
-void Debugger::setMode(Mode m)
+Debugger::Debugger()
 {
-  dmode = m;
+  rep = new DebuggerImp();
 }
 
-Debugger::Mode Debugger::mode() const
+Debugger::~Debugger()
 {
-  return dmode;
-}
+  // detach from all interpreters
+  while (rep->interps)
+    detach(rep->interps->interp);
 
-// supposed to be overriden by the user
-bool Debugger::stopEvent()
-{
-  return true;
+  delete rep;
 }
 
-void Debugger::callEvent(const UString &, const UString &)
+void Debugger::attach(Interpreter *interp)
 {
-}
+  if (interp->imp()->debugger() != this)
+    interp->imp()->setDebugger(this);
 
-void Debugger::returnEvent()
-{
+  // add to the list of attached interpreters
+  if (!rep->interps)
+    rep->interps = new AttachedInterpreter(interp);
+  else {
+    AttachedInterpreter *ai = rep->interps;
+    while (ai->next)
+      ai = ai->next;
+    ai->next = new AttachedInterpreter(interp);;
+  }
 }
 
-void Debugger::reset()
+void Debugger::detach(Interpreter *interp)
 {
-  l = -1;
-}
+  if (interp->imp()->debugger() == this)
+    interp->imp()->setDebugger(this);
 
-int Debugger::freeSourceId() const
-{
-  return eng ? eng->rep->sourceId()+1 : -1;
-}
+  // remove from the list of attached interpreters
+  if (rep->interps->interp == interp) {
+    AttachedInterpreter *old = rep->interps;
+    rep->interps = rep->interps->next;
+    delete old;
+  }
 
-bool Debugger::setBreakpoint(int id, int line)
-{
-  if (!eng)
-    return false;
-  return eng->rep->setBreakpoint(id, line, true);
+  AttachedInterpreter *ai = rep->interps;
+  while (ai->next && ai->next->interp != interp)
+    ai = ai->next;
+  if (ai->next) {
+    AttachedInterpreter *old = ai->next;
+    ai->next = ai->next->next;
+    delete old;
+  }
 }
 
-bool Debugger::deleteBreakpoint(int id, int line)
+bool Debugger::sourceParsed(ExecState */*exec*/, int /*sourceId*/,
+                            const UString &/*source*/, int /*errorLine*/)
 {
-  if (!eng)
-    return false;
-  return eng->rep->setBreakpoint(id, line, false);
+  return true;
 }
 
-void Debugger::clearAllBreakpoints(int id)
+bool Debugger::sourceUnused(ExecState */*exec*/, int /*sourceId*/)
 {
-  if (!eng)
-    return;
-  eng->rep->setBreakpoint(id, -1, false);
+  return true;
 }
 
-UString Debugger::varInfo(const UString &ident)
+bool Debugger::exception(ExecState */*exec*/, int /*sourceId*/, int /*lineno*/,
+                         Object &/*exceptionObj*/)
 {
-  if (!eng)
-    return UString();
-
-  int dot = ident.find('.');
-  if (dot < 0)
-      dot = ident.size();
-  UString sub = ident.substr(0, dot);
-  KJSO obj;
-  // resolve base
-  if (sub == "this") {
-      obj = Context::current()->thisValue();
-  } else {
-      const List *chain = Context::current()->pScopeChain();
-      ListIterator scope = chain->begin();
-      while (scope != chain->end()) {
-         if (scope->hasProperty(ident)) {
-             obj = scope->get(ident);
-             break;
-         }
-         scope++;
-      }
-      if (scope == chain->end())
-       return UString();
-  }
-  // look up each part of a.b.c.
-  while (dot < ident.size()) {
-    int olddot = dot;
-    dot = ident.find('.', olddot+1);
-    if (dot < 0)
-      dot = ident.size();
-    sub = ident.substr(olddot+1, dot-olddot-1);
-    obj = obj.get(sub);
-    if (!obj.isDefined())
-      break;
-  }
-
-  return sub + "=" + objInfo(obj) + ":" + UString(obj.imp()->typeInfo()->name);
+  return true;
 }
 
-// called by varInfo() and recursively by itself on each properties
-UString Debugger::objInfo(const KJSO &obj) const
+bool Debugger::atStatement(ExecState */*exec*/, int /*sourceId*/, int /*firstLine*/,
+                           int /*lastLine*/)
 {
-  const char *cnames[] = { "Undefined", "Array", "String", "Boolean",
-                          "Number", "Object", "Date", "RegExp",
-                          "Error", "Function" };
-  PropList *plist = obj.imp()->propList(0, 0, false);
-  if (!plist)
-    return obj.toString().value();
-  else {
-    UString result = "{";
-    while (1) {
-      result += plist->name + "=";
-      KJSO p = obj.get(plist->name);
-      result += objInfo(p) + ":";
-      Object obj = Object::dynamicCast(p);
-      if (obj.isNull())
-       result += p.imp()->typeInfo()->name;
-      else
-       result += cnames[int(obj.getClass())];
-      plist = plist->next;
-      if (!plist)
-       break;
-      result += ",";
-    }
-    result += "}";
-    return result;
-  }
+  return true;
 }
 
-bool Debugger::setVar(const UString &ident, const KJSO &value)
+bool Debugger::callEvent(ExecState */*exec*/, int /*sourceId*/, int /*lineno*/,
+                         Object &/*function*/, const List &/*args*/)
 {
-  if (!eng)
-    return false;
-  const List *chain = Context::current()->pScopeChain();
-  ListIterator scope = chain->begin();
-  while (scope != chain->end()) {
-    if (scope->hasProperty(ident)) {
-      if (!scope->canPut(ident))
-       return false;
-      scope->put(ident, value);
-      return true;
-    }
-    scope++;
-  }
-  // didn't find variable
-  return false;
+  return true;
 }
 
-// called from the scripting engine each time a statement node is hit.
-bool Debugger::hit(int line, bool breakPoint)
+bool Debugger::returnEvent(ExecState */*exec*/, int /*sourceId*/, int /*lineno*/,
+                           Object &/*function*/)
 {
-  l = line;
-  if (!eng)
-    return true;
-
-  if (!breakPoint && ( mode() == Continue || mode() == Disabled ) )
-      return true;
-
-  bool ret = stopEvent();
-  eng->init(); // in case somebody used a different interpreter meanwhile
-  return ret;
+  return true;
 }
 
-#endif
index b0e97fe7fe35c12065c40194f9605a1c67b800b7..92bc870c1acc0dd2a6b7c3e19e3eab2528a2ec25 100644 (file)
@@ -1,6 +1,8 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id$
  */
 
 #ifndef _KJSDEBUGGER_H_
 #define _KJSDEBUGGER_H_
 
-#include "internal.h"
-
 namespace KJS {
 
-  //
-  // NOTE: this interface is not ready, yet. Do not use unless you
-  // don't mind source and binary incompatible changes that may arise
-  // before the final version is released.
-  //
+  class DebuggerImp;
+  class Interpreter;
+  class ExecState;
+  class Object;
+  class UString;
+  class List;
 
-#ifdef KJS_DEBUGGER
+  /**
+   * @internal
+   *
+   * Provides an interface which receives notification about various
+   * script-execution related events such as statement execution and function
+   * calls.
+   *
+   * WARNING: This interface is still a work in progress and is not yet
+   * offically publicly available. It is likely to change in binary incompatible
+   * (and possibly source incompatible) ways in future versions. It is
+   * anticipated that at some stage the interface will be frozen and made
+   * available for general use.
+   */
   class Debugger {
-    friend class KJScriptImp;
-    friend class StatementNode;
-    friend class DeclaredFunctionImp;
-    friend class FunctionImp;
   public:
+
     /**
-     * Available modes of the debugger.
-     */
-    enum Mode { Disabled = 0, Next, Step, Continue, Stop };
-    /**
-     * Construct a debugger and attach it to the scripting engine s.
+     * Creates a new debugger
      */
-    Debugger(KJScript *s);
+    Debugger();
+
     /**
-     * Destruct the debugger and detach from the scripting engine we
-     * might have been attached to.
+     * Destroys the debugger. If the debugger is attached to any interpreters,
+     * it is automatically detached.
      */
     virtual ~Debugger();
+
+    DebuggerImp *imp() const { return rep; }
+
     /**
-     * Attaches the debugger to specified scripting engine.
-     */
-    void attach(KJScript *e);
-    /**
-     * Returns the engine the interpreter is currently attached to. Null
-     * if there isn't any.
-     */
-    KJScript* engine() const;
-    /**
-     * Detach the debugger from any scripting engine.
-     */
-    void detach();
-    /**
-     * Set debugger into specified mode. This will influence further behaviour
-     * if execution of the programm is started or continued.
-     */
-    virtual void setMode(Mode m);
-    /**
-     * Returns the current operation mode.
-     */
-    Mode mode() const;
-    /**
-     * Returns the line number the debugger currently has stopped at.
-     * -1 if the debugger is not in a break status.
-     */
-    int lineNumber() const { return l; }
-    /**
-     * Returns the source id the debugger currently has stopped at.
-     * -1 if the debugger is not in a break status.
-     */
-    int sourceId() const { return sid; }
-    /**
-     * Sets a breakpoint in the first statement where line lies in between
-     * the statements range. Returns true if sucessfull, false if no
-     * matching statement could be found.
+     * Attaches the debugger to specified interpreter. This will cause this
+     * object to receive notification of events from the interpreter.
+     *
+     * If the interpreter is deleted, the debugger will automatically be
+     * detached.
+     *
+     * Note: only one debugger can be attached to an interpreter at a time.
+     * Attaching another debugger to the same interpreter will cause the
+     * original debugger to be detached from that interpreter.
+     *
+     * @param interp The interpreter to attach to
+     *
+     * @see detach()
      */
-    bool setBreakpoint(int id, int line);
-    bool deleteBreakpoint(int id, int line);
-    void clearAllBreakpoints(int id=-1);
+    void attach(Interpreter *interp);
+
     /**
-     * Returns the value of ident out of the current context in string form
+     * Detach the debugger from an interpreter
+     *
+     * @param interp The interpreter to detach from. If 0, the debugger will be
+     * detached from all interpreters to which it is attached.
+     *
+     * @see attach()
      */
-    UString varInfo(const UString &ident);
+    void detach(Interpreter *interp);
+
     /**
-     * Set variable ident to value. Returns true if successful, false if
-     * the specified variable doesn't exist or isn't writable.
-     */
-    bool setVar(const UString &ident, const KJSO &value);
+     * Called to notify the debugger that some javascript source code has
+     * been parsed. For calls to Interpreter::evaluate(), this will be called
+     * with the supplied source code before any other code is parsed.
+     * Other situations in which this may be called include creation of a
+     * function using the Function() constructor, or the eval() function.
+     *
+     * The default implementation does nothing. Override this method if
+     * you want to process this event.
+     *
+     * @param exec The current execution state
+     * @param sourceId The ID of the source code (corresponds to the
+     * sourceId supplied in other functions such as @ref atStatement()
+     * @param source The source code that was parsed
+     * @param errorLine The line number at which parsing encountered an
+     * error, or -1 if the source code was valid and parsed succesfully
+     * @return true if execution should be continue, false if it should
+     * be aborted
+     */
+    virtual bool sourceParsed(ExecState *exec, int sourceId,
+                             const UString &source, int errorLine);
 
-  protected:
     /**
-     * Invoked in case a breakpoint or the next statement is reached in step
-     * mode. The return value decides whether execution will continue. True
-     * denotes continuation, false an abortion, respectively.
+     * Called when all functions/programs associated with a particular
+     * sourceId have been deleted. After this function has been called for
+     * a particular sourceId, that sourceId will not be used again.
      *
-     * The default implementation does nothing. Overload this method if
+     * The default implementation does nothing. Override this method if
      * you want to process this event.
+     *
+     * @param exec The current execution state
+     * @param sourceId The ID of the source code (corresponds to the
+     * sourceId supplied in other functions such as atLine()
+     * @return true if execution should be continue, false if it should
+     * be aborted
      */
-    virtual bool stopEvent();
+    virtual bool sourceUnused(ExecState *exec, int sourceId);
+
     /**
-     * Returns an integer that will be assigned to the code passed
-     * next to one of the KJScript::evaluate() methods. It's basically
-     * a counter to will only be reset to 0 on KJScript::clear().
-     *
-     * This information is useful in case you evaluate multiple blocks of
-     * code containing some function declarations. Keep a map of source id/
-     * code pairs, query sourceId() in case of a stopEvent() and update
-     * your debugger window with the matching source code.
-     */
-    int freeSourceId() const;
+     * Called when an exception is thrown during script execution.
+     *
+     * The default implementation does nothing. Override this method if
+     * you want to process this event.
+     *
+     * @param exec The current execution state
+     * @param sourceId The ID of the source code being executed
+     * @param lineno The line at which the error occurred
+     * @param exceptionObj The exception object
+     * @return true if execution should be continue, false if it should
+     * be aborted
+     */
+    virtual bool exception(ExecState *exec, int sourceId, int lineno,
+                           Object &exceptionObj);
+
     /**
-     * Invoked on each function call. Use together with @ref returnEvent
+     * Called when a line of the script is reached (before it is executed)
+     *
+     * The default implementation does nothing. Override this method if
+     * you want to process this event.
+     *
+     * @param exec The current execution state
+     * @param sourceId The ID of the source code being executed
+     * @param firstLine The starting line of the statement  that is about to be
+     * executed
+     * @param firstLine The ending line of the statement  that is about to be
+     * executed (usually the same as firstLine)
+     * @return true if execution should be continue, false if it should
+     * be aborted
+     */
+    virtual bool atStatement(ExecState *exec, int sourceId, int firstLine,
+                             int lastLine);
+    /**
+     * Called on each function call. Use together with @ref #returnEvent
      * if you want to keep track of the call stack.
-     */
-    virtual void callEvent(const UString &fn = UString::null,
-                                   const UString &s = UString::null);
+     *
+     * Note: This only gets called for functions that are declared in ECMAScript
+     * source code or passed to eval(), not for internal KJS or
+     * application-supplied functions.
+     *
+     * The default implementation does nothing. Override this method if
+     * you want to process this event.
+     *
+     * @param exec The current execution state
+     * @param sourceId The ID of the source code being executed
+     * @param lineno The line that is about to be executed
+     * @param function The function being called
+     * @param args The arguments that were passed to the function
+     * line is being executed
+     * @return true if execution should be continue, false if it should
+     * be aborted
+     */
+    virtual bool callEvent(ExecState *exec, int sourceId, int lineno,
+                          Object &function, const List &args);
+
     /**
-     * Invoked on each function exit.
-     */
-    virtual void returnEvent();
+     * Called on each function exit. The function being returned from is that
+     * which was supplied in the last callEvent().
+     *
+     * Note: This only gets called for functions that are declared in ECMAScript
+     * source code or passed to eval(), not for internal KJS or
+     * application-supplied functions.
+     *
+     * The default implementation does nothing. Override this method if
+     * you want to process this event.
+     *
+     * @param exec The current execution state
+     * @param sourceId The ID of the source code being executed
+     * @param lineno The line that is about to be executed
+     * @param function The function being called
+     * @return true if execution should be continue, false if it should
+     * be aborted
+     */
+    virtual bool returnEvent(ExecState *exec, int sourceId, int lineno,
+                             Object &function);
 
   private:
-    void reset();
-    bool hit(int line, bool breakPoint);
-    void setSourceId(int i) { sid = i; }
-    UString objInfo(const KJSO &obj) const;
-
-    KJScript *eng;
-    Mode dmode;
-    int l;
-    int sid;
+    DebuggerImp *rep;
   };
-#endif
 
 };
 
index a5aa6d823c0d890c274d5a4b6c7119618e8406aa..3bf338b30eb2f6c174123d48772615f19cd48747 100644 (file)
@@ -1,3 +1,4 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
  */
 
-#include "kjs.h"
-#include "operations.h"
+#include "value.h"
+#include "object.h"
 #include "types.h"
-#include "internal.h"
+#include "interpreter.h"
+#include "operations.h"
 #include "error_object.h"
-#include "debugger.h"
+//#include "debugger.h"
 
 using namespace KJS;
 
-const char *ErrorObject::errName[] = {
-  "No Error",
-  "Error",
-  "EvalError",
-  "RangeError",
-  "ReferenceError",
-  "SyntaxError",
-  "TypeError",
-  "URIError"
-};
-
-ErrorObject::ErrorObject(const Object &funcProto, const Object &errProto,
-                        ErrorType t)
-  : ConstructorImp(funcProto, 1), errType(t)
+// ------------------------------ ErrorPrototypeImp ----------------------------
+
+// ECMA 15.9.4
+ErrorPrototypeImp::ErrorPrototypeImp(ExecState *exec,
+                                     ObjectPrototypeImp *objectProto,
+                                     FunctionPrototypeImp *funcProto)
+  : ObjectImp(Object(objectProto))
 {
-  // ECMA 15.11.3.1 Error.prototype
-  setPrototypeProperty(errProto);
-  const char *n = errName[errType];
+  Value protect(this);
+  setInternalValue(Undefined());
+  // The constructor will be added later in ErrorObjectImp's constructor
 
-  put("name", String(n));
+  put(exec, "name",     String("Error"), DontEnum);
+  put(exec, "message",  String("Unknown error"), DontEnum);
+  put(exec, "toString", Object(new ErrorProtoFuncImp(exec,funcProto)), DontEnum);
 }
 
-ErrorObject::ErrorObject(const Object& proto, ErrorType t,
-                        const char *m, int l)
-  : ConstructorImp(proto, 1), errType(t)
+// ------------------------------ ErrorProtoFuncImp ----------------------------
+
+ErrorProtoFuncImp::ErrorProtoFuncImp(ExecState *exec, FunctionPrototypeImp *funcProto)
+  : InternalFunctionImp(funcProto)
 {
-  const char *n = errName[errType];
+  Value protect(this);
+  put(exec,"length",Number(0),DontDelete|ReadOnly|DontEnum);
+}
 
-  put("name", String(n));
-  put("message", String(m));
-  put("line", Number(l));
-#ifdef KJS_DEBUGGER
-  Debugger *dbg = KJScriptImp::current()->debugger();
-  if (dbg)
-    put("sid", Number(dbg->sourceId()));
-#endif
+bool ErrorProtoFuncImp::implementsCall() const
+{
+  return true;
 }
 
-// ECMA 15.9.2
-Completion ErrorObject::execute(const List &args)
+Value ErrorProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &/*args*/)
 {
-  // "Error()" gives the sames result as "new Error()"
-  return Completion(ReturnValue, construct(args));
+  // toString()
+  UString s = "Error";
+
+  Value v = thisObj.get(exec,"name");
+  if (v.type() != UndefinedType) {
+    s = v.toString(exec);
+  }
+
+  v = thisObj.get(exec,"message");
+  if (v.type() != UndefinedType) {
+    s += ": "+v.toString(exec);
+  }
+
+  return String(s);
+}
+
+// ------------------------------ ErrorObjectImp -------------------------------
+
+ErrorObjectImp::ErrorObjectImp(ExecState *exec, FunctionPrototypeImp *funcProto,
+                               ErrorPrototypeImp *errorProto)
+  : InternalFunctionImp(funcProto)
+{
+  Value protect(this);
+  // ECMA 15.11.3.1 Error.prototype
+  put(exec, "prototype", Object(errorProto), DontEnum|DontDelete|ReadOnly);
+  //put(exec, "name", String(n));
+}
+
+bool ErrorObjectImp::implementsConstruct() const
+{
+  return true;
 }
 
 // ECMA 15.9.3
-Object ErrorObject::construct(const List &args)
+Object ErrorObjectImp::construct(ExecState *exec, const List &args)
 {
-  if (args.isEmpty() == 1 || !args[0].isDefined())
-    return Object::create(ErrorClass, Undefined());
+  Object proto = Object::dynamicCast(exec->interpreter()->builtinErrorPrototype());
+  Object obj(new ObjectImp(proto));
+
+  if (!args.isEmpty() && args[0].type() != UndefinedType) {
+    obj.put(exec,"message", String(args[0].toString(exec)));
+  }
 
-  String message = args[0].toString();
-  return Object::create(ErrorClass, message);
+  return obj;
 }
 
-Object ErrorObject::create(ErrorType e, const char *m, int l)
+bool ErrorObjectImp::implementsCall() const
 {
-  Global global(Global::current());
-  KJSO prot = Global::current().get("[[Error.prototype]]");
-  assert(prot.isObject());
-  Imp *d = new ErrorObject(Object(prot.imp()), e, m, l);
+  return true;
+}
 
-  return Object(d);
+// ECMA 15.9.2
+Value ErrorObjectImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
+{
+  // "Error()" gives the sames result as "new Error()"
+  return construct(exec,args);
 }
 
-// ECMA 15.9.4
-ErrorPrototype::ErrorPrototype(const Object& proto)
-  : ObjectImp(ErrorClass, Undefined(), proto)
+// ------------------------------ NativeErrorPrototypeImp ----------------------
+
+NativeErrorPrototypeImp::NativeErrorPrototypeImp(ExecState *exec, ErrorPrototypeImp *errorProto,
+                                                 ErrorType et, UString name, UString message)
+  : ObjectImp(Object(errorProto))
+{
+  Value protect(this);
+  errType = et;
+  put(exec,"name",String(name));
+  put(exec,"message",String(message));
+}
+
+// ------------------------------ NativeErrorImp -------------------------------
+
+const ClassInfo NativeErrorImp::info = {"Error", &InternalFunctionImp::info, 0, 0};
+
+NativeErrorImp::NativeErrorImp(ExecState *exec, FunctionPrototypeImp *funcProto,
+                               const Object &prot)
+  : InternalFunctionImp(funcProto), proto(0)
 {
-  // The constructor will be added later in ErrorObject's constructor
+  Value protect(this);
+  proto = static_cast<ObjectImp*>(prot.imp());
+
+  put(exec,"length",Number(1),DontDelete|ReadOnly|DontEnum); // ECMA 15.11.7.5
+  put(exec,"prototype",prot);
 }
 
-KJSO ErrorPrototype::get(const UString &p) const
+bool NativeErrorImp::implementsConstruct() const
 {
-  const char *s;
+  return true;
+}
 
-  /* TODO: are these properties dynamic, i.e. should we put() them ? */
-  if (p == "name")
-    s = "Error";
-  else if (p == "message")
-    s = "Error message.";
-  else if (p == "toString")
-    return Function(new ErrorProtoFunc());
-  else
-    return Imp::get(p);
+Object NativeErrorImp::construct(ExecState *exec, const List &args)
+{
+  Object obj(new ObjectImp(Object(proto)));
+  if (args[0].type() != UndefinedType)
+    obj.put(exec, "message", String(args[0].toString(exec)));
+  return obj;
+}
 
-  return String(s);
+bool NativeErrorImp::implementsCall() const
+{
+  return true;
 }
 
-Completion ErrorProtoFunc::execute(const List &)
+Value NativeErrorImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
 {
-  // toString()
-  const char *s = "Error message.";
+  return construct(exec,args);
+}
 
-  return Completion(ReturnValue, String(s));
+void NativeErrorImp::mark()
+{
+  ObjectImp::mark();
+  if (proto && !proto->marked())
+    proto->mark();
 }
 
index 8e515f0352cb767eba7c05ead60dc19b389943ed..0bfba1d6744bba870b6a6c618e1ca68cc93dd17a 100644 (file)
@@ -1,3 +1,4 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  You should have received a copy of the GNU Lesser General Public
  *  License along with this library; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  $Id$
  */
 
 #ifndef _ERROR_OBJECT_H_
 #define _ERROR_OBJECT_H_
 
-#include "object.h"
-#include "function.h"
+#include "internal.h"
+#include "function_object.h"
 
 namespace KJS {
 
-  class ErrorObject : public ConstructorImp {
+  class ErrorPrototypeImp : public ObjectImp {
   public:
-    ErrorObject(const Object &funcProto, const Object &errProto,
-               ErrorType t = GeneralError);
-    ErrorObject(const Object& proto, ErrorType t, const char *m, int l = -1);
-    Completion execute(const List &);
-    Object construct(const List &);
-    static Object create(ErrorType e, const char *m, int ln);
-  private:
-    ErrorType errType;
-    static const char *errName[];
+    ErrorPrototypeImp(ExecState *exec,
+                      ObjectPrototypeImp *objectProto,
+                      FunctionPrototypeImp *funcProto);
   };
 
-  class ErrorPrototype : public ObjectImp {
+  class ErrorProtoFuncImp : public InternalFunctionImp {
   public:
-    ErrorPrototype(const Object& proto);
-    virtual KJSO get(const UString &p) const;
+    ErrorProtoFuncImp(ExecState *exec, FunctionPrototypeImp *funcProto);
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
   };
 
-  class ErrorProtoFunc : public InternalFunctionImp {
+  class ErrorObjectImp : public InternalFunctionImp {
   public:
-    ErrorProtoFunc() { }
-    Completion execute(const List &);
+    ErrorObjectImp(ExecState *exec, FunctionPrototypeImp *funcProto,
+                   ErrorPrototypeImp *errorProto);
+
+    virtual bool implementsConstruct() const;
+    virtual Object construct(ExecState *exec, const List &args);
+
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+  };
+
+
+
+
+
+  class NativeErrorPrototypeImp : public ObjectImp {
+  public:
+    NativeErrorPrototypeImp(ExecState *exec, ErrorPrototypeImp *errorProto,
+                            ErrorType et, UString name, UString message);
+  private:
+    ErrorType errType;
+  };
+
+  class NativeErrorImp : public InternalFunctionImp {
+  public:
+    NativeErrorImp(ExecState *exec, FunctionPrototypeImp *funcProto,
+                   const Object &prot);
+
+    virtual bool implementsConstruct() const;
+    virtual Object construct(ExecState *exec, const List &args);
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+
+    virtual void mark();
+
+    virtual const ClassInfo *classInfo() const { return &info; }
+    static const ClassInfo info;
+  private:
+    ObjectImp *proto;
   };
 
 }; // namespace
index 22db1d2a3e3cb23e89180aa2ab601a94aff86fd3..51382f8c013d25e4c9ca59261ff430c5c2dc1ae0 100644 (file)
@@ -1,6 +1,8 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
  *  along with this library; see the file COPYING.LIB.  If not, write to
  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  *  Boston, MA 02111-1307, USA.
+ *
  */
 
 #include "function.h"
 
-#include "kjs.h"
-#include "types.h"
 #include "internal.h"
-#include "operations.h"
+#include "function_object.h"
+#include "lexer.h"
 #include "nodes.h"
-#ifndef NDEBUG
+#include "operations.h"
+#include "debugger.h"
+
 #include <stdio.h>
-#endif
+#include <assert.h>
+#include <string.h>
 
 using namespace KJS;
 
-const TypeInfo FunctionImp::info = { "Function", FunctionType,
-                                     &ObjectImp::info, 0, 0 };
-const TypeInfo InternalFunctionImp::info = { "InternalFunction",
-                                             InternalFunctionType,
-                                             &FunctionImp::info, 0, 0 };
-const TypeInfo ConstructorImp::info = { "Function", ConstructorType,
-                                        &InternalFunctionImp::info, 0, 0 };
+// ------------------------------ FunctionImp ----------------------------------
 
-namespace KJS {
+const ClassInfo FunctionImp::info = {"Function", &InternalFunctionImp::info, 0, 0};
 
+namespace KJS {
   class Parameter {
   public:
     Parameter(const UString &n) : name(n), next(0L) { }
@@ -48,27 +48,118 @@ namespace KJS {
     UString name;
     Parameter *next;
   };
-
 };
 
-FunctionImp::FunctionImp()
-  : ObjectImp(/*TODO*/BooleanClass), param(0L)
+FunctionImp::FunctionImp(ExecState *exec, const UString &n)
+  : InternalFunctionImp(
+      static_cast<FunctionPrototypeImp*>(exec->interpreter()->builtinFunctionPrototype().imp())
+      ), param(0L), ident(n), argStack(0)
 {
+  Value protect(this);
+  argStack = new ListImp();
+  put(exec,"arguments",Null(),ReadOnly|DontDelete|DontEnum);
 }
 
-FunctionImp::FunctionImp(const UString &n)
-  : ObjectImp(/*TODO*/BooleanClass), ident(n), param(0L)
+FunctionImp::~FunctionImp()
 {
+  argStack->setGcAllowed();
+  // The function shouldn't be deleted while it is still executed; argStack
+  // should be set to 0 by the last call to popArgs()
+  assert(argStack->isEmpty());
+  delete param;
 }
 
-FunctionImp::~FunctionImp()
+void FunctionImp::mark()
 {
-  delete param;
+  InternalFunctionImp::mark();
+  if (argStack && !argStack->marked())
+    argStack->mark();
 }
 
-KJSO FunctionImp::thisValue() const
+bool FunctionImp::implementsCall() const
 {
-  return KJSO(Context::current()->thisValue());
+  return true;
+}
+
+Value FunctionImp::call(ExecState *exec, Object &thisObj, const List &args)
+{
+  Object globalObj = exec->interpreter()->globalObject();
+
+  Debugger *dbg = exec->interpreter()->imp()->debugger();
+  int sid = -1;
+  int lineno = -1;
+  if (dbg) {
+    if (inherits(&DeclaredFunctionImp::info)) {
+      sid = static_cast<DeclaredFunctionImp*>(this)->body->sourceId();
+      lineno = static_cast<DeclaredFunctionImp*>(this)->body->firstLine();
+    }
+
+    Object func(this);
+    int cont = dbg->callEvent(exec,sid,lineno,func,args);
+    if (!cont) {
+      dbg->imp()->abort();
+      return Undefined();
+    }
+  }
+
+  // enter a new execution context
+  ContextImp *ctx = new ContextImp(globalObj, exec, thisObj,
+                                   codeType(), exec->context().imp(), this, args);
+  ExecState *newExec = new ExecState(exec->interpreter(),ctx);
+  newExec->setException(exec->exception()); // could be null
+
+  // In order to maintain our "arguments" property, we maintain a list of arguments
+  // properties from earlier in the execution stack. Upon return, we restore the
+  // previous arguments object using popArgs().
+  // Note: this does not appear to be part of the spec
+  if (codeType() == FunctionCode) {
+    assert(ctx->activationObject().inherits(&ActivationImp::info));
+    Object argsObj = static_cast<ActivationImp*>(ctx->activationObject().imp())->argumentsObject();
+    put(newExec,"arguments", argsObj, DontDelete|DontEnum|ReadOnly);
+    pushArgs(newExec,argsObj);
+  }
+
+  // assign user supplied arguments to parameters
+  processParameters(newExec,args);
+  // add variable declarations (initialized to undefined)
+  processVarDecls(newExec);
+
+  Completion comp = execute(newExec);
+
+  // if an exception occured, propogate it back to the previous execution object
+  if (newExec->hadException())
+    exec->setException(newExec->exception());
+  if (codeType() == FunctionCode)
+    popArgs(newExec);
+  delete newExec;
+  delete ctx;
+
+#ifdef KJS_VERBOSE
+  if (comp.complType() == Throw)
+    printInfo(exec,"throwing", comp.value());
+  else if (comp.complType() == ReturnValue)
+    printInfo(exec,"returning", comp.value());
+  else
+    fprintf(stderr, "returning: undefined\n");
+#endif
+
+  if (dbg) {
+    Object func(this);
+    int cont = dbg->returnEvent(exec,sid,lineno,func);
+    if (!cont) {
+      dbg->imp()->abort();
+      return Undefined();
+    }
+  }
+
+  if (comp.complType() == Throw) {
+    exec->setException(comp.value());
+    return comp.value();
+  }
+  else if (comp.complType() == ReturnValue)
+    return comp.value();
+  else
+    return Undefined();
 }
 
 void FunctionImp::addParameter(const UString &n)
@@ -80,17 +171,11 @@ void FunctionImp::addParameter(const UString &n)
   *p = new Parameter(n);
 }
 
-void FunctionImp::setLength(int l)
-{
-  put("length", Number(l), ReadOnly|DontDelete|DontEnum);
-}
 
-// ECMA 10.1.3
-void FunctionImp::processParameters(const List *args)
+// ECMA 10.1.3q
+void FunctionImp::processParameters(ExecState *exec, const List &args)
 {
-  KJSO variable = Context::current()->variableObject();
-
-  assert(args);
+  Object variable = exec->context().imp()->variableObject();
 
 #ifdef KJS_VERBOSE
   fprintf(stderr, "---------------------------------------------------\n"
@@ -99,257 +184,293 @@ void FunctionImp::processParameters(const List *args)
 #endif
 
   if (param) {
-    ListIterator it = args->begin();
+    ListIterator it = args.begin();
     Parameter **p = &param;
     while (*p) {
-      if (it != args->end()) {
+      if (it != args.end()) {
 #ifdef KJS_VERBOSE
        fprintf(stderr, "setting parameter %s ", (*p)->name.ascii());
-       printInfo("to", *it);
+       printInfo(exec,"to", *it);
 #endif
-       variable.put((*p)->name, *it);
+       variable.put(exec,(*p)->name, *it);
        it++;
       } else
-       variable.put((*p)->name, Undefined());
+       variable.put(exec,(*p)->name, Undefined());
       p = &(*p)->next;
     }
   }
 #ifdef KJS_VERBOSE
   else {
-    for (int i = 0; i < args->size(); i++)
-      printInfo("setting argument", (*args)[i]);
-  }
-#endif
-#ifdef KJS_DEBUGGER
-  if (KJScriptImp::current()->debugger()) {
-    UString argStr;
-    for (int i = 0; i < args->size(); i++) {
-      if (i > 0)
-       argStr += ", ";
-      Imp *a = (*args)[i].imp();
-      argStr += a->toString().value() + " : " +        UString(a->typeInfo()->name);
-    }
-    UString n = name().isEmpty() ? UString( "(internal)" ) : name();
-    KJScriptImp::current()->debugger()->callEvent(n, argStr);
+    for (int i = 0; i < args.size(); i++)
+      printInfo(exec,"setting argument", args[i]);
   }
 #endif
 }
 
-// ECMA 13.2.1
-KJSO FunctionImp::executeCall(Imp *thisV, const List *args)
+void FunctionImp::processVarDecls(ExecState */*exec*/)
 {
-  return executeCall(thisV,args,0);
 }
 
-KJSO FunctionImp::executeCall(Imp *thisV, const List *args, const List *extraScope)
+void FunctionImp::pushArgs(ExecState *exec, const Object &args)
 {
-  bool dummyList = false;
-  if (!args) {
-    args = new List();
-    dummyList = true;
-  }
-
-  KJScriptImp *curr = KJScriptImp::current();
-  Context *save = curr->context();
-
-  Context *ctx = new Context(codeType(), save, this, args, thisV);
-  curr->setContext(ctx);
+  argStack->append(args);
+  put(exec,"arguments",args,ReadOnly|DontDelete|DontEnum);
+}
 
-  int numScopes = 0;
-  if (extraScope) {
-    ListIterator scopeIt = extraScope->begin();
-    for (; scopeIt != extraScope->end(); scopeIt++) {
-      KJSO obj(*scopeIt);
-      ctx->pushScope(obj);
-      numScopes++;
-    }
+void FunctionImp::popArgs(ExecState *exec)
+{
+  argStack->removeLast();
+  if (argStack->isEmpty()) {
+    put(exec,"arguments",Null(),ReadOnly|DontDelete|DontEnum);
   }
-
-  // assign user supplied arguments to parameters
-  processParameters(args);
-
-  Completion comp = execute(*args);
-
-  if (dummyList)
-    delete args;
-
-  int i;
-  for (i = 0; i < numScopes; i++)
-    ctx->popScope();
-
-  put("arguments", Null());
-  delete ctx;
-  curr->setContext(save);
-
-#ifdef KJS_VERBOSE
-  if (comp.complType() == Throw)
-    printInfo("throwing", comp.value());
-  else if (comp.complType() == ReturnValue)
-    printInfo("returning", comp.value());
   else
-    fprintf(stderr, "returning: undefined\n");
-#endif
-#ifdef KJS_DEBUGGER
-  if (KJScriptImp::current()->debugger())
-    KJScriptImp::current()->debugger()->returnEvent();
-#endif
-
-  if (comp.complType() == Throw)
-    return comp.value();
-  else if (comp.complType() == ReturnValue)
-    return comp.value();
-  else
-    return Undefined();
+    put(exec,"arguments",argStack->at(argStack->size()-1),ReadOnly|DontDelete|DontEnum);
 }
 
-UString FunctionImp::name() const
-{
-  return ident;
-}
+// ------------------------------ DeclaredFunctionImp --------------------------
+
+// ### is "Function" correct here?
+const ClassInfo DeclaredFunctionImp::info = {"Function", &FunctionImp::info, 0, 0};
 
-InternalFunctionImp::InternalFunctionImp()
+DeclaredFunctionImp::DeclaredFunctionImp(ExecState *exec, const UString &n,
+                                        FunctionBodyNode *b, const List &sc)
+  : FunctionImp(exec,n), body(b)
 {
+  Value protect(this);
+  body->ref();
+  setScope(sc.copy());
 }
 
-InternalFunctionImp::InternalFunctionImp(int l)
+DeclaredFunctionImp::~DeclaredFunctionImp()
 {
-  if (l >= 0)
-    setLength(l);
+  if ( body->deref() )
+    delete body;
 }
 
-InternalFunctionImp::InternalFunctionImp(const UString &n)
-  : FunctionImp(n)
+bool DeclaredFunctionImp::implementsConstruct() const
 {
+  return true;
 }
 
-String InternalFunctionImp::toString() const
+// ECMA 13.2.2 [[Construct]]
+Object DeclaredFunctionImp::construct(ExecState *exec, const List &args)
 {
-  if (name().isNull())
-    return UString("(Internal function)");
+  Object proto;
+  Value p = get(exec,"prototype");
+  if (p.type() == ObjectType)
+    proto = Object(static_cast<ObjectImp*>(p.imp()));
   else
-    return UString("function " + name() + "()");
-}
+    proto = exec->interpreter()->builtinObjectPrototype();
 
-Completion InternalFunctionImp::execute(const List &)
-{
-  return Completion(ReturnValue, Undefined());
-}
+  Object obj(new ObjectImp(proto));
 
-ConstructorImp::ConstructorImp() {
-  setPrototype(Global::current().functionPrototype());
-  // TODO ???  put("constructor", this);
-  setLength(1);
-}
+  Value res = call(exec,obj,args);
 
-ConstructorImp::ConstructorImp(const UString &n)
-  : InternalFunctionImp(n)
-{
+  if (res.type() == ObjectType)
+    return Object::dynamicCast(res);
+  else
+    return obj;
 }
 
-ConstructorImp::ConstructorImp(const KJSO &p, int len)
+Completion DeclaredFunctionImp::execute(ExecState *exec)
 {
-  setPrototype(p);
-  // TODO ???  put("constructor", *this);
-  setLength(len);
+  Completion result = body->execute(exec);
+
+  if (result.complType() == Throw || result.complType() == ReturnValue)
+      return result;
+  return Completion(Normal, Undefined()); // TODO: or ReturnValue ?
 }
 
-ConstructorImp::ConstructorImp(const UString &n, const KJSO &p, int len)
-  : InternalFunctionImp(n)
+void DeclaredFunctionImp::processVarDecls(ExecState *exec)
 {
-  setPrototype(p);
-  // TODO ???  put("constructor", *this);
-  setLength(len);
+  body->processVarDecls(exec);
 }
 
-ConstructorImp::~ConstructorImp() { }
+// ------------------------------ ArgumentsImp ---------------------------------
 
-Completion ConstructorImp::execute(const List &)
-{
-  /* TODO */
-  return Completion(ReturnValue, Null());
-}
+const ClassInfo ArgumentsImp::info = {"Arguments", 0, 0, 0};
 
-Function::Function(Imp *d)
-  : KJSO(d)
+// ECMA 10.1.8
+ArgumentsImp::ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args)
+  : ObjectImp(exec->interpreter()->builtinObjectPrototype())
 {
-  if (d) {
-    static_cast<FunctionImp*>(rep)->attr = ImplicitNone;
-    assert(Global::current().hasProperty("[[Function.prototype]]"));
-    setPrototype(Global::current().functionPrototype());
+  Value protect(this);
+  put(exec,"callee", Object(func), DontEnum);
+  put(exec,"length", Number(args.size()), DontEnum);
+  if (!args.isEmpty()) {
+    ListIterator arg = args.begin();
+    for (int i = 0; arg != args.end(); arg++, i++) {
+      put(exec,UString::from(i), *arg, DontEnum);
+    }
   }
 }
 
-Completion Function::execute(const List &args)
-{
-  assert(rep);
-  return static_cast<FunctionImp*>(rep)->execute(args);
-}
+// ------------------------------ ActivationImp --------------------------------
 
-bool Function::hasAttribute(FunctionAttribute a) const
-{
-  assert(rep);
-  return static_cast<FunctionImp*>(rep)->hasAttribute(a);
-}
+const ClassInfo ActivationImp::info = {"Activation", 0, 0, 0};
 
-#if 0
-InternalFunction::InternalFunction(Imp *d)
-  : Function(d)
+// ECMA 10.1.6
+ActivationImp::ActivationImp(ExecState *exec, FunctionImp *f, const List &args)
+  : ObjectImp()
 {
-  param = 0L;
+  Value protect(this);
+  arguments = new ArgumentsImp(exec,f, args);
+  put(exec, "arguments", Object(arguments), Internal|DontDelete);
 }
 
-InternalFunction::~InternalFunction()
+ActivationImp::~ActivationImp()
 {
+  arguments->setGcAllowed();
 }
-#endif
 
-Constructor::Constructor(Imp *d)
-  : Function(d)
-{
-  if (d) {
-    assert(Global::current().hasProperty("[[Function.prototype]]"));
-    setPrototype(Global::current().get("[[Function.prototype]]"));
-    put("constructor", *this);
-    KJSO tmp(d); // protect from GC
-    ((FunctionImp*)d)->setLength(1);
-  }
-}
+// ------------------------------ GlobalFunc -----------------------------------
 
-#if 0
-Constructor::Constructor(const Object& proto, int len)
-{
-  setPrototype(proto);
-  put("constructor", *this);
-  put("length", len, DontEnum);
-}
-#endif
 
-Constructor::~Constructor()
+GlobalFuncImp::GlobalFuncImp(ExecState *exec, FunctionPrototypeImp *funcProto, int i, int len)
+  : InternalFunctionImp(funcProto), id(i)
 {
+  Value protect(this);
+  put(exec,"length",Number(len),DontDelete|ReadOnly|DontEnum);
 }
 
-Completion Constructor::execute(const List &)
+CodeType GlobalFuncImp::codeType() const
 {
-  /* TODO: call construct instead ? */
-  return Completion(ReturnValue, Undefined());
+  return id == Eval ? EvalCode : codeType();
 }
 
-Object Constructor::construct(const List &args)
+bool GlobalFuncImp::implementsCall() const
 {
-  assert(rep && rep->type() == ConstructorType);
-  return ((ConstructorImp*)rep)->construct(args);
+  return true;
 }
 
-Constructor Constructor::dynamicCast(const KJSO &obj)
+Value GlobalFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args)
 {
-  // return null object on type mismatch
-  if (!obj.isA(ConstructorType))
-    return Constructor(0L);
-
-  return Constructor(obj.imp());
-}
+  Value res;
+
+  static const char non_escape[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                  "abcdefghijklmnopqrstuvwxyz"
+                                  "0123456789@*_+-./";
+
+  if (id == Eval) { // eval()
+    Value x = args[0];
+    if (x.type() != StringType)
+      return x;
+    else {
+      UString s = x.toString(exec);
+
+      int sid;
+      int errLine;
+      UString errMsg;
+      ProgramNode *progNode = Parser::parse(s.data(),s.size(),&sid,&errLine,&errMsg);
+
+      // no program node means a syntax occurred
+      if (!progNode) {
+       Object err = Error::create(exec,SyntaxError,errMsg.ascii(),errLine);
+        err.put(exec,"sid",Number(sid));
+        exec->setException(err);
+        return err;
+      }
+
+      progNode->ref();
+
+      // enter a new execution context
+      Object glob(exec->interpreter()->globalObject());
+      Object thisVal(Object::dynamicCast(exec->context().thisValue()));
+      ContextImp *ctx = new ContextImp(glob,
+                                       exec,
+                                       thisVal,
+                                       EvalCode,
+                                       exec->context().imp());
+
+      ExecState *newExec = new ExecState(exec->interpreter(),ctx);
+      newExec->setException(exec->exception()); // could be null
+
+      // execute the code
+      Completion c = progNode->execute(newExec);
+
+      // if an exception occured, propogate it back to the previous execution object
+      if (newExec->hadException())
+        exec->setException(newExec->exception());
+      delete newExec;
+      delete ctx;
+
+      if ( progNode->deref() )
+          delete progNode;
+      if (c.complType() == ReturnValue)
+         return c;
+      // ### setException() on throw?
+      else if (c.complType() == Normal) {
+         if (c.isValueCompletion())
+             return c.value();
+         else
+             return Undefined();
+      } else
+         return c;
+    }
+  } else if (id == ParseInt) {
+    String str = args[0].toString(exec);
+    int radix = args[1].toInt32(exec);
+    if (radix == 0)
+      radix = 10;
+    else if (radix < 2 || radix > 36) {
+      res = Number(NaN);
+      return res;
+    }
+    /* TODO: use radix */
+    // Can't use toULong(), we want to accept floating point values too
+    double value = str.value().toDouble( true /*tolerant*/ );
+    if ( isNaN(value) )
+        res = Number(NaN);
+    else
+        res = Number(static_cast<long>(value)); // remove floating-point part
+  } else if (id == ParseFloat) {
+    String str = args[0].toString(exec);
+    res = Number(str.value().toDouble( true /*tolerant*/ ));
+  } else if (id == IsNaN) {
+    res = Boolean(isNaN(args[0].toNumber(exec)));
+  } else if (id == IsFinite) {
+    Number n = args[0].toNumber(exec);
+    res = Boolean(!n.isNaN() && !n.isInf());
+  } else if (id == Escape) {
+    UString r = "", s, str = args[0].toString(exec);
+    const UChar *c = str.data();
+    for (int k = 0; k < str.size(); k++, c++) {
+      int u = c->unicode();
+      if (u > 255) {
+       char tmp[7];
+       sprintf(tmp, "%%u%04X", u);
+       s = UString(tmp);
+      } else if (strchr(non_escape, (char)u)) {
+       s = UString(c, 1);
+      } else {
+       char tmp[4];
+       sprintf(tmp, "%%%02X", u);
+       s = UString(tmp);
+      }
+      r += s;
+    }
+    res = String(r);
+  } else if (id == UnEscape) {
+    UString s, str = args[0].toString(exec);
+    int k = 0, len = str.size();
+    while (k < len) {
+      const UChar *c = str.data() + k;
+      UChar u;
+      if (*c == UChar('%') && k <= len - 6 && *(c+1) == UChar('u')) {
+       u = Lexer::convertUnicode((c+2)->unicode(), (c+3)->unicode(),
+                                 (c+4)->unicode(), (c+5)->unicode());
+       c = &u;
+       k += 5;
+      } else if (*c == UChar('%') && k <= len - 3) {
+       u = UChar(Lexer::convertHex((c+1)->unicode(), (c+2)->unicode()));
+       c = &u;
+       k += 2;
+      }
+      k++;
+      s += UString(c, 1);
+    }
+    res = String(s);
+  }
 
-KJSO Function::thisValue() const
-{
-  return KJSO(Context::current()->thisValue());
+  return res;
 }
index 70c1f3a8b7fa6ee4641ee08f323656b9ea55b8be..56d349163bef8ae2772bafbeb6aa016df7b8f4fe 100644 (file)
@@ -1,3 +1,4 @@
+// -*- c-basic-offset: 2 -*-
 /*
  *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  along with this library; see the file COPYING.LIB.  If not, write to
  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  *  Boston, MA 02111-1307, USA.
+ *
+ *  $Id$
  */
 
 #ifndef _KJS_FUNCTION_H_
 #define _KJS_FUNCTION_H_
 
-#include <assert.h>
-
-#include "object.h"
-#include "types.h"
+#include "internal.h"
 
 namespace KJS {
 
-  enum CodeType { GlobalCode,
-                 EvalCode,
-                 FunctionCode,
-                 AnonymousCode,
-                 HostCode };
-
-  enum FunctionAttribute { ImplicitNone, ImplicitThis, ImplicitParents };
-
-  class Function;
   class Parameter;
 
   /**
-   * @short Implementation class for Functions.
+   * @short Implementation class for internal Functions.
    */
-  class FunctionImp : public ObjectImp {
+  class FunctionImp : public InternalFunctionImp {
     friend class Function;
+    friend class ActivationImp;
   public:
-    FunctionImp();
-    FunctionImp(const UString &n);
+    FunctionImp(ExecState *exec, const UString &n = UString::null);
     virtual ~FunctionImp();
-    virtual const TypeInfo* typeInfo() const { return &info; }
-    static const TypeInfo info;
-    virtual Completion execute(const List &) = 0;
-    bool hasAttribute(FunctionAttribute a) const { return (attr & a) != 0; }
-    virtual CodeType codeType() const = 0;
-    KJSO thisValue() const;
+
+    virtual void mark();
+
+    virtual bool implementsCall() const;
+    virtual Value call(ExecState *exec, Object &thisObj, const List &args);
+
     void addParameter(const UString &n);
-    void setLength(int l);
-    KJSO executeCall(Imp *thisV, const List *args);
-    KJSO executeCall(Imp *thisV, const List *args, const List *extraScope);
-    UString name() const;
+    virtual CodeType codeType() const = 0;
+
+    virtual Completion execute(ExecState *exec) = 0;
+    UString name() const { return ident; }
+
+    virtual const ClassInfo *classInfo() const { return &info; }
+    static const ClassInfo info;
   protected:
-    UString ident;
-    FunctionAttribute attr;
     Parameter *param;
+    UString ident;
+
   private:
-    void processParameters(const List *);
+    void processParameters(ExecState *exec, const List &);
+    virtual void processVarDecls(ExecState *exec);
+
+    void pushArgs(ExecState *exec, const Object &args);
+    void popArgs(ExecState *exec);
+    ListImp *argStack;
   };
 
-  /**
-   * @short Abstract base class for internal functions.
-   */
-  class InternalFunctionImp : public FunctionImp {
+  class DeclaredFunctionImp : public FunctionImp {
   public:
-    InternalFunctionImp();
-    InternalFunctionImp(int l);
-    InternalFunctionImp(const UString &n);
-    virtual ~InternalFunctionImp() { }
-    virtual String toString() const;
-    virtual KJSO toPrimitive(Type) const { return toString(); }
-    virtual const TypeInfo* typeInfo() const { return &info; }
-    static const TypeInfo info;
-    virtual Completion execute(const List &);
-    virtual CodeType codeType() const { return HostCode; }
+    DeclaredFunctionImp(ExecState *exec, const UString &n,
+                       FunctionBodyNode *b, const List &sc);
+    ~DeclaredFunctionImp();
+
+    bool implementsConstruct() const;
+    Object construct(ExecState *exec, const List &args);
+
+    virtual Completion execute(ExecState *exec);
+    CodeType codeType() const { return FunctionCode; }
+    FunctionBodyNode *body;
+
+    virtual const ClassInfo *classInfo() const { return &info; }
+    static const ClassInfo info;
+  private:
+    virtual void processVarDecls(ExecState *exec);
   };
 
-  /**
-   * @short Base class for Function objects.
-   */
-  class Function : public KJSO {
+
+
+
+  class ArgumentsImp : public ObjectImp {
   public:
-    Function(Imp *);
-    virtual ~Function() { }
-    Completion execute(const List &);
-    bool hasAttribute(FunctionAttribute a) const;
-    CodeType codeType() const { return HostCode; }
-    KJSO thisValue() const;
+    ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args);