From 6141d2ef50accda85661cc665f1d25de1e5ae862 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Tue, 18 Nov 2014 13:35:43 +0000 Subject: [PATCH] removed kjs and kjsembed --- CMakeLists.txt | 11 +- kjs/CMakeLists.txt | 284 -- kjs/CommonIdentifiers.cpp | 49 - kjs/CommonIdentifiers.h | 103 - kjs/CompileState.cpp | 292 -- kjs/CompileState.h | 394 -- kjs/DESIGN.ideas | 110 - kjs/ExecState.cpp | 301 -- kjs/ExecState.h | 306 -- kjs/JSImmediate.cpp | 77 - kjs/JSImmediate.h | 311 -- kjs/JSLock.cpp | 84 - kjs/JSLock.h | 85 - kjs/JSType.h | 43 - kjs/JSVariableObject.cpp | 89 - kjs/JSVariableObject.h | 181 - kjs/JSWrapperObject.cpp | 36 - kjs/JSWrapperObject.h | 96 - kjs/LocalStorage.h | 68 - kjs/Mainpage.dox | 30 - kjs/Parser.cpp | 147 - kjs/Parser.h | 106 - kjs/PropertyNameArray.cpp | 35 - kjs/PropertyNameArray.h | 58 - kjs/README | 27 - kjs/SavedBuiltins.h | 81 - kjs/SymbolTable.h | 52 - kjs/THANKS | 7 - kjs/api/CMakeLists.txt | 31 - kjs/api/Mainpage.dox | 37 - kjs/api/kjsapi_export.h | 40 - kjs/api/kjsapitest.cpp | 279 -- kjs/api/kjsarguments.cpp | 39 - kjs/api/kjsarguments.h | 58 - kjs/api/kjscontext.cpp | 58 - kjs/api/kjscontext.h | 68 - kjs/api/kjsinterpreter.cpp | 218 - kjs/api/kjsinterpreter.h | 162 - kjs/api/kjsobject.cpp | 248 - kjs/api/kjsobject.h | 294 -- kjs/api/kjsprivate.h | 67 - kjs/api/kjsprototype.cpp | 311 -- kjs/api/kjsprototype.h | 133 - kjs/array_instance.cpp | 978 ---- kjs/array_instance.h | 88 - kjs/array_object.cpp | 741 --- kjs/array_object.h | 70 - kjs/bool_object.cpp | 131 - kjs/bool_object.h | 91 - kjs/bytecode/codes.def | 1286 ----- kjs/bytecode/generator/codeprinter.cpp | 178 - kjs/bytecode/generator/codeprinter.h | 105 - kjs/bytecode/generator/driver.cpp | 57 - kjs/bytecode/generator/filetemplate.h | 113 - kjs/bytecode/generator/generator.pro | 6 - kjs/bytecode/generator/lexer.cpp | 210 - kjs/bytecode/generator/lexer.h | 154 - kjs/bytecode/generator/parser.cpp | 363 -- kjs/bytecode/generator/parser.h | 117 - kjs/bytecode/generator/tablebuilder.cpp | 449 -- kjs/bytecode/generator/tablebuilder.h | 108 - kjs/bytecode/generator/types.cpp | 287 -- kjs/bytecode/generator/types.h | 135 - kjs/bytecode/machine.cpp.in | 260 - kjs/bytecode/machine.h | 42 - kjs/bytecode/opargs.h | 101 - kjs/bytecode/opcodes.cpp.in | 435 -- kjs/bytecode/opcodes.h.in | 136 - kjs/collector.cpp | 938 ---- kjs/collector.h | 192 - kjs/commonunicode.h | 83 - kjs/completion.h | 85 - kjs/config-kjs.h.cmake | 38 - kjs/context.h | 1 - kjs/create_hash_table | 274 - kjs/create_parser | 16 - kjs/date_object.cpp | 1491 ------ kjs/date_object.h | 109 - kjs/debugger.cpp | 162 - kjs/debugger.h | 240 - kjs/dtoa.cpp | 3204 ------------ kjs/dtoa.h | 31 - kjs/error_object.cpp | 175 - kjs/error_object.h | 90 - kjs/fpconst.cpp | 87 - kjs/function.cpp | 1216 ----- kjs/function.h | 235 - kjs/function_object.cpp | 307 -- kjs/function_object.h | 66 - kjs/global.h.cmake | 92 - kjs/grammar.cpp | 4398 ----------------- kjs/grammar.h | 186 - kjs/grammar.y | 942 ---- kjs/identifier.cpp | 169 - kjs/identifier.h | 132 - kjs/internal.cpp | 365 -- kjs/internal.h | 131 - kjs/interpreter.cpp | 1033 ---- kjs/interpreter.h | 564 --- kjs/json_object.cpp | 186 - kjs/json_object.h | 52 - kjs/jsonlexer.cpp | 642 --- kjs/jsonlexer.h | 105 - kjs/jsonstringify.cpp | 409 -- kjs/jsonstringify.h | 81 - kjs/keywords.table | 72 - kjs/kjs-devel-gdb | 22 - kjs/kjs.cpp | 290 -- kjs/lexer.cpp | 955 ---- kjs/lexer.h | 157 - kjs/libkjs.map | 30 - kjs/list.cpp | 320 -- kjs/list.h | 222 - kjs/lookup.cpp | 95 - kjs/lookup.h | 422 -- kjs/makenodes.h | 318 -- kjs/math_object.cpp | 369 -- kjs/math_object.h | 58 - kjs/nodes.cpp | 1178 ----- kjs/nodes.h | 1277 ----- kjs/nodes2bytecode.cpp | 1678 ------- kjs/nodes2bytecode.h | 37 - kjs/nodes2string.cpp | 836 ---- kjs/number_object.cpp | 591 --- kjs/number_object.h | 113 - kjs/object.cpp | 860 ---- kjs/object.h | 637 --- kjs/object_object.cpp | 466 -- kjs/object_object.h | 85 - kjs/operations.cpp | 287 -- kjs/operations.h | 103 - kjs/package.cpp | 51 - kjs/package.h | 79 - kjs/property_map.cpp | 799 --- kjs/property_map.h | 169 - kjs/property_slot.cpp | 40 - kjs/property_slot.h | 179 - kjs/propertydescriptor.cpp | 293 -- kjs/propertydescriptor.h | 105 - kjs/protect.h | 143 - kjs/regexp.cpp | 599 --- kjs/regexp.h | 122 - kjs/regexp_object.cpp | 519 -- kjs/regexp_object.h | 119 - kjs/scope_chain.cpp | 56 - kjs/scope_chain.h | 227 - kjs/scriptfunction.h | 117 - kjs/string_object.cpp | 935 ---- kjs/string_object.h | 141 - kjs/test.js | 29 - kjs/tests/CMakeLists.txt | 70 - kjs/tests/ecmatest.cpp | 395 -- kjs/tests/ecmatest.h | 34 - kjs/tests/ecmatest_broken_bestPractice | 11 - kjs/tests/ecmatest_broken_ch07 | 93 - kjs/tests/ecmatest_broken_ch08 | 8 - kjs/tests/ecmatest_broken_ch09 | 2 - kjs/tests/ecmatest_broken_ch10 | 154 - kjs/tests/ecmatest_broken_ch11 | 139 - kjs/tests/ecmatest_broken_ch12 | 51 - kjs/tests/ecmatest_broken_ch13 | 81 - kjs/tests/ecmatest_broken_ch14 | 12 - kjs/tests/ecmatest_broken_ch15.1 | 15 - kjs/tests/ecmatest_broken_ch15.10 | 26 - kjs/tests/ecmatest_broken_ch15.11 | 0 kjs/tests/ecmatest_broken_ch15.12 | 0 kjs/tests/ecmatest_broken_ch15.2 | 50 - kjs/tests/ecmatest_broken_ch15.3 | 87 - kjs/tests/ecmatest_broken_ch15.4 | 98 - kjs/tests/ecmatest_broken_ch15.5 | 21 - kjs/tests/ecmatest_broken_ch15.6 | 0 kjs/tests/ecmatest_broken_ch15.7 | 0 kjs/tests/ecmatest_broken_ch15.8 | 0 kjs/tests/ecmatest_broken_ch15.9 | 49 - kjs/tests/testkjs.cpp | 368 -- kjs/tests/updateBroken.sh | 13 - kjs/types.h | 30 - kjs/ustring.cpp | 1474 ------ kjs/ustring.h | 521 -- kjs/value.cpp | 240 - kjs/value.h | 561 --- kjs/wtf/ASCIICType.h | 132 - kjs/wtf/AlwaysInline.h | 49 - kjs/wtf/Assertions.h | 49 - kjs/wtf/CMakeLists.txt | 18 - kjs/wtf/DisallowCType.h | 74 - kjs/wtf/FastMalloc.h | 69 - kjs/wtf/Forward.h | 43 - kjs/wtf/GetPtr.h | 33 - kjs/wtf/HashCountedSet.h | 206 - kjs/wtf/HashFunctions.h | 179 - kjs/wtf/HashIterators.h | 217 - kjs/wtf/HashMap.h | 335 -- kjs/wtf/HashSet.h | 273 - kjs/wtf/HashTable.cpp | 60 - kjs/wtf/HashTable.h | 1140 ----- kjs/wtf/HashTraits.h | 148 - kjs/wtf/ListRefPtr.h | 59 - kjs/wtf/Mainpage.dox | 18 - kjs/wtf/MathExtras.h | 128 - kjs/wtf/Noncopyable.h | 45 - kjs/wtf/OwnArrayPtr.h | 67 - kjs/wtf/OwnPtr.h | 65 - kjs/wtf/PassRefPtr.h | 193 - kjs/wtf/Platform.h | 226 - kjs/wtf/RefCounted.h | 80 - kjs/wtf/RefPtr.h | 203 - kjs/wtf/RefPtrHashMap.h | 337 -- kjs/wtf/SharedPtr.h | 131 - kjs/wtf/UnusedParam.h | 30 - kjs/wtf/Vector.h | 886 ---- kjs/wtf/VectorTraits.h | 117 - kjs/wtf/unicode/Unicode.h | 39 - kjs/wtf/unicode/UnicodeCategory.h | 65 - kjs/wtf/unicode/libc/UnicodeLibC.h | 157 - kjs/wtf/unicode/qt4/UnicodeQt4.h | 138 - kjsembed/AUTHORS | 6 - kjsembed/CMakeLists.txt | 11 - kjsembed/Mainpage.dox | 33 - kjsembed/examples/calc/calc.js | 67 - kjsembed/examples/calc/calc.ui | 148 - kjsembed/examples/console/console.js | 34 - kjsembed/examples/console/console.ui | 42 - kjsembed/examples/docviewer/docviewer.js | 56 - kjsembed/examples/docviewer/docviewer.ui | 47 - kjsembed/examples/fancy/fancy.js | 34 - kjsembed/examples/grammar/grammar.js | 224 - kjsembed/examples/kjsconsole/CMakeLists.txt | 34 - kjsembed/examples/kjsconsole/console.cpp | 149 - kjsembed/examples/kjsconsole/console.h | 55 - kjsembed/examples/kjsconsole/console.qrc | 15 - kjsembed/examples/kjsconsole/images/bug.png | Bin 992 -> 0 bytes kjsembed/examples/kjsconsole/images/class.png | Bin 143 -> 0 bytes .../examples/kjsconsole/images/constant.png | Bin 143 -> 0 bytes .../examples/kjsconsole/images/method.png | Bin 143 -> 0 bytes kjsembed/examples/kjsconsole/images/next.png | Bin 761 -> 0 bytes kjsembed/examples/kjsconsole/images/no.png | Bin 721 -> 0 bytes .../examples/kjsconsole/images/property.png | Bin 143 -> 0 bytes kjsembed/examples/kjsconsole/images/runto.png | Bin 358 -> 0 bytes kjsembed/examples/kjsconsole/images/start.png | Bin 735 -> 0 bytes kjsembed/examples/kjsconsole/images/step.png | Bin 761 -> 0 bytes kjsembed/examples/kjsconsole/images/stop.png | Bin 785 -> 0 bytes kjsembed/examples/kjsconsole/jsconsole.ui | 247 - .../examples/kjsconsole/kjs_object_model.cpp | 185 - .../examples/kjsconsole/kjs_object_model.h | 57 - kjsembed/examples/kjsconsole/main.cpp | 31 - .../examples/kjsconsole/numberedtextview.cpp | 284 -- .../examples/kjsconsole/numberedtextview.h | 148 - kjsembed/examples/scribble/scribble.js | 38 - kjsembed/examples/tests/args.js | 26 - kjsembed/examples/tests/brush.js | 48 - kjsembed/examples/tests/builtins.js | 5 - kjsembed/examples/tests/class.js | 32 - kjsembed/examples/tests/colortest.js | 46 - kjsembed/examples/tests/conio.js | 27 - kjsembed/examples/tests/domtest.js | 51 - kjsembed/examples/tests/events.js | 30 - kjsembed/examples/tests/fileio.js | 43 - kjsembed/examples/tests/fonttest.js | 23 - kjsembed/examples/tests/frame.js | 27 - kjsembed/examples/tests/gc.js | 47 - kjsembed/examples/tests/include.js | 23 - kjsembed/examples/tests/inner.js | 21 - kjsembed/examples/tests/jsslot.js | 43 - kjsembed/examples/tests/layout.js | 34 - kjsembed/examples/tests/library.js | 5 - kjsembed/examples/tests/listproperties.js | 3 - kjsembed/examples/tests/matt.js | 21 - kjsembed/examples/tests/paintertest.js | 36 - kjsembed/examples/tests/paintevent.js | 52 - kjsembed/examples/tests/pixmap.js | 34 - kjsembed/examples/tests/recttest.js | 30 - kjsembed/examples/tests/settings.js | 30 - kjsembed/examples/tests/signslots.js | 37 - kjsembed/examples/tests/statictest.js | 32 - kjsembed/examples/tests/stylesheet.js | 8 - kjsembed/examples/tests/svgtest.js | 37 - kjsembed/examples/tests/system.js | 23 - kjsembed/examples/tests/test.svg | 24 - kjsembed/examples/tests/test.ui | 69 - kjsembed/examples/tests/typecheck.js | 28 - kjsembed/examples/tests/uitest.js | 47 - kjsembed/examples/tests/uitest2.js | 54 - kjsembed/examples/tests/url.js | 15 - kjsembed/examples/tests/widgettest.js | 30 - kjsembed/kjscmd/CMakeLists.txt | 46 - kjsembed/kjscmd/console.js | 22 - kjsembed/kjscmd/kjscmd.cpp | 221 - kjsembed/kjscmd/kjscmd.qrc | 5 - kjsembed/kjsembed/CMakeLists.txt | 79 - kjsembed/kjsembed/QBrush_bind.cpp | 303 -- kjsembed/kjsembed/QBrush_bind.h | 36 - kjsembed/kjsembed/application.cpp | 76 - kjsembed/kjsembed/application.h | 42 - kjsembed/kjsembed/binding_support.cpp | 250 - kjsembed/kjsembed/binding_support.h | 638 --- kjsembed/kjsembed/brush.cpp | 170 - kjsembed/kjsembed/brush.h | 47 - kjsembed/kjsembed/builtins.cpp | 226 - kjsembed/kjsembed/builtins.h | 43 - kjsembed/kjsembed/color.cpp | 194 - kjsembed/kjsembed/color.h | 75 - kjsembed/kjsembed/dom.cpp | 864 ---- kjsembed/kjsembed/dom.h | 124 - kjsembed/kjsembed/eventproxy.cpp | 147 - kjsembed/kjsembed/eventproxy.h | 77 - kjsembed/kjsembed/filedialog_binding.cpp | 90 - kjsembed/kjsembed/filedialog_binding.h | 40 - kjsembed/kjsembed/fileio.cpp | 136 - kjsembed/kjsembed/fileio.h | 46 - kjsembed/kjsembed/font.cpp | 351 -- kjsembed/kjsembed/font.h | 52 - kjsembed/kjsembed/image.cpp | 350 -- kjsembed/kjsembed/image.h | 51 - kjsembed/kjsembed/iosupport.cpp | 90 - kjsembed/kjsembed/iosupport.h | 40 - kjsembed/kjsembed/jseventmapper.cpp | 299 -- kjsembed/kjsembed/jseventmapper.h | 85 - kjsembed/kjsembed/jseventutils.cpp | 318 -- kjsembed/kjsembed/jseventutils.h | 61 - kjsembed/kjsembed/kjseglobal.cpp | 155 - kjsembed/kjsembed/kjseglobal.h | 132 - kjsembed/kjsembed/kjsembed.cpp | 310 -- kjsembed/kjsembed/kjsembed.h | 145 - kjsembed/kjsembed/object_binding.cpp | 114 - kjsembed/kjsembed/object_binding.h | 273 - kjsembed/kjsembed/pen.cpp | 151 - kjsembed/kjsembed/pen.h | 49 - kjsembed/kjsembed/pixmap.cpp | 318 -- kjsembed/kjsembed/pixmap.h | 52 - kjsembed/kjsembed/point.cpp | 109 - kjsembed/kjsembed/point.h | 48 - kjsembed/kjsembed/pointer.h | 145 - kjsembed/kjsembed/qaction_binding.cpp | 95 - kjsembed/kjsembed/qaction_binding.h | 40 - kjsembed/kjsembed/qformbuilder_binding.cpp | 73 - kjsembed/kjsembed/qformbuilder_binding.h | 34 - kjsembed/kjsembed/qlayout_binding.cpp | 100 - kjsembed/kjsembed/qlayout_binding.h | 36 - kjsembed/kjsembed/qobject_binding.cpp | 868 ---- kjsembed/kjsembed/qobject_binding.h | 236 - kjsembed/kjsembed/qpainter_binding.cpp | 517 -- kjsembed/kjsembed/qpainter_binding.h | 35 - kjsembed/kjsembed/quiloader_binding.cpp | 158 - kjsembed/kjsembed/quiloader_binding.h | 36 - kjsembed/kjsembed/qwidget_binding.cpp | 173 - kjsembed/kjsembed/qwidget_binding.h | 36 - kjsembed/kjsembed/rect.cpp | 443 -- kjsembed/kjsembed/rect.h | 50 - kjsembed/kjsembed/settings.cpp | 123 - kjsembed/kjsembed/settings.h | 39 - kjsembed/kjsembed/size.cpp | 154 - kjsembed/kjsembed/size.h | 46 - kjsembed/kjsembed/slotproxy.cpp | 323 -- kjsembed/kjsembed/slotproxy.h | 65 - kjsembed/kjsembed/static_binding.cpp | 155 - kjsembed/kjsembed/static_binding.h | 135 - kjsembed/kjsembed/svg_binding.cpp | 127 - kjsembed/kjsembed/svg_binding.h | 38 - kjsembed/kjsembed/test/QByteArray_bind.cpp | 39 - kjsembed/kjsembed/test/QByteArray_bind.h | 38 - kjsembed/kjsembed/url.cpp | 81 - kjsembed/kjsembed/url.h | 49 - kjsembed/kjsembed/util.h | 84 - kjsembed/kjsembed/value_binding.cpp | 72 - kjsembed/kjsembed/value_binding.h | 223 - kjsembed/kjsembed/variant_binding.cpp | 437 -- kjsembed/kjsembed/variant_binding.h | 257 - kjsembed/qtonly/CMakeLists.txt | 141 - kjsembed/qtonly/FindQJSInternal.cmake | 318 -- kjsembed/qtonly/README | 45 - 371 files changed, 2 insertions(+), 74184 deletions(-) delete mode 100644 kjs/CMakeLists.txt delete mode 100644 kjs/CommonIdentifiers.cpp delete mode 100644 kjs/CommonIdentifiers.h delete mode 100644 kjs/CompileState.cpp delete mode 100644 kjs/CompileState.h delete mode 100644 kjs/DESIGN.ideas delete mode 100644 kjs/ExecState.cpp delete mode 100644 kjs/ExecState.h delete mode 100644 kjs/JSImmediate.cpp delete mode 100644 kjs/JSImmediate.h delete mode 100644 kjs/JSLock.cpp delete mode 100644 kjs/JSLock.h delete mode 100644 kjs/JSType.h delete mode 100644 kjs/JSVariableObject.cpp delete mode 100644 kjs/JSVariableObject.h delete mode 100644 kjs/JSWrapperObject.cpp delete mode 100644 kjs/JSWrapperObject.h delete mode 100644 kjs/LocalStorage.h delete mode 100644 kjs/Mainpage.dox delete mode 100644 kjs/Parser.cpp delete mode 100644 kjs/Parser.h delete mode 100644 kjs/PropertyNameArray.cpp delete mode 100644 kjs/PropertyNameArray.h delete mode 100644 kjs/README delete mode 100644 kjs/SavedBuiltins.h delete mode 100644 kjs/SymbolTable.h delete mode 100644 kjs/THANKS delete mode 100644 kjs/api/CMakeLists.txt delete mode 100644 kjs/api/Mainpage.dox delete mode 100644 kjs/api/kjsapi_export.h delete mode 100644 kjs/api/kjsapitest.cpp delete mode 100644 kjs/api/kjsarguments.cpp delete mode 100644 kjs/api/kjsarguments.h delete mode 100644 kjs/api/kjscontext.cpp delete mode 100644 kjs/api/kjscontext.h delete mode 100644 kjs/api/kjsinterpreter.cpp delete mode 100644 kjs/api/kjsinterpreter.h delete mode 100644 kjs/api/kjsobject.cpp delete mode 100644 kjs/api/kjsobject.h delete mode 100644 kjs/api/kjsprivate.h delete mode 100644 kjs/api/kjsprototype.cpp delete mode 100644 kjs/api/kjsprototype.h delete mode 100644 kjs/array_instance.cpp delete mode 100644 kjs/array_instance.h delete mode 100644 kjs/array_object.cpp delete mode 100644 kjs/array_object.h delete mode 100644 kjs/bool_object.cpp delete mode 100644 kjs/bool_object.h delete mode 100644 kjs/bytecode/codes.def delete mode 100644 kjs/bytecode/generator/codeprinter.cpp delete mode 100644 kjs/bytecode/generator/codeprinter.h delete mode 100644 kjs/bytecode/generator/driver.cpp delete mode 100644 kjs/bytecode/generator/filetemplate.h delete mode 100644 kjs/bytecode/generator/generator.pro delete mode 100644 kjs/bytecode/generator/lexer.cpp delete mode 100644 kjs/bytecode/generator/lexer.h delete mode 100644 kjs/bytecode/generator/parser.cpp delete mode 100644 kjs/bytecode/generator/parser.h delete mode 100644 kjs/bytecode/generator/tablebuilder.cpp delete mode 100644 kjs/bytecode/generator/tablebuilder.h delete mode 100644 kjs/bytecode/generator/types.cpp delete mode 100644 kjs/bytecode/generator/types.h delete mode 100644 kjs/bytecode/machine.cpp.in delete mode 100644 kjs/bytecode/machine.h delete mode 100644 kjs/bytecode/opargs.h delete mode 100644 kjs/bytecode/opcodes.cpp.in delete mode 100644 kjs/bytecode/opcodes.h.in delete mode 100644 kjs/collector.cpp delete mode 100644 kjs/collector.h delete mode 100644 kjs/commonunicode.h delete mode 100644 kjs/completion.h delete mode 100644 kjs/config-kjs.h.cmake delete mode 100644 kjs/context.h delete mode 100755 kjs/create_hash_table delete mode 100755 kjs/create_parser delete mode 100644 kjs/date_object.cpp delete mode 100644 kjs/date_object.h delete mode 100644 kjs/debugger.cpp delete mode 100644 kjs/debugger.h delete mode 100644 kjs/dtoa.cpp delete mode 100644 kjs/dtoa.h delete mode 100644 kjs/error_object.cpp delete mode 100644 kjs/error_object.h delete mode 100644 kjs/fpconst.cpp delete mode 100644 kjs/function.cpp delete mode 100644 kjs/function.h delete mode 100644 kjs/function_object.cpp delete mode 100644 kjs/function_object.h delete mode 100644 kjs/global.h.cmake delete mode 100644 kjs/grammar.cpp delete mode 100644 kjs/grammar.h delete mode 100644 kjs/grammar.y delete mode 100644 kjs/identifier.cpp delete mode 100644 kjs/identifier.h delete mode 100644 kjs/internal.cpp delete mode 100644 kjs/internal.h delete mode 100644 kjs/interpreter.cpp delete mode 100644 kjs/interpreter.h delete mode 100644 kjs/json_object.cpp delete mode 100644 kjs/json_object.h delete mode 100644 kjs/jsonlexer.cpp delete mode 100644 kjs/jsonlexer.h delete mode 100644 kjs/jsonstringify.cpp delete mode 100644 kjs/jsonstringify.h delete mode 100644 kjs/keywords.table delete mode 100644 kjs/kjs-devel-gdb delete mode 100644 kjs/kjs.cpp delete mode 100644 kjs/lexer.cpp delete mode 100644 kjs/lexer.h delete mode 100644 kjs/libkjs.map delete mode 100644 kjs/list.cpp delete mode 100644 kjs/list.h delete mode 100644 kjs/lookup.cpp delete mode 100644 kjs/lookup.h delete mode 100644 kjs/makenodes.h delete mode 100644 kjs/math_object.cpp delete mode 100644 kjs/math_object.h delete mode 100644 kjs/nodes.cpp delete mode 100644 kjs/nodes.h delete mode 100644 kjs/nodes2bytecode.cpp delete mode 100644 kjs/nodes2bytecode.h delete mode 100644 kjs/nodes2string.cpp delete mode 100644 kjs/number_object.cpp delete mode 100644 kjs/number_object.h delete mode 100644 kjs/object.cpp delete mode 100644 kjs/object.h delete mode 100644 kjs/object_object.cpp delete mode 100644 kjs/object_object.h delete mode 100644 kjs/operations.cpp delete mode 100644 kjs/operations.h delete mode 100644 kjs/package.cpp delete mode 100644 kjs/package.h delete mode 100644 kjs/property_map.cpp delete mode 100644 kjs/property_map.h delete mode 100644 kjs/property_slot.cpp delete mode 100644 kjs/property_slot.h delete mode 100644 kjs/propertydescriptor.cpp delete mode 100644 kjs/propertydescriptor.h delete mode 100644 kjs/protect.h delete mode 100644 kjs/regexp.cpp delete mode 100644 kjs/regexp.h delete mode 100644 kjs/regexp_object.cpp delete mode 100644 kjs/regexp_object.h delete mode 100644 kjs/scope_chain.cpp delete mode 100644 kjs/scope_chain.h delete mode 100644 kjs/scriptfunction.h delete mode 100644 kjs/string_object.cpp delete mode 100644 kjs/string_object.h delete mode 100644 kjs/test.js delete mode 100644 kjs/tests/CMakeLists.txt delete mode 100644 kjs/tests/ecmatest.cpp delete mode 100644 kjs/tests/ecmatest.h delete mode 100644 kjs/tests/ecmatest_broken_bestPractice delete mode 100644 kjs/tests/ecmatest_broken_ch07 delete mode 100644 kjs/tests/ecmatest_broken_ch08 delete mode 100644 kjs/tests/ecmatest_broken_ch09 delete mode 100644 kjs/tests/ecmatest_broken_ch10 delete mode 100644 kjs/tests/ecmatest_broken_ch11 delete mode 100644 kjs/tests/ecmatest_broken_ch12 delete mode 100644 kjs/tests/ecmatest_broken_ch13 delete mode 100644 kjs/tests/ecmatest_broken_ch14 delete mode 100644 kjs/tests/ecmatest_broken_ch15.1 delete mode 100644 kjs/tests/ecmatest_broken_ch15.10 delete mode 100644 kjs/tests/ecmatest_broken_ch15.11 delete mode 100644 kjs/tests/ecmatest_broken_ch15.12 delete mode 100644 kjs/tests/ecmatest_broken_ch15.2 delete mode 100644 kjs/tests/ecmatest_broken_ch15.3 delete mode 100644 kjs/tests/ecmatest_broken_ch15.4 delete mode 100644 kjs/tests/ecmatest_broken_ch15.5 delete mode 100644 kjs/tests/ecmatest_broken_ch15.6 delete mode 100644 kjs/tests/ecmatest_broken_ch15.7 delete mode 100644 kjs/tests/ecmatest_broken_ch15.8 delete mode 100644 kjs/tests/ecmatest_broken_ch15.9 delete mode 100644 kjs/tests/testkjs.cpp delete mode 100755 kjs/tests/updateBroken.sh delete mode 100644 kjs/types.h delete mode 100644 kjs/ustring.cpp delete mode 100644 kjs/ustring.h delete mode 100644 kjs/value.cpp delete mode 100644 kjs/value.h delete mode 100644 kjs/wtf/ASCIICType.h delete mode 100644 kjs/wtf/AlwaysInline.h delete mode 100644 kjs/wtf/Assertions.h delete mode 100644 kjs/wtf/CMakeLists.txt delete mode 100644 kjs/wtf/DisallowCType.h delete mode 100644 kjs/wtf/FastMalloc.h delete mode 100644 kjs/wtf/Forward.h delete mode 100644 kjs/wtf/GetPtr.h delete mode 100644 kjs/wtf/HashCountedSet.h delete mode 100644 kjs/wtf/HashFunctions.h delete mode 100644 kjs/wtf/HashIterators.h delete mode 100644 kjs/wtf/HashMap.h delete mode 100644 kjs/wtf/HashSet.h delete mode 100644 kjs/wtf/HashTable.cpp delete mode 100644 kjs/wtf/HashTable.h delete mode 100644 kjs/wtf/HashTraits.h delete mode 100644 kjs/wtf/ListRefPtr.h delete mode 100644 kjs/wtf/Mainpage.dox delete mode 100644 kjs/wtf/MathExtras.h delete mode 100644 kjs/wtf/Noncopyable.h delete mode 100644 kjs/wtf/OwnArrayPtr.h delete mode 100644 kjs/wtf/OwnPtr.h delete mode 100644 kjs/wtf/PassRefPtr.h delete mode 100644 kjs/wtf/Platform.h delete mode 100644 kjs/wtf/RefCounted.h delete mode 100644 kjs/wtf/RefPtr.h delete mode 100644 kjs/wtf/RefPtrHashMap.h delete mode 100644 kjs/wtf/SharedPtr.h delete mode 100644 kjs/wtf/UnusedParam.h delete mode 100644 kjs/wtf/Vector.h delete mode 100644 kjs/wtf/VectorTraits.h delete mode 100644 kjs/wtf/unicode/Unicode.h delete mode 100644 kjs/wtf/unicode/UnicodeCategory.h delete mode 100644 kjs/wtf/unicode/libc/UnicodeLibC.h delete mode 100644 kjs/wtf/unicode/qt4/UnicodeQt4.h delete mode 100644 kjsembed/AUTHORS delete mode 100644 kjsembed/CMakeLists.txt delete mode 100644 kjsembed/Mainpage.dox delete mode 100644 kjsembed/examples/calc/calc.js delete mode 100644 kjsembed/examples/calc/calc.ui delete mode 100644 kjsembed/examples/console/console.js delete mode 100644 kjsembed/examples/console/console.ui delete mode 100644 kjsembed/examples/docviewer/docviewer.js delete mode 100644 kjsembed/examples/docviewer/docviewer.ui delete mode 100644 kjsembed/examples/fancy/fancy.js delete mode 100644 kjsembed/examples/grammar/grammar.js delete mode 100644 kjsembed/examples/kjsconsole/CMakeLists.txt delete mode 100644 kjsembed/examples/kjsconsole/console.cpp delete mode 100644 kjsembed/examples/kjsconsole/console.h delete mode 100644 kjsembed/examples/kjsconsole/console.qrc delete mode 100644 kjsembed/examples/kjsconsole/images/bug.png delete mode 100644 kjsembed/examples/kjsconsole/images/class.png delete mode 100644 kjsembed/examples/kjsconsole/images/constant.png delete mode 100644 kjsembed/examples/kjsconsole/images/method.png delete mode 100644 kjsembed/examples/kjsconsole/images/next.png delete mode 100644 kjsembed/examples/kjsconsole/images/no.png delete mode 100644 kjsembed/examples/kjsconsole/images/property.png delete mode 100644 kjsembed/examples/kjsconsole/images/runto.png delete mode 100644 kjsembed/examples/kjsconsole/images/start.png delete mode 100644 kjsembed/examples/kjsconsole/images/step.png delete mode 100644 kjsembed/examples/kjsconsole/images/stop.png delete mode 100644 kjsembed/examples/kjsconsole/jsconsole.ui delete mode 100644 kjsembed/examples/kjsconsole/kjs_object_model.cpp delete mode 100644 kjsembed/examples/kjsconsole/kjs_object_model.h delete mode 100644 kjsembed/examples/kjsconsole/main.cpp delete mode 100644 kjsembed/examples/kjsconsole/numberedtextview.cpp delete mode 100644 kjsembed/examples/kjsconsole/numberedtextview.h delete mode 100644 kjsembed/examples/scribble/scribble.js delete mode 100644 kjsembed/examples/tests/args.js delete mode 100644 kjsembed/examples/tests/brush.js delete mode 100644 kjsembed/examples/tests/builtins.js delete mode 100644 kjsembed/examples/tests/class.js delete mode 100644 kjsembed/examples/tests/colortest.js delete mode 100644 kjsembed/examples/tests/conio.js delete mode 100644 kjsembed/examples/tests/domtest.js delete mode 100644 kjsembed/examples/tests/events.js delete mode 100644 kjsembed/examples/tests/fileio.js delete mode 100644 kjsembed/examples/tests/fonttest.js delete mode 100644 kjsembed/examples/tests/frame.js delete mode 100644 kjsembed/examples/tests/gc.js delete mode 100644 kjsembed/examples/tests/include.js delete mode 100644 kjsembed/examples/tests/inner.js delete mode 100644 kjsembed/examples/tests/jsslot.js delete mode 100644 kjsembed/examples/tests/layout.js delete mode 100644 kjsembed/examples/tests/library.js delete mode 100644 kjsembed/examples/tests/listproperties.js delete mode 100644 kjsembed/examples/tests/matt.js delete mode 100644 kjsembed/examples/tests/paintertest.js delete mode 100644 kjsembed/examples/tests/paintevent.js delete mode 100644 kjsembed/examples/tests/pixmap.js delete mode 100644 kjsembed/examples/tests/recttest.js delete mode 100644 kjsembed/examples/tests/settings.js delete mode 100644 kjsembed/examples/tests/signslots.js delete mode 100644 kjsembed/examples/tests/statictest.js delete mode 100644 kjsembed/examples/tests/stylesheet.js delete mode 100644 kjsembed/examples/tests/svgtest.js delete mode 100644 kjsembed/examples/tests/system.js delete mode 100644 kjsembed/examples/tests/test.svg delete mode 100644 kjsembed/examples/tests/test.ui delete mode 100644 kjsembed/examples/tests/typecheck.js delete mode 100644 kjsembed/examples/tests/uitest.js delete mode 100644 kjsembed/examples/tests/uitest2.js delete mode 100644 kjsembed/examples/tests/url.js delete mode 100644 kjsembed/examples/tests/widgettest.js delete mode 100644 kjsembed/kjscmd/CMakeLists.txt delete mode 100644 kjsembed/kjscmd/console.js delete mode 100644 kjsembed/kjscmd/kjscmd.cpp delete mode 100644 kjsembed/kjscmd/kjscmd.qrc delete mode 100644 kjsembed/kjsembed/CMakeLists.txt delete mode 100644 kjsembed/kjsembed/QBrush_bind.cpp delete mode 100644 kjsembed/kjsembed/QBrush_bind.h delete mode 100644 kjsembed/kjsembed/application.cpp delete mode 100644 kjsembed/kjsembed/application.h delete mode 100644 kjsembed/kjsembed/binding_support.cpp delete mode 100644 kjsembed/kjsembed/binding_support.h delete mode 100644 kjsembed/kjsembed/brush.cpp delete mode 100644 kjsembed/kjsembed/brush.h delete mode 100644 kjsembed/kjsembed/builtins.cpp delete mode 100644 kjsembed/kjsembed/builtins.h delete mode 100644 kjsembed/kjsembed/color.cpp delete mode 100644 kjsembed/kjsembed/color.h delete mode 100644 kjsembed/kjsembed/dom.cpp delete mode 100644 kjsembed/kjsembed/dom.h delete mode 100644 kjsembed/kjsembed/eventproxy.cpp delete mode 100644 kjsembed/kjsembed/eventproxy.h delete mode 100644 kjsembed/kjsembed/filedialog_binding.cpp delete mode 100644 kjsembed/kjsembed/filedialog_binding.h delete mode 100644 kjsembed/kjsembed/fileio.cpp delete mode 100644 kjsembed/kjsembed/fileio.h delete mode 100644 kjsembed/kjsembed/font.cpp delete mode 100644 kjsembed/kjsembed/font.h delete mode 100644 kjsembed/kjsembed/image.cpp delete mode 100644 kjsembed/kjsembed/image.h delete mode 100644 kjsembed/kjsembed/iosupport.cpp delete mode 100644 kjsembed/kjsembed/iosupport.h delete mode 100644 kjsembed/kjsembed/jseventmapper.cpp delete mode 100644 kjsembed/kjsembed/jseventmapper.h delete mode 100644 kjsembed/kjsembed/jseventutils.cpp delete mode 100644 kjsembed/kjsembed/jseventutils.h delete mode 100644 kjsembed/kjsembed/kjseglobal.cpp delete mode 100644 kjsembed/kjsembed/kjseglobal.h delete mode 100644 kjsembed/kjsembed/kjsembed.cpp delete mode 100644 kjsembed/kjsembed/kjsembed.h delete mode 100644 kjsembed/kjsembed/object_binding.cpp delete mode 100644 kjsembed/kjsembed/object_binding.h delete mode 100644 kjsembed/kjsembed/pen.cpp delete mode 100644 kjsembed/kjsembed/pen.h delete mode 100644 kjsembed/kjsembed/pixmap.cpp delete mode 100644 kjsembed/kjsembed/pixmap.h delete mode 100644 kjsembed/kjsembed/point.cpp delete mode 100644 kjsembed/kjsembed/point.h delete mode 100644 kjsembed/kjsembed/pointer.h delete mode 100644 kjsembed/kjsembed/qaction_binding.cpp delete mode 100644 kjsembed/kjsembed/qaction_binding.h delete mode 100644 kjsembed/kjsembed/qformbuilder_binding.cpp delete mode 100644 kjsembed/kjsembed/qformbuilder_binding.h delete mode 100644 kjsembed/kjsembed/qlayout_binding.cpp delete mode 100644 kjsembed/kjsembed/qlayout_binding.h delete mode 100644 kjsembed/kjsembed/qobject_binding.cpp delete mode 100644 kjsembed/kjsembed/qobject_binding.h delete mode 100644 kjsembed/kjsembed/qpainter_binding.cpp delete mode 100644 kjsembed/kjsembed/qpainter_binding.h delete mode 100644 kjsembed/kjsembed/quiloader_binding.cpp delete mode 100644 kjsembed/kjsembed/quiloader_binding.h delete mode 100644 kjsembed/kjsembed/qwidget_binding.cpp delete mode 100644 kjsembed/kjsembed/qwidget_binding.h delete mode 100644 kjsembed/kjsembed/rect.cpp delete mode 100644 kjsembed/kjsembed/rect.h delete mode 100644 kjsembed/kjsembed/settings.cpp delete mode 100644 kjsembed/kjsembed/settings.h delete mode 100644 kjsembed/kjsembed/size.cpp delete mode 100644 kjsembed/kjsembed/size.h delete mode 100644 kjsembed/kjsembed/slotproxy.cpp delete mode 100644 kjsembed/kjsembed/slotproxy.h delete mode 100644 kjsembed/kjsembed/static_binding.cpp delete mode 100644 kjsembed/kjsembed/static_binding.h delete mode 100644 kjsembed/kjsembed/svg_binding.cpp delete mode 100644 kjsembed/kjsembed/svg_binding.h delete mode 100644 kjsembed/kjsembed/test/QByteArray_bind.cpp delete mode 100644 kjsembed/kjsembed/test/QByteArray_bind.h delete mode 100644 kjsembed/kjsembed/url.cpp delete mode 100644 kjsembed/kjsembed/url.h delete mode 100644 kjsembed/kjsembed/util.h delete mode 100644 kjsembed/kjsembed/value_binding.cpp delete mode 100644 kjsembed/kjsembed/value_binding.h delete mode 100644 kjsembed/kjsembed/variant_binding.cpp delete mode 100644 kjsembed/kjsembed/variant_binding.h delete mode 100644 kjsembed/qtonly/CMakeLists.txt delete mode 100644 kjsembed/qtonly/FindQJSInternal.cmake delete mode 100644 kjsembed/qtonly/README diff --git a/CMakeLists.txt b/CMakeLists.txt index e8ddd711..5b2c3a88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ if(UNIX AND Q_WS_X11) endif(UNIX AND Q_WS_X11) #required features: -# Perl is used e.g. in khtml, kjs, kjsembed and others +# FIXME: is perl really needed? find_package(Perl) set_package_properties(Perl PROPERTIES URL "http://www.perl.org" TYPE REQUIRED PURPOSE "Needed for building kdelibs") @@ -150,12 +150,7 @@ endif(QCA2_FOUND) # Use the one variable for the lib you depend upon. # E.g. kdeui uses ${KDE4_KDECORE_INCLUDES}. Something that depends on kparts uses ${KDE4_KPARTS_INCLUDES}. -set(KDE4_KJS_INCLUDES ${CMAKE_SOURCE_DIR}/kjs - ${CMAKE_BINARY_DIR}/kjs) - -set(KDE4_KDECORE_INCLUDES ${KDE4_KJS_INCLUDES} ) - -# kdecore depends on Qt (need only headers from kjs) +# kdecore depends on Qt set(KDE4_KDECORE_INCLUDES ${KDE4_KDECORE_INCLUDES} ${CMAKE_SOURCE_DIR}/kdecore ${CMAKE_BINARY_DIR}/kdecore @@ -247,8 +242,6 @@ add_subdirectory( kdecore ) add_subdirectory( kdeui ) add_subdirectory( kpty ) add_subdirectory( kdesu ) -add_subdirectory( kjs ) -add_subdirectory( kjsembed ) add_subdirectory( kio ) add_subdirectory( solid ) add_subdirectory( kded ) diff --git a/kjs/CMakeLists.txt b/kjs/CMakeLists.txt deleted file mode 100644 index 48f52317..00000000 --- a/kjs/CMakeLists.txt +++ /dev/null @@ -1,284 +0,0 @@ - -project(kjs) - -add_subdirectory(tests) - -# Conflict between KJS::HashTable and WTF::HashTable, due to "using namespace" of both namespaces. -kde4_no_enable_final(kjs) - -# Configuration checks -include(FindThreads) -check_library_exists(pthread pthread_attr_get_np "" HAVE_PTHREAD_ATTR_GET_NP) -check_library_exists(pthread pthread_getattr_np "" HAVE_PTHREAD_GETATTR_NP) -check_include_files(float.h HAVE_FLOAT_H) -check_include_files(sys/timeb.h HAVE_SYS_TIMEB_H) -check_include_files(ieeefp.h HAVE_IEEEFP_H) -check_include_files("pthread.h;pthread_np.h" HAVE_PTHREAD_NP_H) -check_include_files(valgrind/memcheck.h HAVE_MEMCHECK_H) -check_struct_member(tm tm_gmtoff time.h HAVE_TM_GMTOFF) - -macro_push_required_vars() -if(NOT WIN32) - set(CMAKE_REQUIRED_LIBRARIES "-lm") -endif(NOT WIN32) -check_function_exists(_finite HAVE_FUNC__FINITE) -check_function_exists(finite HAVE_FUNC_FINITE) -check_function_exists(posix_memalign HAVE_FUNC_POSIX_MEMALIGN) -check_symbol_exists(isnan "math.h" HAVE_FUNC_ISNAN) -check_symbol_exists(isinf "math.h" HAVE_FUNC_ISINF) -macro_pop_required_vars() - -#Do not make PCRE optional here. PCRE is a hard requirement for modern systems -#but we give old systems some slack... that's why we don't specify "REQUIRED". -find_package(PCRE) -set_package_properties(PCRE PROPERTIES DESCRIPTION "Perl-compatible regular expressions in KJS" - URL "http://www.pcre.org" - TYPE OPTIONAL - PURPOSE "Without PCRE, KJS will have extremely poor regular expression support, breaking many webpages." - ) - -macro_bool_to_01(PCRE_FOUND HAVE_PCREPOSIX) - -option(KJS_FORCE_DISABLE_PCRE "Force building of KJS without PCRE. Doing this will result in many webpage working incorrectly, due to extremely poor regular expression support") - -# Generate global.h -configure_file(global.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/global.h ) -configure_file(config-kjs.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kjs.h ) - -include_directories(${KDE4_KDECORE_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR}/wtf ${KDEWIN_INCLUDES} ) - - -# the check for pcre is in kdelibs/CMakeLists.txt -if(PCRE_FOUND AND NOT KJS_FORCE_DISABLE_PCRE) - include_directories(${PCRE_INCLUDE_DIR}) - - # tell check_symbol_exists to -I pcre dirs. - macro_push_required_vars() - set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${PCRE_INCLUDE_DIR}) - - check_symbol_exists(PCRE_CONFIG_UTF8 "pcre.h" HAVE_PCRE_UTF8) - check_symbol_exists(PCRE_CONFIG_STACKRECURSE "pcre.h" HAVE_PCRE_STACK) - - macro_pop_required_vars() - - # Even though we "support" non-PCRE builds, if we build PCRE, we want a version - # recent enough, and we don't want to fallback to a completely crippled - # POSIX code just like that. - if (NOT HAVE_PCRE_UTF8 OR NOT HAVE_PCRE_STACK) - message(FATAL_ERROR "Your libPCRE is too old. KJS requires at least PCRE4.5") - endif (NOT HAVE_PCRE_UTF8 OR NOT HAVE_PCRE_STACK) - -else (PCRE_FOUND AND NOT KJS_FORCE_DISABLE_PCRE) - # if we're here, either PCRE support is disabled, or it's not found... - # it better be disabled. - if (NOT KJS_FORCE_DISABLE_PCRE) - message(FATAL_ERROR "The PCRE regular expression library has not been found. KJS requires PCRE >= 4.5 to function properly. If you for some reason can not install it, you can force a build with POSIX regex.h by passing -DKJS_FORCE_DISABLE_PCRE=true to cmake. However, be advised that it'll result in many websites breaking") - endif (NOT KJS_FORCE_DISABLE_PCRE) - # if pcre is not installed or disabled, at least the posix regex.h has to be available - if(APPLE) - check_include_files("sys/types.h;regex.h" HAVE_REGEX_H) - else(APPLE) - check_include_files(regex.h HAVE_REGEX_H) - endif(APPLE) - if (NOT HAVE_REGEX_H) - message(FATAL_ERROR "Neither the PCRE regular expression library nor the POSIX regex.h header have been found. Consider installing PCRE.") - endif (NOT HAVE_REGEX_H) -endif(PCRE_FOUND AND NOT KJS_FORCE_DISABLE_PCRE) - -# The crosscompiling parts are commented out on purpose. Alex -# if (CMAKE_CROSSCOMPILING) -# set(IMPORT_ICEMAKER_EXECUTABLE "${KDE_HOST_TOOLS_PATH}/ImportIcemakerExecutable.cmake" CACHE FILEPATH "Point it to the export file of icemaker from a native build") -# include(${IMPORT_ICEMAKER_EXECUTABLE}) -# set(ICEMAKER_EXECUTABLE icemaker) -# else (CMAKE_CROSSCOMPILING) - - ########### icemaker, generates some tables for kjs/frostbyte ############### - set(icemaker_SRCS - bytecode/generator/tablebuilder.cpp - bytecode/generator/types.cpp - bytecode/generator/codeprinter.cpp - bytecode/generator/driver.cpp - bytecode/generator/lexer.cpp - bytecode/generator/parser.cpp - ) - kde4_add_executable(icemaker NOGUI ${icemaker_SRCS}) - - # get the name of the generated wrapper script (which sets up LD_LIBRARY_PATH) - get_target_property(ICEMAKER_EXECUTABLE icemaker WRAPPER_SCRIPT) - -# export(TARGETS icemaker FILE ${CMAKE_BINARY_DIR}/ImportIcemakerExecutable.cmake) -# endif (CMAKE_CROSSCOMPILING) - -# and the custom command -add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/opcodes.h ${CMAKE_CURRENT_BINARY_DIR}/opcodes.cpp - ${CMAKE_CURRENT_BINARY_DIR}/machine.cpp - COMMAND ${ICEMAKER_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/bytecode - DEPENDS icemaker ${CMAKE_CURRENT_SOURCE_DIR}/bytecode/codes.def - ${CMAKE_CURRENT_SOURCE_DIR}/bytecode/opcodes.cpp.in - ${CMAKE_CURRENT_SOURCE_DIR}/bytecode/opcodes.h.in - ${CMAKE_CURRENT_SOURCE_DIR}/bytecode/machine.cpp.in -) - -########### next target ############### - -# We don't want -pedantic/--pedantic for KJS since we want to use GCC extension when available -string(REPLACE "--pedantic" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") -string(REPLACE "-pedantic" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - -add_definitions(-DBUILDING_KDE__) - -add_subdirectory( wtf ) - -set(CREATE_HASH_TABLE ${CMAKE_CURRENT_SOURCE_DIR}/create_hash_table ) - -macro(CREATE_LUT _srcs_LIST _in_FILE _out_FILE _dep_FILE) - - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_out_FILE} - COMMAND ${PERL_EXECUTABLE} ${CREATE_HASH_TABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${_in_FILE} -i > ${CMAKE_CURRENT_BINARY_DIR}/${_out_FILE} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_in_FILE} ) - set( ${_srcs_LIST} ${${_srcs_LIST}} ${CMAKE_CURRENT_BINARY_DIR}/${_out_FILE}) -endmacro(CREATE_LUT) - -create_lut(kjs_LIB_SRCS date_object.cpp date_object.lut.h date_object.cpp) -create_lut(kjs_LIB_SRCS number_object.cpp number_object.lut.h number_object.cpp) -create_lut(kjs_LIB_SRCS string_object.cpp string_object.lut.h string_object.cpp) -create_lut(kjs_LIB_SRCS array_object.cpp array_object.lut.h array_object.cpp) -create_lut(kjs_LIB_SRCS math_object.cpp math_object.lut.h math_object.cpp) -create_lut(kjs_LIB_SRCS json_object.cpp json_object.lut.h json_object.cpp) -create_lut(kjs_LIB_SRCS regexp_object.cpp regexp_object.lut.h regexp_object.cpp) -create_lut(kjs_LIB_SRCS keywords.table lexer.lut.h lexer.cpp) - -set(kjs_LIB_SRCS - ${kjs_LIB_SRCS} - ustring.cpp - date_object.cpp - collector.cpp - nodes.cpp - grammar.cpp - lexer.cpp - lookup.cpp - operations.cpp - regexp.cpp - function_object.cpp - string_object.cpp - bool_object.cpp - number_object.cpp - internal.cpp - ExecState.cpp - Parser.cpp - array_object.cpp - array_instance.cpp - math_object.cpp - object_object.cpp - regexp_object.cpp - error_object.cpp - function.cpp - debugger.cpp - value.cpp - list.cpp - object.cpp - interpreter.cpp - package.cpp - property_map.cpp - property_slot.cpp - nodes2string.cpp - identifier.cpp - scope_chain.cpp - dtoa.cpp - fpconst.cpp - JSLock.cpp - JSImmediate.cpp - PropertyNameArray.cpp - JSWrapperObject.cpp - CommonIdentifiers.cpp - JSVariableObject.cpp - ${CMAKE_CURRENT_BINARY_DIR}/opcodes.cpp - ${CMAKE_CURRENT_BINARY_DIR}/machine.cpp - nodes2bytecode.cpp - CompileState.cpp - jsonlexer.cpp - json_object.cpp - jsonstringify.cpp - propertydescriptor.cpp - ) - -if (NOT DEFINED QT_ONLY) - set(KJSLIBNAME kjs) -else (NOT DEFINED QT_ONLY) - set(KJSLIBNAME qkjs) -endif (NOT DEFINED QT_ONLY) - - -kde4_add_library(${KJSLIBNAME} ${LIBRARY_TYPE} ${kjs_LIB_SRCS}) - -if(WIN32) - target_link_libraries(${KJSLIBNAME} ${KDEWIN_LIBRARIES}) -endif(WIN32) - -if(CMAKE_THREAD_LIBS_INIT) - target_link_libraries(${KJSLIBNAME} ${CMAKE_THREAD_LIBS_INIT}) -endif(CMAKE_THREAD_LIBS_INIT) - -if(UNIX) - target_link_libraries(${KJSLIBNAME} m) -endif(UNIX) - -if(PCRE_FOUND) - target_link_libraries(${KJSLIBNAME} ${PCRE_LIBRARIES}) -endif(PCRE_FOUND) - -set_target_properties(${KJSLIBNAME} PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) -install(TARGETS ${KJSLIBNAME} EXPORT kdelibsLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) - -########### kjs - basic shell ############### - -set(kjs_SRCS kjs.cpp) - -#required by win32 see kdelibs/cmake/modules/kde4Macros.cmake kde4_add_manifest -set (kjs_bin_OUTPUT_NAME kjs) - -# 'kjs_bin' because cmake doesn't like having a lib and app with the same name -kde4_add_executable(kjs_bin NOGUI ${kjs_SRCS}) - -set_target_properties(kjs_bin PROPERTIES RUNTIME_OUTPUT_NAME ${kjs_bin_OUTPUT_NAME}) - -target_link_libraries(kjs_bin ${KJSLIBNAME}) - -install(TARGETS kjs_bin ${INSTALL_TARGETS_DEFAULT_ARGS}) - -########### KDE-specific API ############## - -add_subdirectory(api) - -########### install files ############### -# install( FILES -# ExecState.h -# JSImmediate.h -# JSLock.h -# JSType.h -# PropertyNameArray.h -# collector.h -# completion.h -# function.h -# identifier.h -# interpreter.h -# list.h -# lookup.h -# object.h -# operations.h -# package.h -# property_map.h -# property_slot.h -# protect.h -# scope_chain.h -# types.h -# ustring.h -# value.h -# CommonIdentifiers.h -# -# ${CMAKE_CURRENT_BINARY_DIR}/global.h -# -# DESTINATION ${INCLUDE_INSTALL_DIR}/kjs COMPONENT Devel ) - - - diff --git a/kjs/CommonIdentifiers.cpp b/kjs/CommonIdentifiers.cpp deleted file mode 100644 index 8d4aa3d1..00000000 --- a/kjs/CommonIdentifiers.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2003, 2007 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "CommonIdentifiers.h" - -#include -#include "JSLock.h" - -namespace KJS { - -const char* const nullCString = 0; - -#define INITIALIZE_PROPERTY_NAME(name) , name ( #name ) - -CommonIdentifiers::CommonIdentifiers() - : nullIdentifier(nullCString) - , underscoreProto("__proto__") - KJS_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME) -{ -} - -CommonIdentifiers* CommonIdentifiers::shared() -{ - static CommonIdentifiers* sharedInstance; - if (!sharedInstance) { - JSLock lock; - sharedInstance = new CommonIdentifiers; - } - return sharedInstance; -} - -} // namespace KJS diff --git a/kjs/CommonIdentifiers.h b/kjs/CommonIdentifiers.h deleted file mode 100644 index a6b7b831..00000000 --- a/kjs/CommonIdentifiers.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2003,2007 Apple Computer, Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJS_COMMON_IDENTIFIERS_H -#define KJS_COMMON_IDENTIFIERS_H - -#include "identifier.h" -#include - -// List of property names, passed to a macro so we can do set them up various -// ways without repeating the list. -#define KJS_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \ - macro(arguments) \ - macro(callee) \ - macro(caller) \ - macro(constructor) \ - macro(fromCharCode) \ - macro(global) \ - macro(ignoreCase) \ - macro(index) \ - macro(input) \ - macro(lastIndex) \ - macro(length) \ - macro(message) \ - macro(multiline) \ - macro(name) \ - macro(prototype) \ - macro(source) \ - macro(toExponential) \ - macro(toFixed) \ - macro(toLocaleString) \ - macro(toPrecision) \ - macro(toString) \ - macro(valueOf) \ - macro(toJSON) \ - macro(configurable) \ - macro(value) \ - macro(writable) \ - macro(enumerable) \ - macro(get) \ - macro(set) \ - macro(toISOString) - -namespace KJS { - - class KJS_EXPORT CommonIdentifiers : Noncopyable { - - private: - CommonIdentifiers(); - - public: - static CommonIdentifiers* shared(); - - const Identifier nullIdentifier; - const Identifier underscoreProto; - -#define KJS_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL(name) const Identifier name; - KJS_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(KJS_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL) -#undef KJS_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL - }; -} // namespace KJS - -// ### better place in identifier.h. only here because of the shared null -namespace WTF { - // Provide hashing of Identifiers --- using the rep ptr - struct IdentHash { - static unsigned hash(const KJS::Identifier& key) { - return PtrHash::hash(key.ustring().rep()); - } - static bool equal(const KJS::Identifier& a, const KJS::Identifier& b) { return a == b; } - static const bool safeToCompareToEmptyOrDeleted = false; - }; - - template<> struct DefaultHash { typedef IdentHash Hash; }; - - template<> struct HashTraits : GenericHashTraits { - static const bool emptyValueIsZero = false; - static const bool needsDestruction = true; - static void constructDeletedValue(KJS::Identifier* slot) { new (slot) KJS::Identifier(); } - static bool isDeletedValue(const KJS::Identifier& value) { return value.isNull(); } - }; - -} // namespace WTF - -#endif // KJS_COMMON_IDENTIFIERS_H - diff --git a/kjs/CompileState.cpp b/kjs/CompileState.cpp deleted file mode 100644 index d6be23d7..00000000 --- a/kjs/CompileState.cpp +++ /dev/null @@ -1,292 +0,0 @@ -// -*- 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) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. - * Copyright (C) 2007, 2008 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#include "CompileState.h" -#include "nodes.h" - -#include -#include - -namespace KJS { - -CompileState::~CompileState() -{ - deleteAllValues(locals); - deleteAllValues(freeMarkTemps); - deleteAllValues(freeNonMarkTemps); -} - -CodeBlock& CompileState::codeBlock() -{ - return fbody->code(); -} - -void CompileState::requestTemporary(OpType type, OpValue* value, OpValue* reference) -{ - ASSERT(type == OpType_value || type == OpType_bool || type == OpType_int32 || type == OpType_number); - - value->type = type; - value->immediate = false; - - reference->type = OpType_reg; - reference->immediate = true; - - RegDescriptor* temp = 0; - - bool markable = (type == OpType_value); - - if (markable && !freeMarkTemps.isEmpty()) { - temp = freeMarkTemps.last(); - freeMarkTemps.removeLast(); - } else if (!markable && !freeNonMarkTemps.isEmpty()) { - temp = freeNonMarkTemps.last(); - freeNonMarkTemps.removeLast(); - } - - if (!temp) { - Register id = maxTemp; - fbody->reserveSlot(id, markable); - temp = new RegDescriptor(this, id, markable); - ++maxTemp; - } - - value->ownedReg = temp; - - reference->ownedReg = temp; - reference->value.narrow.regVal = temp->reg(); -} - -OpValue CompileState::localReadVal(Register regNum) -{ - OpValue val; - val.immediate = false; - val.type = OpType_value; - - RegDescriptor* desc = locals[regNum]; - if (!desc) { - desc = new RegDescriptor(this, regNum, true, false /*not a temp!*/); - locals[regNum] = desc; - } - - val.ownedReg = desc; - return val; -} - -void CompileState::localFlushAll(CodeBlock& block) -{ - for (Register r = 0; r < initialMaxTemp; ++r) { - if (locals[r] && locals[r]->live()) - flushLocal(block, r); - } -} - -void CompileState::flushLocal(CodeBlock& /*block*/, Register regNum) -{ - if (locals[regNum] && locals[regNum]->live()) { - OpValue localVal; - localVal.immediate = false; - localVal.type = OpType_value; - localVal.ownedReg = locals[regNum]; - - OpValue out, outReg; - requestTemporary(OpType_value, &out, &outReg); - - CodeGen::emitOp(this, Op_RegPutValue, 0, &outReg, &localVal); - - // Now, patch up the descriptor to point to the same place as the temporary, and to - // take ownership of it, and remove it from local descriptors list. - locals[regNum]->adopt(out.ownedReg.get()); - locals[regNum] = 0; - } -} - -OpValue CompileState::localWriteRef(CodeBlock& block, Register regNum) -{ - // Detach any live value copies. - flushLocal(block, regNum); - - OpValue rval; - rval.immediate = true; - rval.type = OpType_reg; - rval.value.narrow.regVal = regNum; - return rval; -} - -bool CompileState::pushLabel(const Identifier& label) -{ - if (!seenLabels.add(label).second) - return false; // Dupe! - - seenLabelsStack.append(label); - pendingLabels.append(label); - - return true; -} - -void CompileState::popLabel() -{ - Identifier name = seenLabelsStack.last(); - - seenLabelsStack.removeLast(); - seenLabels.remove (name); - labelTargets.remove(name); - ASSERT(pendingLabels.isEmpty()); -} - -void CompileState::bindLabels(Node* node) -{ - for (size_t l = 0; l < pendingLabels.size(); ++l) - labelTargets.set(pendingLabels[l], node); - pendingLabels.clear(); -} - -Node* CompileState::resolveBreakLabel(Identifier label) -{ - if (label.isEmpty()) { - if (defaultBreakTargets.isEmpty()) - return 0; - else - return defaultBreakTargets.last(); - } else { - return labelTargets.get(label); - } -} - -Node* CompileState::resolveContinueLabel(Identifier label) -{ - if (label.isEmpty()) { - if (defaultContinueTargets.isEmpty()) - return 0; - else - return defaultContinueTargets.last(); - } else { - return labelTargets.get(label); - } -} - -void CompileState::pushNest(NestType type, Node* node) -{ - if (type == Scope) - ++scopeDepth; - else if (type == TryFinally) - ++finallyDepth; - - NestInfo inf; - inf.type = type; - inf.node = node; - nests.append(inf); - - assert(!(type == ContBreakTarget && !node)); -} - -void CompileState::popNest() -{ - if (nests.last().type == Scope) - --scopeDepth; - else if (nests.last().type == TryFinally) - --finallyDepth; - - nests.removeLast(); -} - -void CompileState::pushDefaultBreak(Node* node) -{ - defaultBreakTargets.append(node); -} - -void CompileState::pushDefaultContinue(Node* node) -{ - defaultContinueTargets.append(node); -} - -void CompileState::popDefaultBreak() -{ - defaultBreakTargets.removeLast(); -} - -void CompileState::popDefaultContinue() -{ - defaultContinueTargets.removeLast(); -} - -void CompileState::addPendingBreak(Node* node, Addr addr) -{ - if (!pendingBreaks.contains(node)) - pendingBreaks.set(node, new WTF::Vector()); - pendingBreaks.get(node)->append(addr); -} - -void CompileState::addPendingContinue(Node* node, Addr addr) -{ - if (!pendingContinues.contains(node)) - pendingContinues.set(node, new WTF::Vector()); - pendingContinues.get(node)->append(addr); -} - -void CompileState::resolvePendingBreaks(Node* node, Addr dest) -{ - const WTF::Vector* stats = pendingBreaks.get(node); - if (!stats) - return; - - CodeBlock& block = codeBlock(); - OpValue newDest = OpValue::immAddr(dest); - for (size_t c = 0; c < stats->size(); ++c) - CodeGen::patchOpArgument(block, (*stats)[c], 0, newDest); - - pendingBreaks.remove(node); - delete stats; -} - -void CompileState::resolvePendingContinues(Node* node, Addr dest) -{ - const WTF::Vector* stats = pendingContinues.get(node); - if (!stats) - return; - - CodeBlock& block = codeBlock(); - OpValue newDest = OpValue::immAddr(dest); - for (size_t c = 0; c < stats->size(); ++c) - CodeGen::patchOpArgument(block, (*stats)[c], 0, newDest); - - pendingContinues.remove(node); - delete stats; -} - - -static OpValue* addrDummy; - -OpValue* OpValue::dummyAddr() -{ - if (!addrDummy) { - addrDummy = new OpValue; - *addrDummy = OpValue::immAddr(0); - } - return addrDummy; -} - - -} //namespace KJS - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/CompileState.h b/kjs/CompileState.h deleted file mode 100644 index 9b0c4578..00000000 --- a/kjs/CompileState.h +++ /dev/null @@ -1,394 +0,0 @@ -// -*- 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) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. - * Copyright (C) 2007, 2008 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef COMPILE_STATE_H -#define COMPILE_STATE_H - -#include "ExecState.h" // For codetype... Kinda odd. - -#include "opcodes.h" -#include "bytecode/opargs.h" - -#include -#include -#include - -using WTF::HashSet; -using WTF::HashMap; -using WTF::Vector; - - -namespace KJS { - -class RegDescriptor; -class FunctionBodyNode; - - -enum CompileType -{ - NotCompiled, - Release, - Debug -}; - -class CompileState -{ -public: - CompileState(CodeType ctype, CompileType compType, FunctionBodyNode* fbody, Register initialMaxTemp): - localScopeVal(0), thisVal(0), globalScopeVal(0), evalResRegister(0), - ctype(ctype), compType(compType), locals(initialMaxTemp, 0), initialMaxTemp(initialMaxTemp), - maxTemp(initialMaxTemp), fbody(fbody), scopeDepth(0), finallyDepth(0), neededClosures(false) - { } - - FunctionBodyNode* functionBody() { - return fbody; - } - - CodeType codeType() const { - return ctype; - } - - CodeBlock& codeBlock(); - - CompileType compileType() const { - return compType; - } - - - ~CompileState(); - - // Returns true if the register is a formal temporary. - bool isTemporaryReg(Register regNum) { - return regNum >= initialMaxTemp; - } - - // We distinguish two kinds of temporaries --- markable and not. They'll get - // corresponding bits set in localStore when that's initialized. - void requestTemporary(OpType type, OpValue* value, OpValue* reference); - - // This method is used to acquire a read value of a local... - OpValue localReadVal(Register regNum); - - // And this one returns a reference, acquiring it for (immediate) write. - // If there are any active read copies, we will backup the old value to - // a temporary, and petchup their register descriptor to point to the backup. - OpValue localWriteRef(CodeBlock& block, Register regNum); - - // This forces all live locals to temporaries. - void localFlushAll(CodeBlock& block); - - // This sets the registers containing the local scope and - // 'this' values... It should be the rvalue, not the regnums - void setPreloadRegs(OpValue* localReg, OpValue* globalReg, OpValue* thisReg) { - localScopeVal = localReg; - globalScopeVal = globalReg; - thisVal = thisReg; - } - - OpValue* localScope() { - return localScopeVal; - } - - OpValue* thisValue() { - return thisVal; - } - - OpValue* globalScope() { - return globalScopeVal; - } - - void setEvalResultRegister(OpValue* val) { - evalResRegister = val; - } - - OpValue* evalResultReg() { - return evalResRegister; - } - - // To properly implement operations like continue and break, we need to keep track whether we - // are nested inside with, try-catch and try-finally operations. - // This serves two purposes: - // 1) if we're not jumping out of a try-finally, we have to unwind the cleanup stacks - // 2) if we're inside a try-finally, we have to jump to the finally and not - // do the normal operation (this applies to return as well) - // Also, if we're inside a 'with' or a catch we cannot optimize local variable access. - - enum NestType { - Scope, - OtherCleanup, - TryFinally, - ContBreakTarget - }; - - void pushNest(NestType type, Node* node = 0); - void popNest (); - - struct NestInfo { - NestType type; - Node* node; - }; - - bool inNestedScope() { - return scopeDepth > 0; - } - - bool inTryFinally() { - return finallyDepth > 0; - } - - const WTF::Vector& nestStack() { - return nests; - } - - // Some constructs can be detected at compile time to involve - // taking of closures. We keep track of that and avoid stack-allocation - // if those are present. - bool needsClosures() { - return neededClosures; - } - - void setNeedsClosures() { - neededClosures = true; - } - - // Label stuff.... - - // Registers a pending label. Returns true if the label is OK, false if it's a duplicate. - // If it fails, the label stack isn't touched! - bool pushLabel(const Identifier& label); - void popLabel(); - - // Binds all the labels to the given node - void bindLabels(Node* node); - - // Returns destination for the label (node will be 0 if not found) - Node* resolveContinueLabel(Identifier label); - Node* resolveBreakLabel (Identifier label); - - // Sets the targets for break/continues w/o label name - void pushDefaultBreak (Node* node); - void pushDefaultContinue(Node* node); - void popDefaultBreak (); - void popDefaultContinue(); - - // Helpers for these and resolvePendingBreak - void enterLoop(Node* node) { - pushNest(ContBreakTarget, node); - pushDefaultBreak(node); - pushDefaultContinue(node); - } - - void exitLoop(Node* node) { - popNest(); - popDefaultBreak(); - popDefaultContinue(); - resolvePendingBreaks(node, CodeGen::nextPC(this)); - } - - // Adds break/continue as needing relevant target for given node - void addPendingBreak (Node* node, Addr addr); - void addPendingContinue(Node* node, Addr addr); - - // Patches up all pending break/continue statements to given destination. - // LabelNode takes care of the breaks itself, the loops need to deal - // with continue, though. - void resolvePendingBreaks (Node* node, Addr dest); - void resolvePendingContinues(Node* node, Addr dest); -private: - OpValue* localScopeVal; - OpValue* thisVal; - OpValue* globalScopeVal; - OpValue* evalResRegister; - - CodeType ctype; - CompileType compType; - - // Makes sure that any values of a local are - void flushLocal(CodeBlock& block, Register reg); - - friend class RegDescriptor; - WTF::Vector locals; - WTF::Vector freeMarkTemps; - WTF::Vector freeNonMarkTemps; - Register initialMaxTemp; - Register maxTemp; - - FunctionBodyNode* fbody; - - void reuse(RegDescriptor* desc, bool markable) { - if (markable) - freeMarkTemps.append(desc); - else - freeNonMarkTemps.append(desc); - } - - // Cached version of #of Scopes's from below. - int scopeDepth; - - // Cached version of #of Finally's from below... - int finallyDepth; - - WTF::Vector nests; - - // This is true if we see code constructs that require taking a closure - // inside here, which means we should not stack-allocate activations. - bool neededClosures; - - // Label resolution.. - WTF::HashSet seenLabels; // all labels we're inside - WTF::Vector seenLabelsStack; - WTF::Vector pendingLabels; // labels tha that haven't been bound to - // a statement yet. - - // Targets for continue/break w/o destination. - WTF::Vector defaultBreakTargets; - WTF::Vector defaultContinueTargets; - - // Named label targets - WTF::HashMap labelTargets; - - WTF::HashMap* > pendingBreaks; - WTF::HashMap* > pendingContinues; -}; - -// We used register descriptors for two reasons: -// 1) For temporaries, we ref-counted them by OpValue in order to manage their lifetime -// 2) For locals, we use them to do COW of values... -class RegDescriptor -{ -public: - RegDescriptor(CompileState* owner, Register reg, bool markable, bool temp = true): - owner(owner), regNo(reg), temp(temp), markable(markable), killed(false), refCount(0) - {} - - Register reg() const { - return regNo; - } - - void ref() { - ++refCount; - } - - void deref() { - --refCount; - if (refCount == 0) { - if (killed) - delete this; - else if (temp) - owner->reuse(this, markable); - } - } - - bool live() { - return refCount > 0; - } - - void adopt(RegDescriptor* other) { - // Make this point to the same as an another descriptor, which is about to die.. - temp = other->temp; - markable = other->markable; - regNo = other->regNo; - - // Mark the other descriptor as killed, as we took ownership of this. - other->killed = true; - } -private: - CompileState* owner; - Register regNo; - bool temp; - bool markable; - bool killed; - int refCount; -}; - -inline OpValue OpValue::immInt32(int32_t in) { - OpValue res; - initImm(&res, OpType_int32); - res.value.narrow.int32Val = in; - return res; -} - -inline OpValue OpValue::immNumber(double in) { - OpValue res; - initImm(&res, OpType_number); - res.value.wide.numberVal = in; - return res; -} - -inline OpValue OpValue::immValue(JSValue* in) { - assert(in); - OpValue res; - initImm(&res, OpType_value); - res.value.wide.valueVal = in; - return res; -} - -inline OpValue OpValue::immBool(bool in) { - OpValue res; - initImm(&res, OpType_bool); - res.value.narrow.boolVal = in; - return res; -} - -inline OpValue OpValue::immString(UString* in) { - OpValue res; - initImm(&res, OpType_string); - res.value.wide.stringVal = in; - return res; -} - -inline OpValue OpValue::immIdent(Identifier* in) { - OpValue res; - initImm(&res, OpType_ident); - res.value.wide.identVal = in; - return res; -} - -inline OpValue OpValue::immNode(KJS::Node* in) { - OpValue res; - initImm(&res, OpType_node); - res.value.wide.nodeVal = in; - return res; -} - -inline OpValue OpValue::immCStr(const char* in) { - OpValue res; - initImm(&res, OpType_cstr); - res.value.wide.cstrVal = in; - return res; -} - -inline OpValue OpValue::immAddr(Addr in) { - OpValue res; - initImm(&res, OpType_addr); - res.value.narrow.addrVal = in; - return res; -} - -inline OpValue::OpValue(): type(OpType_void) {} // since should never occur as an argument.. - -} - -#endif -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/DESIGN.ideas b/kjs/DESIGN.ideas deleted file mode 100644 index d7684b45..00000000 --- a/kjs/DESIGN.ideas +++ /dev/null @@ -1,110 +0,0 @@ -Get rid of SourceElementsNode by integrating its functionality into -StatementNode. - -========================================================================== - -The hash value of a string could be calculated at creation time and be -stored in the UString instance for later use by the lookup functions. - -========================================================================== - -Proposal for a new object model. Far from being complete. - - Object Type -+---------+ +-------------+ -| type | ----------------> | toString() | -| | | toNumber() | -| data | | .... | -+---------+ | construct() | - | +-------------+ - | | /|\ - \|/ | | -+---------+ | | -| type | | | -| | Shared (optional) \|/ | -| data | +-------------+ -+---------+ +---------+ | types | - /|\ | |<------| gc | Interpreter/Environment - +-------| | | .... | - | | | excp state | - +---------+ +-------------+ - Garbage Collector - -Features: - - offers class static data (nice replacement for pointers to member - function objects in the prototype object) - - no more need to pass around ExecState pointers for the C++ user - (substituted with the need for Object* in the type implementation) - - simple types are stored simple (no new'ed Imp objects) - -Alternative A: pass around Object by pointer rather than value - rather than new'ing they should come out of a pool - -Alternative B: instead of virtual functions like toBoolean(), Type could - have an array of function pointers which can be modified - on the fly and checked for != 0. - -Limitations: Konqueror's requirement to allow access to other frame's - interpreter data but flagging errors on the caller's side - is not satisfied. - -class Interpreter; - -class Type { -public: - Type(Interpreter* i, Type *b) : ip(i), bs(b) { } - virtual UString name() const = 0; - Type* base() const { return bs; } - Interpreter* interpreter() const { return ip; } - - virtual bool toBoolean(Object *o); - // .... - virtual Object construct(const List &args); - - // factory - Boolean newBoolean(bool b) { return Boolean(interpreter(), b); } - -private: - Interpreter* ip; - Type* bs; -}; - -union Data { - bool b; - double d; - // UString ??? - Shared* sh; -}; - -class Object { -public: - // creation - Boolean newBoolean(bool b) { return Boolean(typ->interpreter(), b); } - - // conversion - bool to Boolean() const { return typ->toBoolean(this); } - - // this object's "parent" - Interpreter* interpreter() const { return typ->ip; } -private: - Type* typ; - Data dat; -}; - -class Boolean : public Object { -public: - // used by convenience function newBoolean() - Boolean(Interpreter *i, bool b) { - typ = i->booleanType(); - dat.b = b; - } - Boolean(const Boolean &b) { - typ = b.typ; - dat.b = b.b; - } - Boolean& operator=(const Boolean &b) { - type = b.typ; - dat.b = b.b; - return *this; - } -}; diff --git a/kjs/ExecState.cpp b/kjs/ExecState.cpp deleted file mode 100644 index a47c4c98..00000000 --- a/kjs/ExecState.cpp +++ /dev/null @@ -1,301 +0,0 @@ -// -*- 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) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "ExecState.h" -#include "function.h" -#include "scriptfunction.h" -#include "internal.h" -#include "nodes.h" -#include "debugger.h" - -namespace KJS { - -Interpreter* ExecState::lexicalInterpreter() const -{ - JSObject* outerScope = scopeChain().bottom(); - assert(outerScope->isGlobalObject()); - - Interpreter* result = static_cast(outerScope)->interpreter(); - - if (!result) - return dynamicInterpreter(); - - return result; -} - -void ExecState::markSelf() -{ - if (m_codeType != FunctionCode && m_localStore) { - //### some code dupe here with JSVariableObject::mark. Not sure how to best - // restructure. - - // Note: the m_localStore check is needed here, since for non-function code, - // we may create function object in declaration elaboration stage, before - // compilation and set up of this - size_t size = m_localStoreSize; - LocalStorageEntry* entries = m_localStore; - - for (size_t i = 0; i < size; ++i) { - JSValue* value = entries[i].val.valueVal; - if (!(entries[i].attributes & DontMark) && !value->marked()) - value->mark(); - } - } - - for (size_t i = 0; i < m_deferredCompletions.size(); ++i) { - JSValue* e = m_deferredCompletions[i].value(); - if (e && !e->marked()) - e->mark(); - } - - JSValue* e = m_completion.value(); - if (e && !e->marked()) - e->mark(); - - scope.mark(); - - // Propagate up to other eval chains.. - if (m_savedExec && m_savedExec != m_callingExec) { - ASSERT(m_savedExec != this); - m_savedExec->mark(); - } -} - -void ExecState::mark() -{ - for (ExecState* exec = this; exec; exec = exec->m_callingExec) - exec->markSelf(); -} - -ExecState::ExecState(Interpreter* intp, ExecState* save) : - m_interpreter(intp), - m_propertyNames(CommonIdentifiers::shared()), - m_callingExec(0), - m_savedExec(save), - m_currentBody(0), - m_function(0), - m_localStore(0), - m_pcBase(0), - m_pc(0), - m_machineLocalStore(0) -{ - /** - The reason we need m_savedExec and can't just be content with m_callingExec is two-fold. - First of all, in many cases KHTML (and ktranscript) invoke functions such as event handlers - on globalExec. When that happens, we still need to be able to mark the previous call-chain. - Also, it is possible for the client to call Interpreter::evaluate again; and we still - need to mark things from the outside when that happens - */ - - if (m_callingExec && m_savedExec && m_callingExec != m_savedExec) - assert(m_callingExec == intp->globalExec()); - m_interpreter->setExecState(this); -} - -ExecState::~ExecState() -{ - m_interpreter->setExecState(m_savedExec); -} - -void ExecState::pushExceptionHandler(HandlerType type, Addr addr) -{ - m_exceptionHandlers.append(ExceptionHandler(type, addr)); -} - -void ExecState::popExceptionHandler() -{ - m_exceptionHandlers.removeLast(); -} - - -JSValue* ExecState::reactivateCompletion(bool insideTryFinally) -{ - // First, unwind and get the old completion.. - ASSERT(m_exceptionHandlers.last().type == RemoveDeferred); - popExceptionHandler(); - Completion comp = m_deferredCompletions.last(); - m_deferredCompletions.removeLast(); - - // Now, our behavior behaves on whether we're inside an another - // try..finally or not. If we're, we must route even - // continue/break/return completions via the EH machinery; - // if not, we execute them directly - if (comp.complType() == Normal) { - // We just straight fell into 'finally'. Nothing fancy to do. - return 0; - } - - if (comp.complType() == Throw || insideTryFinally) { - setAbruptCompletion(comp); - } else { - if (comp.complType() == ReturnValue) { - return comp.value(); - } else { - assert(comp.complType() == Break || comp.complType() == Continue); - *m_pc = m_pcBase + comp.target(); - } - } - - return 0; -} - -void ExecState::setException(JSValue* e) -{ - if (e) - setAbruptCompletion(Completion(Throw, e)); - else - clearException(); -} - - -void ExecState::setAbruptCompletion(Completion comp) -{ - // If we already had an exception, merely update the object, to permit - // users to refine the exception, being careful not to double-unwind. - // However, warn about it in debug builds. - if (hadException()) { -#ifndef NDEBUG - printInfo(this, "warning: overriding already set exception ", m_completion.value()); - printInfo(this, "with ", comp.value()); -#endif - - m_completion = comp; - return; - } - - // Trace to debugger if needed. - Debugger* dbg = dynamicInterpreter()->debugger(); - if (dbg && comp.complType() == Throw) - dbg->reportException(this, comp.value()); - - m_completion = comp; - - while (!m_exceptionHandlers.isEmpty()) { - switch (m_exceptionHandlers.last().type) { - case JumpToCatch: - *m_pc = m_pcBase + m_exceptionHandlers.last().dest; - m_exceptionHandlers.removeLast(); - return; // done handling it - case PopScope: - popScope(); - m_exceptionHandlers.removeLast(); - continue; // get the next handler - case RemoveDeferred: - m_deferredCompletions.removeLast(); - m_exceptionHandlers.removeLast(); - continue; // get the next handler - case Silent: - // Exception blocked by tracing code. nothing to do. - return; - } - } -} - -void ExecState::quietUnwind(int depth) -{ - ASSERT(m_exceptionHandlers.size() >= size_t(depth)); - for (int e = 0; e < depth; ++e) { - HandlerType type = m_exceptionHandlers.last().type; - m_exceptionHandlers.removeLast(); - - switch (type) { - case JumpToCatch: - break; //Nothing to do here! - case PopScope: - popScope(); - break; - case RemoveDeferred: - m_deferredCompletions.removeLast(); - break; - case Silent: - ASSERT(0); // Should not happen in the middle of the code. - break; - } - } -} - -GlobalExecState::GlobalExecState(Interpreter* intp, JSGlobalObject* glob): ExecState(intp, 0 /* nothing else constructed yet*/) -{ - scope.push(glob); - m_codeType = GlobalCode; - m_variable = glob; - m_thisVal = glob; -} - -InterpreterExecState::InterpreterExecState(Interpreter* intp, JSGlobalObject* glob, - JSObject* thisObject, ProgramNode* body): - ExecState(intp, intp->execState()) -{ - m_currentBody = body; - scope.push(glob); - m_codeType = GlobalCode; - m_variable = glob; - // Per 10.2.1, we should use the global object here, but - // Interpreter::evaluate permits it to be overridden, e.g. for LiveConnect. - m_thisVal = thisObject; -} - -EvalExecState::EvalExecState(Interpreter* intp, JSGlobalObject* glob, - ProgramNode* body, ExecState* callingExecState): - ExecState(intp, intp->execState()) -{ - m_currentBody = body; - m_codeType = EvalCode; - m_callingExec = callingExecState; - if (m_callingExec) { - scope = m_callingExec->scopeChain(); - m_variable = m_callingExec->variableObject(); - m_thisVal = m_callingExec->thisValue(); - return; - } - - // 10.2.2 talks about the behavior w/o a calling context here, - // saying it should be like global code. This can not happen - // in actual JS code, but it may be synthesized by e.g. - // the JS debugger calling 'eval' itself, from globalExec - m_thisVal = glob; - m_variable = glob; - scope.push(glob); -} - -FunctionExecState::FunctionExecState(Interpreter* intp, JSObject* thisObject, - FunctionBodyNode* body, ExecState* callingExecState, - FunctionImp* function): ExecState(intp, intp->execState()) -{ - m_function = function; - m_currentBody = body; - - m_codeType = FunctionCode; - m_callingExec = callingExecState; - scope = function->scope(); // Activation will push itself when setting up - m_variable = m_interpreter->getRecycledActivation();// TODO: DontDelete ? (ECMA 10.2.3) - if (!m_variable) - m_variable = new ActivationImp(); - m_thisVal = thisObject; -} - -} // namespace KJS - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/ExecState.h b/kjs/ExecState.h deleted file mode 100644 index bc85bcc1..00000000 --- a/kjs/ExecState.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - * 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) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef ExecState_H -#define ExecState_H - -#include "completion.h" -#include "value.h" -#include "types.h" -#include "CommonIdentifiers.h" -#include "scope_chain.h" -#include "LocalStorage.h" -#include "wtf/Vector.h" -#include "PropertyNameArray.h" - -namespace KJS { - class ActivationImp; - class Interpreter; - class FunctionImp; - class FunctionBodyNode; - class ProgramNode; - class JSGlobalObject; - - enum CodeType { GlobalCode, EvalCode, FunctionCode }; - - /** - * Represents the current state of script execution. This object allows you - * obtain a handle the interpreter that is currently executing the script, - * and also the current execution context. - */ - class KJS_EXPORT ExecState : Noncopyable { - friend class Interpreter; - friend class FunctionImp; - friend class GlobalFuncImp; - public: - /** - * Returns the interpreter associated with this execution state - * - * @return The interpreter executing the script - */ - Interpreter* dynamicInterpreter() const { return m_interpreter; } - - /** - * Returns the interpreter associated with the current scope's - * global object - * - * @return The interpreter currently in scope - */ - Interpreter* lexicalInterpreter() const; - - /** - * This describes how an exception should be handled - */ - enum HandlerType { - JumpToCatch, ///< jump to the specified address - PopScope, ///< remove a scope chain entry, and run the next handler - RemoveDeferred, ///< remove any deferred exception object, and run the next entry - Silent ///< just update the exception object. For debugger-type use only - }; - - void pushExceptionHandler(HandlerType type, Addr addr = 0); - - void popExceptionHandler(); - - // Cleanup depth entries from the stack, w/o running jumps - void quietUnwind(int depth); - - void setMachineRegisters(const unsigned char* pcBase, const unsigned char** pcLoc, LocalStorageEntry** machineLocalStoreLoc) { - m_pcBase = pcBase; - m_pc = pcLoc; - m_machineLocalStore = machineLocalStoreLoc; - } - - /** - The below methods deal with deferring of completions inside finally clauses. - Essentially, we clear any set exceptions and memorize any non-normal completion - (including the target addresses for the continue/break statements) on - the m_deferredCompletions stack. If the 'finally' finishes normally, - we will resume the previous completion. If not, finally's abnormal - termination is handled as usually; a RemoveDeferred cleanup stack - entry is added to unwind m_deferredCompletions if that happens. - */ - - void deferCompletion() { - pushExceptionHandler(RemoveDeferred); - m_deferredCompletions.append(abruptCompletion()); - clearException(); - } - - /** - This resumes dispatch of a completion that was deferred due to a try ... finally, - handling it as appropriate for whether it's inside an another try-finally. - This will handle all the cases itself except for one: return, - for which it will return the value to return (otherwise returning 0) - */ - JSValue* reactivateCompletion(bool insideTryFinally); - - /** - * Set the exception associated with this execution state, - * updating the program counter appropriately, and executing any relevant EH cleanups. - * @param e The JSValue of the exception being set - */ - void setException(JSValue* e); - - /** - * Records an abrupt completion of code, and jumps to the closest catch or finally. - * This always happens for exceptions, but can also happen for continue/break/return when - * they're inside try ... finally, since that case gets routed through the EH machinery. - */ - void setAbruptCompletion(Completion comp); - - /** - * Clears the exception or other abnormal completion set on this execution state. - */ - void clearException() { m_completion = Completion(); } - - /** - * Returns the exception associated with this execution state. - * @return The current execution state exception - */ - JSValue* exception() const { return m_completion.complType() == Throw ? m_completion.value() : 0; } - - /** - * Use this to check if an exception was thrown in the current - * execution state. - * - * @return Whether an exception was thrown - */ - bool hadException() const { return m_completion.complType() == Throw; } - - Completion abruptCompletion() const { return m_completion; } - - /** - * Returns the scope chain for this execution context. This is used for - * variable lookup, with the list being searched from start to end until a - * variable is found. - * - * @return The execution context's scope chain - */ - const ScopeChain& scopeChain() const { return scope; } - - /** - * Returns the variable object for the execution context. This contains a - * property for each variable declared in the execution context. - * - * @return The execution context's variable object - */ - JSObject* variableObject() const { return m_variable; } - void setVariableObject(JSObject* v) { m_variable = v; } - - /** - * Returns the "this" value for the execution context. This is the value - * returned when a script references the special variable "this". It should - * always be an Object, unless application-specific code has passed in a - * different type. - * - * The object that is used as the "this" value depends on the type of - * execution context - for global contexts, the global object is used. For - * function objewcts, the value is given by the caller (e.g. in the case of - * obj.func(), obj would be the "this" value). For code executed by the - * built-in "eval" function, the this value is the same as the calling - * context. - * - * @return The execution context's "this" value - */ - JSObject* thisValue() const { return m_thisVal; } - - /** - * Returns the context from which the current context was invoked. For - * global code this will be a null context (i.e. one for which - * isNull() returns true). You should check isNull() on the returned - * value before calling any of its methods. - * - * @return The calling execution context - */ - ExecState* callingExecState() { return m_callingExec; } - - /** - * Returns the execState of a previous nested evaluation session, if any. - */ - ExecState* savedExecState() { return m_savedExec; } - - JSObject* activationObject() { - assert(m_codeType == FunctionCode); - return m_variable; - } - - CodeType codeType() { return m_codeType; } - FunctionBodyNode* currentBody() { return m_currentBody; } - FunctionImp* function() const { return m_function; } - - void pushVariableObjectScope(JSVariableObject* s) { scope.pushVariableObject(s); } - void pushScope(JSObject* s) { scope.push(s); } - void popScope() { scope.pop(); } - - void mark(); - - void initLocalStorage(LocalStorageEntry* store, size_t size) { - m_localStore = store; - m_localStoreSize = size; - } - - void updateLocalStorage(LocalStorageEntry* newStore) { - m_localStore = newStore; - *m_machineLocalStore = newStore; - } - - LocalStorageEntry* localStorage() { return m_localStore; } - - // This is a workaround to avoid accessing the global variables for these identifiers in - // important property lookup functions, to avoid taking PIC branches in Mach-O binaries - const CommonIdentifiers& propertyNames() const { return *m_propertyNames; } - - // Compatibility stuff: - ExecState* context() { return this; } - ExecState* callingContext() { return callingExecState(); } - protected: - ExecState(Interpreter* intp, ExecState* save); - ~ExecState(); - void markSelf(); - - Interpreter* m_interpreter; - Completion m_completion; - CommonIdentifiers* m_propertyNames; - ExecState* m_callingExec; - ExecState* m_savedExec; // in case of recursion of evaluation. Needed to mark things properly; - // note that this is disjoint from the above, since that's only used for - // eval/function, while this is for global. - - FunctionBodyNode* m_currentBody; - FunctionImp* m_function; - - ScopeChain scope; - JSObject* m_variable; - JSObject* m_thisVal; - - LocalStorageEntry* m_localStore; - size_t m_localStoreSize; - - struct ExceptionHandler { - ExceptionHandler() {} - ExceptionHandler(HandlerType type, Addr dest): - type(type), dest(dest) {} - - HandlerType type; - Addr dest; - }; - - const unsigned char* m_pcBase; // The address of pc = 0 - const unsigned char** m_pc; // Where the current fetch address is stored - LocalStorageEntry** m_machineLocalStore; // Machine's copy of m_localStore - WTF::Vector m_exceptionHandlers; - WTF::Vector m_deferredCompletions; - - CodeType m_codeType; - }; - - typedef ExecState Context; // Compatibility only - - class GlobalExecState : public ExecState { - public: - GlobalExecState(Interpreter* intp, JSGlobalObject* global); - }; - - class InterpreterExecState : public ExecState { - public: - InterpreterExecState(Interpreter* intp, JSGlobalObject* global, JSObject* thisObject, ProgramNode*); - }; - - class EvalExecState : public ExecState { - public: - EvalExecState(Interpreter* intp, JSGlobalObject* global, ProgramNode* body, ExecState* callingExecState); - }; - - // Note: this does not push the activation on the scope chain, - // as the activation is not initialized at this point. - class FunctionExecState : public ExecState { - public: - FunctionExecState(Interpreter* intp, JSObject* thisObject, - FunctionBodyNode*, ExecState* callingExecState, FunctionImp*); - }; - -} // namespace KJS - -#endif // ExecState_H diff --git a/kjs/JSImmediate.cpp b/kjs/JSImmediate.cpp deleted file mode 100644 index ab90c8e6..00000000 --- a/kjs/JSImmediate.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2003-2006 Apple Computer, Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "JSImmediate.h" -#include "object.h" - -namespace KJS { - -JSObject *JSImmediate::toObject(const JSValue *v, ExecState *exec) -{ - assert(isImmediate(v)); - if (v == jsNull()) - return throwError(exec, TypeError, "Null value"); - else if (v == jsUndefined()) - return throwError(exec, TypeError, "Undefined value"); - else if (isBoolean(v)) { - List args; - args.append(const_cast(v)); - return exec->lexicalInterpreter()->builtinBoolean()->construct(exec, args); - } else { - ASSERT(isNumber(v)); - List args; - args.append(const_cast(v)); - return exec->lexicalInterpreter()->builtinNumber()->construct(exec, args); - } -} - -UString JSImmediate::toString(const JSValue *v) -{ - ASSERT(isImmediate(v)); - - if (v == jsNull()) - return "null"; - else if (v == jsUndefined()) - return "undefined"; - else if (v == jsBoolean(true)) - return "true"; - else if (v == jsBoolean(false)) - return "false"; - else { - assert(isNumber(v)); - double d = toDouble(v); - if (d == 0.0) // +0.0 or -0.0 - return "0"; - return UString::from(d); - } -} - -JSType JSImmediate::type(const JSValue *v) -{ - ASSERT(isImmediate(v)); - - uintptr_t tag = getTag(v); - if (tag == UndefinedType) - return v == jsUndefined() ? UndefinedType : NullType; - return static_cast(tag); -} - -} // namespace KJS diff --git a/kjs/JSImmediate.h b/kjs/JSImmediate.h deleted file mode 100644 index 8ce29479..00000000 --- a/kjs/JSImmediate.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJS_JS_IMMEDIATE_H -#define KJS_JS_IMMEDIATE_H - -#include -#include "JSType.h" -#include -#include -#include -#ifdef HAVE_STDINT_H -#include -#endif -#include - -#if PLATFORM(SOLARIS_OS) -static inline int signbit(double x) -{ - return (x<0.0) ? 1 : 0; -} -#endif - -namespace KJS { - -class ExecState; -class JSObject; -class JSValue; -class UString; - -KJS_EXPORT extern const double NaN; -KJS_EXPORT extern const double Inf; - -/* - * A JSValue* is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged - * signed int masquerading as a pointer). The low two bits in a JSValue* are available - * for type tagging because allocator alignment guarantees they will be 00 in cell pointers. - * - * For example, on a 32 bit system: - * - * JSCell*: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 00 - * [ high 30 bits: pointer address ] [ low 2 bits -- always 0 ] - * - * JSImmediate: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TT - * [ high 30 bits: signed int ] [ low 2 bits -- type tag ] - * - * The bit "payload" (the high 30 bits) is a 30 bit signed int for immediate numbers, a flag to distinguish true/false - * and undefined/null. - * - * Notice that the JSType value of NullType is 4, which requires 3 bits to encode. Since we only have 2 bits - * available for type tagging, we tag the null immediate with UndefinedType, and JSImmediate::type() has - * to sort them out. - */ - -class KJS_EXPORT JSImmediate { -public: - static ALWAYS_INLINE bool isImmediate(const JSValue* v) - { - return getTag(v) != 0; - } - - static ALWAYS_INLINE bool isNumber(const JSValue* v) - { - return (getTag(v) == NumberType); - } - - static ALWAYS_INLINE bool isBoolean(const JSValue* v) - { - return (getTag(v) == BooleanType); - } - - // Since we have room for only 3 unique tags, null and undefined have to share. - static ALWAYS_INLINE bool isUndefinedOrNull(const JSValue* v) - { - return (getTag(v) == UndefinedType); - } - - static JSValue* from(char); - static JSValue* from(signed char); - static JSValue* from(unsigned char); - static JSValue* from(short); - static JSValue* from(unsigned short); - static JSValue* from(int); - static JSValue* from(unsigned); - static JSValue* from(long); - static JSValue* from(unsigned long); - static JSValue* from(long long); - static JSValue* from(unsigned long long); - static JSValue* from(double); - - static ALWAYS_INLINE bool areBothImmediateNumbers(const JSValue* v1, const JSValue* v2) - { - return (reinterpret_cast(v1) & reinterpret_cast(v2) & TagMask) == NumberType; - } - - static ALWAYS_INLINE JSValue* andImmediateNumbers(const JSValue* v1, const JSValue* v2) - { - ASSERT(areBothImmediateNumbers(v1, v2)); - return reinterpret_cast(reinterpret_cast(v1) & reinterpret_cast(v2)); - } - - static double toDouble(const JSValue*); - - // Non-converting getters for Number's - static double getNumber(const JSValue*); // This returns NaN if the value is not a Number. - static bool getNumber(const JSValue*, double& valOut); - - static bool toBoolean(const JSValue*); - static JSObject* toObject(const JSValue*, ExecState*); - static UString toString(const JSValue*); - static JSType type(const JSValue*); - - static bool getUInt32(const JSValue*, uint32_t&); - static bool getTruncatedInt32(const JSValue*, int32_t&); - static bool getTruncatedUInt32(const JSValue*, uint32_t&); - - static int32_t getTruncatedInt32(const JSValue*); - - static JSValue* trueImmediate(); - static JSValue* falseImmediate(); - static JSValue* undefinedImmediate(); - static JSValue* nullImmediate(); - -private: - static const uintptr_t TagMask = 3; // type tags are 2 bits long - - // Immediate values are restricted to a 30 bit signed value. - static const int minImmediateInt = -(1 << 29); - static const int maxImmediateInt = (1 << 29) - 1; - static const unsigned maxImmediateUInt = maxImmediateInt; - - static ALWAYS_INLINE JSValue* tag(uintptr_t bits, uintptr_t tag) - { - return reinterpret_cast(bits | tag); - } - - static ALWAYS_INLINE uintptr_t unTag(const JSValue* v) - { - return reinterpret_cast(v) & ~TagMask; - } - - static ALWAYS_INLINE uintptr_t getTag(const JSValue* v) - { - return reinterpret_cast(v) & TagMask; - } -}; - -ALWAYS_INLINE JSValue* JSImmediate::trueImmediate() { return tag(1 << 2, BooleanType); } -ALWAYS_INLINE JSValue* JSImmediate::falseImmediate() { return tag(0, BooleanType); } -ALWAYS_INLINE JSValue* JSImmediate::undefinedImmediate() { return tag(1 << 2, UndefinedType); } -ALWAYS_INLINE JSValue* JSImmediate::nullImmediate() { return tag(0, UndefinedType); } - -ALWAYS_INLINE bool JSImmediate::toBoolean(const JSValue* v) -{ - ASSERT(isImmediate(v)); - uintptr_t bits = unTag(v); - return (bits != 0) & (JSImmediate::getTag(v) != UndefinedType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(char i) -{ - return tag(i << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(signed char i) -{ - return tag(i << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(unsigned char i) -{ - return tag(i << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(short i) -{ - return tag(i << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(unsigned short i) -{ - return tag(i << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(int i) -{ - if ((i < minImmediateInt) || (i > maxImmediateInt)) - return 0; - return tag(i << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(unsigned i) -{ - if (i > maxImmediateUInt) - return 0; - return tag(i << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(long i) -{ - if ((i < minImmediateInt) || (i > maxImmediateInt)) - return 0; - return tag(i << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(unsigned long i) -{ - if (i > maxImmediateUInt) - return 0; - return tag(i << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(long long i) -{ - if ((i < minImmediateInt) || (i > maxImmediateInt)) - return 0; - return tag(static_cast(i) << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(unsigned long long i) -{ - if (i > maxImmediateUInt) - return 0; - return tag(static_cast(i) << 2, NumberType); -} - -ALWAYS_INLINE JSValue* JSImmediate::from(double d) -{ - const int intVal = static_cast(d); - - if ((intVal < minImmediateInt) || (intVal > maxImmediateInt)) - return 0; - - // Check for data loss from conversion to int. - if ((intVal != d) || (!intVal && signbit(d))) - return 0; - - return tag(intVal << 2, NumberType); -} - -ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(const JSValue* v) -{ - ASSERT(isNumber(v)); - return static_cast(unTag(v)) >> 2; -} - -ALWAYS_INLINE double JSImmediate::toDouble(const JSValue* v) -{ - ASSERT(isImmediate(v)); - const int32_t i = static_cast(unTag(v)) >> 2; - if (JSImmediate::getTag(v) == UndefinedType && i) - return NaN; - return i; -} - -ALWAYS_INLINE double JSImmediate::getNumber(const JSValue* v) -{ - ASSERT(isImmediate(v)); - const int32_t i = static_cast(unTag(v)) >> 2; - if (JSImmediate::getTag(v) != NumberType) - return NaN; - return i; -} - -ALWAYS_INLINE bool JSImmediate::getNumber(const JSValue* v, double& numberOut) -{ - ASSERT(isImmediate(v)); - numberOut = static_cast(unTag(v)) >> 2; - return (JSImmediate::getTag(v) == NumberType); -} - -ALWAYS_INLINE bool JSImmediate::getUInt32(const JSValue* v, uint32_t& i) -{ - const int32_t si = static_cast(unTag(v)) >> 2; - i = si; - return isNumber(v) & (si >= 0); -} - -ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(const JSValue* v, int32_t& i) -{ - i = static_cast(unTag(v)) >> 2; - return isNumber(v); -} - -ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(const JSValue* v, uint32_t& i) -{ - return getUInt32(v, i); -} - -} // namespace KJS - -#endif diff --git a/kjs/JSLock.cpp b/kjs/JSLock.cpp deleted file mode 100644 index 4c3b4082..00000000 --- a/kjs/JSLock.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 2005 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA - * - */ - -#include "JSLock.h" -#include - -#include "collector.h" - -namespace KJS { - -#if USE(MULTIPLE_THREADS) - -static pthread_once_t interpreterLockOnce = PTHREAD_ONCE_INIT; -static pthread_mutex_t interpreterLock; -static int interpreterLockCount = 0; - -static void initializeJSLock() -{ - pthread_mutexattr_t attr; - - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); - - pthread_mutex_init(&interpreterLock, &attr); -} - -void JSLock::lock() -{ - pthread_once(&interpreterLockOnce, initializeJSLock); - pthread_mutex_lock(&interpreterLock); - interpreterLockCount++; - Collector::registerThread(); -} - -void JSLock::unlock() -{ - interpreterLockCount--; - pthread_mutex_unlock(&interpreterLock); -} - -int JSLock::lockCount() -{ - return interpreterLockCount; -} - -#endif - -JSLock::DropAllLocks::DropAllLocks() -{ - int lockCount = JSLock::lockCount(); - for (int i = 0; i < lockCount; i++) { - JSLock::unlock(); - } - m_lockCount = lockCount; -} - -JSLock::DropAllLocks::~DropAllLocks() -{ - int lockCount = m_lockCount; - for (int i = 0; i < lockCount; i++) { - JSLock::lock(); - } -} - -} diff --git a/kjs/JSLock.h b/kjs/JSLock.h deleted file mode 100644 index 882927ff..00000000 --- a/kjs/JSLock.h +++ /dev/null @@ -1,85 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 2005 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSLOCK_H -#define JSLOCK_H - -#include "global.h" - -namespace KJS { - - // to make it safe to use JavaScript on multiple threads, it is - // important to lock before doing anything that allocates a - // garbage-collected object or which may affect other shared state - // such as the protect count hash table. The simplest way to do - // this is by having a local JSLock object for the scope - // where the lock must be held. The lock is recursive so nesting - // is ok. - - // Sometimes it is necessary to temporarily release the lock - - // since it is recursive you have to actually release all locks - // held by your thread. This is safe to do if you are executing - // code that doesn't require the lock, and reacquire the right - // number of locks at the end. You can do this by constructing a - // locally scoped JSLock::DropAllLocks object. - - class KJS_EXPORT JSLock - { - public: - JSLock() - { - lock(); - } - ~JSLock() { - unlock(); - } - - static void lock(); - static void unlock(); - static int lockCount(); - - class DropAllLocks { - public: - DropAllLocks(); - ~DropAllLocks(); - private: - int m_lockCount; - - DropAllLocks(const DropAllLocks&); - DropAllLocks& operator=(const DropAllLocks&); - }; - - private: - JSLock(const JSLock&); - JSLock& operator=(const JSLock&); - }; - -#if !USE(MULTIPLE_THREADS) - inline void JSLock::lock() {} - inline void JSLock::unlock() {} - // Fix the lock count at 1 so assertions that the lock is held don't fail - inline int JSLock::lockCount() { return 1; } -#endif - -} // namespace - -#endif // JSLOCK_H diff --git a/kjs/JSType.h b/kjs/JSType.h deleted file mode 100644 index 1b7ad94c..00000000 --- a/kjs/JSType.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2006 Apple Computer, Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJS_JSTYPE_H -#define KJS_JSTYPE_H - -namespace KJS { - -/** - * Primitive types - */ -enum JSType { - UnspecifiedType = 0, - NumberType = 1, - BooleanType = 2, - UndefinedType = 3, - NullType = 4, - StringType = 5, - ObjectType = 6, - GetterSetterType = 7 -}; - -} // namespace KJS - -#endif diff --git a/kjs/JSVariableObject.cpp b/kjs/JSVariableObject.cpp deleted file mode 100644 index 3cc9b58e..00000000 --- a/kjs/JSVariableObject.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * (C) 2008 Maksim Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Portions of this code that are (C) 2007, 2008 Apple Inc. were - * originally distributed under the following terms - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include "JSVariableObject.h" - -#include "PropertyNameArray.h" -#include "property_map.h" - -namespace KJS { - -bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propertyName) -{ - if (symbolTable->contains(propertyName.ustring().rep())) - return false; - - return JSObject::deleteProperty(exec, propertyName); -} - -void JSVariableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, PropertyMap::PropertyMode mode) -{ - SymbolTable::const_iterator::Keys end = symbolTable->end().keys(); - for (SymbolTable::const_iterator::Keys it = symbolTable->begin().keys(); it != end; ++it) - propertyNames.add(Identifier(it->get())); - - JSObject::getOwnPropertyNames(exec, propertyNames, mode); -} - -void JSVariableObject::mark() -{ - JSObject::mark(); - - if (!localStorage) - return; - - size_t size = lengthSlot(); - LocalStorageEntry* entries = localStorage; - - for (size_t i = 0; i < size; ++i) { - JSValue* value = entries[i].val.valueVal; - if (!(entries[i].attributes & DontMark) && !value->marked()) - value->mark(); - } -} - -} // namespace KJS diff --git a/kjs/JSVariableObject.h b/kjs/JSVariableObject.h deleted file mode 100644 index 6c90e76d..00000000 --- a/kjs/JSVariableObject.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * (C) 2008 Maksim Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Portions of this code that are (C) 2007, 2008 Apple Inc. were - * originally distributed under the following terms - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JSVariableObject_h -#define JSVariableObject_h - -#include "LocalStorage.h" -#include "SymbolTable.h" -#include "object.h" - -#include - -namespace KJS { - class Interpreter; - - class JSVariableObject : public JSObject { - public: - using KJS::JSObject::deleteProperty; - virtual bool deleteProperty(ExecState*, const Identifier&); - - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, PropertyMap::PropertyMode mode); - - virtual void mark(); - - enum { - LengthSlot, - TearOffNeeded, // Set when a tearoff is requested; - // the actual tearoff will only happen once the function - // stops running, though - ScopeLink, - NumVarObjectSlots = 3 - }; - - int32_t& lengthSlot() { return localStorage[LengthSlot].val.int32Val; } - const int32_t& lengthSlot() const { return localStorage[LengthSlot].val.int32Val; } - - bool& tearOffNeededSlot() { return localStorage[TearOffNeeded].val.boolVal; } - - ScopeChainLink& scopeLink() { return localStorage[ScopeLink].val.scopeVal; } - protected: - JSVariableObject(): localStorage(0), symbolTable(0) { } - ~JSVariableObject(); - - bool symbolTableGet(const Identifier&, PropertySlot&); - bool symbolTablePut(const Identifier&, JSValue*, bool checkReadOnly); - - public: - LocalStorageEntry* localStorage; // Storage for variables in the symbol table. - SymbolTable* symbolTable; // Maps name -> index in localStorage. - }; - - inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot) - { - size_t index = symbolTable->get(propertyName.ustring().rep()); - if (index != missingSymbolMarker()) { - slot.setValueSlot(this, &localStorage[index].val.valueVal); - return true; - } - return false; - } - - inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value, bool checkReadOnly) - { - size_t index = symbolTable->get(propertyName.ustring().rep()); - if (index == missingSymbolMarker()) - return false; - LocalStorageEntry& entry = localStorage[index]; - if (checkReadOnly && (entry.attributes & ReadOnly)) - return true; - entry.val.valueVal = value; - return true; - } - - inline JSVariableObject::~JSVariableObject() - { - if (localStorage) { - scopeLink().deref(); - if (tearOffNeededSlot()) - delete[] localStorage; - } - } - - inline JSObject* ScopeChainLink::object() const - { - if (isToScopeChainNode()) - return asScopeChainNode()->object; - else - return asVariableObject(); - } - - inline ScopeChainLink ScopeChainLink::next() const - { - if (isToScopeChainNode()) - return asScopeChainNode()->next; - else - return asVariableObject()->scopeLink(); - } - - inline void ScopeChain::mark() - { - for (ScopeChainLink n = m_top; n.ptr; n = n.next()) { - JSObject *o = n.object(); - if (!o->marked()) - o->mark(); - } - } - - inline void ScopeChain::pushVariableObject(JSVariableObject* act) - { - // note: this assumes the new variable object is not in any - // scope chain in the moment. - - // Set the item's next pointer to the current top. - // there is no refcount ops since it's transferring a reference - act->scopeLink() = m_top; - - // new top! - m_top.set(act); - } - - - class KJS_EXPORT JSGlobalObject : public JSObject // ### TODO: should inherit off JSVariableObject - { - public: - JSGlobalObject(): m_interpreter(0) {} - JSGlobalObject(JSValue* proto): JSObject(proto), m_interpreter(0) {} - virtual bool isGlobalObject() const { return true; } - - void setInterpreter(Interpreter* intp) { m_interpreter = intp; } - Interpreter* interpreter() const { return m_interpreter; } - private: - Interpreter* m_interpreter; - }; -} // namespace KJS - -#endif // JSVariableObject_h -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/JSWrapperObject.cpp b/kjs/JSWrapperObject.cpp deleted file mode 100644 index 514da1a8..00000000 --- a/kjs/JSWrapperObject.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * Copyright (C) 2006 Maks Orlovich - * Copyright (C) 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "JSWrapperObject.h" - -namespace KJS { - -void JSWrapperObject::mark() -{ - JSObject::mark(); - if (m_internalValue && !m_internalValue->marked()) - m_internalValue->mark(); - if (!m_originalProto->marked()) - m_originalProto->mark(); -} - -} // namespace KJS diff --git a/kjs/JSWrapperObject.h b/kjs/JSWrapperObject.h deleted file mode 100644 index 9639cf92..00000000 --- a/kjs/JSWrapperObject.h +++ /dev/null @@ -1,96 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 -*- -/* - * Copyright (C) 2006 Maks Orlovich - * Copyright (C) 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJS_JSWrapperObject_h -#define KJS_JSWrapperObject_h - -#include "object.h" - -namespace KJS { - - /** - This class is used as a base for classes such as String, - Number, Boolean and Date which which are wrappers for primitive - types. These classes stores the internal value, which is the - actual value represented by the wrapper objects. - */ - class JSWrapperObject : public JSObject { - public: - JSWrapperObject(JSValue* proto); - - /** - * Returns the internal value of the object. This is used for objects such - * as String and Boolean which are wrappers for native types. The interal - * value is the actual value represented by the wrapper objects. - * - * @see ECMA 8.6.2 - * @return The internal value of the object - */ - JSValue* internalValue() const; - - /** - * Sets the internal value of the object - * - * @see internalValue() - * - * @param v The new internal value - */ - void setInternalValue(JSValue* v); - - virtual void mark(); - - /** - * Returns the prototype this object had during construction - */ - JSValue* originalProto() const; - private: - JSValue* m_internalValue; - JSValue* m_originalProto; - }; - - inline JSWrapperObject::JSWrapperObject(JSValue* proto) - : JSObject(proto) - , m_internalValue(0) - , m_originalProto(proto) - { - } - - inline JSValue* JSWrapperObject::internalValue() const - { - return m_internalValue; - } - - inline JSValue* JSWrapperObject::originalProto() const - { - return m_originalProto; - } - - inline void JSWrapperObject::setInternalValue(JSValue* v) - { - ASSERT(v); - m_internalValue = v; - } - -} // namespace KJS - -#endif // KJS_JSWrapperObject_h -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; hl c++; diff --git a/kjs/LocalStorage.h b/kjs/LocalStorage.h deleted file mode 100644 index d8445aeb..00000000 --- a/kjs/LocalStorage.h +++ /dev/null @@ -1,68 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 -*- -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maks Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJS_LOCAL_STORAGE_H -#define KJS_LOCAL_STORAGE_H - -#include "kjs/global.h" - -#ifdef HAVE_STDINT_H -#include // int32_t -#endif -#include -#include -#include "scope_chain.h" // for ScopeChainLink - -namespace KJS { - class JSValue; - - struct LocalStorageEntry { - LocalStorageEntry() - { - } - - LocalStorageEntry(JSValue* v, unsigned a) : - attributes(a) - { - val.valueVal = v; - } - - union { - double numberVal; //### TODO: use 2 entries for this on 32-bit.. - JSValue* valueVal; - bool boolVal; - int32_t int32Val; - ScopeChainLink scopeVal; - } val; - unsigned attributes; - }; - - typedef Vector LocalStorage; -} - -namespace WTF { - template<> struct VectorTraits : VectorTraitsBase { }; -} - -#endif // KJS_LOCAL_STORAGE_H diff --git a/kjs/Mainpage.dox b/kjs/Mainpage.dox deleted file mode 100644 index e27a193c..00000000 --- a/kjs/Mainpage.dox +++ /dev/null @@ -1,30 +0,0 @@ -/** @mainpage KDE JavaScript/EcmaScript Engine - -This library provides an ECMAScript compatible interpreter. The ECMA standard -is based on well known scripting languages such as Netscape's JavaScript and -Microsoft's JScript. - -@authors -Harri Porten \
-Maks Orlovich \
-Apple Computer, Inc.
-Richard Moore \
-Daegeun Lee \
-Marco Pinelli \
-Christian Kirsch \ - -@maintainers -Maks Orlovich \
-Harri Porten \ - -@licenses -@lgpl - -*/ - -// DOXYGEN_REFERENCES = kdecore -// DOXYGEN_SET_PROJECT_NAME = KJS -// DOXYGEN_SET_EXCLUDE_PATTERNS += */wtf/* -// DOXYGEN_SET_EXCLUDE_PATTERNS += */kjs/*.cpp */kjs/*.h - -// vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/kjs/Parser.cpp b/kjs/Parser.cpp deleted file mode 100644 index f8b80880..00000000 --- a/kjs/Parser.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// -*- c-basic-offset: 4 -*- -/* - * 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) - * Copyright (C) 2003, 2006, 2007 Apple Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "Parser.h" -#include - -#include "lexer.h" -#include "nodes.h" -#include -#include - -#ifdef KJS_VERBOSE -#include -#endif - -extern int kjsyyparse(); - -namespace KJS { - -Parser::Parser() - : m_sourceId(0) -{ -} - -PassRefPtr Parser::parseProgram(const UString& sourceURL, int startingLineNumber, - const UChar* code, unsigned length, - int* sourceId, int* errLine, UString* errMsg) -{ - parse(sourceURL, startingLineNumber, code, length, sourceId, errLine, errMsg); - return m_progNode.release(); -} - -static HashSet* nodeCycles; - - -void Parser::noteNodeCycle(Node *node) -{ - if (!nodeCycles) - nodeCycles = new HashSet; - nodeCycles->add(node); -} - -void Parser::removeNodeCycle(Node *node) -{ - ASSERT(nodeCycles); - nodeCycles->remove(node); -} - -static void clearNewNodes() -{ - if (nodeCycles) { - for (HashSet::iterator it = nodeCycles->begin(); it != nodeCycles->end(); ++it) - (*it)->breakCycle(); - delete nodeCycles; - nodeCycles = 0; - } - Node::clearNewNodes(); -} - -PassRefPtr Parser::parseFunctionBody(const UString& sourceURL, int startingLineNumber, - const UChar* code, unsigned length, - int* sourceId, int* errLine, UString* errMsg) -{ - parse(sourceURL, startingLineNumber, code, length, sourceId, errLine, errMsg); - return m_progNode.release(); -} - -void Parser::parse(const UString& sourceURL, int startingLineNumber, - const UChar* code, unsigned length, - int* sourceId, int* errLine, UString* errMsg) -{ - pushFunctionContext(0); - - ASSERT(!m_progNode); - - if (errLine) - *errLine = -1; - if (errMsg) - *errMsg = 0; - - Lexer& lexer = KJS::lexer(); - - lexer.setCode(sourceURL, startingLineNumber, code, length); - m_sourceId++; - if (sourceId) - *sourceId = m_sourceId; - - // Enable this and the #define YYDEBUG in grammar.y to debug a parse error - //extern int kjsyydebug; - //kjsyydebug=1; - - int parseError = kjsyyparse(); - - bool lexError = lexer.sawError(); - lexer.clear(); - - clearNewNodes(); - - if (parseError || lexError) { - if (errLine) - *errLine = lexer.lineNo(); - if (errMsg) - *errMsg = "Parse error"; - m_progNode = 0; - return; - } - -#ifdef KJS_VERBOSE - fprintf( stderr, "%s\n", m_progNode->toString().ascii() ); -#endif -} - -void Parser::didFinishParsing(PassRefPtr progNode) -{ - m_progNode = progNode; -} - -Parser& parser() -{ - // ASSERT(JSLock::currentThreadIsHoldingLock()); - - static Parser staticParser; - return staticParser; -} - -} // namespace KJS diff --git a/kjs/Parser.h b/kjs/Parser.h deleted file mode 100644 index 7c4a3baf..00000000 --- a/kjs/Parser.h +++ /dev/null @@ -1,106 +0,0 @@ -// -*- c-basic-offset: 4 -*- -/* - * 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) - * Copyright (C) 2003, 2006, 2007 Apple Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef Parser_h -#define Parser_h - -#include -#include -#include -#include - -namespace KJS { - - class Node; - class FunctionBodyNode; - class ProgramNode; - class UString; - - struct UChar; - - /** - * @internal - * - * Parses ECMAScript source code and converts into ProgramNode objects, which - * represent the root of a parse tree. The tree is then semantically - * checked with a semantic analyzer. This class provides a convenient - * workaround for the problem of the bison parser working in a static context. - */ - class Parser : Noncopyable { - public: - PassRefPtr parseProgram(const UString& sourceURL, int startingLineNumber, - const UChar* code, unsigned length, - int* sourceId = 0, int* errLine = 0, UString* errMsg = 0); - - PassRefPtr parseFunctionBody(const UString& sourceURL, int startingLineNumber, - const UChar* code, unsigned length, - int* sourceId = 0, int* errLine = 0, UString* errMsg = 0); - - int sourceId() { return m_sourceId; } - - void didFinishParsing(PassRefPtr); - - static void noteNodeCycle(Node*); - static void removeNodeCycle(Node*); - - // We keep track of various flags about the function body we're - // tracking on a stack; the FunctionBody ctor pops them off - // when we're done parsing and are making the body node. - void pushFunctionContext(unsigned initialFlags); - void setFunctionFlags(unsigned newFlags); - unsigned popFunctionContext(); - - private: - friend Parser& parser(); - - Parser(); // Use parser() instead. - void parse(const UString& sourceURL, int startingLineNumber, - const UChar* code, unsigned length, - int* sourceId = 0, int* errLine = 0, UString* errMsg = 0); - - int m_sourceId; - RefPtr m_progNode; - WTF::Vector m_functionFlags; - }; - - Parser& parser(); // Returns the singleton JavaScript parser. - - inline void Parser::pushFunctionContext(unsigned initialFlags) { - m_functionFlags.append(initialFlags); - } - - inline void Parser::setFunctionFlags(unsigned newFlags) { - m_functionFlags.last() |= newFlags; - } - - inline unsigned Parser::popFunctionContext() { - unsigned flags = m_functionFlags.last(); - m_functionFlags.removeLast(); - return flags; - } - -} // namespace KJS - -#endif // Parser_h -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/PropertyNameArray.cpp b/kjs/PropertyNameArray.cpp deleted file mode 100644 index 7d8f90bb..00000000 --- a/kjs/PropertyNameArray.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 -*- -/* - * Copyright (C) 2006 Apple Computer, Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "PropertyNameArray.h" - -namespace KJS { - -void PropertyNameArray::add(const Identifier& ident) -{ - if (!m_set.add(ident.ustring().rep()).second) - return; - - m_vector.append(ident); -} - -} // namespace KJS - diff --git a/kjs/PropertyNameArray.h b/kjs/PropertyNameArray.h deleted file mode 100644 index 27176096..00000000 --- a/kjs/PropertyNameArray.h +++ /dev/null @@ -1,58 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 -*- -/* - * Copyright (C) 2006 Apple Computer, Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJS_PROPERTY_NAME_ARRAY_H -#define KJS_PROPERTY_NAME_ARRAY_H - -#include "identifier.h" - -#include -#include - -namespace KJS { - - class PropertyNameArray; - - typedef Vector::const_iterator PropertyNameArrayIterator; - - class KJS_EXPORT PropertyNameArray { - public: - typedef PropertyNameArrayIterator iterator; - - void add(const Identifier&); - iterator begin() const { return m_vector.begin(); } - iterator end() const { return m_vector.end(); } - int size() const { return m_vector.size(); } - - Identifier& operator[](unsigned i) { return m_vector[i]; } - const Identifier& operator[](unsigned i) const { return m_vector[i]; } - - private: - typedef HashSet > IdentifierSet; - IdentifierSet m_set; - Vector m_vector; - }; - - -} // namespace KJS - - -#endif // KJS_PROPERTY_NAME_ARRAY_H diff --git a/kjs/README b/kjs/README deleted file mode 100644 index 7e01b0b4..00000000 --- a/kjs/README +++ /dev/null @@ -1,27 +0,0 @@ -This library provides an ECMAScript compatible interpreter. The ECMA standard -is based on well known scripting languages such as Netscape's JavaScript and -Microsoft's JScript. - -I'm currently pursuing to be compliant with Edition 3 of ECMA-262. Postscript -and pdf versions of the standard are available at: - -http://www.ecma-international.org/publications/files/ecma-st/Ecma-262.pdf -for PDF and -http://www.ecma-international.org/publications/standards/Ecma-262.htm -for the standard page. - -About 95% of the required features should be covered by now. Note that this -number covers the core language elements only. Features like the famous -roll-over buttons on the www are NOT part of the standard. Those extensions -are added via a module loaded dynamically by the KHTML Widget. - -I'll provide some examples of how to extend this library for various needs at -a later point in time. Feel free to contact me via mail if you have any -questions on how to provide scripting capabilities for your application. - -A debugger is being worked on. - -Bug reports, patches or feedback of any kind is very welcome. - -Harri Porten - diff --git a/kjs/SavedBuiltins.h b/kjs/SavedBuiltins.h deleted file mode 100644 index c8967b36..00000000 --- a/kjs/SavedBuiltins.h +++ /dev/null @@ -1,81 +0,0 @@ -// -*- 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) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef SavedBuiltins_H -#define SavedBuiltins_H - -namespace KJS { - -class SavedBuiltinsInternal; - -class SavedBuiltins { - friend class Interpreter; -public: - SavedBuiltins(); - ~SavedBuiltins(); -private: - SavedBuiltinsInternal *_internal; -}; - -class SavedBuiltinsInternal { - friend class Interpreter; -private: - ProtectedPtr m_Object; - ProtectedPtr m_Function; - ProtectedPtr m_Array; - ProtectedPtr m_Boolean; - ProtectedPtr m_String; - ProtectedPtr m_Number; - ProtectedPtr m_Date; - ProtectedPtr m_RegExp; - ProtectedPtr m_Error; - - ProtectedPtr m_ObjectPrototype; - ProtectedPtr m_FunctionPrototype; - ProtectedPtr m_ArrayPrototype; - ProtectedPtr m_BooleanPrototype; - ProtectedPtr m_StringPrototype; - ProtectedPtr m_NumberPrototype; - ProtectedPtr m_DatePrototype; - ProtectedPtr m_RegExpPrototype; - ProtectedPtr m_ErrorPrototype; - - ProtectedPtr m_EvalError; - ProtectedPtr m_RangeError; - ProtectedPtr m_ReferenceError; - ProtectedPtr m_SyntaxError; - ProtectedPtr m_TypeError; - ProtectedPtr m_UriError; - - ProtectedPtr m_EvalErrorPrototype; - ProtectedPtr m_RangeErrorPrototype; - ProtectedPtr m_ReferenceErrorPrototype; - ProtectedPtr m_SyntaxErrorPrototype; - ProtectedPtr m_TypeErrorPrototype; - ProtectedPtr m_UriErrorPrototype; -}; - -} // namespace - -#endif // SavedBuiltins_H diff --git a/kjs/SymbolTable.h b/kjs/SymbolTable.h deleted file mode 100644 index 81e2af17..00000000 --- a/kjs/SymbolTable.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SymbolTable_h -#define SymbolTable_h - -#include "ustring.h" -#include - -namespace KJS { - - struct IdentifierRepHash : PtrHash > { - static unsigned hash(const RefPtr& key) { return key->computedHash(); } - static unsigned hash(UString::Rep* key) { return key->computedHash(); } - }; - - static ALWAYS_INLINE size_t missingSymbolMarker() { return std::numeric_limits::max(); } - - struct SymbolTableIndexHashTraits : HashTraits { - static const bool emptyValueIsZero = false; - static size_t emptyValue() { return missingSymbolMarker(); } - }; - - typedef HashMap, size_t, IdentifierRepHash, HashTraits >, SymbolTableIndexHashTraits> SymbolTable; -} // namespace KJS - -#endif // SymbolTable_h diff --git a/kjs/THANKS b/kjs/THANKS deleted file mode 100644 index 036e5e75..00000000 --- a/kjs/THANKS +++ /dev/null @@ -1,7 +0,0 @@ -I would like to thank the following people for their help: - -Richard Moore - for filling the Math object with some life -Daegeun Lee - for pointing out some bugs and providing - much code for the String and Date object. -Marco Pinelli - for his patches -Christian Kirsch - for his contribution to the Date object diff --git a/kjs/api/CMakeLists.txt b/kjs/api/CMakeLists.txt deleted file mode 100644 index 1dba4b23..00000000 --- a/kjs/api/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -include_directories(${KDE4_KDECORE_INCLUDES}) - -set(kjsapi_LIB_SRCS - kjsinterpreter.cpp - kjscontext.cpp - kjsobject.cpp - kjsprototype.cpp - kjsarguments.cpp - ) - -kde4_add_library(kjsapi ${LIBRARY_TYPE} ${kjsapi_LIB_SRCS}) - -target_link_libraries(kjsapi ${KJSLIBNAME} ${KDE4_KDECORE_LIBS}) - -set_target_properties(kjsapi PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) -install(TARGETS kjsapi EXPORT kdelibsLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) - -install(FILES - kjsapi_export.h - kjsinterpreter.h - kjscontext.h - kjsobject.h - kjsprototype.h - kjsarguments.h - DESTINATION ${INCLUDE_INSTALL_DIR}/kjs) - - -############# tests ######################## - -kde4_add_unit_test(kjsapitest NOGUI kjsapitest.cpp) -target_link_libraries(kjsapitest kjsapi ${KDE4_KDECORE_LIBS} ${QT_QTTEST_LIBRARY}) diff --git a/kjs/api/Mainpage.dox b/kjs/api/Mainpage.dox deleted file mode 100644 index 3f54116f..00000000 --- a/kjs/api/Mainpage.dox +++ /dev/null @@ -1,37 +0,0 @@ -/** @mainpage KDE ECMAScript Engine - -This library provides an extensible interpreter for ECMAScript - a -dynamic scripting language also known as JavaScript or JScript. Within -the set of KDE libraries is used in the HTML component of Konqueror -and the application scripting solutions KJSEmbed and Kross. - -KJS is made up of an internal core library and a public kjsapi library -that provides a stable and easy-to-use interface for developers -wanting to embed the engine as well as implement custom object types. - -See the class list for an overview of -classes representing the interpreter, standard types as well as -extension interfaces. - -@authors -Harri Porten \
-Maks Orlovich \
-Apple Computer, Inc.
-Peter Kelly \
-Christopher E. Hyde \
-David Faure \
- -Plus various contributors like Richard Moore, Daegeun Lee, Marco -Pinelli and Christian Kirsch. - -@maintainers -Maks Orlovich \
-Harri Porten \ - -@licenses -@lgpl - -*/ - -// DOXYGEN_SET_PROJECT_NAME = KJS-API -// vim:ts=4:sw=4:expandtab:filetype=doxygen diff --git a/kjs/api/kjsapi_export.h b/kjs/api/kjsapi_export.h deleted file mode 100644 index 2b79d2e8..00000000 --- a/kjs/api/kjsapi_export.h +++ /dev/null @@ -1,40 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2007 David Faure - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KJSAPI_EXPORT_H -#define KJSAPI_EXPORT_H - -/* needed for KDE_EXPORT and KDE_IMPORT macros */ -#include - -#ifndef KJSAPI_EXPORT -# if defined(MAKE_KJSAPI_LIB) - /* We are building this library */ -# define KJSAPI_EXPORT KDE_EXPORT -# else - /* We are using this library */ -# define KJSAPI_EXPORT KDE_IMPORT -# endif -#endif - -# ifndef KJSAPI_EXPORT_DEPRECATED -# define KJSAPI_EXPORT_DEPRECATED KDE_DEPRECATED KJSAPI_EXPORT -# endif - -#endif diff --git a/kjs/api/kjsapitest.cpp b/kjs/api/kjsapitest.cpp deleted file mode 100644 index debb8369..00000000 --- a/kjs/api/kjsapitest.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "kjsobject.h" -#include "kjsprototype.h" -#include "kjsarguments.h" -#include "kjsinterpreter.h" - -#include "qtest_kde.h" - -class KJSApiTest : public QObject -{ - Q_OBJECT - -private Q_SLOTS: - void objectConstruction(); - void interpreterEvaluate(); - void interpreterNormalizeCode(); - void objectProperties(); - void prototypeConstants(); - void prototypeProperties(); - void prototypeFunctions(); - void globalObject(); -}; - -void KJSApiTest::objectConstruction() -{ - KJSInterpreter ip; - KJSContext* ctx = ip.globalContext(); - - // Object - QVERIFY2(KJSObject().isObject(), "Broken default object"); - - // undefined - QVERIFY2(KJSUndefined().isUndefined(), - "Undefined object is not undefined"); - // null - QVERIFY2(KJSNull().isNull(), - "Null object is not null"); - - // Boolean - KJSBoolean boolObject(true); - QVERIFY2(boolObject.isBoolean(), "Boolean object is not of boolean type"); - QVERIFY2(boolObject.toBoolean(ctx), "Boolean object has wrong value"); - QVERIFY2(!ctx->hasException(), "Boolean conversion threw exception"); - - // Number - KJSNumber numObject(42.0); - QVERIFY2(numObject.isNumber(), "Number object is not of number type"); - QCOMPARE(numObject.toNumber(ctx), 42.0); - QCOMPARE(numObject.toInt32(ctx), 42); - QVERIFY2(!ctx->hasException(), "Number conversion threw exception"); - - // String - KJSString stringObject("Trunk"); - QVERIFY2(stringObject.isString(), "String object is not of string type"); - QCOMPARE(stringObject.toString(ctx), QLatin1String("Trunk")); - QVERIFY2(!ctx->hasException(), "String conversion threw exception"); - - // Array - KJSArray arrayObject(ctx, 3); - QVERIFY2(arrayObject.isObject(), "Array object is not of object type"); - QCOMPARE(arrayObject.property(ctx, "length").toNumber(ctx), 3.0); - QCOMPARE(arrayObject.toString(ctx), QLatin1String(",,")); - QVERIFY2(!ctx->hasException(), "Array conversion threw exception"); - - // copying - KJSObject copy(stringObject); - QCOMPARE(copy.toString(ctx), QLatin1String("Trunk")); - copy = numObject; - QCOMPARE(copy.toNumber(ctx), 42.0); -} - -void KJSApiTest::interpreterEvaluate() -{ - KJSInterpreter ip; - KJSContext* ctx = ip.globalContext(); - KJSResult res; - - // syntax error - res = ip.evaluate(")("); - QVERIFY2(res.isException(), "Syntax error not caught"); - - res = ip.evaluate("11+22"); - QVERIFY2(!res.isException(), "Evaluation returned non-number object"); - QCOMPARE(res.value().toNumber(ctx), 33.0); -} - -void KJSApiTest::interpreterNormalizeCode() -{ - int errLine = -1; - QString errMsg; - QString norm; - bool ok; - - // syntax error case - ok = KJSInterpreter::normalizeCode(")(", &norm, &errLine, &errMsg); - QVERIFY(!ok); - QVERIFY(!errMsg.isEmpty()); - QVERIFY(errLine >= 0 && errLine <= 2); // ### imprecise - - // success case - ok = KJSInterpreter::normalizeCode("foo(); bar();", &norm); - QVERIFY(ok); - QVERIFY(!norm.isEmpty()); - QStringList lines = norm.split('\n'); - QVERIFY(lines.size() >= 2); // ### imprecise - int fooLine = lines.indexOf(QRegExp(" *foo\\(\\);")); - int barLine = lines.indexOf(QRegExp(" *bar\\(\\);")); - QVERIFY(fooLine >= 0); - QVERIFY(barLine > fooLine); -} - -void KJSApiTest::objectProperties() -{ - KJSInterpreter ip; - KJSContext* ctx = ip.globalContext(); - - KJSObject global = ip.globalObject(); - KJSObject v; - - // bool - global.setProperty(ctx, "myprop", true); - v = global.property(ctx, "myprop"); - QVERIFY(v.isBoolean()); - QCOMPARE(v.toBoolean(ctx), true); - - // double - global.setProperty(ctx, "myprop", 21.0); - v = global.property(ctx, "myprop"); - QVERIFY(v.isNumber()); - QCOMPARE(v.toNumber(ctx), 21.0); - - // int - global.setProperty(ctx, "myprop", 22); - v = global.property(ctx, "myprop"); - QVERIFY(v.isNumber()); - QCOMPARE(v.toNumber(ctx), 22.0); - - // string (8-bit) - global.setProperty(ctx, "myprop", "myvalue8"); - v = global.property(ctx, "myprop"); - QVERIFY(v.isString()); - QCOMPARE(v.toString(ctx), QLatin1String("myvalue8")); - - // string (Unicode) - global.setProperty(ctx, "myprop", QLatin1String("myvalue16")); - v = global.property(ctx, "myprop"); - QVERIFY(v.isString()); - QCOMPARE(v.toString(ctx), QLatin1String("myvalue16")); -} - -void KJSApiTest::prototypeConstants() -{ - KJSInterpreter ip; - KJSContext* ctx = ip.globalContext(); - - KJSPrototype proto; - - proto.defineConstant("d0", 44.4); - proto.defineConstant("s0", QLatin1String("XYZ")); - - KJSObject obj = proto.constructObject(ctx, 0); - - QCOMPARE(obj.property(ctx, "d0").toNumber(ctx), 44.4); - QCOMPARE(obj.property(ctx, "s0").toString(ctx), QLatin1String("XYZ")); -} - -static struct O { int x; } o0 = { 42 }; - -static KJSObject getX(KJSContext* /*context*/, void* object) -{ - O* o = reinterpret_cast(object); - int x = o->x; - return KJSNumber(x); -} - -static void setX(KJSContext* context, void* object, KJSObject value) -{ - O* o = reinterpret_cast(object); - double n = value.toNumber(context); - o->x = n; -} - -void KJSApiTest::prototypeProperties() -{ - KJSInterpreter ip; - KJSContext* ctx = ip.globalContext(); - - KJSPrototype proto; - - proto.defineProperty(ctx, "x", getX, setX); - proto.defineProperty(ctx, "readOnlyX", getX); - - KJSObject obj = proto.constructObject(ctx, &o0); - - // read/write property - QCOMPARE(obj.property(ctx, "x").toNumber(ctx), 42.0); - obj.setProperty(ctx, "x", KJSNumber(43)); - QCOMPARE(obj.property(ctx, "x").toNumber(ctx), 43.0); - - QCOMPARE(obj.property(ctx, "readOnlyX").toNumber(ctx), 43.0); - obj.setProperty(ctx, "readOnlyX", KJSNumber(44)); - QVERIFY2(ctx->hasException(), "Write access caused no exception"); - QCOMPARE(obj.property(ctx, "readOnlyX").toNumber(ctx), 43.0); -} - -static KJSObject multiply(KJSContext* context, void* object, - const KJSArguments& arguments) -{ - double factor = *reinterpret_cast(object); - - // test number of arguments - if (arguments.count() != 1) - return context->throwException("Missing argument"); - - KJSObject a0 = arguments.at(0); - if (!a0.isNumber()) - return KJSNumber(-2); - - double v0 = a0.toNumber(context); - - return KJSNumber(factor * v0); -} - -void KJSApiTest::prototypeFunctions() -{ - KJSInterpreter ip; - KJSContext* ctx = ip.globalContext(); - - KJSPrototype proto; - - proto.defineFunction(ctx, "multiply", multiply); - - double factor = 3.0; - KJSObject obj = proto.constructObject(ctx, &factor); - ip.globalObject().setProperty(ctx, "obj", obj); - - KJSResult res = ip.evaluate("obj.multiply(4)"); - QCOMPARE(res.value().toNumber(ctx), 12.0); - - // expect exception - res = ip.evaluate("obj.multiply()"); - QVERIFY2(res.isException(), "Exception did not work"); -} - -void KJSApiTest::globalObject() -{ - KJSPrototype proto; - proto.defineConstant("g0", 55.5); - - KJSGlobalObject glob = proto.constructGlobalObject(0); - - KJSInterpreter ip(glob); - KJSResult res = ip.evaluate("2 * g0"); - QCOMPARE(res.value().toNumber(ip.globalContext()), 111.0); -} - -QTEST_KDEMAIN_CORE(KJSApiTest) - -#include "kjsapitest.moc" diff --git a/kjs/api/kjsarguments.cpp b/kjs/api/kjsarguments.cpp deleted file mode 100644 index 052d49ea..00000000 --- a/kjs/api/kjsarguments.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "kjsarguments.h" -#include "kjsprivate.h" - -int KJSArguments::count() const -{ - const KJS::List* l = LIST(this); - return l->size(); -} - -KJSObject KJSArguments::at(int idx) const -{ - const KJS::List* l = LIST(this); - if (idx < 0 || idx >= l->size()) - return KJSUndefined(); - KJS::JSValue* a = l->at(idx); - return KJSObject(JSVALUE_HANDLE(a)); -} - diff --git a/kjs/api/kjsarguments.h b/kjs/api/kjsarguments.h deleted file mode 100644 index 1d5d85e3..00000000 --- a/kjs/api/kjsarguments.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJSARGUMENTS_H -#define KJSARGUMENTS_H - -#include "kjsapi_export.h" -#include "kjsobject.h" - -class KJSArgumentsHandle; -class KJSCustomFunction; - -/** - * A class representing a list of JavaScript arguments. - * - * @short Argument list - */ -class KJSAPI_EXPORT KJSArguments -{ - friend class KJSCustomFunction; -public: - /** - * Returns the number of arguments. - */ - int count() const; - /** - * Returns the argument at the specified index. Accessing an - * argument outside of the valid range will return an object of - * type "undefined". - */ - KJSObject at(int idx) const; -private: - KJSArguments(const KJSArguments&); // undefined - KJSArguments& operator=(const KJSArguments&); // undefined - - KJSArguments(const KJSArgumentsHandle* h) : hnd(h) { } - const KJSArgumentsHandle* hnd; -}; - -#endif diff --git a/kjs/api/kjscontext.cpp b/kjs/api/kjscontext.cpp deleted file mode 100644 index 5859140d..00000000 --- a/kjs/api/kjscontext.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "kjscontext.h" -#include "kjsinterpreter.h" -#include "kjsprivate.h" -#include "kjs/object.h" -#include "kjs/ExecState.h" -#include "kjs/interpreter.h" - -using namespace KJS; - -KJSContext::KJSContext(KJSContextHandle* h) - : hnd(h) -{ -} - -bool KJSContext::hasException() const -{ - return EXECSTATE(this)->hadException(); -} - -KJSObject KJSContext::throwException(const QString& message) const -{ - ExecState* exec = EXECSTATE(this); - - JSValue* ex = Error::create(exec, GeneralError, toUString(message), - -1, -1, UString()); - exec->setException(ex); - - return KJSObject(JSVALUE_HANDLE(ex)); -} - -KJSInterpreter KJSContext::interpreter() -{ - ExecState* exec = EXECSTATE(this); - Interpreter* ip = exec->dynamicInterpreter(); - - return KJSInterpreter(INTERPRETER_HANDLE(ip)); -} diff --git a/kjs/api/kjscontext.h b/kjs/api/kjscontext.h deleted file mode 100644 index de70ef08..00000000 --- a/kjs/api/kjscontext.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJSCONTEXT_H -#define KJSCONTEXT_H - -#include "kjsapi_export.h" - -class KJSObject; -class KJSArray; -class KJSInterpreter; -class KJSContextHandle; -class KJSCustomProperty; -class KJSCustomFunction; - -/** - * A class representing a JavaScript execution context. - * - * @short Execution context - */ -class KJSAPI_EXPORT KJSContext -{ - friend class KJSObject; - friend class KJSArray; - friend class KJSPrototype; - friend class KJSInterpreter; - friend class KJSCustomProperty; - friend class KJSCustomFunction; -public: - /** - * Returns true if this context has an unhandled exception. - */ - bool hasException() const; - /** - * Throws a general exception with the specified error message. - */ - KJSObject throwException(const QString& message) const; - /** - * Returns the currently executing interpreter. - */ - KJSInterpreter interpreter(); -private: - KJSContext(KJSContextHandle* h); - KJSContext(const KJSContext&); // undefined - KJSContext& operator=(const KJSContext&); // undefined - - KJSContextHandle* hnd; -}; - -#endif diff --git a/kjs/api/kjsinterpreter.cpp b/kjs/api/kjsinterpreter.cpp deleted file mode 100644 index 6a346b6b..00000000 --- a/kjs/api/kjsinterpreter.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "kjsinterpreter.h" -#include "kjsprivate.h" -#include "kjs/interpreter.h" -#include "kjs/completion.h" -#include "kjs/object.h" -#include "kjs/JSVariableObject.h" -#include -#include - -using namespace KJS; - -class KJSResultHandle -{ -public: - KJSResultHandle() : rc(1), val(KJSUndefined()) { } - - int rc; - KJSObject val; - UString errMsg; - - void ref() { ++rc; } - void deref() { if (--rc == 0) delete this; } -}; - -KJSResult::KJSResult() - : hnd(new KJSResultHandle()) -{ -} - -KJSResult::KJSResult(const KJSResult& r) -{ - hnd = r.hnd; - hnd->ref(); -} - -KJSResult& KJSResult::operator=(const KJSResult& r) -{ - if (hnd != r.hnd) { - r.hnd->ref(); - hnd->deref(); - hnd = r.hnd; - } - - return *this; -} - -KJSResult::~KJSResult() -{ - hnd->deref(); -} - -bool KJSResult::isException() const -{ - return !hnd->errMsg.isNull(); -} - -QString KJSResult::errorMessage() const -{ - return toQString(hnd->errMsg); -} - -KJSObject KJSResult::value() const -{ - return hnd->val; -} - -KJSInterpreter::KJSInterpreter() - : globCtx(0) -{ - Interpreter* ip = new Interpreter(); - ip->ref(); - hnd = INTERPRETER_HANDLE(ip); -} - -KJSInterpreter::KJSInterpreter(const KJSGlobalObject& global) - : globCtx(0) -{ - JSValue* gv = JSVALUE(&global); - assert(gv->isObject()); - JSObject* go = static_cast(gv); - assert(go->isGlobalObject()); - Interpreter* ip = new Interpreter(static_cast(go)); - ip->ref(); - assert(go->prototype()->isObject()); - JSObject* p = static_cast(go->prototype()); - JSObject* objectProto = ip->builtinObjectPrototype(); - p->setPrototype(objectProto); - hnd = INTERPRETER_HANDLE(ip); -} - -KJSInterpreter::KJSInterpreter(const KJSInterpreter& other) - : globCtx(0) -{ - Interpreter* ip = INTERPRETER(&other); - ip->ref(); - hnd = INTERPRETER_HANDLE(ip); - globCtx.hnd = EXECSTATE_HANDLE(ip->globalExec()); -} - -KJSInterpreter& KJSInterpreter::operator=(const KJSInterpreter& other) -{ - Interpreter* thisIp = INTERPRETER(this); - Interpreter* otherIp = INTERPRETER(&other); - if (otherIp != thisIp) { - otherIp->ref(); - thisIp->deref(); - hnd = INTERPRETER_HANDLE(otherIp); - globCtx.hnd = EXECSTATE_HANDLE(otherIp->globalExec()); - } - return *this; -} - -KJSInterpreter::KJSInterpreter(KJSInterpreterHandle* h) - : hnd(h), globCtx(0) -{ - Interpreter* ip = INTERPRETER(this); - globCtx.hnd = EXECSTATE_HANDLE(ip->globalExec()); -} - -KJSInterpreter::~KJSInterpreter() -{ - Interpreter* ip = INTERPRETER(this); - ip->deref(); - ip = 0; -} - -KJSContext* KJSInterpreter::globalContext() -{ - Interpreter* ip = INTERPRETER(this); - - globCtx.hnd = EXECSTATE_HANDLE(ip->globalExec()); - return &globCtx; -} - -KJSObject KJSInterpreter::globalObject() -{ - Interpreter* ip = INTERPRETER(this); - - return KJSObject(JSVALUE_HANDLE(ip->globalObject())); -} - -KJSResult KJSInterpreter::evaluate(const QString& sourceURL, - int startingLineNumber, - const QString& code, - KJSObject* thisValue) -{ - Interpreter* ip = INTERPRETER(this); - - JSValue* tv = thisValue ? JSVALUE(thisValue) : 0; - KJS::Completion c = ip->evaluate(toUString(sourceURL), startingLineNumber, - toUString(code), tv); - - KJSResult res; - if (c.complType() == Throw) { - ExecState* exec = ip->globalExec(); - UString msg = c.value()->toString(exec); -#if 0 - JSObject* resObj = c.value()->toObject(exec); - CString message = resObj->toString(exec).UTF8String(); - int line = resObj->toObject(exec)->get(exec, "line")->toUInt32(exec); - - if (!sourceURL.isEmpty()) - fprintf(stderr, "%s (line %d): ", qPrintable(sourceURL), line); - fprintf(stderr, "%s\n", msg.c_str()); -#endif - fprintf(stderr, "evaluate() threw an exception\n"); - res.hnd->errMsg = msg; - } else { - if (c.isValueCompletion()) - res.hnd->val = KJSObject(JSVALUE_HANDLE(c.value())); - } - - return res; -} - -KJSResult KJSInterpreter::evaluate(const QString& code, - KJSObject* thisValue) -{ - return evaluate("", 0, code, thisValue); -} - -bool KJSInterpreter::normalizeCode(const QString& code, QString* normalized, - int* errLine, QString* errMsg) -{ - assert(normalized); - - UString codeOut, msg; - bool success = Interpreter::normalizeCode(toUString(code), &codeOut, - errLine, &msg); - - *normalized = toQString(codeOut); - if (errMsg) - *errMsg = toQString(msg); - - return success; -} - diff --git a/kjs/api/kjsinterpreter.h b/kjs/api/kjsinterpreter.h deleted file mode 100644 index 61c3325e..00000000 --- a/kjs/api/kjsinterpreter.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJSINTERPRETER_H -#define KJSINTERPRETER_H - -#include "kjsapi_export.h" -#include "kjsobject.h" -#include "kjscontext.h" - -class KJSPrototype; -class KJSInterpreter; -class KJSInterpreterHandle; -class KJSResultHandle; - -/** - * A class representing the result of a script evaluation. - */ -class KJSAPI_EXPORT KJSResult -{ - friend class KJSInterpreter; -public: - /** - * Constructs a default result object. - */ - KJSResult(); - /** - * Constructs a copy of another result object. - */ - KJSResult(const KJSResult&); - /** - * Assigns the properties of another result object to this one. - */ - KJSResult& operator=(const KJSResult&); - /** - * Frees resources held by this result object. - */ - ~KJSResult(); - /** - * Returns true if the script evaluation has caused an exception. - */ - bool isException() const; - - /** - * Returns the error message if this is an exception result. - */ - QString errorMessage() const; - /* - * If the evaluation was successful, i.e. isException() is false - * this function returns the value returned by the script. Can be - * an "undefined" (isUndefined()) value. - */ - KJSObject value() const; - -private: - KJSResultHandle* hnd; -}; - -/** - * A class representing a JavaScript interpreter - * - * @short JavaScript interpreter - */ -class KJSAPI_EXPORT KJSInterpreter -{ - friend class KJSResult; - friend class KJSPrototype; - friend class KJSContext; -public: - /** - * Constructs an interpreter with a default global object. - */ - KJSInterpreter(); - /** - * Constructs an interpreter with a custom global object. - */ - KJSInterpreter(const KJSGlobalObject& global); - /** - * Creates a copy of another interpreter. - */ - KJSInterpreter(const KJSInterpreter& other); - /** - * Assign another interpreter instance to this object. - */ - KJSInterpreter& operator=(const KJSInterpreter& other); - /** - * Destructs this interpreter and frees resources it has - * allocated. This renders any still existing objects referencing - * those invalid. - */ - ~KJSInterpreter(); - - /** - * Returns a handle to the global execution context. - */ - KJSContext* globalContext(); - /** - * @overload - */ - const KJSContext* globalContext() const; - /** - * Returns the object that is used as the global object during all - * script execution performed by this interpreter, - */ - KJSObject globalObject(); - /** - * Evaluates a piece of code with a "this" set to (optionally set) - * value. The sourceURL and startingLineNumber parameters are used - * to provide information about the origin of a parse error or - * runtime exception. - */ - KJSResult evaluate(const QString& sourceURL, int startingLineNumber, - const QString& code, - KJSObject* thisValue = 0); - /** - * @overload - */ - KJSResult evaluate(const QString& code, - KJSObject* thisValue = 0); - - /** - * Reformat the given script code to an easy to read format with - * only one statement per line. This can be useful when debugging - * a script that was e.g. condensed into a single line to a single - * line. While comments will be removed the script will remain - * unchanged semantically. - * - * @param codeIn The code to be reformatted - * @param codeOut Points to string holding the result. - * @param errLine Will hold the line of a parse error - * @param errMsg Will hold the message of a parse error - * - * @return Returns true if the reformatting was successful, false - * on a parse error. - */ - static bool normalizeCode(const QString& codeIn, QString* codeOut, - int* errLine = 0, QString* errMsg = 0); -private: - KJSInterpreter(KJSInterpreterHandle* h); - KJSInterpreterHandle* hnd; - KJSContext globCtx; -}; - -#endif diff --git a/kjs/api/kjsobject.cpp b/kjs/api/kjsobject.cpp deleted file mode 100644 index cb53a2f8..00000000 --- a/kjs/api/kjsobject.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "kjsobject.h" -#include "kjsprivate.h" -#include "kjscontext.h" -#include "kjs/value.h" -#include "kjs/object.h" -#include "kjs/protect.h" -#include "kjs/ExecState.h" -#include "kjs/JSVariableObject.h" - -#include -#include - -using namespace KJS; - -KJSObject::KJSObject() - : hnd(JSVALUE_HANDLE(new JSObject())) -{ - gcProtect(JSVALUE(this)); -} - -KJSObject::KJSObject(const KJSObject& o) - : hnd(o.hnd) -{ - gcProtectNullTolerant(JSVALUE(this)); -} - -KJSObject& KJSObject::operator=(const KJSObject& o) -{ - gcUnprotectNullTolerant(JSVALUE(this)); - - hnd = o.hnd; - gcProtectNullTolerant(JSVALUE(this)); - - return *this; -} - -KJSObject::~KJSObject() -{ - gcUnprotectNullTolerant(JSVALUE(this)); -} - -KJSNull::KJSNull() - : KJSObject(JSVALUE_HANDLE(jsNull())) -{ -} - -KJSUndefined::KJSUndefined() - : KJSObject(JSVALUE_HANDLE(jsUndefined())) -{ -} - -KJSBoolean::KJSBoolean(bool b) - : KJSObject(JSVALUE_HANDLE(jsBoolean(b))) -{ -} - -KJSNumber::KJSNumber(double d) - : KJSObject(JSVALUE_HANDLE(jsNumber(d))) -{ - gcProtect(JSVALUE(this)); -} - -KJSString::KJSString(const QString& s) - : KJSObject(JSVALUE_HANDLE(jsString(toUString(s)))) -{ - gcProtect(JSVALUE(this)); -} - -KJSString::KJSString(const char* s) - : KJSObject(JSVALUE_HANDLE(jsString(s))) -{ - gcProtect(JSVALUE(this)); -} - -static JSValue* constructArrayHelper(ExecState* exec, int len) -{ - JSObject* builtinArray = exec->lexicalInterpreter()->builtinArray(); - JSObject* newArray = builtinArray->construct(exec, List()); - newArray->put(exec, exec->propertyNames().length, jsNumber(len), - DontDelete|ReadOnly|DontEnum); - return newArray; -} - -KJSArray::KJSArray(KJSContext* ctx, int len) - : KJSObject(JSVALUE_HANDLE(constructArrayHelper(EXECSTATE(ctx), len))) - -{ - gcProtect(JSVALUE(this)); -} - -static JSValue* constructDateHelper(KJSContext* ctx, const QDateTime& dt) -{ - Q_UNUSED(ctx); - Q_UNUSED(dt); - kWarning() << "converDateTimeHelper() not implemented, yet"; - - // ### make call into data_object.cpp - - return jsNumber(42.0); -} - - -KJSDate::KJSDate(KJSContext* ctx, const QDateTime& dt) - : KJSObject(JSVALUE_HANDLE(constructDateHelper(ctx, dt))) -{ - gcProtect(JSVALUE(this)); -} - -bool KJSObject::isUndefined() const -{ - return JSVALUE(this)->isUndefined(); -} - -bool KJSObject::isNull() const -{ - return JSVALUE(this)->isNull(); -} - -bool KJSObject::isBoolean() const -{ - return JSVALUE(this)->isBoolean(); -} - -bool KJSObject::isNumber() const -{ - return JSVALUE(this)->isNumber(); -} - -bool KJSObject::isString() const -{ - return JSVALUE(this)->isString(); -} - -bool KJSObject::isObject() const -{ - return JSVALUE(this)->isObject(); -} - -bool KJSObject::toBoolean(KJSContext* ctx) -{ - ExecState* exec = EXECSTATE(ctx); - assert(exec); - return JSVALUE(this)->toBoolean(exec); -} - -double KJSObject::toNumber(KJSContext* ctx) -{ - ExecState* exec = EXECSTATE(ctx); - assert(exec); - return JSVALUE(this)->toNumber(exec); -} - -int KJSObject::toInt32(KJSContext* ctx) -{ - ExecState* exec = EXECSTATE(ctx); - assert(exec); - return JSVALUE(this)->toInt32(exec); -} - -QString KJSObject::toString(KJSContext* ctx) -{ - ExecState* exec = EXECSTATE(ctx); - assert(exec); - return toQString(JSVALUE(this)->toString(exec)); -} - -KJSObject KJSObject::property(KJSContext* ctx, const QString& name) -{ - JSValue* v = JSVALUE(this); - assert(v); - -#if 0 - // would normally throw an exception - if (v == jsUndefined || v == jsNull()) - return KJSUndefined(); -#endif - - ExecState* exec = EXECSTATE(ctx); - JSObject* o = v->toObject(exec); - JSValue* res = o->get(exec, toIdentifier(name)); - - return KJSObject(JSVALUE_HANDLE(res)); -} - -void KJSObject::setProperty(KJSContext* ctx, const QString& name, - const KJSObject& value) -{ - JSValue* v = JSVALUE(this); - assert(v); - - ExecState* exec = EXECSTATE(ctx); - JSObject* o = v->toObject(exec); - o->put(exec, toIdentifier(name), JSVALUE(&value)); -} - -void KJSObject::setProperty(KJSContext* ctx, const QString& name, bool value) -{ - setProperty(ctx, name, KJSBoolean(value)); -} - -void KJSObject::setProperty(KJSContext* ctx, const QString& name, - double value) -{ - setProperty(ctx, name, KJSNumber(value)); -} - -void KJSObject::setProperty(KJSContext* ctx, const QString& name, - int value) -{ - setProperty(ctx, name, KJSNumber(double(value))); -} - -void KJSObject::setProperty(KJSContext* ctx, const QString& name, - const QString &value) -{ - setProperty(ctx, name, KJSString(value)); -} - -void KJSObject::setProperty(KJSContext* ctx, const QString& name, - const char* value) -{ - setProperty(ctx, name, KJSString(value)); -} - -KJSGlobalObject::KJSGlobalObject(): KJSObject(JSVALUE_HANDLE(new JSGlobalObject())) -{ -} diff --git a/kjs/api/kjsobject.h b/kjs/api/kjsobject.h deleted file mode 100644 index 68b29e62..00000000 --- a/kjs/api/kjsobject.h +++ /dev/null @@ -1,294 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJSOBJECT_H -#define KJSOBJECT_H - -#include "kjsapi_export.h" -#include - -class QDateTime; -class KJSContext; -class KJSNull; -class KJSUndefined; -class KJSBoolean; -class KJSNumber; -class KJSString; -class KJSArray; -class KJSDate; -class KJSArguments; -class KJSInterpreter; -class KJSObjectHandle; -class KJSCustomProperty; -class KJSCustomFunction; - -/** - * A class representing a JavaScript value. - * - * @short Script object - */ -class KJSAPI_EXPORT KJSObject -{ - friend class KJSNull; - friend class KJSUndefined; - friend class KJSBoolean; - friend class KJSNumber; - friend class KJSString; - friend class KJSArray; - friend class KJSDate; - friend class KJSGlobalObject; - friend class KJSPrototype; - friend class KJSContext; - friend class KJSArguments; - friend class KJSInterpreter; - friend class KJSCustomProperty; - friend class KJSCustomFunction; -public: - /** - * Constructs a JavaScript object of the generic Object type. - */ - KJSObject(); - /** - * Constructs on object from another one - */ - KJSObject(const KJSObject& o); - /** - * Assigns another JS object references to this one. - */ - KJSObject& operator=(const KJSObject& o); - /** - * Destructs this object freeing any references it might have held. - */ - ~KJSObject(); - /** - * Returns whether this object is undefined. - */ - bool isUndefined() const; - /** - * Returns whether this object is null. - */ - bool isNull() const; - /** - * Returns whether this object is a boolean. - */ - bool isBoolean() const; - /** - * Returns whether this object is a number. - */ - bool isNumber() const; - /** - * Returns whether this object is a string. - */ - bool isString() const; - /** - * Returns whether this object is a full blown object. - */ - bool isObject() const; - - /** - * Returns this value converted to a boolean. If the conversion - * fails the context will have an exception set. - */ - bool toBoolean(KJSContext* ctx); - /** - * Returns this value converted to a number. If the conversion - * fails the context will have an exception set. - */ - double toNumber(KJSContext* ctx); - /** - * Returns this value converted to a 32-bit integer number. NaN, - * positive and negative Infinity will be converted to 0. If the - * conversion fails the context will have an exception set. - */ - int toInt32(KJSContext* ctx); - /** - * Returns this value converted to a string. If the conversion - * fails the context will have an exception set. - */ - QString toString(KJSContext* ctx); - /** - * Reads the specified property from this object. This operation - * might throw an exception. - */ - KJSObject property(KJSContext* ctx, const QString& name); - /** - * Sets the specified property on this object. This operation - * might throw an exception. - */ - void setProperty(KJSContext* ctx, const QString& name, - const KJSObject& value); - /** - * @overload - */ - void setProperty(KJSContext* ctx, const QString& name, bool value); - /** - * @overload - */ - void setProperty(KJSContext* ctx, const QString& name, double value); - /** - * @overload - */ - void setProperty(KJSContext* ctx, const QString& name, int value); - /** - * @overload - */ - void setProperty(KJSContext* ctx, const QString& name, - const QString &value); - /** - * @overload - * - * Accepts a Latin1 encoded, null-terminated string. - */ - void setProperty(KJSContext* ctx, const QString& name, - const char* value); - - -private: - KJSObject(KJSObjectHandle* h) : hnd(h) { } - KJSObjectHandle* hnd; -}; - -/** - * A class representing a JavaScript null value. - * - * @short Null value - */ -class KJSAPI_EXPORT KJSNull : public KJSObject -{ -public: - /** - * Constructs a null object. - */ - KJSNull(); -}; - -/** - * A class representing an undefined JavaScript value. - * - * @short Undefined value - */ -class KJSAPI_EXPORT KJSUndefined : public KJSObject -{ -public: - /** - * Constructs an undefined object. - */ - KJSUndefined(); -}; - -/** - * A class representing a boolean JavaScript value. - * - * @short Boolean value - */ -class KJSAPI_EXPORT KJSBoolean : public KJSObject -{ -public: - /** - * Constructs a boolean object. - */ - KJSBoolean(bool b); -}; - -/** - * A class representing a JavaScript number value. - * - * @short Number value - */ -class KJSAPI_EXPORT KJSNumber : public KJSObject -{ -public: - /** - * Constructs a number object. - */ - KJSNumber(double d); -}; - -/** - * A class representing a JavaScript string value. - * - * @short String value - */ -class KJSAPI_EXPORT KJSString : public KJSObject -{ -public: - /** - * Constructs a string object. - */ - KJSString(const QString& s); - /** - * Constructs a string object from an Latin1 encoded, - * null-terminated string. Note the limited input character range - * which rules out a big part of Unicode. - * - * @overload - */ - KJSString(const char* s); -}; - -/** - * A class representing a JavaScript array object. - * - * @short Array object - */ -class KJSAPI_EXPORT KJSArray : public KJSObject -{ -public: - /** - * Constructs an array object with the specified length. - */ - KJSArray(KJSContext* ctx, int len = 0); -}; - -/** - * A class representing a JavaScript date object. - * - * @short Date object - */ -class KJSAPI_EXPORT KJSDate : public KJSObject -{ -public: - /** - * Constructs a date object from the specified date and time. - */ - KJSDate(KJSContext* ctx, const QDateTime& dt); -}; - -/** - * A class representing a global object of an execution environment. - * - * @short Global object - */ -class KJSAPI_EXPORT KJSGlobalObject : public KJSObject -{ - friend class KJSPrototype; -public: - /** - * Constructs an empty global object. Usually done through - * KJSPrototype::constructGlobalObject(). - */ - KJSGlobalObject(); - -private: - KJSGlobalObject(KJSObjectHandle* h) : KJSObject(h) { } -}; - -#endif diff --git a/kjs/api/kjsprivate.h b/kjs/api/kjsprivate.h deleted file mode 100644 index 86bc4955..00000000 --- a/kjs/api/kjsprivate.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJSPRIVATE_H -#define KJSPRIVATE_H - -#include "kjs/ustring.h" -#include "kjs/identifier.h" -#include "kjs/list.h" -#include - -#define JSVALUE_HANDLE(v) reinterpret_cast(v) -#define JSVALUE(h) reinterpret_cast((h)->hnd) - -#define EXECSTATE_HANDLE(c) reinterpret_cast(c) -#define EXECSTATE(ctx) reinterpret_cast((ctx)->hnd) - -#define INTERPRETER_HANDLE(i) reinterpret_cast(i) -#define INTERPRETER(h) reinterpret_cast((h)->hnd) - -#define PROTOTYPE_HANDLE(p) reinterpret_cast(p) -#define PROTOTYPE(h) reinterpret_cast((h)->hnd) - -#define LIST_HANDLE(l) reinterpret_cast(l) -#define LIST(h) reinterpret_cast((h)->hnd) - -static inline KJS::UString toUString(const QString& s) -{ - // ### can be done faster. see khtml/ecma/kjs_binding.cpp - int l = s.length(); - const KJS::UChar* u = reinterpret_cast(s.unicode()); - return KJS::UString(u, l); -} - -static inline KJS::Identifier toIdentifier(const QString& s) -{ - int l = s.length(); - const KJS::UChar* u = reinterpret_cast(s.unicode()); - return KJS::Identifier(u, l); -} - -static inline QString toQString(const KJS::UString& s) -{ - int l = s.size(); - const QChar* u = reinterpret_cast(s.data()); - return QString(u, l); -} - -#endif diff --git a/kjs/api/kjsprototype.cpp b/kjs/api/kjsprototype.cpp deleted file mode 100644 index e61701e0..00000000 --- a/kjs/api/kjsprototype.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "kjsprototype.h" -#include "kjsinterpreter.h" -#include "kjsarguments.h" -#include "kjsprivate.h" - -#include "kjs/object.h" -#include "kjs/JSVariableObject.h" -#include "kjs/context.h" -#include "kjs/interpreter.h" - -#include - -using namespace KJS; - -class KJSCustomProperty -{ -public: - KJSCustomProperty(KJSPrototype::PropertyGetter g, - KJSPrototype::PropertySetter s) - : getter(g), setter(s) - { - } - - JSValue* read(ExecState* exec, void* object); - void write(ExecState* exec, void* object, JSValue* value); - -private: - KJSPrototype::PropertyGetter getter; - KJSPrototype::PropertySetter setter; -}; - -class CustomObjectInfo { -public: - CustomObjectInfo(void* v): iv(v) {} - virtual ~CustomObjectInfo() {} - void* internalValue() { return iv; } -protected: - void* iv; -}; - -template -class CustomObject : public Base, public CustomObjectInfo { -public: - CustomObject(JSValue* proto, void* v) - : Base(proto), - CustomObjectInfo(v) - {} - - using Base::put; - void put(ExecState* exec, const Identifier& id, - JSValue *value, int attr = None); - - - // rtti - static const ClassInfo info; - const ClassInfo* classInfo() const { return &info; } -}; - -template<> -const ClassInfo CustomObject::info = { "CustomObject", 0, 0, 0 }; - -template<> -const ClassInfo CustomObject::info = { "CustomGlobalObject", 0, 0, 0 }; - -class KJSCustomFunction : public JSObject { -public: - KJSCustomFunction(ExecState* exec, KJSPrototype::FunctionCall f) - : callback(f) - { - setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype()); - } - - JSValue* callAsFunction(ExecState* exec, JSObject* thisObj, - const List &args); - bool implementsCall() const { return true; } - -private: - KJSPrototype::FunctionCall callback; -}; - -JSValue* KJSCustomFunction::callAsFunction(ExecState* exec, JSObject* thisObj, - const List &args) -{ - // FIXME: does not protect against mixing custom objects - CustomObjectInfo* inf = dynamic_cast(thisObj); - - if (!inf) { - const char* errMsg = "Attempt at calling a function with an invalid receiver"; - KJS::JSObject *err = KJS::Error::create(exec, KJS::TypeError, errMsg); - exec->setException(err); - return err; - } - - void* thisValue = inf->internalValue(); - - KJSContext ctx(EXECSTATE_HANDLE(exec)); - KJSArguments a(LIST_HANDLE(&args)); - KJSObject res = (*callback)(&ctx, thisValue, a); - return JSVALUE(&res); -} - -JSValue* KJSCustomProperty::read(ExecState* exec, void* object) -{ - assert(getter); - - KJSContext ctx(EXECSTATE_HANDLE(exec)); - KJSObject res = (*getter)(&ctx, object); - return JSVALUE(&res); -} - -void KJSCustomProperty::write(ExecState* exec, void* object, JSValue* value) -{ - KJSContext ctx(EXECSTATE_HANDLE(exec)); - - if (setter) { - KJSObject vo(JSVALUE_HANDLE(value)); - (*setter)(&ctx, object, vo); - } else { - JSObject *e = Error::create(exec, GeneralError, - "Property is read-only"); - exec->setException(e); - } -} - -static JSValue* getPropertyValue(ExecState* exec, JSObject *originalObject, - const Identifier&, const PropertySlot& sl) -{ - CustomObjectInfo* inf = dynamic_cast(originalObject); - if (!inf) - return jsUndefined(); - - KJSCustomProperty* p = - reinterpret_cast(sl.customValue()); - - return p->read(exec, inf->internalValue()); -} - -// FIXME: or use Identifier? -// FIXME: use values -typedef QMap CustomPropertyMap; - -class CustomPrototype : public JSObject { -public: - CustomPrototype() - { - } - ~CustomPrototype() - { - qDeleteAll(properties); - } - - using KJS::JSObject::getOwnPropertySlot; - bool getOwnPropertySlot(ExecState *exec, const Identifier& id, - PropertySlot& sl) - { - CustomPropertyMap::iterator it = properties.find(id.ustring()); - if (it == properties.end()) - return JSObject::getOwnPropertySlot(exec, id, sl); - - sl.setCustomValue(0, *it, getPropertyValue); - - return true; - } - - void registerProperty(const QString& name, - KJSPrototype::PropertyGetter g, - KJSPrototype::PropertySetter s) - { - properties.insert(toUString(name), new KJSCustomProperty(g, s)); - } - - void registerFunction(ExecState* exec, - const QString& name, KJSPrototype::FunctionCall f) - { - putDirect(toIdentifier(name), new KJSCustomFunction(exec, f)); - } - - template - bool setProperty(ExecState* exec, CustomObject* obj, - const Identifier& id, JSValue* value) - { - CustomPropertyMap::iterator it = properties.find(id.ustring()); - if (it == properties.end()) - return false; - - (*it)->write(exec, obj->internalValue(), value); - - return true; - } - -private: - CustomPropertyMap properties; -}; - -template -void CustomObject::put(ExecState* exec, const Identifier& id, - JSValue* value, int attr) -{ - CustomPrototype* p = static_cast(this->prototype()); - - if (!p->setProperty(exec, this, id, value)) - Base::put(exec, id, value, attr); -} - -KJSPrototype::KJSPrototype() -{ - CustomPrototype* p = new CustomPrototype; - gcProtect(p); - - hnd = PROTOTYPE_HANDLE(p); -} - -KJSPrototype::~KJSPrototype() -{ - gcUnprotect(PROTOTYPE(this)); -} - -void KJSPrototype::defineConstant(const QString& name, double value) -{ - CustomPrototype* p = PROTOTYPE(this); - - p->putDirect(toIdentifier(name), jsNumber(value), - DontEnum|DontDelete|ReadOnly); -} - -void KJSPrototype::defineConstant(const QString& name, const QString& value) -{ - CustomPrototype* p = PROTOTYPE(this); - - p->putDirect(toIdentifier(name), jsString(toUString(value)), - DontEnum|DontDelete|ReadOnly); -} - -void KJSPrototype::defineConstant(const QString& name, const KJSObject& value) -{ - CustomPrototype* p = PROTOTYPE(this); - - p->putDirect(toIdentifier(name), JSVALUE(&value), - DontEnum|DontDelete|ReadOnly); -} - -KJSObject KJSPrototype::constructObject(KJSContext* ctx, void *internalValue) -{ - CustomPrototype* p = PROTOTYPE(this); - - if (ctx && !p->prototype()) { - ExecState* exec = EXECSTATE(ctx); - KJS::Interpreter* i = exec->lexicalInterpreter(); - JSObject* objectProto = i->builtinObjectPrototype(); - p->setPrototype(objectProto); - } - - CustomObject* newObj = new CustomObject(p, internalValue); - return KJSObject(JSVALUE_HANDLE(newObj)); -} - -KJSGlobalObject KJSPrototype::constructGlobalObject(void *internalValue) -{ - CustomPrototype* p = PROTOTYPE(this); - - CustomObject* newObj = new CustomObject(p, internalValue); - return KJSGlobalObject(JSVALUE_HANDLE(newObj)); -} - -void KJSPrototype::defineProperty(KJSContext* ctx, - const QString& name, - PropertyGetter getter, - PropertySetter setter) -{ - Q_UNUSED(ctx); - assert(getter); - - CustomPrototype* p = PROTOTYPE(this); - - p->registerProperty(name, getter, setter); -} - -void KJSPrototype::defineFunction(KJSContext* ctx, - const QString& name, FunctionCall callback) -{ - assert(callback); - - CustomPrototype* p = PROTOTYPE(this); - ExecState* exec = EXECSTATE(ctx); - - p->registerFunction(exec, name, callback); -} - - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/api/kjsprototype.h b/kjs/api/kjsprototype.h deleted file mode 100644 index f75fe3fa..00000000 --- a/kjs/api/kjsprototype.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2008 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJSPROTOTYPE_H -#define KJSPROTOTYPE_H - -#include "kjsapi_export.h" -#include "kjscontext.h" - -class KJSInterpreter; -class KJSArguments; -class KJSGlobalObject; -class KJSPrototypeHandle; - -/** - * A class representing a JavaScript prototype object. - * - * @short Prototype object. - */ -class KJSAPI_EXPORT KJSPrototype -{ -public: - /** - * Constructs a prototype object with its own prototype property - * set to the Object prototype. - */ - KJSPrototype(); - /** - * Destructs this prototype object. - */ - ~KJSPrototype(); - /** - * Add a read-only numerical property to this object. - */ - void defineConstant(const QString& name, double value); - /** - * Add a read-only string property to this object. - * - * @overload - */ - void defineConstant(const QString& name, const QString& value); - /** - * Add a read-only object property to this object. - * - * @overload - */ - void defineConstant(const QString& name, const KJSObject& value); - /** - * Function signature for a property getter function. Describes - * one of the defineProperty() argument types. - */ - typedef KJSObject (*PropertyGetter)(KJSContext* context, void* object); - /** - * Function signature for a property setter function. Describes - * one of the defineProperty() argument types. - */ - typedef void (*PropertySetter)(KJSContext* context, void* object, - KJSObject value); - /** - * Defines a property of this prototype with C++ callback - * functions for getting and setting the property value. If the - * setter is set to 0 then the property is treated as read-only. - */ - void defineProperty(KJSContext* ctx, - const QString& name, - PropertyGetter getter, - PropertySetter setter = 0); - - /** - * Signature for function call callback function. The - * defineFunction() function parameter accepts a reference to a - * function of this type as a parameter. - */ - typedef KJSObject (*FunctionCall)(KJSContext* context, void* object, - const KJSArguments& arguments); - - /** - * Define a function. The specified C++ callback function will - * be called upon invocation. - */ - void defineFunction(KJSContext* ctx, - const QString& name, FunctionCall callback); - -#if 0 - /** - * Define a finalization function. - * - */ - void defineFinalization(FinalizeFunction callback); -#endif - - /** - * Construct an object with this prototype and the specified - * internal value. The value pointer will be passed as the object - * parameter to the callbacks defined via defineProperty() and - * defineFunction(). - * - * @todo Provide a better type than void* - */ - KJSObject constructObject(KJSContext* ctx, void *internalValue = 0); - - /** - * Similar to constructObject() but specialized on the - * construction of global objects. - */ - KJSGlobalObject constructGlobalObject(void *internalValue = 0); - -private: - KJSPrototype(const KJSPrototype&); // undefined - KJSPrototype& operator=(const KJSPrototype&); // undefined - - KJSPrototypeHandle* hnd; -}; - -#endif diff --git a/kjs/array_instance.cpp b/kjs/array_instance.cpp deleted file mode 100644 index 23fe8273..00000000 --- a/kjs/array_instance.cpp +++ /dev/null @@ -1,978 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2003 Peter Kelly (pmk@post.com) - * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include -#include "array_instance.h" - -#include "PropertyNameArray.h" -#include "JSVariableObject.h" -#include -#include - -#include -#include - -using std::min; -using std::max; - - -namespace KJS { - -struct ArrayEntity { - ArrayEntity() - : value(0), - attributes(0) - { - } - - ArrayEntity(JSValue* jsVal, uint32_t attr) - : value(jsVal), - attributes(attr) - { - } - - JSValue* value; - uint32_t attributes; -}; - -typedef HashMap SparseArrayValueMap; - -struct ArrayStorage { - unsigned m_numValuesInVector; - SparseArrayValueMap* m_sparseValueMap; - ArrayEntity m_vector[1]; -}; - -// (2^32)-1 -static const unsigned maxArrayLength = 0xFFFFFFFFU; -// 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer -static const unsigned maxArrayIndex = 0xFFFFFFFEU; - -// Our policy for when to use a vector and when to use a sparse map. -// For all array indices under sparseArrayCutoff, we always use a vector. -// When indices greater than sparseArrayCutoff are involved, we use a vector -// as long as it is 1/8 full. If more sparse than that, we use a map. -static const unsigned sparseArrayCutoff = 10000; -static const unsigned minDensityMultiplier = 8; - -static const unsigned mergeSortCutoff = 10000; - -const ClassInfo ArrayInstance::info = {"Array", 0, 0, 0}; - -static inline size_t storageSize(unsigned vectorLength) -{ - return sizeof(ArrayStorage) - sizeof(ArrayEntity) + vectorLength * sizeof(ArrayEntity); -} - -static inline unsigned increasedVectorLength(unsigned newLength) -{ - return (newLength * 3 + 1) / 2; -} - -static inline bool isDenseEnoughForVector(unsigned length, unsigned numValues) -{ - return length / minDensityMultiplier <= numValues; -} - -ArrayInstance::ArrayInstance(JSObject* prototype, unsigned initialLength) - : JSObject(prototype) -{ - unsigned initialCapacity = min(initialLength, sparseArrayCutoff); - - m_length = initialLength; - m_vectorLength = initialCapacity; - m_storage = static_cast(fastCalloc(storageSize(initialCapacity), 1)); - m_lengthAttributes = DontDelete | DontEnum; - - Collector::reportExtraMemoryCost(initialCapacity * sizeof(ArrayEntity)); -} - -ArrayInstance::ArrayInstance(JSObject* prototype, const List& list) - : JSObject(prototype) -{ - unsigned length = list.size(); - - m_length = length; - m_vectorLength = length; - m_lengthAttributes = DontDelete | DontEnum; - - ArrayStorage* storage = static_cast(fastMalloc(storageSize(length))); - - storage->m_numValuesInVector = length; - storage->m_sparseValueMap = 0; - - ListIterator it = list.begin(); - for (unsigned i = 0; i < length; ++i) { - storage->m_vector[i].value = it++; - storage->m_vector[i].attributes = 0; - } - - m_storage = storage; - - // When the array is created non-empty, its cells are filled, so it's really no worse than - // a property map. Therefore don't report extra memory cost. -} - -ArrayInstance::~ArrayInstance() -{ - delete m_storage->m_sparseValueMap; - fastFree(m_storage); -} - -JSValue* ArrayInstance::getItem(unsigned i) const -{ - ASSERT(i <= maxArrayIndex); - - ArrayEntity* ent = getArrayEntity(i); - if (ent) - return ent->value; - return jsUndefined(); -} - -JSValue* ArrayInstance::lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot) -{ - return jsNumber(static_cast(slot.slotBase())->m_length); -} - -ALWAYS_INLINE bool ArrayInstance::inlineGetOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot) -{ - if (i >= m_length) { - if (i > maxArrayIndex) - return getOwnPropertySlot(exec, Identifier::from(i), slot); - return false; - } - - ArrayEntity* ent = getArrayEntity(i); - if (ent) { - if (ent->attributes & GetterSetter) { - GetterSetterImp *gs = static_cast(ent->value); - JSObject *getterFunc = gs->getGetter(); - if (getterFunc) - slot.setGetterSlot(this, getterFunc); - else - slot.setUndefined(this); - return true; - } - slot.setValueSlot(this, &ent->value); - return true; - } - - return false; -} - -ArrayEntity* ArrayInstance::getArrayEntity(unsigned int i) const -{ - if (i >= m_length) - return 0; - - ArrayStorage* storage = m_storage; - if (i < m_vectorLength) { - if (storage->m_vector[i].value) - return &storage->m_vector[i]; - } - - SparseArrayValueMap* map = storage->m_sparseValueMap; - if (map && i > 0 && i <= maxArrayIndex) { - SparseArrayValueMap::iterator it = map->find(i); - if (it != map->end()) { - return &it->second; - } - } - - return 0; -} - -bool ArrayInstance::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - if (propertyName == exec->propertyNames().length) { - slot.setCustom(this, lengthGetter); - return true; - } - - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); - if (isArrayIndex) - return inlineGetOwnPropertySlot(exec, i, slot); - - return JSObject::getOwnPropertySlot(exec, propertyName, slot); -} - -bool ArrayInstance::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot) -{ - return inlineGetOwnPropertySlot(exec, i, slot); -} - -// ECMA 15.4.5.1 -void ArrayInstance::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attributes) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); - if (isArrayIndex) { - put(exec, i, value, attributes); - return; - } - - if (propertyName == exec->propertyNames().length) { - if (m_lengthAttributes & ReadOnly) - return; - unsigned newLength = value->toUInt32(exec); - if (value->toNumber(exec) != static_cast(newLength)) { - throwError(exec, RangeError, "Invalid array length."); - return; - } - m_lengthAttributes = attributes; - setLength(newLength); - return; - } - - JSObject::put(exec, propertyName, value, attributes); -} - -void ArrayInstance::put(ExecState* exec, unsigned i, JSValue* value, int attributes) -{ - ArrayEntity *ent = getArrayEntity(i); - if (ent) { - if (ent->attributes & ReadOnly) - return; - attributes |= ent->attributes; - - JSValue* gs = ent->value; - if (gs && !gs->isUndefined()) { - if (ent->attributes & GetterSetter) { - JSObject *setterFunc = static_cast(gs)->getSetter(); - - if (!setterFunc) { - if (false) //if strict is true - throwError(exec, TypeError, "setting a property that has only a getter"); - return; - } - - List args; - args.append(value); - - setterFunc->call(exec, this, args); - return; - } - } - } - - KJS::ArrayInstance::putDirect(i, value, attributes); -} - -bool ArrayInstance::deleteProperty(ExecState* exec, const Identifier& propertyName) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); - if (isArrayIndex) - return deleteProperty(exec, i); - - if (propertyName == exec->propertyNames().length) - return false; - - return JSObject::deleteProperty(exec, propertyName); -} - -bool ArrayInstance::deleteProperty(ExecState* exec, unsigned i) -{ - ArrayStorage* storage = m_storage; - - if (i < m_vectorLength) { - ArrayEntity* ent = &storage->m_vector[i]; - if (ent->value) { - if (ent->attributes & DontDelete) - return false; - - JSValue*& valueSlot = ent->value; - bool hadValue = valueSlot; - valueSlot = 0; - storage->m_numValuesInVector -= hadValue; - ent->value = 0; - return hadValue; - } - } - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap::iterator it = map->find(i); - if (it != map->end()) { - if ((*it).second.attributes & DontDelete) - return false; - map->remove(it->first); - return true; - } - } - - if (i > maxArrayIndex) - return JSObject::deleteProperty(exec, Identifier::from(i)); - - return true; -} - -void ArrayInstance::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, PropertyMap::PropertyMode mode) -{ - // FIXME: Filling PropertyNameArray with an identifier for every integer - // is incredibly inefficient for large arrays. We need a different approach. - - ArrayStorage* storage = m_storage; - - unsigned usedVectorLength = min(m_length, m_vectorLength); - for (unsigned i = 0; i < usedVectorLength; ++i) { - if (storage->m_vector[i].value && - (!(storage->m_vector[i].attributes & DontEnum) || - mode == PropertyMap::IncludeDontEnumProperties)) - propertyNames.add(Identifier::from(i)); - } - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap::iterator end = map->end(); - for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) - if (!((*it).second.attributes & DontEnum) || - mode == PropertyMap::IncludeDontEnumProperties) - propertyNames.add(Identifier::from(it->first)); - } - - if (mode == PropertyMap::IncludeDontEnumProperties) - propertyNames.add(exec->propertyNames().length); - - JSObject::getOwnPropertyNames(exec, propertyNames, mode); -} - -bool ArrayInstance::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) -{ - if (propertyName == exec->propertyNames().length) { - descriptor.setPropertyDescriptorValues(exec, jsNumber(m_length), m_lengthAttributes); - return true; - } - - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); - - if (isArrayIndex) { - ArrayEntity* ent = getArrayEntity(i); - if (ent) { - descriptor.setPropertyDescriptorValues(exec, ent->value, ent->attributes); - return true; - } - } - return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); -} - - -//ECMAScript Edition 5.1r6 - 15.4.5.1 -bool ArrayInstance::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& desc, bool shouldThrow) -{ - PropertyDescriptor oldLenDesc; - getOwnPropertyDescriptor(exec, exec->propertyNames().length, oldLenDesc); - unsigned int oldLen = oldLenDesc.value()->toUInt32(exec); - - //4a - bool isArrayIndex; - unsigned index = propertyName.toArrayIndex(&isArrayIndex); - - //Step 3 - if (propertyName == exec->propertyNames().length) { - //a - if (!desc.value()) - return JSObject::defineOwnProperty(exec, propertyName, desc, shouldThrow); - - //b - PropertyDescriptor newLenDesc(desc); - //c - unsigned int newLen = desc.value()->toUInt32(exec); - //d - if (newLen != desc.value()->toNumber(exec) || desc.value()->toNumber(exec) > maxArrayLength) { - throwError(exec, RangeError, "Index out of range"); - return false; - } - //e - newLenDesc.setValue(jsNumber(newLen)); - //f - if (newLen >= oldLen) - return JSObject::defineOwnProperty(exec, propertyName, newLenDesc, shouldThrow); - //g - if (!oldLenDesc.writable()) { - if (shouldThrow) - throwError(exec, TypeError, "length is not writable"); - return false; - } - //h - bool newWriteable; - if (!newLenDesc.writableSet() || newLenDesc.writable()) { - newWriteable = true; - } else { //i - if (anyItemHasAttribute(DontDelete)) - newLenDesc.setWritable(false); - else - newLenDesc.setWritable(true); - newWriteable = false; - } - //j - bool succeeded = JSObject::defineOwnProperty(exec, propertyName, newLenDesc, shouldThrow); - //k - if (!succeeded) return false; - //l - while (newLen < oldLen) { - --oldLen; - bool deleteSucceeded = deleteProperty(exec, oldLen); // 3. argument should be false - if (!deleteSucceeded) { - newLenDesc.setValue(jsNumber(oldLen+1)); - if (!newWriteable) - newLenDesc.setWritable(false); - JSObject::defineOwnProperty(exec, propertyName, newLenDesc, false); - if (shouldThrow) - throwError(exec, TypeError); - return false; - } - } - //m - if (!newWriteable) { - PropertyDescriptor writableDesc; - writableDesc.setWritable(false); - return JSObject::defineOwnProperty(exec, propertyName, writableDesc, false); - } - return true; - } else if (isArrayIndex) {//Step 4 - //b - if (index >= oldLen && !oldLenDesc.writable()) { - if (shouldThrow) - throwError(exec, TypeError); - return false; - } - //c - bool succeeded = JSObject::defineOwnProperty(exec, propertyName, desc, false); - //d - if (!succeeded) { - if (shouldThrow) - throwError(exec, TypeError); - return false; - } - //e - if (index >= oldLen) { - oldLenDesc.setValue(jsNumber(index+1)); - JSObject::defineOwnProperty(exec, exec->propertyNames().length, oldLenDesc, false); - } - return true; - } - - return JSObject::defineOwnProperty(exec, propertyName, desc, shouldThrow); -} - -bool ArrayInstance::getPropertyAttributes(const Identifier& propertyName, unsigned int& attributes) const -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); - - if (isArrayIndex) { - ArrayEntity* ent = getArrayEntity(i); - if (ent) { - attributes = ent->attributes; - return true; - } - } - - return KJS::JSObject::getPropertyAttributes(propertyName, attributes); -} - -JSValue* ArrayInstance::getDirect(const Identifier& propertyName) const -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); - - if (isArrayIndex) { - ArrayEntity* ent = getArrayEntity(i); - if (ent) { - if (ent->value) - return ent->value; - } - } - - return KJS::JSObject::getDirect(propertyName); -} - -void ArrayInstance::putDirect(unsigned i, JSValue* value, int attributes) -{ - unsigned length = m_length; - - if (i >= length) { - if (i > maxArrayIndex) { - KJS::JSObject::putDirect(Identifier::from(i), value, attributes); - return; - } - length = i + 1; - m_length = length; - } - - ArrayStorage* storage = m_storage; - - if (i < m_vectorLength) { - ArrayEntity* ent = &storage->m_vector[i]; - if (!ent->value && !isExtensible()) - return; - JSValue*& valueSlot = ent->value; - storage->m_numValuesInVector += !valueSlot; - valueSlot = value; - ent->attributes = attributes; - return; - } - - if (!isExtensible()) - return; - - SparseArrayValueMap* map = storage->m_sparseValueMap; - if (i >= sparseArrayCutoff) { - // If the index is high, go to the map unless we're pretty dense. - if (!map) { - map = new SparseArrayValueMap; - storage->m_sparseValueMap = map; - - // If we create a sparse map, we need to ensure that there is at least one spot - // in the vector map, however, since the sparse map can't put/get key 0. - // It's safe to do it here, since put(0) will always put it in the vector part, - // but we have to do it before a get(0) or it will crash - if (!m_vectorLength) - increaseVectorLength(1); - } - - map->set(i, ArrayEntity(value, attributes)); - return; - } - - // note: an invariant here is that indeces < sparseArrayCutoff - // are always inside the vector portion. - - // lowish indeces or high density -> we have decided that we'll put the new item into the vector. - // Fast case is when there is no sparse map, so we can increase the vector size without moving values from the sparse map. - if (!map || map->isEmpty()) { - increaseVectorLength(i + 1); - storage = m_storage; - ++storage->m_numValuesInVector; - storage->m_vector[i].value = value; - storage->m_vector[i].attributes = attributes; - return; - } - - // Decide just how large we want to make the vector to be. - unsigned newNumValuesInVector = storage->m_numValuesInVector + 1; - unsigned newVectorLength = increasedVectorLength(i + 1); - - // First, count how much stuff we are guaranteed to move over, now - // that we've decided to at least include i in the vector. - for (unsigned j = max(m_vectorLength, sparseArrayCutoff); j < newVectorLength; ++j) - newNumValuesInVector += map->contains(j); - if (i >= sparseArrayCutoff) - newNumValuesInVector -= map->contains(i); - - // Continue increasing the vector portion as long as the things in the map are dense enough - if (isDenseEnoughForVector(newVectorLength, newNumValuesInVector)) { - unsigned proposedNewNumValuesInVector = newNumValuesInVector; - while (true) { - unsigned proposedNewVectorLength = increasedVectorLength(newVectorLength + 1); - for (unsigned j = max(newVectorLength, sparseArrayCutoff); j < proposedNewVectorLength; ++j) - proposedNewNumValuesInVector += map->contains(j); - if (!isDenseEnoughForVector(proposedNewVectorLength, proposedNewNumValuesInVector)) - break; - newVectorLength = proposedNewVectorLength; - newNumValuesInVector = proposedNewNumValuesInVector; - } - } - - storage = static_cast(fastRealloc(storage, storageSize(newVectorLength))); - - unsigned vectorLength = m_vectorLength; - - // Special case: if we just added a single value, we don't have to scan the map - // to see what to remove from it - if (newNumValuesInVector == storage->m_numValuesInVector + 1) { - for (unsigned j = vectorLength; j < newVectorLength; ++j) - storage->m_vector[j].value = 0; - if (i > sparseArrayCutoff) - map->remove(i); - } else { - // Move over things from the map to the new array portion - for (unsigned j = vectorLength; j < max(vectorLength, sparseArrayCutoff); ++j) - storage->m_vector[j].value = 0; - for (unsigned j = max(vectorLength, sparseArrayCutoff); j < newVectorLength; ++j) - storage->m_vector[j] = map->take(j); - } - - storage->m_vector[i].value = value; - storage->m_vector[i].attributes = attributes; - - m_vectorLength = newVectorLength; - storage->m_numValuesInVector = newNumValuesInVector; - - m_storage = storage; -} - -void ArrayInstance::putDirect(const Identifier& propertyName, JSValue* value, int attr) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); - - if (isArrayIndex) { - KJS::ArrayInstance::putDirect(i, value, attr); - return; - } - - KJS::JSObject::putDirect(propertyName, value, attr); -} - -void ArrayInstance::putDirect(const Identifier& propertyName, int value, int attr) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); - - if (isArrayIndex) { - KJS::ArrayInstance::putDirect(i, jsNumber(value), attr); - return; - } - - KJS::JSObject::putDirect(propertyName, jsNumber(value), attr); -} - -void ArrayInstance::removeDirect(const Identifier& propertyName) -{ - bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); - - if (isArrayIndex) { - ArrayStorage* storage = m_storage; - - if (i < m_vectorLength) { - ArrayEntity* ent = &storage->m_vector[i]; - if (ent->value) { - JSValue*& valueSlot = ent->value; - bool hadValue = valueSlot; - valueSlot = 0; - storage->m_numValuesInVector -= hadValue; - ent->value = 0; - return; - } - } - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap::iterator it = map->find(i); - if (it != map->end()) { - map->remove(it->first); - return; - } - } - } - - JSObject::removeDirect(Identifier::from(i)); -} - -void ArrayInstance::increaseVectorLength(unsigned newLength) -{ - // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map - // to the vector. Callers have to account for that, because they can do it more efficiently. - - ArrayStorage* storage = m_storage; - - unsigned vectorLength = m_vectorLength; - ASSERT(newLength > vectorLength); - unsigned newVectorLength = increasedVectorLength(newLength); - - storage = static_cast(fastRealloc(storage, storageSize(newVectorLength))); - m_vectorLength = newVectorLength; - - for (unsigned i = vectorLength; i < newVectorLength; ++i) - storage->m_vector[i].value = 0; - - m_storage = storage; -} - -void ArrayInstance::setLength(unsigned newLength) -{ - ArrayStorage* storage = m_storage; - - unsigned length = m_length; - unsigned newLenSet = newLength; - - if (newLength < length) { - unsigned usedVectorLength = min(length, m_vectorLength); - if (usedVectorLength > 0) { - for (unsigned i = usedVectorLength-1; i >= newLength && i > 0; --i) { - ArrayEntity* ent = &storage->m_vector[i]; - if (ent->value) { - if (ent->attributes & DontDelete) { - newLenSet = i+1; - break; - } - JSValue*& valueSlot = ent->value; - bool hadValue = valueSlot; - valueSlot = 0; - ent->value = 0; - storage->m_numValuesInVector -= hadValue; - } - } - } - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap copy = *map; - SparseArrayValueMap::iterator end = copy.end(); - for (SparseArrayValueMap::iterator it = copy.begin(); it != end; ++it) { - if (it->first >= newLength) { - if (it->second.attributes & DontDelete) { - newLenSet = it->first + 1; - } - } - } - - for (SparseArrayValueMap::iterator it = copy.begin(); it != end; ++it) { - if (it->first >= newLenSet) { - map->remove(it->first); - } - } - - if (map->isEmpty()) { - delete map; - storage->m_sparseValueMap = 0; - } - } - } - - m_length = newLenSet; -} - -void ArrayInstance::mark() -{ - JSObject::mark(); - - ArrayStorage* storage = m_storage; - - unsigned usedVectorLength = min(m_length, m_vectorLength); - for (unsigned i = 0; i < usedVectorLength; ++i) { - ArrayEntity* ent = &storage->m_vector[i]; - if (ent->value && !ent->value->marked()) - ent->value->mark(); - } - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap::iterator end = map->end(); - for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) { - ArrayEntity* ent = &it->second; - if (!ent->value->marked()) - ent->value->mark(); - } - } -} - -static ExecState* execForCompareByStringForQSort; - -static int compareByStringForQSort(const void* a, const void* b) -{ - ExecState* exec = execForCompareByStringForQSort; - - const ArrayEntity* va = static_cast(a); - const ArrayEntity* vb = static_cast(b); - - ASSERT(va->value && !va->value->isUndefined()); - ASSERT(vb->value && !vb->value->isUndefined()); - - return compare(va->value->toString(exec), vb->value->toString(exec)); -} - -void ArrayInstance::sort(ExecState* exec) -{ - unsigned lengthNotIncludingUndefined = compactForSorting(); - - ExecState* oldExec = execForCompareByStringForQSort; - execForCompareByStringForQSort = exec; - -#if HAVE(MERGESORT) - // Because mergesort usually does fewer compares, it is faster than qsort here. - // However, because it requires extra copies of the storage buffer, don't use it for very - // large arrays. - - // FIXME: Since we sort by string value, a fast algorithm might be to convert all the - // values to string once up front, and then use a radix sort. That would be O(N) rather - // than O(N log N). - - if (lengthNotIncludingUndefined < mergeSortCutoff) { - // During the sort, we could do a garbage collect, and it's important to still - // have references to every object in the array for ArrayInstance::mark. - // The mergesort algorithm does not guarantee this, so we sort a copy rather - // than the original. - size_t size = storageSize(m_vectorLength); - ArrayStorage* copy = static_cast(fastMalloc(size)); - memcpy(copy, m_storage, size); - mergesort(copy->m_vector, lengthNotIncludingUndefined, sizeof(ArrayEntity), compareByStringForQSort); - fastFree(m_storage); - m_storage = copy; - execForCompareByStringForQSort = oldExec; - return; - } -#endif - - qsort(m_storage->m_vector, lengthNotIncludingUndefined, sizeof(ArrayEntity), compareByStringForQSort); - execForCompareByStringForQSort = oldExec; -} - -struct CompareWithCompareFunctionArguments { - CompareWithCompareFunctionArguments(ExecState *e, JSObject *cf) - : exec(e) - , compareFunction(cf) - , globalObject(e->dynamicInterpreter()->globalObject()) - { - } - - ExecState *exec; - JSObject *compareFunction; - List arguments; - JSObject *globalObject; -}; - -static CompareWithCompareFunctionArguments* compareWithCompareFunctionArguments; - -static int compareWithCompareFunctionForQSort(const void* a, const void* b) -{ - CompareWithCompareFunctionArguments *args = compareWithCompareFunctionArguments; - - const ArrayEntity* va = static_cast(a); - const ArrayEntity* vb = static_cast(b); - - ASSERT(va->value && !va->value->isUndefined()); - ASSERT(vb->value && !vb->value->isUndefined()); - - args->arguments.clear(); - args->arguments.append(va->value); - args->arguments.append(vb->value); - double compareResult = args->compareFunction->call - (args->exec, args->globalObject, args->arguments)->toNumber(args->exec); - return compareResult < 0 ? -1 : compareResult > 0 ? 1 : 0; -} - -void ArrayInstance::sort(ExecState* exec, JSObject* compareFunction) -{ - size_t lengthNotIncludingUndefined = compactForSorting(); - - CompareWithCompareFunctionArguments* oldArgs = compareWithCompareFunctionArguments; - CompareWithCompareFunctionArguments args(exec, compareFunction); - compareWithCompareFunctionArguments = &args; - -#if HAVE(MERGESORT) - // Because mergesort usually does fewer compares, it is faster than qsort here. - // However, because it requires extra copies of the storage buffer, don't use it for very - // large arrays. - - // FIXME: A tree sort using a perfectly balanced tree (e.g. an AVL tree) could do an even - // better job of minimizing compares. - - if (lengthNotIncludingUndefined < mergeSortCutoff) { - // During the sort, we could do a garbage collect, and it's important to still - // have references to every object in the array for ArrayInstance::mark. - // The mergesort algorithm does not guarantee this, so we sort a copy rather - // than the original. - size_t size = storageSize(m_vectorLength); - ArrayStorage* copy = static_cast(fastMalloc(size)); - memcpy(copy, m_storage, size); - mergesort(copy->m_vector, lengthNotIncludingUndefined, sizeof(ArrayEntity), compareWithCompareFunctionForQSort); - fastFree(m_storage); - m_storage = copy; - compareWithCompareFunctionArguments = oldArgs; - return; - } -#endif - - qsort(m_storage->m_vector, lengthNotIncludingUndefined, sizeof(ArrayEntity), compareWithCompareFunctionForQSort); - compareWithCompareFunctionArguments = oldArgs; -} - - -unsigned ArrayInstance::compactForSorting() -{ - ArrayStorage* storage = m_storage; - - unsigned usedVectorLength = min(m_length, m_vectorLength); - - unsigned numDefined = 0; - unsigned numUndefined = 0; - - // This compacts normal values (e.g. not undefined) in a contiguous run - // at the beginning of the array, and then puts any set undefined values - // at the end - - // count the first contiguous run of defined values in the vector store - for (; numDefined < usedVectorLength; ++numDefined) { - ArrayEntity* v = &storage->m_vector[numDefined]; - if (!v->value || v->value->isUndefined()) - break; - } - - // compact the rest, counting along the way - for (unsigned i = numDefined; i < usedVectorLength; ++i) { - ArrayEntity v = storage->m_vector[i]; - if (!v.value || v.value->isUndefined()) - ++numUndefined; - else - storage->m_vector[numDefined++] = storage->m_vector[i]; - } - - unsigned newUsedVectorLength = numDefined + numUndefined; - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - newUsedVectorLength += map->size(); - if (newUsedVectorLength > m_vectorLength) { - increaseVectorLength(newUsedVectorLength); - storage = m_storage; - } - - SparseArrayValueMap::iterator end = map->end(); - for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) - storage->m_vector[numDefined++] = it->second; - - delete map; - storage->m_sparseValueMap = 0; - } - - for (unsigned i = numDefined; i < newUsedVectorLength; ++i) - storage->m_vector[i].value = 0; - for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) - storage->m_vector[i].value = 0; - - return numDefined; -} - -bool KJS::ArrayInstance::anyItemHasAttribute(unsigned int attributes) const -{ - ArrayStorage* storage = m_storage; - - unsigned usedVectorLength = min(m_length, m_vectorLength); - for (unsigned i = 0; i < usedVectorLength; ++i) { - if (storage->m_vector[i].value && storage->m_vector[i].attributes & attributes) - return true; - } - - if (SparseArrayValueMap* map = storage->m_sparseValueMap) { - SparseArrayValueMap::iterator end = map->end(); - for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) - if ((*it).second.attributes & attributes) - return true; - } - - return false; -} - -} -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; hl c++; diff --git a/kjs/array_instance.h b/kjs/array_instance.h deleted file mode 100644 index 22ff8817..00000000 --- a/kjs/array_instance.h +++ /dev/null @@ -1,88 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ARRAY_INSTANCE_H -#define ARRAY_INSTANCE_H - -#include "object.h" - -namespace KJS { - struct ArrayStorage; - - class KJS_EXPORT ArrayInstance : public JSObject { - public: - ArrayInstance(JSObject* prototype, unsigned initialLength); - ArrayInstance(JSObject* prototype, const List& initialValues); - ~ArrayInstance(); - - virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); - virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - virtual void put(ExecState*, const Identifier& propertyName, JSValue*, int attributes = None); - virtual void put(ExecState*, unsigned propertyName, JSValue*, int attributes = None); - virtual bool deleteProperty(ExecState *, const Identifier& propertyName); - virtual bool deleteProperty(ExecState *, unsigned propertyName); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, PropertyMap::PropertyMode mode); - - virtual bool defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& desc, bool shouldThrow); - virtual void mark(); - - virtual bool getPropertyAttributes(const Identifier& propertyName, unsigned& attributes) const; - - virtual JSValue *getDirect(const Identifier& propertyName) const; - - virtual void putDirect(unsigned index, JSValue *value, int attr = 0); - virtual void putDirect(const Identifier &propertyName, JSValue *value, int attr = 0); - virtual void putDirect(const Identifier &propertyName, int value, int attr = 0); - - virtual void removeDirect(const Identifier &propertyName); - - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; - - unsigned getLength() const { return m_length; } - JSValue* getItem(unsigned) const; - - void sort(ExecState*); - void sort(ExecState*, JSObject* compareFunction); - - private: - static JSValue* lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&); - bool inlineGetOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); - inline struct ArrayEntity* getArrayEntity(unsigned) const; - - void setLength(unsigned); - void increaseVectorLength(unsigned newLength); - - unsigned compactForSorting(); - - unsigned m_length; - unsigned m_vectorLength; - ArrayStorage* m_storage; - - inline bool anyItemHasAttribute(unsigned attributes) const; - uint32_t m_lengthAttributes; - }; - -} // namespace KJS - -#endif diff --git a/kjs/array_object.cpp b/kjs/array_object.cpp deleted file mode 100644 index e3f0b621..00000000 --- a/kjs/array_object.cpp +++ /dev/null @@ -1,741 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2003 Peter Kelly (pmk@post.com) - * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) - * Copyright (C) 2008 Janusz Lewandowski (lew21st@gmail.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "array_object.h" -#include -#include "array_object.lut.h" - -#include "error_object.h" -#include "lookup.h" -#include "operations.h" -#include "PropertyNameArray.h" -#include -#include - -// GCC cstring uses these automatically, but not all implementations do. -using std::strlen; -using std::strcpy; -using std::strncpy; -using std::memset; -using std::memcpy; - -namespace KJS { - -/** - * @internal - * - * Class to implement all methods that are properties of the - * Object object - */ -class ArrayObjectFuncImp : public InternalFunctionImp { -public: - ArrayObjectFuncImp(ExecState *, FunctionPrototype *, int i, int len, const Identifier& ); - - virtual JSValue *callAsFunction(ExecState *, JSObject *thisObj, const List &args); - - enum { IsArray }; - -private: - int id; -}; - -// ------------------------------ ArrayPrototype ---------------------------- - -const ClassInfo ArrayPrototype::info = {"Array", &ArrayInstance::info, &arrayTable, 0}; - -/* Source for array_object.lut.h -@begin arrayTable 16 - toString ArrayProtoFunc::ToString DontEnum|Function 0 - toLocaleString ArrayProtoFunc::ToLocaleString DontEnum|Function 0 - concat ArrayProtoFunc::Concat DontEnum|Function 1 - join ArrayProtoFunc::Join DontEnum|Function 1 - pop ArrayProtoFunc::Pop DontEnum|Function 0 - push ArrayProtoFunc::Push DontEnum|Function 1 - reverse ArrayProtoFunc::Reverse DontEnum|Function 0 - shift ArrayProtoFunc::Shift DontEnum|Function 0 - slice ArrayProtoFunc::Slice DontEnum|Function 2 - sort ArrayProtoFunc::Sort DontEnum|Function 1 - splice ArrayProtoFunc::Splice DontEnum|Function 2 - unshift ArrayProtoFunc::UnShift DontEnum|Function 1 - every ArrayProtoFunc::Every DontEnum|Function 1 - forEach ArrayProtoFunc::ForEach DontEnum|Function 1 - some ArrayProtoFunc::Some DontEnum|Function 1 - indexOf ArrayProtoFunc::IndexOf DontEnum|Function 1 - lastIndexOf ArrayProtoFunc::LastIndexOf DontEnum|Function 1 - filter ArrayProtoFunc::Filter DontEnum|Function 1 - map ArrayProtoFunc::Map DontEnum|Function 1 - reduce ArrayProtoFunc::Reduce DontEnum|Function 1 - reduceRight ArrayProtoFunc::ReduceRight DontEnum|Function 1 -@end -*/ - -// ECMA 15.4.4 -ArrayPrototype::ArrayPrototype(ExecState*, ObjectPrototype* objProto) - : ArrayInstance(objProto, 0) -{ -} - -bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - return getStaticFunctionSlot(exec, &arrayTable, this, propertyName, slot); -} - -// ------------------------------ ArrayProtoFunc ---------------------------- - -ArrayProtoFunc::ArrayProtoFunc(ExecState* exec, int i, int len, const Identifier& name) - : InternalFunctionImp(static_cast - (exec->lexicalInterpreter()->builtinFunctionPrototype()), name) - , id(i) -{ - put(exec, exec->propertyNames().length, jsNumber(len), DontDelete | ReadOnly | DontEnum); -} - -static JSValue *getProperty(ExecState *exec, JSObject *obj, unsigned index) -{ - PropertySlot slot; - if (!obj->getPropertySlot(exec, index, slot)) - return NULL; - return slot.getValue(exec, obj, index); -} - -// ECMA 15.4.4 -JSValue* ArrayProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) -{ - unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec); - - JSValue *result = 0; // work around gcc 4.0 bug in uninitialized variable warning - - switch (id) { - case ToLocaleString: - case ToString: - - if (!thisObj->inherits(&ArrayInstance::info)) - return throwError(exec, TypeError); - - // fall through - case Join: { - static HashSet visitedElems; - static const UString* empty = new UString(""); - static const UString* comma = new UString(","); - bool alreadyVisited = !visitedElems.add(thisObj).second; - if (alreadyVisited) - return jsString(*empty); - UString separator = *comma; - UString str = *empty; - - if (id == Join && !args[0]->isUndefined()) - separator = args[0]->toString(exec); - for (unsigned int k = 0; k < length; k++) { - if (k >= 1) - str += separator; - if (str.isNull()) { - JSObject *error = Error::create(exec, GeneralError, "Out of memory"); - exec->setException(error); - break; - } - - JSValue* element = thisObj->get(exec, k); - if (element->isUndefinedOrNull()) - continue; - - bool fallback = false; - if (id == ToLocaleString) { - JSObject* o = element->toObject(exec); - JSValue* conversionFunction = o->get(exec, exec->propertyNames().toLocaleString); - if (conversionFunction->isObject() && static_cast(conversionFunction)->implementsCall()) - str += static_cast(conversionFunction)->call(exec, o, List())->toString(exec); - else - // try toString() fallback - fallback = true; - } - - if (id == ToString || id == Join || fallback) { - str += element->toString(exec); - if (exec->hadException()) - break; - - if (str.isNull()) { - JSObject* error = Error::create(exec, GeneralError, "Out of memory"); - exec->setException(error); - } - } - - if (exec->hadException()) - break; - } - visitedElems.remove(thisObj); - result = jsString(str); - break; - } - case Concat: { - JSObject *arr = static_cast(exec->lexicalInterpreter()->builtinArray()->construct(exec,List::empty())); - int n = 0; - JSValue *curArg = thisObj; - JSObject *curObj = static_cast(thisObj); - ListIterator it = args.begin(); - for (;;) { - if (curArg->isObject() && - curObj->inherits(&ArrayInstance::info)) { - unsigned int k = 0; - // Older versions tried to optimize out getting the length of thisObj - // by checking for n != 0, but that doesn't work if thisObj is an empty array. - length = curObj->get(exec, exec->propertyNames().length)->toUInt32(exec); - while (k < length) { - if (JSValue *v = getProperty(exec, curObj, k)) - arr->put(exec, n, v); - n++; - k++; - } - } else { - arr->put(exec, n, curArg); - n++; - } - if (it == args.end()) - break; - curArg = *it; - curObj = static_cast(it++); // may be 0 - } - arr->put(exec, exec->propertyNames().length, jsNumber(n), DontEnum | DontDelete); - - result = arr; - break; - } - case Pop:{ - if (length == 0) { - thisObj->put(exec, exec->propertyNames().length, jsNumber(length), DontEnum | DontDelete); - result = jsUndefined(); - } else { - result = thisObj->get(exec, length - 1); - thisObj->put(exec, exec->propertyNames().length, jsNumber(length - 1), DontEnum | DontDelete); - } - break; - } - case Push: { - for (int n = 0; n < args.size(); n++) - thisObj->put(exec, length + n, args[n]); - length += args.size(); - thisObj->put(exec, exec->propertyNames().length, jsNumber(length), DontEnum | DontDelete); - result = jsNumber(length); - break; - } - case Reverse: { - - unsigned int middle = length / 2; - - for (unsigned int k = 0; k < middle; k++) { - unsigned lk1 = length - k - 1; - JSValue *obj2 = getProperty(exec, thisObj, lk1); - JSValue *obj = getProperty(exec, thisObj, k); - - if (obj2) - thisObj->put(exec, k, obj2); - else - thisObj->deleteProperty(exec, k); - - if (obj) - thisObj->put(exec, lk1, obj); - else - thisObj->deleteProperty(exec, lk1); - } - result = thisObj; - break; - } - case Shift: { - if (length == 0) { - thisObj->put(exec, exec->propertyNames().length, jsNumber(length), DontEnum | DontDelete); - result = jsUndefined(); - } else { - result = thisObj->get(exec, 0); - for(unsigned int k = 1; k < length; k++) { - if (JSValue *obj = getProperty(exec, thisObj, k)) - thisObj->put(exec, k-1, obj); - else - thisObj->deleteProperty(exec, k-1); - } - thisObj->deleteProperty(exec, length - 1); - thisObj->put(exec, exec->propertyNames().length, jsNumber(length - 1), DontEnum | DontDelete); - } - break; - } - case Slice: { - // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10 - - // We return a new array - JSObject *resObj = static_cast(exec->lexicalInterpreter()->builtinArray()->construct(exec,List::empty())); - result = resObj; - double begin = 0; - if (!args[0]->isUndefined()) { - begin = args[0]->toInteger(exec); - if (begin >= 0) { // false for NaN - if (begin > length) - begin = length; - } else { - begin += length; - if (!(begin >= 0)) // true for NaN - begin = 0; - } - } - double end = length; - if (!args[1]->isUndefined()) { - end = args[1]->toInteger(exec); - if (end < 0) { // false for NaN - end += length; - if (end < 0) - end = 0; - } else { - if (!(end <= length)) // true for NaN - end = length; - } - } - - //printf( "Slicing from %d to %d \n", begin, end ); - int n = 0; - int b = static_cast(begin); - int e = static_cast(end); - for(int k = b; k < e; k++, n++) { - if (JSValue *v = getProperty(exec, thisObj, k)) - resObj->put(exec, n, v); - } - resObj->put(exec, exec->propertyNames().length, jsNumber(n), DontEnum | DontDelete); - break; - } - case Sort:{ -#if 0 - printf("KJS Array::Sort length=%d\n", length); - for ( unsigned int i = 0 ; iget(exec, i)->toString(exec).ascii() ); -#endif - JSObject *sortFunction = NULL; - if (!args[0]->isUndefined()) - { - sortFunction = args[0]->toObject(exec); - if (!sortFunction->implementsCall()) - sortFunction = NULL; - } - - if (thisObj->classInfo() == &ArrayInstance::info) { - if (sortFunction) - ((ArrayInstance *)thisObj)->sort(exec, sortFunction); - else - ((ArrayInstance *)thisObj)->sort(exec); - result = thisObj; - break; - } - - if (length == 0) { - thisObj->put(exec, exec->propertyNames().length, jsNumber(0), DontEnum | DontDelete); - result = thisObj; - 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 ; iget(exec,i); - unsigned int themin = i; - JSValue *minObj = iObj; - for ( unsigned int j = i+1 ; jget(exec,j); - double cmp; - if (jObj->isUndefined()) { - cmp = 1; // don't check minObj because there's no need to differentiate == (0) from > (1) - } else if (minObj->isUndefined()) { - cmp = -1; - } else if (sortFunction) { - List l; - l.append(jObj); - l.append(minObj); - cmp = sortFunction->call(exec, exec->dynamicInterpreter()->globalObject(), l)->toNumber(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, i, minObj ); - thisObj->put( exec, themin, iObj ); - } - } -#if 0 - printf("KJS Array::Sort -- Resulting array:\n"); - for ( unsigned int i = 0 ; iget(exec, i)->toString(exec).ascii() ); -#endif - result = thisObj; - break; - } - case Splice: { - // 15.4.4.12 - oh boy this is huge - JSObject *resObj = static_cast(exec->lexicalInterpreter()->builtinArray()->construct(exec,List::empty())); - result = resObj; - double start = args[0]->toInteger(exec); - uint32_t begin = 0; - if ( start < 0 ) - begin = static_cast(std::max(start + length, 0)); - else - begin = static_cast(std::min(start, length)); - uint32_t deleteCount = static_cast(std::min(std::max(args[1]->toInteger(exec), 0 ), length - begin)); - - //printf( "Splicing from %d, deleteCount=%d \n", begin, deleteCount ); - for(unsigned int k = 0; k < deleteCount; k++) { - if (JSValue *v = getProperty(exec, thisObj, k+begin)) - resObj->put(exec, k, v); - } - resObj->put(exec, exec->propertyNames().length, jsNumber(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 ) - { - if (JSValue *v = getProperty(exec, thisObj, k+deleteCount)) - thisObj->put(exec, k+additionalArgs, v); - else - thisObj->deleteProperty(exec, k+additionalArgs); - } - for ( unsigned int k = length ; k > length - deleteCount + additionalArgs; --k ) - thisObj->deleteProperty(exec, k-1); - } - else - { - for ( unsigned int k = length - deleteCount; k > begin; --k ) - { - if (JSValue *obj = getProperty(exec, thisObj, k + deleteCount - 1)) - thisObj->put(exec, k + additionalArgs - 1, obj); - else - thisObj->deleteProperty(exec, k+additionalArgs-1); - } - } - } - for ( unsigned int k = 0; k < additionalArgs; ++k ) - { - thisObj->put(exec, k+begin, args[k+2]); - } - thisObj->put(exec, exec->propertyNames().length, jsNumber(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 ) - { - if (JSValue *v = getProperty(exec, thisObj, k - 1)) - thisObj->put(exec, k+nrArgs-1, v); - else - thisObj->deleteProperty(exec, k+nrArgs-1); - } - for ( unsigned int k = 0; k < nrArgs; ++k ) - thisObj->put(exec, k, args[k]); - result = jsNumber(length + nrArgs); - thisObj->put(exec, exec->propertyNames().length, result, DontEnum | DontDelete); - break; - } - case Filter: - case Map: { - JSObject *eachFunction = args[0]->toObject(exec); - - if (!eachFunction->implementsCall()) - return throwError(exec, TypeError); - - JSObject *applyThis = args[1]->isUndefinedOrNull() ? exec->dynamicInterpreter()->globalObject() : args[1]->toObject(exec); - JSObject *resultArray; - - if (id == Filter) - resultArray = static_cast(exec->lexicalInterpreter()->builtinArray()->construct(exec, List::empty())); - else { - List args; - args.append(jsNumber(length)); - resultArray = static_cast(exec->lexicalInterpreter()->builtinArray()->construct(exec, args)); - } - - unsigned filterIndex = 0; - for (unsigned k = 0; k < length && !exec->hadException(); ++k) { - PropertySlot slot; - - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - - JSValue *v = slot.getValue(exec, thisObj, k); - - List eachArguments; - - eachArguments.append(v); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - JSValue *result = eachFunction->call(exec, applyThis, eachArguments); - - if (id == Map) - resultArray->put(exec, k, result); - else if (result->toBoolean(exec)) - resultArray->put(exec, filterIndex++, v); - } - - return resultArray; - } - case Every: - case ForEach: - case Some: { - //Documentation for these three is available at: - //http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:every - //http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach - //http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some - - JSObject *eachFunction = args[0]->toObject(exec); - - if (!eachFunction->implementsCall()) - return throwError(exec, TypeError); - - JSObject *applyThis = args[1]->isUndefinedOrNull() ? exec->dynamicInterpreter()->globalObject() : args[1]->toObject(exec); - - if (id == Some || id == Every) - result = jsBoolean(id == Every); - else - result = jsUndefined(); - - for (unsigned k = 0; k < length && !exec->hadException(); ++k) { - PropertySlot slot; - - if (!thisObj->getPropertySlot(exec, k, slot)) - continue; - - List eachArguments; - - eachArguments.append(slot.getValue(exec, thisObj, k)); - eachArguments.append(jsNumber(k)); - eachArguments.append(thisObj); - - bool predicateResult = eachFunction->call(exec, applyThis, eachArguments)->toBoolean(exec); - - if (id == Every && !predicateResult) { - result = jsBoolean(false); - break; - } - if (id == Some && predicateResult) { - result = jsBoolean(true); - break; - } - } - break; - } - - case IndexOf: { - // JavaScript 1.5 Extension by Mozilla - // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf - - unsigned index = 0; - double d = args[1]->toInteger(exec); - if (d < 0) - d += length; - if (d > 0) { - if (d > length) - index = length; - else - index = static_cast(d); - } - - JSValue* searchElement = args[0]; - for (; index < length; ++index) { - JSValue* e = getProperty(exec, thisObj, index); - if (!e) - continue; - if (strictEqual(exec, searchElement, e)) - return jsNumber(index); - } - - return jsNumber(-1); - } - - case LastIndexOf: { - // JavaScript 1.6 Extension by Mozilla - // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf - - int index = length - 1; - double d = args[1]->toIntegerPreserveNaN(exec); - - if (d < 0) { - d += length; - if (d < 0) - return jsNumber(-1); - } - if (d < length) - index = static_cast(d); - - JSValue* searchElement = args[0]; - for (; index >= 0; --index) { - JSValue* e = getProperty(exec, thisObj, index); - if (!e) - continue; - if (strictEqual(exec, searchElement, e)) - return jsNumber(index); - } - - return jsNumber(-1); - } - - case Reduce: - case ReduceRight: { - // JavaScript 1.8 Extensions by Mozilla - // Documentation: - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight - - JSObject *callback = args[0]->toObject(exec); - - if (!callback->implementsCall()) - return throwError(exec, TypeError); - - JSObject *applyThis = args[2]->isUndefinedOrNull() ? exec->dynamicInterpreter()->globalObject() : args[2]->toObject(exec); - - if (!length && args.size() < 2) - return throwError(exec, TypeError); - - unsigned k = 0; - unsigned last = length - 1; - - if (args.size() >= 2) - result = args[1]; - else { - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot; - - if (!thisObj->getPropertySlot(exec, (id == Reduce) ? k : (last - k), slot)) - continue; - - result = slot.getValue(exec, thisObj, (id == Reduce) ? k++ : (last - k++)); - break; - } - } - - for (; k < length && !exec->hadException(); ++k) { - PropertySlot slot; - - if (!thisObj->getPropertySlot(exec, (id == Reduce) ? k : (last - k), slot)) - continue; - - JSValue* v = slot.getValue(exec, thisObj, (id == Reduce) ? k : (last - k)); - - List eachArguments; - - eachArguments.append(result); - eachArguments.append(v); - eachArguments.append(jsNumber((id == Reduce) ? k : (last - k))); - eachArguments.append(thisObj); - - result = callback->call(exec, applyThis, eachArguments); - } - - break; - } - - default: - assert(0); - result = 0; - break; - } - return result; -} - -// ------------------------------ ArrayObjectImp ------------------------------- - -ArrayObjectImp::ArrayObjectImp(ExecState *exec, - FunctionPrototype *funcProto, - ArrayPrototype *arrayProto) - : InternalFunctionImp(funcProto) -{ - static const Identifier* isArrayName = new Identifier("isArray"); - - // ECMA 15.4.3.1 Array.prototype - put(exec, exec->propertyNames().prototype, arrayProto, DontEnum|DontDelete|ReadOnly); - - putDirectFunction(new ArrayObjectFuncImp(exec, funcProto, ArrayObjectFuncImp::IsArray, 1, *isArrayName), DontEnum); - - // no. of arguments for constructor - put(exec, exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum); -} - -bool ArrayObjectImp::implementsConstruct() const -{ - return true; -} - -// ECMA 15.4.2 -JSObject *ArrayObjectImp::construct(ExecState *exec, const List &args) -{ - // a single numeric argument denotes the array size (!) - if (args.size() == 1 && args[0]->isNumber()) { - uint32_t n = args[0]->toUInt32(exec); - if (n != args[0]->toNumber(exec)) - return throwError(exec, RangeError, "Array size is not a small enough positive integer."); - return new ArrayInstance(exec->lexicalInterpreter()->builtinArrayPrototype(), n); - } - - // otherwise the array is constructed with the arguments in it - return new ArrayInstance(exec->lexicalInterpreter()->builtinArrayPrototype(), args); -} - -// ECMA 15.6.1 -JSValue *ArrayObjectImp::callAsFunction(ExecState *exec, JSObject * /*thisObj*/, const List &args) -{ - // equivalent to 'new Array(....)' - return construct(exec,args); -} - -// ------------------------------ ArrayObjectFuncImp ---------------------------- - -ArrayObjectFuncImp::ArrayObjectFuncImp(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) - : InternalFunctionImp(funcProto, name), id(i) -{ - putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); -} - -JSValue *ArrayObjectFuncImp::callAsFunction(ExecState* exec, JSObject*, const List& args) -{ - switch (id) { - case IsArray: { - JSObject* jso = args[0]->getObject(); - if (!jso) - return jsBoolean(false); - return jsBoolean(jso->inherits(&ArrayInstance::info)); - } - default: - return jsUndefined(); - } -} - -} - - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; hl c++; diff --git a/kjs/array_object.h b/kjs/array_object.h deleted file mode 100644 index db94bfcf..00000000 --- a/kjs/array_object.h +++ /dev/null @@ -1,70 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ARRAY_OBJECT_H_ -#define ARRAY_OBJECT_H_ - -#include "array_instance.h" -#include "internal.h" -#include "function_object.h" - -namespace KJS { - - class ArrayPrototype : public ArrayInstance { - public: - ArrayPrototype(ExecState *exec, - ObjectPrototype *objProto); - using KJS::ArrayInstance::getOwnPropertySlot; - bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); - virtual const ClassInfo *classInfo() const { return &info; } - static const ClassInfo info; - }; - - class ArrayProtoFunc : public InternalFunctionImp { - public: - ArrayProtoFunc(ExecState *exec, int i, int len, const Identifier& name); - - virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); - - enum { ToString, ToLocaleString, Concat, Join, Pop, Push, - Reverse, Shift, Slice, Sort, Splice, UnShift, - Every, ForEach, Some, IndexOf, Filter, Map, LastIndexOf, - Reduce, ReduceRight }; - private: - int id; - }; - - class ArrayObjectImp : public InternalFunctionImp { - public: - ArrayObjectImp(ExecState *exec, - FunctionPrototype *funcProto, - ArrayPrototype *arrayProto); - - virtual bool implementsConstruct() const; - using KJS::JSObject::construct; - virtual JSObject *construct(ExecState *exec, const List &args); - virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); - - }; - -} // namespace - -#endif diff --git a/kjs/bool_object.cpp b/kjs/bool_object.cpp deleted file mode 100644 index 33fde923..00000000 --- a/kjs/bool_object.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "bool_object.h" -#include - -#include "operations.h" -#include "error_object.h" - -using namespace KJS; - -// ------------------------------ BooleanInstance --------------------------- - -const ClassInfo BooleanInstance::info = {"Boolean", 0, 0, 0}; - -BooleanInstance::BooleanInstance(JSObject *proto) - : JSWrapperObject(proto) -{ -} - -JSObject* BooleanInstance::valueClone(Interpreter* targetCtx) const -{ - BooleanInstance* copy = new BooleanInstance(targetCtx->builtinBooleanPrototype()); - copy->setInternalValue(internalValue()); - return copy; -} - -// ------------------------------ BooleanPrototype -------------------------- - -// ECMA 15.6.4 - -BooleanPrototype::BooleanPrototype(ExecState* exec, ObjectPrototype* objectProto, FunctionPrototype* funcProto) - : BooleanInstance(objectProto) -{ - // The constructor will be added later by Interpreter::Interpreter() - - putDirectFunction(new BooleanProtoFunc(exec, funcProto, BooleanProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum); - putDirectFunction(new BooleanProtoFunc(exec, funcProto, BooleanProtoFunc::ValueOf, 0, exec->propertyNames().valueOf), DontEnum); - setInternalValue(jsBoolean(false)); -} - - -// ------------------------------ BooleanProtoFunc -------------------------- - -BooleanProtoFunc::BooleanProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) - : InternalFunctionImp(funcProto, name) - , id(i) -{ - putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); -} - - -// ECMA 15.6.4.2 + 15.6.4.3 -JSValue *BooleanProtoFunc::callAsFunction(ExecState* exec, JSObject *thisObj, const List &/*args*/) -{ - // no generic function. "this" has to be a Boolean object - if (!thisObj->inherits(&BooleanInstance::info)) - return throwError(exec, TypeError); - - // execute "toString()" or "valueOf()", respectively - - JSValue *v = static_cast(thisObj)->internalValue(); - assert(v); - - if (id == ToString) - return jsString(v->toString(exec)); - return jsBoolean(v->toBoolean(exec)); /* TODO: optimize for bool case */ -} - -// ------------------------------ BooleanObjectImp ----------------------------- - - -BooleanObjectImp::BooleanObjectImp(ExecState* exec, FunctionPrototype* funcProto, BooleanPrototype* booleanProto) - : InternalFunctionImp(funcProto) -{ - putDirect(exec->propertyNames().prototype, booleanProto, DontEnum|DontDelete|ReadOnly); - - // no. of arguments for constructor - putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum); -} - - -bool BooleanObjectImp::implementsConstruct() const -{ - return true; -} - -// ECMA 15.6.2 -JSObject *BooleanObjectImp::construct(ExecState *exec, const List &args) -{ - BooleanInstance *obj(new BooleanInstance(exec->lexicalInterpreter()->builtinBooleanPrototype())); - - bool b; - if (args.size() > 0) - b = args.begin()->toBoolean(exec); - else - b = false; - - obj->setInternalValue(jsBoolean(b)); - - return obj; -} - -// ECMA 15.6.1 -JSValue *BooleanObjectImp::callAsFunction(ExecState *exec, JSObject * /*thisObj*/, const List &args) -{ - if (args.isEmpty()) - return jsBoolean(false); - else - return jsBoolean(args[0]->toBoolean(exec)); /* TODO: optimize for bool case */ -} - diff --git a/kjs/bool_object.h b/kjs/bool_object.h deleted file mode 100644 index cf21c842..00000000 --- a/kjs/bool_object.h +++ /dev/null @@ -1,91 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef BOOL_OBJECT_H_ -#define BOOL_OBJECT_H_ - -#include "internal.h" -#include "function_object.h" -#include "JSWrapperObject.h" - -namespace KJS { - - class BooleanInstance : public JSWrapperObject { - public: - BooleanInstance(JSObject *proto); - - virtual JSObject* valueClone(Interpreter* targetCtx) const; - - virtual const ClassInfo *classInfo() const { return &info; } - static const ClassInfo info; - }; - - /** - * @internal - * - * The initial value of Boolean.prototype (and thus all objects created - * with the Boolean constructor - */ - class BooleanPrototype : public BooleanInstance { - public: - BooleanPrototype(ExecState *exec, - ObjectPrototype *objectProto, - FunctionPrototype *funcProto); - }; - - /** - * @internal - * - * Class to implement all methods that are properties of the - * Boolean.prototype object - */ - class BooleanProtoFunc : public InternalFunctionImp { - public: - BooleanProtoFunc(ExecState*, FunctionPrototype*, int i, int len, const Identifier&); - - virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); - - enum { ToString, ValueOf }; - private: - int id; - }; - - /** - * @internal - * - * The initial value of the global variable's "Boolean" property - */ - class BooleanObjectImp : public InternalFunctionImp { - friend class BooleanProtoFunc; - public: - BooleanObjectImp(ExecState *exec, FunctionPrototype *funcProto, - BooleanPrototype *booleanProto); - - virtual bool implementsConstruct() const; - using KJS::JSObject::construct; - virtual JSObject *construct(ExecState *exec, const List &args); - - virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); - }; - -} // namespace - -#endif diff --git a/kjs/bytecode/codes.def b/kjs/bytecode/codes.def deleted file mode 100644 index aa044b3a..00000000 --- a/kjs/bytecode/codes.def +++ /dev/null @@ -1,1286 +0,0 @@ -/* - * This describe the various bytecode operations for KJS/Frostbyte, and gives their implementations - * - * This file is part of the KDE libraries - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2007, 2008 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -// JS types. -type bool: bool [register, immediate]; - -// We have to be careful about uint32/int32, as while number -> them behaves -// transparently, the results may be converted back to a number, which may show -// a sign -type int32: int32_t [register, immediate]; - -// We provide immediate JSValue's, for the following: -// 1) Small numeric constants -// 2) undefined and null. -// This relies on immediate value JSValue conversion rountines not touching exec! -type value: JSValue* [register, immediate, align8]; - -type number: double [register, immediate, align8]; - -// Program types; these all represent stuff in source code and not actual program values -// Hence, no conversions for them. -type ident: Identifier* [immediate, align8]; -type addr: Addr [immediate]; -type reg: Register [immediate]; // an output register - -// We have to be careful with this type --- it only represents -// string literals in the program, as we have no nice way of memory managing others.. -// ### we may want to use a register jsString type instead, in particular to -// infer the proper overload of +, when appropriate -type string: UString* [immediate, align8]; - -// AST nodes passed to helpers... They may cast it further.. -type node: Node* [immediate, align8]; - -// for error messages and the like -type cstr: const char* [immediate, align8]; - -// Just for the return type... -type void: void [immediate]; - -/** -Notes on the conversion rules from the spec: -The conversion operations in general do not form a commutative diagram --- -one can call toBoolean(toUInt32(foo)) and get something different -from toBoolean(foo). We don't worry about this, however, because when we -know the type enough to annotate it as uint32, etc., it's when the computation -would naturally produces a 32-bit int, so we would never marshal an object to it! - -We also never chain multiple conversions ourselves. -*/ - -/* - Conversions from bool -*/ -conversion bool => int32 { - impl [[ - return in ? 1 : 0; - ]] - - tile costs 0; //cost in tile.. - register costs 0; // we always store bool as 0/1, so this is free. -} - -conversion bool => value { - impl [[ - return jsBoolean(in); - ]] - - tile costs 0; - register costs 10; // Separate jsBoolean instruction -} - -conversion bool => number { - impl [[ - return in ? 1.0 : 0.0; - ]] - - tile costs 0; - register costs 10; -} - -/* - Conversions from values -*/ -conversion value => bool { - impl [[ - return in->toBoolean(exec); - ]] - - tile costs 5; // it is a virtual call - register costs 15; // ToBoolean instr, includes a virtual call.. -} - -conversion value => int32 { - impl [mayThrow] [[ - return in->toInt32(exec); - ]] - - tile costs 40; // toInt32 uses toNumber --- expensive - register costs 50; // above, plus a separate instr -} - -conversion value => number { - impl [mayThrow] [[ - return in->toNumber(exec); - ]] - - tile costs 37; - register costs 49; -} - -/* - Conversions from int32 -*/ -conversion int32 => bool { - impl [[ - return in ? true : false; // Expect stupid MSVC 0/1 warning - ]] - - tile costs 0; - register costs 10; -} - -conversion int32 => value { - impl [checked, mayThrow] /* due to OOM */ [[ - return jsNumber(in); - ]] - - tile costs 15; - register costs 25; -} - -conversion int32 => number { - impl [[ - return in; - ]] - - tile costs 3; - register costs 10; -} - -/* - Conversions from number -*/ -conversion number => bool { - impl [[ - return in < 0.0 || in > 0.0; // false for NaN - ]] - - tile costs 15; - register costs 25; -} - -conversion number => value { - impl [checked, mayThrow] /* due to OOM */ [[ - return jsNumber(in); - ]] - - tile costs 15; - register costs 35; -} - -conversion number => int32 { - impl [[ - return JSValue::toInt32(in); - ]] - - tile costs 10; - register costs 20; -} - -/* - These are specializes versions for when we have an immediate # and are trying for - an immediate value --- avoids extra check -*/ -operation RInt32_Value_NonImm { - impl value(int32 val) [[ - $$ = jsNumberCell(val); - ]] -} - -operation RNum_Value_NonImm { - impl value(number val) [[ - $$ = jsNumberCell(val); - ]] -} - -/*************************************************************************** - WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING - $$/localStore should never be set on the same call that can tearoff - the frame or reallocate the stack, since the evaluation order if undefined -****************************************************************************/ - -/** - Debug only.. - */ -operation PrintInfo { - impl void(value in) [[ - printInfo(exec, "", in); - ]] -} - -/** - Actual debugger support... -*/ -operation AtStatement { - impl void(node in) [[ - static_cast(in)->hitStatement(exec); - ]] -} - -/** - Control flow stuff -*/ -operation Exit[endsBB] { - impl void exit() [[ - return jsUndefined(); - ]] -} - -operation Jump[endsBB] { - impl void jmp(addr dest) [[ - pc = base + dest; - ]] -} - -operation IfJump[endsBB] { - impl void executeIfJump(bool condResult, addr dest) [[ - if (condResult) - pc = base + dest; - ]] - - tile (value, addr) as executeIfJump; -} - -operation IfNotJump[endsBB] { - impl void executeIfNotJump(bool condResult, addr dest) [[ - if (!condResult) - pc = base +dest; - ]] - - tile (value, addr) as executeIfNotJump; -} - -// Fetches the propertly list, if any, and sets up the iterator state in given -// register. Returns the value to iterator -operation BeginForIn[endsBB] { - impl value (value e, reg stateReg) [[ - ForInState* st = new ForInState(); - localStore[stateReg].val.valueVal = st; - - if (!e->isUndefinedOrNull()) { - JSObject* v = e->toObject(exec); - // The above might raise an exception.. - if (pc != localPC) continue; - - v->getPropertyNames(exec, *st->array); - $$ = v; - } else { - // empty array, so this doesn't matter. - $$ = jsUndefined(); - } - ]] -} - -operation NextForInEntry { - impl value(value[noimm] e, value[noimm] ctx, addr jumpToIfDone) [[ - ForInState* st = static_cast(ctx); - PropertyNameArray& pa = *st->array; - - // Invariant: pos = next entry to consider. - int& pos = st->pos; - - $$ = jsUndefined(); - while (pos < pa.size()) { - ASSERT(e->isObject()); - JSObject* v = static_cast(e); - - Identifier& name = pa[pos]; - ++pos; - - if (v->hasProperty(exec, name)) { - // Wasn't deleted during iteration.. - $$ = jsOwnedString(name.ustring()); - break; - } - } - - if ($$ == jsUndefined()) // Nothing found. Jump to end of the loop - pc = base + jumpToIfDone; - ]] -} - -// These update the scope chain, and sets the special unwind exception handler, which is used to -// restore the chain if an exception happens -operation PushScope { - impl void pushScope(value in) [[ - JSObject* obj = in->toObject(exec); - if (exec->hadException()) - continue; // will jump to handler. - - exec->pushScope(obj); - exec->pushExceptionHandler(ExecState::PopScope); - ]] -} - -operation UnwindStacks { - impl void(int32 handlers) [[ - // This op is used when a break or continue is used to jump out - // of a context that updated various stacks in ExecState, - // in order to clean them up. Each of those ops contributes an - // entry to the main exception handler stack, and perhaps some others. - // We unwind the main stack, using the cleanup entries on it as appropriate. - exec->quietUnwind(handlers); - ]] -} - -operation PopScope { - impl void () [[ - // As PushScope does not Push anything on Exception case, we can not Pop. - // NOTE: the Exception checking on Push/Pop-Scope is not optimal. - // Such a Situation, where PushScope already has a Exception can only - // occour if import is used inside the the "with"-statement. As import is - // executed at the beginning of the code (as val decl) and can leave a exception. - // As "import" is not (yet) part of ECMA-262 the correct behavior is unknown - // when this changes we can rework the bahavior, but for now just fix the crash. - if (exec->hadException()) - continue; - - exec->popScope(); - exec->popExceptionHandler(); - ]] -} - -operation PopExceptionHandler { - impl void popCatch() [[ - exec->popExceptionHandler(); - ]] -} - -operation PushExceptionHandler { - impl void (addr handler) [[ - exec->pushExceptionHandler(ExecState::JumpToCatch, handler); - ]] -} - -operation EnterCatch { - impl void (ident exceptionIdent) [[ - // First, check if we have a non-exception indirect continuation, - // if so, we re-raise it directly to the finally (and skip the rest of the catch section) - if (exec->abruptCompletion().complType() != Throw) { - // By this point, the previous handler has been popped, so we should have the - // 'finally' bound as the handler. Hence, set the completion again to jump to it. - exec->setAbruptCompletion(exec->abruptCompletion()); - continue; - } - - // Now we have a plain, old exception. Grab & clear exception it exec state, - // and put it in a scope w/a name to it - JSValue* exception = exec->exception(); - exec->clearException(); - - JSObject *obj = new JSObject; - obj->put(exec, *exceptionIdent, exception, DontDelete); - exec->pushScope(obj); - exec->pushExceptionHandler(ExecState::PopScope); - ]] -} - -operation ExitCatch { - impl void() [[ - exec->popScope(); - exec->popExceptionHandler(); - ]] -} - -operation DeferCompletion { - impl void() [[ - exec->deferCompletion(); - ]] -} - -operation ReactivateCompletion { - impl void(bool insideFinally) [[ - JSValue* retVal = exec->reactivateCompletion(insideFinally); - if (retVal) - return retVal; - ]] -} - -operation ReactivateCompletionDebug { - // version for inside functions + debug mode, which calls ExitContext - impl void(bool insideFinally, node n) [[ - JSValue* retVal = exec->reactivateCompletion(insideFinally); - if (retVal) { - changeDebugContext(Exit, exec, n); - return retVal; - } - ]] -} - -operation Throw { - impl void throw(value exception) [[ - exec->setException(exception); - ]] -} - -operation ContBreakInTryFinally { - impl void (addr dest) [[ - exec->setAbruptCompletion(Completion(Continue /*or break, doesn't matter*/, 0, dest)); - ]] -} - -operation ReturnInTryFinally { - impl void(value val) [[ - exec->setAbruptCompletion(Completion(ReturnValue, val)); - ]] -} - -operation PropagateException { - impl void() [[ - JSValue* e = exec->exception(); - if (parentExec) - parentExec->setException(e); - return e; - ]] -} - -operation Return[endsBB] { - impl void return (value retVal) [[ - return retVal; - ]] -} - -operation RaiseError { - impl void (node node, int32 errorType, cstr msg) [[ - node->throwError(exec, ErrorType(errorType), msg); - ]] -} - -// Function entry: set things we cache in registers -operation Preamble { - impl void(reg scopeReg, reg globalReg, reg thisReg) [[ - localStore[scopeReg ].val.valueVal = exec->variableObject(); - localStore[thisReg ].val.valueVal = exec->thisValue(); - localStore[globalReg].val.valueVal = globalObject; - ]] -} - -operation EnterDebugContext { - impl void(node n) [[ - changeDebugContext(Enter, exec, n); - ]] -} - -operation ExitDebugContext { - impl void(node n) [[ - changeDebugContext(Exit, exec, n); - ]] -} - -// Variable stuff... Locals access can just use register addressing, -// not specific get/put, but when we have to do symbolic lookup, we use these. - - -operation FunctionLookupAndGet { - impl value(reg thisOutReg, ident varName) [[ - JSValue* res; - JSValue* thisOut; - lookupScopeAndFetch - (exec, varName, thisOut, res); - localStore[thisOutReg].val.valueVal = thisOut; - $$ = res; - ]] -} - -operation NonLocalFunctionLookupAndGet { - impl value(reg thisOutReg, ident varName) [[ - JSValue* res; - JSValue* thisOut; - lookupScopeAndFetch - (exec, varName, thisOut, res); - $$ = res; - localStore[thisOutReg].val.valueVal = thisOut; - ]] -} - -operation ScopeLookupAndGetChecked { - impl value(reg valOutReg, ident varName) [[ - JSValue* scopeOut; - JSValue* val; - - lookupScopeAndFetch - (exec, varName, scopeOut, val); - $$ = scopeOut; - localStore[valOutReg].val.valueVal = val; - ]] -} - -operation ScopeLookupAndGet { - impl value(reg valOutReg, ident varName) [[ - JSValue* scopeOut; - JSValue* val; - - lookupScopeAndFetch - (exec, varName, scopeOut, val); - $$ = scopeOut; - localStore[valOutReg].val.valueVal = val; - ]] -} - -operation NonLocalScopeLookupAndGetChecked { - impl value(reg valOutReg, ident varName) [[ - JSValue* scopeOut; - JSValue* val; - - lookupScopeAndFetch - (exec, varName, scopeOut, val); - $$ = scopeOut; - localStore[valOutReg].val.valueVal = val; - ]] -} - -operation NonLocalScopeLookupAndGet { - impl value(reg valOutReg, ident varName) [[ - JSValue* scopeOut; - JSValue* val; - - lookupScopeAndFetch - (exec, varName, scopeOut, val); - $$ = scopeOut; - localStore[valOutReg].val.valueVal = val; - ]] -} - - -operation ScopeLookup { - // Find which scope the variable is in, e.g. basically evaluates to a reference. - // If we want failures detected, the errorNode is set to non-zero, to help with line #s, etc - impl value scopeLookup(ident varName, node errorNode) [[ - const ScopeChain& chain = exec->scopeChain(); - ScopeChainIterator iter = chain.begin(); - ScopeChainIterator end = chain.end(); - - // we must always have something in the scope chain - assert(iter != end); - - JSObject *scopeObj; - PropertySlot slot; - do { - scopeObj = *iter; - - if (scopeObj->getPropertySlot(exec, *varName, slot)) - break; - ++iter; - } while (iter != end); - - if (errorNode && iter == end) { - $$ = errorNode->throwUndefinedVariableError(exec, *varName); - continue; - } - - $$ = scopeObj; - ]] -} - -operation NonLocalScopeLookup { - // As above, but may skip one step - impl value scopeLookup(ident varName, node errorNode) [[ - const ScopeChain& chain = exec->scopeChain(); - ScopeChainIterator iter = chain.begin(); - ScopeChainIterator end = chain.end(); - - // we must always have something in the scope chain - assert(iter != end); - - JSObject *scopeObj = *iter; - if (!scopeObj->isLocalInjected()) { - // Unless eval introduced new variables dynamically, - // we know this isn't in the top scope - ++iter; - } - - PropertySlot slot; - do { - scopeObj = *iter; - - if (scopeObj->getPropertySlot(exec, *varName, slot)) - break; - ++iter; - } while (iter != end); - - if (errorNode && iter == end) { - $$ = errorNode->throwUndefinedVariableError(exec, *varName); - continue; - } - $$ = scopeObj; - ]] -} - - -// Looks up a given variable in the scope chain, returns its value -operation VarGet { - impl value varGet(ident varName) [[ - JSValue* scopeOut; - JSValue* val; - - lookupScopeAndFetch(exec, varName, scopeOut, val); - $$ = val; - ]] -} - -// Like above, but skips the first step, if possible. -operation NonLocalVarGet { - impl value nonLocalVarGet(ident varName) [[ - JSValue* scopeOut; - JSValue* val; - - lookupScopeAndFetch(exec, varName, scopeOut, val); - $$ = val; - ]] -} - -operation RegPutValue { - impl void regPut(reg destReg, value val) [[ - localStore[destReg].val.valueVal = val; - ]] - - tile (reg, number) as regPut; -} - -operation RegPutNumber { - impl void (reg destReg, number val) [[ - localStore[destReg].val.numberVal = val; - ]] -} - -operation RegPutBool { - impl void (reg destReg, bool val) [[ - localStore[destReg].val.boolVal = val; - ]] -} - -operation RegPutInt32 { - impl void (reg destReg, int32 val) [[ - localStore[destReg].val.int32Val = val; - ]] -} - -operation ToObject { - impl value toObject(value val) [[ - $$ = val->toObject(exec); - ]] -} - -// Put for an object.. -operation SymPutKnownObject { - impl void symPutKnownObject(value [noimm] scope, ident varName, value val) [[ - ASSERT(scope->isObject()); - static_cast(scope)->put(exec, *varName, val); - ]] - - tile (value, ident, number) as symPutKnownObject; -} - -// Generic get.. -operation SymGet { - impl value symGet(value base, ident prop) [[ - JSObject* baseObj = base->toObject(exec); - // toObject may fail and return an exception object, but get from it is harmless - - // IMPORTANT: The call and store to $$ should be two steps, since ::get can tear off frames! - JSValue* val = baseObj->get(exec, *prop); - $$ = val; - ]] -} - -// Get when we know the base is an object -operation SymGetKnownObject { - impl value symGet(value base, ident prop) [[ - ASSERT(base->isObject()); - - $$ = static_cast(base)->get(exec, *prop); - ]] -} - -// As above, but also stores the object -operation SymGetAndBind { - impl value (reg objDest, value [noimm] base, ident varName) [[ - JSObject* baseObj = base->toObject(exec); - // toObject may fail and return an exception object, but get from it is harmless - localStore[objDest].val.valueVal = baseObj; - - // IMPORTANT: The call and store to $$ should be two steps, since ::get can tear off frames! - JSValue* val = baseObj->get(exec, *varName); - $$ = val; - ]] -} - -operation BracketGet { - impl value (value [noimm] v1, value v2) costs 50 [[ - uint32_t i; - - if (v2->getUInt32(i)) { - $$ = v1->getByIndex(exec, i); - continue; - } - - JSObject *o = v1->toObject(exec); - // Make sure to handle exception immediately, here, since toString might throw, too! - if (exec->hadException()) - continue; - - // IMPORTANT: The call and store to $$ should be two steps, since ::get can tear off frames! - JSValue* val = o->get(exec, Identifier(v2->toString(exec))); - $$ = val; - ]] - - impl value (value [noimm] base, int32 [exact] prop) [[ - if (prop >= 0) { - $$ = base->getByIndex(exec, static_cast(prop)); - } else { - // Have to go as a string, as above. - JSObject* o = base->toObject(exec); - JSValue* val = o->get(exec, Identifier(UString::from(prop))); - $$ = val; - } - ]] -} - -// Also computes the base object -operation BracketGetAndBind { - impl value (reg objDest, value [noimm] v1, value v2) costs 50 [[ - uint32_t i; - JSObject *o = v1->toObject(exec); - // Make sure to handle exception immediately, here, since toString might throw, too! - if (exec->hadException()) - continue; - - localStore[objDest].val.valueVal = o; - - JSValue* val; - if (v2->getUInt32(i)) - val = o->get(exec, i); - else - val = o->get(exec, Identifier(v2->toString(exec))); - $$ = val; - ]] - - impl value (reg objDest, value [noimm] base, int32 [exact] prop) [[ - JSObject* baseObj = base->toObject(exec); - // toObject may fail and return an exception object, but get from it is harmless - localStore[objDest].val.valueVal = baseObj; - - if (prop >= 0) { - $$ = baseObj->get(exec, static_cast(prop)); - } else { - JSValue* val = baseObj->get(exec, Identifier(UString::from(prop))); - $$ = val; - } - ]] -} - - -operation BracketPutKnownObject { - impl void (value [noimm] v1, value v2, value v3) costs 50 [[ - ASSERT(v1->isObject()); - uint32_t i; - JSObject *o = static_cast(v1); - - if (v2->getUInt32(i)) - o->put(exec, i, v3); - else - o->put(exec, Identifier(v2->toString(exec)), v3); - ]] - - impl void (value [noimm] base, int32 [exact] prop, value val) [[ - ASSERT(base->isObject()); - if (prop >= 0) { - static_cast(base)->put(exec, static_cast(prop), val); - } else { - static_cast(base)->put(exec, Identifier(UString::from(prop)), val); - } - ]] -} - -operation GlobalObjectGet { - impl value(ident varName) [[ - JSObject* scopeObj = globalObject; - PropertySlot slot; - if (scopeObj->getPropertySlot(exec, *varName, slot)) { - JSValue* val = slot.getValue(exec, scopeObj, *varName);; - $$ = val; - } else { - throwUndefinedVariableError(exec, *varName); - } - ]] -} - -operation SymDeleteKnownObject { - impl bool(value scope, ident name) [[ - ASSERT(scope->isObject()); - $$ = static_cast(scope)->deleteProperty(exec, *name); - ]] -} - -operation SymDelete { - impl bool(value scope, ident name) [[ - JSObject* o = scope->toObject(exec); - if (pc == localPC) // No exception! - $$ = o->deleteProperty(exec, *name); - ]] -} - -operation BracketDelete { - impl bool(value [noimm] v1, value v2) costs 50 [[ - uint32_t i; - JSObject *o = v1->toObject(exec); - if (pc != localPC) - continue; - - if (v2->getUInt32(i)) - $$ = o->deleteProperty(exec, i); - else - $$ = o->deleteProperty(exec, Identifier(v2->toString(exec))); - ]] - - impl bool(value v1, int32 [exact] i) [[ - JSObject *o = v1->toObject(exec); - if (pc != localPC) - continue; - - if (i >= 0) - $$ = o->deleteProperty(exec, static_cast(i)); - else - $$ = o->deleteProperty(exec, Identifier(UString::from(i))); - ]] -} - -/** - Making things.. -*/ -operation OwnedString { - impl value ownedString(string in) [[ - $$ = jsOwnedString(*in); - ]] -} - -operation NewEmptyArray { - impl value() [[ - $$ = exec->lexicalInterpreter()->builtinArray()->construct(exec, List::empty()); - ]] -} - -operation NewObject { - impl value() [[ - $$ = new JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()); - ]] -} - -operation NewRegExp { - impl value(string pattern, string flags) [[ - // ### TODO: this is -very- wasteful - List list; - list.append(jsOwnedString(*pattern)); - list.append(jsOwnedString(*flags)); - - JSObject *reg = exec->lexicalInterpreter()->builtinRegExp(); - $$ = reg->construct(exec,list); - ]] -} - -operation DefineGetter { - impl void(value [noimm] base, ident name, value getter) [[ - ASSERT(base->isObject()); - ASSERT(getter->isObject()); - static_cast(base)->defineGetter(exec, *name, static_cast(getter)); - ]] -} - -operation DefineSetter { - impl void(value [noimm] base, ident name, value setter) [[ - ASSERT(base->isObject()); - ASSERT(setter->isObject()); - static_cast(base)->defineSetter(exec, *name, static_cast(setter)); - ]] -} - - -/** - Numeric ops - */ -operation Add1 { - impl number add1(number old) [[ - $$ = old + 1.0; - ]] - - tile (value) as add1; -} - -operation Sub1 { - impl number sub1(number old) [[ - $$ = old - 1.0; - ]] -} - -operation Neg { - impl number neg(number old) [[ - $$ = -old; - ]] - - tile (value) as neg; -} - -operation Mult { - impl number mult (number v1, number v2) [[ - $$ = v1 * v2; - ]] - - tile (value, value) as mult; - tile (value, number) as mult; - tile (number, value) as mult; -} - -operation Div { - impl number(number v1, number v2) [[ - $$ = v1 / v2; - ]] -} - -operation Mod { - impl number(number v1, number v2) [[ - $$ = fmod(v1, v2); - ]] -} - -operation Sub { - impl number(number v1, number v2) [[ - $$ = v1 - v2; - ]] -} - -operation Add { - impl value(value v1, value v2) costs 50 [[ - // exception for the Date exception in defaultValue() - JSValue *p1 = v1->toPrimitive(exec, UnspecifiedType); - if (pc != localPC) continue; - JSValue *p2 = v2->toPrimitive(exec, UnspecifiedType); - if (pc != localPC) continue; - - if (p1->isString() || p2->isString()) { - UString value = p1->toString(exec) + p2->toString(exec); - if (value.isNull()) { - JSObject *error = Error::create(exec, GeneralError, "Out of memory"); - exec->setException(error); - } else { - $$ = jsString(value); - } - } else { - $$ = jsNumber(p1->toNumber(exec) + p2->toNumber(exec)); - } - ]] - - impl number(number[exact] n1, number[exact] n2) [[ - $$ = n1 + n2; - ]] -} - - -operation LShift { - impl int32(int32 v1, int32 v2) [[ - $$ = (v1 << ((uint32_t)v2 & 0x1f)); - ]] -} - -operation RShift { - impl int32(int32 v1, int32 v2) [[ - $$ = (v1 >> ((uint32_t)v2 & 0x1f)); - ]] -} - -operation URShift { - // This returns number since we don't have a uint32 type (yet?) - impl number(int32 v1, int32 v2) [[ - $$ = (uint32_t(v1) >> ((uint32_t)v2 & 0x1f)); - ]] -} - -operation Less { - // ### ??? TODO: conversion-less overloads here, when core supports them ??? - - impl bool(value v1, value v2) costs 40 [[ - // operator < - // -1: NaN, undefined => false - // 0: v1 >= v2 => false - // 1: v1 < v2 => true; - $$ = (relation(exec, v1, v2) == 1); - ]] - - impl bool(value v1, number[exact] n2) [[ - // As above.. - $$ = (relation(exec, v1, n2) == 1); - ]] - - impl bool(value v1, int32[exact] n2) [[ - // As above... - $$ = (relation(exec, v1, n2) == 1); - ]] -} - -operation GreaterEq { - impl bool(value v1, value v2) [[ - // operator >= - // -1: NaN, undefined => false - // 0: v1 >= v2 => true - // 1: v1 < v2 => false; - $$ = (relation(exec, v1, v2) == 0); - ]] -} - -operation Greater { - impl bool(value v1, value v2) [[ - // operator > - // -1: NaN, undefined => false - // 0: v2 >= v1 => false - // 1: v2 < v1 => true - $$ = (relation(exec, v2, v1, false) == 1); - ]] -} - -operation LessEq { - impl bool(value v1, value v2) [[ - // operator <= - // -1: NaN, undefined => false - // 0: v2 >= v1 => true - // 1: v2 < v1 => false - $$ = (relation(exec, v2, v1, false) == 0); - ]] -} - -operation EqEq { - impl bool(value v1, value v2) costs 30 [[ - // operator == - $$ = equal(exec, v1, v2); - ]] - - impl bool(value v1, int32[exact] n2) [[ - double n1; - if (v1->getNumber(n1)) - $$ = (n1 == n2); - else - $$ = equal(exec, v1, jsNumber(n2)); - ]] -} - -operation NotEq { - impl bool(value v1, value v2) costs 30 [[ - // operator != - $$ = !equal(exec,v1, v2); - ]] - - impl bool(value v1, int32[exact] n2) [[ - double n1; - if (v1->getNumber(n1)) - $$ = (n1 != n2); - else - $$ = !equal(exec, v1, jsNumber(n2)); - ]] -} - - -operation StrEq { - impl bool(value v1, value v2) [[ - // operator === - $$ = strictEqual(exec,v1, v2); - ]] -} - -operation StrNEq { - impl bool(value v1, value v2) [[ - // operator !== - $$ = !strictEqual(exec,v1, v2); - ]] -} - - -/** - Bitops stuff -*/ -operation BitNot { - impl int32 bitNot(int32 old) [[ - $$ = ~old; - ]] -} - -operation BitAnd { - impl int32 andOp(int32 a0, int32 a1) [[ - $$ = a0 & a1; - ]] - - tile (value, value) as andOp; - tile (value, int32) as andOp; - tile (int32, value) as andOp; -} - -operation BitXOr { - impl int32 (int32 a0, int32 a1) [[ - $$ = a0 ^ a1; - ]] -} - -operation BitOr { - impl int32 (int32 a0, int32 a1) [[ - $$ = a0 | a1; - ]] -} - - -/** - Logical ops... All one of them! -*/ -operation LogicalNot { - impl bool logicalNot(bool old) [[ - $$ = !old; - ]] -} - -/** - Miscellaneous ops -*/ -operation TypeOf { - impl value typeOf(value v) [[ - $$ = typeStringForValue(v); - ]] -} - -operation In { - impl bool (value v1, value v2) [[ - if (!v2->isObject()) { - throwError(exec, TypeError, "Value is not an object. Cannot be used with IN expression."); - continue; - } - JSObject* o2 = static_cast(v2); - $$ = o2->hasProperty(exec, Identifier(v1->toString(exec))); - ]] -} - -operation InstanceOf { - impl bool (value v1, value v2) [[ - if (!v2->isObject()) { - throwError(exec, TypeError, "Value is not an object. Cannot be used with instanceof operator."); - continue; - } - - JSObject* o2 = static_cast(v2); - if (!o2->implementsHasInstance()) - // According to the spec, only some types of objects "implement" the [HasInstance] property. - // But we are supposed to throw an exception where the object does not "have" the [HasInstance] - // property. It seems that all object have the property, but not all implement it, so in this - // case we return false (consistent with mozilla) - $$ = false; - else - $$ = o2->hasInstance(exec, v1); - ]] -} - - -/** - Function call stuff, for first prototype. -*/ -operation ClearArgs { - impl void() [[ - workList.clear(); - ]] -} - -operation AddArg { - impl void(value val) [[ - workList.append(val); - ]] -} - -operation Add2Arg { - impl void(value a1, value a2) [[ - workList.append(a1); - workList.append(a2); - ]] -} - -operation Add3Arg { - impl void(value a1, value a2, value a3) [[ - workList.append(a1); - workList.append(a2); - workList.append(a3); - ]] -} - -operation FunctionCall { - impl value(value v, value thisVal) [[ - ASSERT(thisVal->isObject()); - ASSERT(!static_cast(thisVal)->isActivation()); - - if (!v->implementsCall()) { - throwError(exec, TypeError, "Attempt to use a non-function object or a value as a function."); - //return throwError(exec, TypeError, notAnObjectMessage(), v, expr.get()); - continue; - } - - JSObject *func = static_cast(v); - JSValue* val; - val = func->call(exec, static_cast(thisVal), workList); - $$ = val; - ]] -} - -operation CtorCall { - impl value(value v) [[ - if (!v->isObject()) { - throwError(exec, TypeError, "Value is not an object. Cannot be used with new."); - //return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr.get()); - continue; - } - - JSObject *constr = static_cast(v); - if (!constr->implementsConstruct()) { - throwError(exec, TypeError, "Value is not a constructor. Cannot be used with new."); - // ### TODO - // return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr.get()); - continue; - } - - JSValue* val = constr->construct(exec, workList); - $$ = val; - ]] -} - -operation EvalFuncExpr { - impl value(ident ident, node body) [[ - bool named = !ident->isNull(); - JSObject *functionScopeObject = 0; - - if (named) { - // named FunctionExpressions can recursively call themselves, - // but they won't register with the current scope chain and should - // be contained as single property in an anonymous object. - functionScopeObject = new JSObject; - exec->pushScope(functionScopeObject); - } - - FunctionImp *func = new FunctionImp(exec, *ident, static_cast(body), exec->scopeChain()); - JSObject *proto = exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty()); - proto->put(exec, exec->propertyNames().constructor, func, DontEnum); - func->put(exec, exec->propertyNames().prototype, proto, Internal|DontDelete|DontEnum); - - if (named) { - functionScopeObject->put(exec, *ident, func, Internal | ReadOnly | (exec->codeType() == EvalCode ? 0 : DontDelete)); - exec->popScope(); - } - - $$ = func; - ]] -} - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; hl c++; diff --git a/kjs/bytecode/generator/codeprinter.cpp b/kjs/bytecode/generator/codeprinter.cpp deleted file mode 100644 index 4af07097..00000000 --- a/kjs/bytecode/generator/codeprinter.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#include "codeprinter.h" -#include -#include -#include -#include "assert.h" -#include -#include -#include - -using namespace std; - -void Enum::printDeclaration(ostream& hStream) -{ - hStream << "enum " << name << " {\n"; - for (unsigned p = 0; p < values.size(); ++p) { - hStream << " " << prefix << values[p] << ",\n"; - } - hStream << " " << prefix << "NumValues\n"; - hStream << "};\n"; - hStream << "extern const char* const " << name << "Vals[];\n\n"; -} - -void Enum::printDefinition(ostream& cppStream) -{ - Array vals(cppStream, "const char* const", name + "Vals"); - for (unsigned p = 0; p < values.size(); ++p) - vals.item("\"" + prefix + values[p] + "\""); - vals.endArray(); -} - -Array::Array(ostream& out, const std::string& type, const std::string &name): - out(out), ended(false), first(true) -{ - out << type << " " << name << "[] = {\n"; -} - -Array::~Array() -{ - assert(ended); -} - -void Array::item(const std::string& val, const std::string& newComment) -{ - if (!first) { - out << ", "; - if (!comment.empty()) - out << "// " << comment; - - out << "\n"; - } else { - first = false; - } - - comment = newComment; - - out << " " << val; -} - -void Array::endArray() -{ - assert(!ended); - ended = true; - - if (!comment.empty()) - out << " // " << comment; - out << "\n};\n\n"; -} - -void CodePrinter::issueError(const string& err) -{ - std::cerr << err << "\n"; - exit(-1); -} - -std::string CodePrinter::stringFromInt(int val) -{ - std::stringstream out; - out << val; - return out.str(); -} - -ostream& CodePrinter::mInd(int ind) -{ - for (int i = 0; i < ind; ++i) - *mStream << ' '; - return *mStream; -} - -static bool isWhitespaceString(const string& str) -{ - for (unsigned c = 0; c < str.length(); ++c) { - if (!WTF::isASCIISpace(str[c])) - return false; - } - - return true; -} - -static StringList splitLines(const string& in) -{ - StringList lines; - string curLine; - for (unsigned c = 0; c < in.length(); ++c) { - if (in[c] == '\n') { - lines.push_back(curLine); - curLine = ""; - } else { - curLine += in[c]; - } - } - return lines; -} - -void CodePrinter::printCode(ostream& out, int baseIndent, const string& code, int baseLine) -{ - StringList lines = splitLines(code); - - if (!lines.empty() && isWhitespaceString(lines.front())) { - ++baseLine; - lines.erase(lines.begin()); - } - - if (!lines.empty() && isWhitespaceString(lines.back())) - lines.pop_back(); - - out << "#line " << baseLine << " \"codes.def\"\n"; - - // Compute "leading" whitespace, from codes.def indentation - unsigned minWhiteSpace = 100000; - for (unsigned c = 0; c < lines.size(); ++c) { - const string& line = lines[c]; - if (isWhitespaceString(line)) - continue; - - unsigned ws = 0; - while (ws < line.length() && WTF::isASCIISpace(line[ws])) - ++ws; - if (ws < minWhiteSpace) - minWhiteSpace = ws; - } - - // Print out w/it stripped, and replaced with the indent - // specified by the generator - for (unsigned c = 0; c < lines.size(); ++c) { - const string& line = lines[c]; - if (line.length() < minWhiteSpace) - out << "\n"; - else { - for (int c = 0; c < baseIndent; ++c) - out << ' '; - out << line.substr(minWhiteSpace) << "\n"; - } - } -} - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/generator/codeprinter.h b/kjs/bytecode/generator/codeprinter.h deleted file mode 100644 index 26f2e782..00000000 --- a/kjs/bytecode/generator/codeprinter.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef CODE_PRINTER_H -#define CODE_PRINTER_H - -#include -#include -#include - -using std::ostream; -using std::vector; -using std::string; - -typedef std::vector StringList; - -// This class generates a declaration for an enum, -// and also declares & defines instrospection tables. -class Enum { -public: - Enum(const string& name, const string& prefix, StringList values): - name(name), prefix(prefix), values(values) - {} - - void printDeclaration(ostream& cppStream); - void printDefinition (ostream& hStream); -private: - string name; - string prefix; - StringList values; -}; - -// A helper for bracing, commas, etc., of constant array tables -class Array { -public: - Array(ostream& out, const std::string& type, const std::string &name); - void item(const std::string& val, const std::string& pendingComment = ""); - void endArray(); - ~Array(); -private: - ostream& out; - std::string comment; - bool ended, first; -}; - -enum CodeStream { - OpH, - OpCpp, - MaCpp -}; - -class CodePrinter -{ -public: - CodePrinter(ostream* hStream, ostream* cppStream, ostream* mStream): - hStream(hStream), cppStream(cppStream), mStream(mStream) {} - - void printCode(ostream& out, int baseIndent, const string& code, int baseLine); - - ostream& operator()(CodeStream stream) { - switch (stream) { - case OpH: - return *hStream; - case OpCpp: - return *cppStream; - default: - return *mStream; - } - } - - static std::string stringFromInt(int val); - - // Indented print to machine.cpp. - ostream& mInd(int ind); - - void issueError(const string& err); - -private: - ostream* hStream; - ostream* cppStream; - ostream* mStream; -}; - -#endif -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/generator/driver.cpp b/kjs/bytecode/generator/driver.cpp deleted file mode 100644 index d819ec5b..00000000 --- a/kjs/bytecode/generator/driver.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "tablebuilder.h" -#include "filetemplate.h" - -int main(int argc, char* argv[]) -{ - if (argc != 2) { - std::cerr << "Usage: icemaker \n"; - } - - std::string path = std::string(argv[1]) + "/"; // krazy:exclude=doublequote_chars - - ifstream def; - def.open((path + "codes.def").c_str()); - if (def.fail()) { - std::cerr << "Unable to open codes.def\n"; - return -1; - } - - FileTemplate opcodesH (path + "opcodes.h.in", "opcodes.h"); - FileTemplate opcodesCpp(path + "opcodes.cpp.in", "opcodes.cpp"); - FileTemplate machineCpp(path + "machine.cpp.in", "machine.cpp"); - - if (!opcodesH.ok() || !opcodesCpp.ok() || !machineCpp.ok()) - return -1; - - std::cout << "icemaker -41.9 for KJS/FrostByte\n"; - std::cout << "Generating bytecode instruction selection tables and VM dispatcher...\n"; - - TableBuilder build(&def, &opcodesH.out, &opcodesCpp.out, &machineCpp, &machineCpp.out); - build.generateCode(); - return 0; -} - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/generator/filetemplate.h b/kjs/bytecode/generator/filetemplate.h deleted file mode 100644 index 8a102811..00000000 --- a/kjs/bytecode/generator/filetemplate.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include -#include -#include - -using std::ifstream; -using std::ofstream; -using std::string; - -#ifndef FILE_TEMPLATE_H -#define FILE_TEMPLATE_H - -static inline bool stringEndsWith(string base, string suffix) -{ - if (base.length() < suffix.length()) - return false; - return base.substr(base.length() - suffix.length()) == suffix; -} - -struct FileTemplate -{ - FileTemplate(string inFileName, string outFileName): - inFileName(inFileName), outFileName(outFileName) - { - isOK = true; - lines = 0; - - in.open(inFileName.c_str()); - if (in.fail()) { - std::cerr << "Unable to open:" << inFileName << "\n"; - isOK = false; - } - - out.open(outFileName.c_str()); - if (out.fail()) { - std::cerr << "Unable to open:" << outFileName << "\n"; - isOK = false; - } - - if (isOK) { - out << "// WARNING: Portions of this file are autogenerated from codes.def and " << inFileName << ".\n"; - out << "// (which is what the licensing terms apply to)\n"; - out << "// Any changes you make here may be lost!\n"; - handleUntilGenerate(); - } - } - - ~FileTemplate() - { - if (isOK) - handleUntilGenerate(); - } - - // Goes until @generate.. - void handleUntilGenerate() - { - out << "#line " << (lines + 1) << " \"" << inFileName << "\"\n"; - while (!in.eof()) { - string line; - getline(in, line); - ++lines; - if (stringEndsWith(line, "@generate")) - break; - else - out << line << "\n"; - } - } - - void handleSuffix() - { - out << "#line " << (lines + 1) << " \"" << inFileName << "\"\n"; - while (!in.eof()) { - string line; - getline(in, line); - out << line << "\n"; - } - } - - string inFileName; - string outFileName; - ifstream in; - ofstream out; - bool isOK; - bool ok() { return isOK; } - int lines; // from the template - -}; - -#endif - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/generator/generator.pro b/kjs/bytecode/generator/generator.pro deleted file mode 100644 index ec9ad39e..00000000 --- a/kjs/bytecode/generator/generator.pro +++ /dev/null @@ -1,6 +0,0 @@ -HEADERS = lexer.h parser.h tablebuilder.h -SOURCES = lexer.cpp parser.cpp tablebuilder.cpp driver.cpp -CONFIG+=debug - - - diff --git a/kjs/bytecode/generator/lexer.cpp b/kjs/bytecode/generator/lexer.cpp deleted file mode 100644 index 5f5f46c1..00000000 --- a/kjs/bytecode/generator/lexer.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "lexer.h" -#include - -#ifndef _WIN32 -using std::isspace; -#endif - -#include -using namespace WTF; - -const char EndOfFileChar = 0; - -Lexer::Lexer(istream* _stream): stream(_stream), charLoaded(false), lineNum(0) -{ - keywords["type"] = Type; - keywords["conversion" ] = Conversion; - keywords["register"] = Register; - keywords["operation"] = Operation; - keywords["costs"] = Costs; - keywords["impl"] = Impl; - keywords["tile"] = Tile; - keywords["as"] = As; - keywords["runtime"] = Runtime; - lineNum = 1; -} - -Lexer::Token Lexer::lexComment() -{ - char in = getNext(); - if (in == '/') { - // Single-line comment -- read until the end of line (or file) - do { - in = getNext(); - } while (in != '\n' && in != EndOfFileChar); - } else if (in == '*') { - // Multi-line comment --- scan until */ - do { - in = getNext(); - if (in == EndOfFileChar) - return Token(Error, "Unterminated multiline comment"); - } - while (!(in == '*' && peekNext() == '/')); - getNext(); // Eat the / - } else { - return Token(Error, string("/ can only start comments, but is followed by: ") + in); - } - - // Wee. Worked fine. Recurse to get next stuff - return nextToken(); -} - -Lexer::Token Lexer::nextToken() -{ - char begin; - - // Skip any whitespace characters.. - do { - begin = getNext(); - } - while (isspace(begin)); - - if (begin == EndOfFileChar) - return Token(EndOfFile); - - // Check for simple chars.. - if (begin == '{') - return Token(LBrace); - else if (begin == '}') - return Token(RBrace); - if (begin == '(') - return Token(LParen); - else if (begin == ')') - return Token(RParen); - else if (begin == ':') { - if (peekNext() != ':') { - return Token(Colon); - } else { - getNext(); - return Token(Scope); - } - } else if (begin == ';') - return Token(SemiColon); - else if (begin == '*') - return Token(Star); - else if (begin == ',') - return Token(Comma); - else if (begin == ']') - return Token(RBracket); - else if (begin == '[' && peekNext() != '[') - return Token(LBracket); - - // => - if (begin == '=') { - char c2 = getNext(); - if (c2 == '>') - return Token(Arrow); - else - return Token(Error, "- not part of ->"); - } - - // Check for comments.. - if (begin == '/') - return lexComment(); - - // Numbers - if (isASCIIDigit(begin)) { - string text; - text += begin; - while (isASCIIDigit(peekNext())) - text += getNext(); - return Token(Number, text); - } - - // Code.. - if (begin == '[') { - char next = getNext(); - if (next != '[') - return Token(Error, string("[ continued with:") + next); - int line = lineNumber(); - string text; - while(true) { - char letter = getNext(); - if (letter == EndOfFileChar) - return Token(Error, "Unterminated code fragment"); - if (letter == ']' && peekNext() == ']') { - getNext(); //Eat 2nd ']' - return Token(Code, text, line); - } - text += letter; - } - } - - // Identifiers - if (isASCIIAlpha(begin)) { - string text; - text = begin; - while (isASCIIAlphanumeric(peekNext()) || peekNext() == '_') - text += getNext(); - - TokenType t = Ident; - if (keywords.find(text) != keywords.end()) - t = keywords[text]; - return Token(t, text); - } else { - return Token(Error, string("Invalid start of token:") + begin); - } -} - -char Lexer::peekNext() -{ - if (charLoaded) - return nextChar; - - nextChar = stream->get(); - - if (stream->eof()) - return EndOfFileChar; - - if (nextChar == '\n') - ++lineNum; - charLoaded = true; - return nextChar; -} - -char Lexer::getNext() -{ - if (charLoaded) { - charLoaded = false; - return nextChar; - } - - char in = stream->get(); - - if (stream->eof()) { - // Make sure to let peekNext know. - nextChar = EndOfFileChar; - charLoaded = true; - return EndOfFileChar; - } - - if (in == '\n') - ++lineNum; - - return in; -} - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/generator/lexer.h b/kjs/bytecode/generator/lexer.h deleted file mode 100644 index da34ff8a..00000000 --- a/kjs/bytecode/generator/lexer.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef LEXER_H -#define LEXER_H - -#include -#include -#include - -using std::string; -using std::map; -using std::istream; - -class Lexer -{ -public: - enum TokenType { - Ident, - Number, - Code, - LBrace, // { - RBrace, // } - LParen, // ( - RParen, // ) - LBracket, // [ - RBracket, // ] - Colon, // : - Scope, // :: - SemiColon, // ; - Star, // * - Arrow, // => - Comma, // , - Error, - EndOfFile, - // Keywords: - Type, - Conversion, - Register, - Operation, - Costs, - Impl, - Tile, - As, - Runtime - }; - - struct Token { - TokenType type; - string value; - - int lineNum; //only set for code tokens. - - Token() : type(Error), value("Uninitialized token") {} - Token(TokenType t): type(t) {} - Token(TokenType t, const string& v, int line = -1): type(t), value(v), lineNum(line) {} - - bool isKeyword() const { - return type > EndOfFile; - } - - string toString(Lexer* lex) - { - switch (type) { - case LBrace: - return "'{'"; - case RBrace: - return "'}'"; - case LBracket: - return "'['"; - case RBracket: - return "']'"; - case LParen: - return "'('"; - case RParen: - return "')'"; - case Scope: - return "'::'"; - case Colon: - return "':'"; - case SemiColon: - return "';'"; - case Star: - return "'*'"; - case Arrow: - return "'=>'"; - case Comma: - return "','"; - case EndOfFile: - return ""; - case Error: - return ""; - case Code: - return "[[" + value + "]]"; - case Ident: - case Number: - return value; - default: { - // keywords - for (map::iterator it = lex->keywords.begin(); - it != lex->keywords.end(); ++it) { - - if (it->second == type) - return it->first; - } - return "???"; - } // default : - } // switch(type) - } - }; - - Lexer(istream* _stream); - - Token nextToken(); - - int lineNumber() const { return lineNum; } -private: - friend struct Token; - Token lexComment(); - - char peekNext(); - char getNext(); - - istream* stream; - - bool charLoaded; - char nextChar; - int lineNum; - - map keywords; -}; - -#endif -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/generator/parser.cpp b/kjs/bytecode/generator/parser.cpp deleted file mode 100644 index eeb630da..00000000 --- a/kjs/bytecode/generator/parser.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#include "parser.h" - -#include -#include - -/** - This is a fairly straightforward affair. It's written in a - recursive descent style, but the language is actually regular. - - The error recovert is even simpler: we just exit. That's it. -*/ - -Parser::Parser(istream* stream): tokenLoaded(false), hadError(false), lexer(new Lexer(stream)) -{} - -Parser::~Parser() -{ - delete lexer; -} - -string Parser::matchIdentifier() -{ - Lexer::Token tok = getNext(); - if (tok.type == Lexer::Ident) - return tok.value; - issueError("Expected identifier, got:" + tok.toString(lexer)); - return ""; -} - -void Parser::matchCode(std::string* strOut, int* lineOut) -{ - Lexer::Token tok = getNext(); - if (tok.type == Lexer::Code) { - *lineOut = tok.lineNum; - *strOut = tok.value; - return; - } - issueError("Expected code, got:" + tok.toString(lexer)); -} - -int Parser::matchNumber() -{ - Lexer::Token tok = getNext(); - if (tok.type == Lexer::Number) - return std::atol(tok.value.c_str()); - issueError("Expected number, got:" + tok.toString(lexer)); - return 0; -} - -void Parser::match(Lexer::TokenType t) -{ - Lexer::Token tok = getNext(); - if (tok.type != t) - issueError("Expected " + Lexer::Token(t).toString(lexer) + " got:" + tok.toString(lexer)); -} - -bool Parser::check(Lexer::TokenType t) -{ - if (peekNext().type == t) { - getNext(); // tasty! - return true; - } else { - return false; - } -} - -unsigned Parser::matchFlags(const Flag* permittedFlags) -{ - unsigned flagsVal = 0; - if (check(Lexer::LBracket)) { - while (true) { - std::string flag; - - // We permit keywords to double as flags. - if (peekNext().isKeyword()) - flag = getNext().toString(lexer); - else - flag = matchIdentifier(); - - // Lookup the name. - bool found = false; - for (int pos = 0; permittedFlags[pos].name; ++pos) { - if (flag == std::string(permittedFlags[pos].name)) { - found = true; - flagsVal |= permittedFlags[pos].value; - } - } - - if (!found) - issueError("invalid flag:" + flag); - - // Done or more? - if (check(Lexer::RBracket)) - return flagsVal; - else - match(Lexer::Comma); - } - } - return 0; -} - -void Parser::issueError(const string& msg) -{ - std::cerr << "Parse error:" << msg << " at about line:" << lexer->lineNumber() << "\n"; - std::exit(-1); -} - -Lexer::Token Parser::peekNext() -{ - if (!tokenLoaded) { - nextToken = lexer->nextToken(); - tokenLoaded = true; - } - - return nextToken; -} - -Lexer::Token Parser::getNext() -{ - if (tokenLoaded) { - tokenLoaded = false; - return nextToken; - } - - return lexer->nextToken(); -} - -void Parser::parse() -{ - Lexer::Token tok = peekNext(); - - // The types are first.. - while (tok.type == Lexer::Type) { - parseType(); - tok = peekNext(); - } - - // Now we may have conversions or operations - while (tok.type == Lexer::Conversion || tok.type == Lexer::Operation) { - if (tok.type == Lexer::Conversion) - parseConversion(); - else - parseOperation(); - tok = peekNext(); - } - - match(Lexer::EndOfFile); -} - -void Parser::parseType() -{ - //type identifier: nativeName *? [immediate?, register?, ?align8]?; - match(Lexer::Type); - - string name = matchIdentifier(); - match(Lexer::Colon); - string nativeName = matchIdentifier(); - - if (nativeName == "const") - nativeName += " " + matchIdentifier(); // krazy:exclude=doublequote_chars - - while (check(Lexer::Scope)) - nativeName += "::" + matchIdentifier(); - - if (check(Lexer::Star)) - nativeName += "*"; // krazy:exclude=doublequote_chars - - const Flag typeFlags[] = { - {"immediate", Type_HaveImm}, - {"register", Type_HaveReg}, - {"align8", Type_Align8}, - {0, 0} - }; - - unsigned flags = matchFlags(typeFlags); - match(Lexer::SemiColon); - - handleType(name, nativeName, flags); -} - -void Parser::parseConversion() -{ - // conversion from => to { clauses .. } - // clause := tile costs number; || impl [checked?, mayThrow?]? code; || register ident costs number; - match(Lexer::Conversion); - string from = matchIdentifier(); - match(Lexer::Arrow); - string to = matchIdentifier(); - - match(Lexer::LBrace); - - // impl clause info.. - const Flag conversionFlags[] = { - {"checked", Conv_Checked}, - {"mayThrow", Conv_MayThrow}, - {0, 0} - }; - - - unsigned flags = 0; - string code; - int codeLine = 0; - - // tile clause info - int tileCost = 0; - - // register clause info - string registerIdent; - int registerCost = 0; - - while (!check(Lexer::RBrace)) { - if (check(Lexer::Impl)) { - // impl [[code]] - flags = matchFlags(conversionFlags); - matchCode(&code, &codeLine); - } else if (check(Lexer::Tile)) { - // tile costs number; - match(Lexer::Costs); - tileCost = matchNumber(); - match(Lexer::SemiColon); - } else if (check(Lexer::Register)) { - //register costs number; - flags |= Conv_HaveReg; - match(Lexer::Costs); - registerCost = matchNumber(); - match(Lexer::SemiColon); - } else { - issueError("Invalid start of a clause within conversion block:" + peekNext().toString(lexer)); - } - } - - handleConversion(code, codeLine, flags, from, to, tileCost, registerCost); -} - -void Parser::parseOperation() -{ - // operation identifier { ... }, where ... is a list of impl or tile statements. - match(Lexer::Operation); - - const Flag opFlags[] = { - {"endsBB", Op_EndsBB}, - {"hint", Op_Hint}, - {0, 0} - }; - - std::string name = matchIdentifier(); - unsigned flags = matchFlags(opFlags); - - handleOperation(name, flags); - - match(Lexer::LBrace); - Lexer::Token tok = peekNext(); - while (tok.type == Lexer::Tile || tok.type == Lexer::Impl) { - if (tok.type == Lexer::Tile) - parseTile(); - else - parseImpl(); - tok = peekNext(); - } - match(Lexer::RBrace); -} - -void Parser::parseImpl() -{ - match(Lexer::Impl); - // impl identifier identifier? ( paramList? ) code - // paramList := ident ident - // paramList := ident ident , paramList - - string ret = matchIdentifier(); - - string fn; - if (peekNext().type == Lexer::Ident) - fn = matchIdentifier(); - match(Lexer::LParen); - - const Flag paramFlags[] = { - {"noimm", Param_NoImm}, - {"noreg", Param_NoReg}, - {"exact", Param_Exact}, - {0, 0} - }; - - // Parse parameter types and names, if any.. - vector params; - while (peekNext().type != Lexer::RParen) { - Parameter param; - param.typeName = matchIdentifier(); - param.flags = matchFlags(paramFlags); - param.name = matchIdentifier(); - - params.push_back(param); - - if (!check(Lexer::Comma)) - break; - - // Make sure we have an ident next, and not an rparen.. - if (peekNext().type != Lexer::Ident) - issueError("Parameter signature in impl doesn't start with an identifier!"); - } - match(Lexer::RParen); - - int cost = 0; - if (peekNext().type == Lexer::Costs) { - getNext(); - cost = matchNumber(); - } - - int codeLine; - string code; - matchCode(&code, &codeLine); - - handleImpl(fn, code, codeLine, cost, ret, params); -} - -void Parser::parseTile() -{ - // tile signature as identifier; - match(Lexer::Tile); - - StringList paramSigs; - match(Lexer::LParen); - while (peekNext().type != Lexer::RParen) { - paramSigs.push_back(matchIdentifier()); - if (peekNext().type != Lexer::Comma) - break; - getNext(); // Eat the comma.. - // Make sure we have an ident next, and not an rparen.. - if (peekNext().type != Lexer::Ident) - issueError("Parameter signature in tile doesn't start with an identifier!"); - } - - match(Lexer::RParen); - - match(Lexer::As); - string fn = matchIdentifier(); - handleTile(fn, paramSigs); - match(Lexer::SemiColon); -} - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/generator/parser.h b/kjs/bytecode/generator/parser.h deleted file mode 100644 index 0c2f7c96..00000000 --- a/kjs/bytecode/generator/parser.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef PARSER_H -#define PARSER_H - -#include "lexer.h" - -#include "types.h" // for various flags - -#include - -enum ParamFlags { - Param_NoImm = 1, - Param_NoReg = 2, - Param_Exact = 4 -}; - -enum OpFlags { - Op_EndsBB = 1, - Op_Hint = 2 -}; - -struct Parameter -{ - string name; - string typeName; // name of the type of the parameter, set by the parser - Type type; // the actual type of the parameter, resolved by the TableBuilder. - unsigned flags; - - Parameter(): flags(0) {} -}; - -class Parser -{ -public: - Parser(istream* stream); - ~Parser(); - - void parse(); -private: - // Note: signatures here are just a list of strings; - // the last one is the return type - - virtual void handleType(const string& type, const string& nativeName, unsigned flags) = 0; - - virtual void handleConversion(const string& runtimeRoutine, int codeLine, - unsigned flags, const string& from, const string& to, - int tileCost, int registerCost) = 0; - - virtual void handleOperation(const string& name, unsigned flags) = 0; - virtual void handleImpl(const string& fnName, const string& code, int codeLine, int cost, - const string& retType, vector sig) = 0; - virtual void handleTile(const string& fnName, StringList sig) = 0; - - struct Flag { - const char* name; - unsigned value; - }; - - // Matches flags specified as a zero-terminated pair array above, - // and returns their or. In syntax, they look like - // [flag1, flag2, flag3] and are optional. - unsigned matchFlags(const Flag* permittedFlags); - - // These unconditionally parse items of given type. - string matchIdentifier(); - void matchCode(std::string* stringOut, int* lineOut); - int matchNumber(); - void match(Lexer::TokenType t); - - // These conditionally consume given token if it's there, - // and return true if so. - bool check(Lexer::TokenType t); - - void parseType(); - void parseConversion(); - void parseOperation(); - void parseImpl(); - void parseTile(); - - bool tokenLoaded; - Lexer::Token nextToken; - - void issueError(const string& msg); - - bool hadError; - - Lexer* lexer; - - Lexer::Token peekNext(); - Lexer::Token getNext(); -}; - -#endif -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; - diff --git a/kjs/bytecode/generator/tablebuilder.cpp b/kjs/bytecode/generator/tablebuilder.cpp deleted file mode 100644 index 24b2c4e9..00000000 --- a/kjs/bytecode/generator/tablebuilder.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#include "tablebuilder.h" -#include -#include -#include "assert.h" -#include -#include -#include - -using namespace std; - -static string strReplace(string where, string from, string to) { - string res = where; - size_t pos; - while ((pos = res.find(from)) != string::npos) { - res = res.substr(0, pos) + to + res.substr(pos + from.length()); - } - return res; -} - -TableBuilder::TableBuilder(istream* inStream, ostream* hStream, - ostream* cppStream, FileTemplate* fTemplate, ostream* mStream): - Parser(inStream), out(hStream, cppStream, mStream), types(this, out), fTemplate(fTemplate) -{} - -void TableBuilder::generateCode() -{ - parse(); - - types.generateCode(); - - // Operations - Enum opNamesEnum("OpName", "Op_", operationNames); - opNamesEnum.printDeclaration(out(OpH)); - opNamesEnum.printDefinition (out(OpCpp)); - - // Enumerate all the variants.. - for (unsigned c = 0; c < operations.size(); ++c) { - vector parIm; - expandOperationVariants(operations[c], parIm); - } - - // Return types for each.. - out(OpCpp) << "static const OpType opRetTypes[] = {\n"; - for (unsigned c = 0; c < operationNames.size(); ++c) { - out(OpCpp) << " OpType_" << operationRetTypes[operationNames[c]]; - if (c != operationNames.size() - 1) - out(OpCpp) << ","; - out(OpCpp) << " //" << operationNames[c] << "\n"; - } - out(OpCpp) << "};\n\n"; - - // Now we have all our bytecode names... Whee. - Enum opByteCodesEnum("OpByteCode", "OpByteCode_", variantNames); - opByteCodesEnum.printDeclaration(out(OpH)); - opByteCodesEnum.printDefinition (out(OpCpp)); - - // We can now emit the actual tables... - - // ... first descriptors for each bytecode op.. - out(OpCpp) << "const Op opsForOpCodes[] = {\n"; - for (unsigned c = 0; c < variants.size(); ++c) { - const OperationVariant& variant = variants[c]; - if (variant.needsPadVariant) - dumpOpStructForVariant(variant, true, variant.needsPadVariant, true); - dumpOpStructForVariant(variant, false, variant.needsPadVariant, c != variants.size() - 1); - } - out(OpCpp) << "};\n\n"; - - // then variant tables for each main op.. - for (unsigned c = 0; c < operationNames.size(); ++c) { - const string& opName = operationNames[c]; - out(OpCpp) << "static const Op* const op" << opName << "Variants[] = {"; - StringList variants = variantNamesForOp[opName]; - for (unsigned v = 0; v < variants.size(); ++v) { - out(OpCpp) << "&opsForOpCodes[OpByteCode_" << variants[v] << "], "; - } - out(OpCpp) << "0};\n"; - } - out(OpCpp) << "\n"; - - out(OpCpp) << "const Op* const* const opSpecializations[] = {\n"; - for (unsigned o = 0; o < operationNames.size(); ++o) { - out(OpCpp) << " op" << operationNames[o] << "Variants"; - if (o != (operationNames.size() - 1)) - out(OpCpp) << ","; - out(OpCpp) << "\n"; - } - out(OpCpp) << "};\n\n"; - - // Jump table, if needed - Array jumps(out(MaCpp), "static void*", "kjsVMOpHandlers"); - for (unsigned c = 0; c < variants.size(); ++c) { - const OperationVariant& var = variants[c]; - if (var.needsPadVariant) - jumps.item("__extension__ &&l" + var.sig + "_Pad"); - - jumps.item("__extension__ &&l" + var.sig); - } - - jumps.endArray(); - - fTemplate->handleUntilGenerate(); - - - // Now, generate the VM loop. - mInd(8) << "OpByteCode op = *reinterpret_cast(pc);\n"; - - mInd(0) << "#ifdef USE_LABEL_VALS\n"; - mInd(8) << "goto *kjsVMOpHandlers[op];\n"; - mInd(8) << "{\n"; - mInd(0) << "#else\n"; - mInd(8) << "switch (op) {\n"; - mInd(0) << "#endif\n"; - for (unsigned c = 0; c < variants.size(); ++c) { - const OperationVariant& var = variants[c]; - if (var.needsPadVariant) { - mInd(12) << "handler(" + var.sig + "_Pad):\n"; - mInd(16) << "pc += 4;\n"; - mInd(16) << "// Fallthrough\n"; - } - - mInd(12) << "handler(" + var.sig + "): {\n"; - generateVariantImpl(var); - mInd(12) << "}\n"; - mInd(12) << "continue;\n\n"; - } - - mInd(8) << "}\n\n"; -} - -void TableBuilder::handleType(const string& type, const string& nativeName, unsigned flags) -{ - types.handleType(type, nativeName, flags); -} - -void TableBuilder::handleConversion(const string& code, int codeLine, - unsigned flags, const string& from, const string& to, - int tileCost, int registerCost) -{ - types.handleConversion(code, codeLine, flags, from, to, tileCost, registerCost); -} - -void TableBuilder::handleOperation(const string& name, unsigned flags) -{ - operationNames.push_back(name); - operationFlags = flags; -} - -void TableBuilder::handleImpl(const string& fnName, const string& code, int codeLine, int cost, - const string& retType, vector sig) -{ - // If the return type isn't 'void', we prepend a destination register as a parameter in the encoding. - // emitOp will convert things as needed - vector extSig; - if (retType != "void") { - Parameter ret; - ret.typeName = "reg"; - ret.name = "fbDestReg"; - ret.flags = 0; - extSig.push_back(ret); - } - - for (unsigned c = 0; c < sig.size(); ++c) - extSig.push_back(sig[c]); - - // Now go through and resolve each type. These are also - // the types of the params of this base op. - Operation op; - for (unsigned c = 0; c < extSig.size(); ++c) { - extSig[c].type = types.resolveType(extSig[c].typeName); - op.opParamTypes.push_back(extSig[c].type); - } - - op.name = operationNames.back(); - op.retType = retType; - operationRetTypes[op.name] = retType; - op.isTile = false; - op.implementAs = code; - op.implParams = extSig; - op.codeLine = codeLine; - op.cost = cost; - op.flags = operationFlags; - operations.push_back(op); - if (!fnName.empty()) - implementations[fnName] = op; -} - -void TableBuilder::handleTile(const string& fnName, StringList sig) -{ - if (implementations.find(fnName) == implementations.end()) - out.issueError("Unknown implementation name " + fnName + " in a tile definition"); - const Operation& impl = implementations[fnName]; - - // Add in a return reg if need be - StringList extSig; - if (impl.retType != "void") - extSig.push_back("reg"); - - for (unsigned c = 0; c < sig.size(); ++c) - extSig.push_back(sig[c]); - - - - // Most of the stuff is the same as in the base impl, - // but we have a different external signature, and are a tile. - Operation op = impl; - op.isTile = true; - op.opParamTypes = types.resolveSignature(extSig); - - // Now also include the cost of inline conversions. - for (unsigned p = 0; p < op.opParamTypes.size(); ++p) - op.cost += types.immConv(op.opParamTypes[p], op.implParams[p].type).cost; - - operations.push_back(op); -} - -void TableBuilder::expandOperationVariants(const Operation& op, vector& paramIsIm) -{ - unsigned numParams = op.opParamTypes.size(); - if (paramIsIm.size() < numParams) { - int paramPos = paramIsIm.size(); - bool hasIm = (op.opParamTypes[paramPos].flags & Type_HaveImm) == Type_HaveImm; - bool hasReg = (op.opParamTypes[paramPos].flags & Type_HaveReg) == Type_HaveReg; - - bool genIm = hasIm; - bool genReg = hasReg; - - // Don't generate non-register variants for tiles when possible. - if (op.isTile && hasReg) - genIm = false; - - // There may be hints saying not to generate some version - if (op.implParams[paramPos].flags & Param_NoImm) - genIm = false; - - if (op.implParams[paramPos].flags & Param_NoReg) - genReg = false; - - if (genIm) { - paramIsIm.push_back(true); - expandOperationVariants(op, paramIsIm); - paramIsIm.pop_back(); - } - - if (genReg) { - paramIsIm.push_back(false); - expandOperationVariants(op, paramIsIm); - paramIsIm.pop_back(); - } - return; - } - - // Have a full variant... Build a signature. - - string sig = op.name; - for (unsigned p = 0; p < numParams; ++p) { - sig += "_"; // krazy:exclude=doublequote_chars - sig += paramIsIm[p] ? "I" : "R"; - sig += op.opParamTypes[p].name; - } - - // We may need padding if we have an immediate align8 param.. - bool needsPad = false; - for (unsigned c = 0; c < numParams; ++c) - needsPad |= (paramIsIm[c] & op.opParamTypes[c].alignTo8()); - - OperationVariant var; - var.sig = sig; - var.op = op; - var.paramIsIm = paramIsIm; - var.needsPadVariant = needsPad; - - // Build offset table, giving param positions.. - while (var.paramOffsets.size() < numParams) // no setSize in QList.. - var.paramOffsets.push_back(0); - - int pos = 4; - // pad8/align ones go first. - for (unsigned c = 0; c < numParams; ++c) { - if (paramIsIm[c] & op.opParamTypes[c].alignTo8()) { - var.paramOffsets[c] = pos; - pos += 8; - } - } - - // Then the rest.. - for (unsigned c = 0; c < numParams; ++c) { - if (!paramIsIm[c] || !op.opParamTypes[c].alignTo8()) { - var.paramOffsets[c] = pos; - pos += 4; - } - } - var.size = pos; - - variants.push_back(var); - if (needsPad) { // we put the pad before, due to the fallthrough idiom.. - string pSig = sig + "_Pad"; - variantNames.push_back(pSig); - variantNamesForOp[op.name].push_back(pSig); - } - variantNames.push_back(sig); - variantNamesForOp[op.name].push_back(sig); -} - -void TableBuilder::dumpOpStructForVariant(const OperationVariant& variant, bool doPad, - bool hasPadVariant, bool needsComma) -{ - out(OpCpp) << " {"; - out(OpCpp) << "Op_" << variant.op.name << ", "; // baseInstr.. - out(OpCpp) << "OpByteCode_" << (doPad ? variant.sig + "_Pad" : variant.sig) << ", "; // byteCode op - out(OpCpp) << variant.op.cost << ", "; // uhm, cost. doh. - int numParams = variant.op.opParamTypes.size(); - out(OpCpp) << numParams << ", "; // # of params - - // Param types. - out(OpCpp) << "{"; - for (int p = 0; p < numParams; ++p) { - out(OpCpp) << "OpType_" << variant.op.opParamTypes[p].name; - if (p != numParams - 1) - out(OpCpp) << ", "; - } - out(OpCpp) << "}, "; - - // Immediate flag.. - out(OpCpp) << "{"; - for (int p = 0; p < numParams; ++p) { - out(OpCpp) << (variant.paramIsIm[p] ? "true" : "false"); - if (p != numParams - 1) - out(OpCpp) << ", "; - } - out(OpCpp) << "}, "; - - // Exact params flag. - out(OpCpp) << "{"; - for (int p = 0; p < numParams; ++p) { - out(OpCpp) << ((variant.op.implParams[p].flags & Param_Exact) ? "true" : "false"); - if (p != numParams - 1) - out(OpCpp) << ", "; - } - out(OpCpp) << "}, "; - - // Return type. - out(OpCpp) << "OpType_" << variant.op.retType << ", "; - - int adjust = doPad ? 4 : 0; // padded version has 4 extra bytes, - // between the opcode and the first arg. - // Size.. - out(OpCpp) << (variant.size + adjust) << ", "; - - // Offset table.. - out(OpCpp) << "{"; - for (int p = 0; p < numParams; ++p) { - out(OpCpp) << (variant.paramOffsets[p] + adjust); - if (p != numParams - 1) - out(OpCpp) << ", "; - } - - out(OpCpp) << "}, "; - - // Whether this is a padded version.. - out(OpCpp) << (doPad ? "true" : "false") << ", "; - - // And whether a padded version exists. - out(OpCpp) << (hasPadVariant ? "true" : "false") << ", "; - - // Whether this ends a basic block. - out(OpCpp) << (variant.op.flags & Op_EndsBB ? "true" : "false"); - - if (needsComma) - out(OpCpp) << "},\n"; - else - out(OpCpp) << "}\n"; -} - -void TableBuilder::generateVariantImpl(const OperationVariant& variant) -{ - mInd(16) << "pc += " << variant.size << ";\n"; - mInd(16) << "const unsigned char* localPC = pc;\n"; - int numParams = variant.paramIsIm.size(); - for (int p = 0; p < numParams; ++p) { - const Type& type = variant.op.opParamTypes[p]; - bool inReg = !variant.paramIsIm[p]; - int negPos = variant.paramOffsets[p] - variant.size; - - bool wideArg = !inReg && type.alignTo8(); - - char negPosStr[64]; - std::sprintf(negPosStr, "%d", negPos); - - string accessString = "reinterpret_castval." + type.name + "Val"; - } - - mInd(16) << variant.op.implParams[p].type.nativeName << " " << variant.op.implParams[p].name - << " = "; - if (type == variant.op.implParams[p].type) { - // We don't need a conversion, just fetch it directly into name.. - out(MaCpp) << accessString << ";\n"; - } else { - ConversionInfo conv = types.immConv(type, variant.op.implParams[p].type); - out(MaCpp) << "convert" << conv.name << "(exec, " << accessString << ");\n"; - - if (conv.flags & Conv_MayThrow) { - // Check for an exception being raised, or perhaps a reload request - mInd(16) << "if (pc != localPC) // {// Exception or reload\n"; - //mInd(20) << "if (exec->h - mInd(20) << "continue;\n"; - } - } - } - - // Replace $$ with destination register - string storeCode = "localStore[fbDestReg].val." + variant.op.retType + "Val"; - string code = variant.op.implementAs; - code = strReplace(code, "$$", storeCode); - - // Print out the impl code.. - out.printCode(out(MaCpp), 16, code, variant.op.codeLine); -} - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/generator/tablebuilder.h b/kjs/bytecode/generator/tablebuilder.h deleted file mode 100644 index 032c0e3a..00000000 --- a/kjs/bytecode/generator/tablebuilder.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef TABLE_BUILDER_H -#define TABLE_BUILDER_H - -#include "filetemplate.h" -#include "codeprinter.h" -#include "types.h" -#include "parser.h" - -// Actually, a specialization, but who cares? -struct Operation -{ - string name; - string retType; - int cost; - int codeLine; - unsigned flags; - bool isTile; - - string implementAs; - vector opParamTypes; // the types of params of the bytecode operation - vector implParams; // the params the [[ code ]] block takes -}; - -struct OperationVariant -{ - string sig; - Operation op; - vector paramIsIm; - vector paramOffsets; - int size; - bool needsPadVariant; -}; - -class TableBuilder: public Parser -{ -public: - TableBuilder(istream* inStream, ostream* hStream, ostream* cppStream, - FileTemplate* fTemplate, ostream* mStream); - - void generateCode(); -private: - // Interface to the parser; also (ab)used by the type system to emit - // conversion ops. - friend class TypeTable; - - virtual void handleType(const string& type, const string& nativeName, unsigned flags); - virtual void handleConversion(const string& runtimeRoutine, int codeLine, - unsigned flags, const string& from, const string& to, - int tileCost, int registerCost); - - virtual void handleOperation(const string& name, unsigned flags); - virtual void handleImpl(const string& fnName, const string& code, int codeLine, int cost, - const string& retType, vector sig); - virtual void handleTile(const string& fnName, StringList sig); - - // Enumerates all r/i/pad variants; plus computes the shuffle table. - void expandOperationVariants(const Operation& op, vector& paramIsIm); - - void dumpOpStructForVariant(const OperationVariant& variant, bool doPad, - bool hasPadVariant, bool needsComma); - - void generateVariantImpl(const OperationVariant& variant); - - CodePrinter out; - TypeTable types; - - ostream& mInd(int ind) { - return out.mInd(ind); - } - - StringList operationNames; - unsigned operationFlags; - map operationRetTypes; // uglily enough specified on the impl. I suck. - vector operations; - map implementations; - - StringList variantNames; - vector variants; - map variantNamesForOp; - - FileTemplate* fTemplate; -}; - -#endif -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/generator/types.cpp b/kjs/bytecode/generator/types.cpp deleted file mode 100644 index a0bd821d..00000000 --- a/kjs/bytecode/generator/types.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "types.h" - -#include -#include -#include "assert.h" -#include -#include -#include - -#include "tablebuilder.h" - -using namespace std; - -// # of bits store 'vals' values, e.g. 3 for 8, etc. -static unsigned neededBits(unsigned vals) -{ - unsigned bits = 1; - while ((1U << bits) < vals) - ++bits; - return bits; -} - -TypeTable::TypeTable(TableBuilder* instrBuilder, CodePrinter& out): - instrBuilder(instrBuilder), out(out) -{ - // Builtin stuff... - conversionNames.push_back("NoConversion"); - conversionNames.push_back("NoOp"); - - // Special ones for checked; opcodes.cpp.in has code to generate these. - conversionNames.push_back("I_R_Int32_Value"); - conversionNames.push_back("I_R_Number_Value"); -} - -void TypeTable::generateCode() -{ - // Types... First we just want to list them - Enum typesEnum("OpType", "OpType_", typeNames); - typesEnum.printDeclaration(out(OpH)); - typesEnum.printDefinition (out(OpCpp)); - - // Also, print out the width array... - Array widths(out(OpCpp), "const bool", "opTypeIsAlign8"); - for (unsigned t = 0; t < typeNames.size(); ++t) { - const Type& type = types[typeNames[t]]; - widths.item(type.alignTo8() ? "true": "false", type.name); - } - widths.endArray(); - - // Conversion ops. Those go entirely in the .cpp - Enum convOps("ConvOp", "Conv_", conversionNames); - convOps.printDeclaration(out(OpH)); - convOps.printDefinition (out(OpCpp)); - - out(OpCpp) << "struct ConvInfo {\n"; - out(OpCpp) << " ConvOp routine;\n"; - out(OpCpp) << " int costCode;\n"; - out(OpCpp) << "};\n\n"; - - // For conversion info, we use upper bit for register/immediate (immediate is set), - // and then enough bits for the from/to types as the index. - Array convArr(out(OpCpp), "ConvInfo", "conversions"); - printConversionInfo(convArr, rgConversions, true); - printConversionInfo(convArr, imConversions, false); - convArr.endArray(); - - int numBits = neededBits(types.size()); - out(OpCpp) << "static inline const ConvInfo* getConversionInfo(bool immediate, OpType from, OpType to)\n{\n"; - out(OpCpp) << " return &conversions[((int)immediate << " << (2 * numBits) << ")" - << " | ((int)from << " << numBits << ") | (int)to];\n"; - out(OpCpp) << "}\n\n"; - - // Emit inline conversion helpers based on the [[ code ]] specified - // in codes.def - for (unsigned c = 0; c < imConversionList.size(); ++c) - printConversionRoutine(imConversionList[c]); - - // Now we generate a helper that invokes those. - out(OpCpp) << "static bool emitImmediateConversion(ConvOp convType, OpValue* original, OpValue& out)\n{\n"; - out(OpCpp) << " out.immediate = true;\n"; - out(OpCpp) << " switch(convType) {\n"; - out(OpCpp) << " case Conv_NoOp:\n"; - out(OpCpp) << " out = *original;\n"; - out(OpCpp) << " break;\n"; - for (unsigned c = 0; c < imConversionList.size(); ++c) { - const ConversionInfo& inf = imConversionList[c]; - out(OpCpp) << " case Conv_" << inf.name << ":\n"; - out(OpCpp) << " out.type = OpType_" << inf.to.name << ";\n"; - out(OpCpp) << " out.value." << inf.to.field() << " = " - << "convert" << inf.name << "(0, " - << "original->value." << inf.from.field() << ");\n"; - - out(OpCpp) << " break;\n"; - } - - out(OpCpp) << " default:\n"; - out(OpCpp) << " return false;\n"; - out(OpCpp) << " }\n"; - out(OpCpp) << " return true;\n"; - out(OpCpp) << "}\n\n"; - - // Similar helper for simple register conversions, which actually emits ops - out(OpCpp) << "static bool emitSimpleRegisterConversion(CompileState* comp, ConvOp convType, OpValue* original, OpValue& out)\n{\n"; - out(OpCpp) << " switch(convType) {\n"; - out(OpCpp) << " case Conv_NoOp:\n"; - out(OpCpp) << " out = *original;\n"; - out(OpCpp) << " break;\n"; - for (unsigned c = 0; c < rgConversionList.size(); ++c) { - const ConversionInfo& inf = rgConversionList[c]; - out(OpCpp) << " case Conv_" << inf.name << ":\n"; - out(OpCpp) << " CodeGen::emitOp(comp, Op_" << inf.name << ", &out, original);\n"; - out(OpCpp) << " break;\n"; - } - out(OpCpp) << " default:\n"; - out(OpCpp) << " return false;\n"; - out(OpCpp) << " }\n"; - out(OpCpp) << " return true;\n"; - out(OpCpp) << "}\n\n"; -} - -void TypeTable::printConversionInfo(Array& outArr, map >& table, bool reg) -{ - unsigned numBits = neededBits(types.size()); - unsigned fullRange = 1 << numBits; - for (unsigned from = 0; from < fullRange; ++from) { - for (unsigned to = 0; to < fullRange; ++to) { - if (from < types.size() && to < types.size()) { - string fromName = typeNames[from]; - string toName = typeNames[to]; - - string item; - - // For register conversion, we need it to be possible for source + dest to be in - // registers. For immediate, we only require source, since dest will just go - // into local value. - bool representable; - if (reg) - representable = types[fromName].hasReg() && types[toName].hasReg(); - else - representable = types[fromName].hasImm(); - - if (from == to) { - item = "{Conv_NoOp, 0}"; - } else if (table[fromName].find(toName) != table[fromName].end() && representable) { - const ConversionInfo& inf = table[fromName][toName]; - - item = "{Conv_" + inf.name + ", "; - if (inf.flags & Conv_Checked) - item += "Cost_Checked"; - else - item += CodePrinter::stringFromInt(reg ? inf.cost : 0); - item += "}"; // krazy:exclude=doublequote_chars - } else { - item = "{Conv_NoConversion, Cost_NoConversion}"; - } - - outArr.item(item, fromName + " => " + toName); - } else { - outArr.item("{Conv_NoConversion, Cost_NoConversion}"); - } - } // for to.. - } // for from.. -} - -void TypeTable::printConversionRoutine(const ConversionInfo& conversion) -{ - out(OpH) << "ALWAYS_INLINE " << conversion.to.nativeName << " convert" << conversion.name - << "(ExecState* exec, " << conversion.from.nativeName << " in)\n"; - out(OpH) << "{\n"; - out(OpH) << " (void)exec;\n"; - out.printCode(out(OpH), 4, conversion.impl, conversion.codeLine); - out(OpH) << "}\n\n"; -} - -void TypeTable::handleType(const string& type, const string& nativeName, unsigned flags) -{ - typeNames.push_back(type); - Type t; - t.name = type; - t.nativeName = nativeName; - t.flags = flags; - types[type] = t; -} - -static string capitalized(const string& in) -{ - return WTF::toASCIIUpper(in[0]) + in.substr(1); -} - -void TypeTable::handleConversion(const string& code, int codeLine, - unsigned flags, const string& from, const string& to, - int tileCost, int registerCost) -{ - // Compute the conversion names. The register one (if any) would also create an operation. - string immName = "I" + capitalized(from) + "_" + capitalized(to); // krazy:exclude=doublequote_chars - string regName = "R" + capitalized(from) + "_" + capitalized(to); // krazy:exclude=doublequote_chars - - // Register immediate conversion - conversionNames.push_back(immName); - ConversionInfo inf; - inf.name = immName; - inf.cost = tileCost; - inf.flags = flags; - inf.impl = code; - inf.codeLine = codeLine; - inf.from = types[from]; - inf.to = types[to]; - - imConversions[from][to] = inf; - imConversionList.push_back(inf); - - // ... and, if it exists, register one. - if (flags & Conv_HaveReg) { - conversionNames.push_back(regName); - inf.name = regName; - inf.cost = registerCost; - inf.flags &= ~Conv_Checked; // 'checked' makes no sense here - rgConversions[from][to] = inf; - rgConversionList.push_back(inf); - - // We also generate the corresponding bytecode routine, using - // the immediate conversion helper we'll emit in it. - instrBuilder->handleOperation(regName, false); - - vector sig; - Parameter param; - param.name = "in"; - param.typeName = from; - param.flags = Param_Exact; - sig.push_back(param); - - string code = inf.to.nativeName + " out = convertI" + inf.name.substr(1) + "(exec, in);\n"; - code += "$$ = out;\n"; - instrBuilder->handleImpl("", code, codeLine, 0, to, sig); - } -} - -Type TypeTable::resolveType(const string& type) -{ - if (types.find(type) != types.end()) - return types[type]; - else - out.issueError("Unknown type:" + type); - - // return something in nonvoid function - Type t; - return t; -} - -vector TypeTable::resolveSignature(const StringList& in) -{ - vector sig; - for (unsigned c = 0; c < in.size(); ++c) - sig.push_back(resolveType(in[c])); - - return sig; -} - -ConversionInfo TypeTable::immConv(const Type& from, const Type& to) -{ - return imConversions[from.name][to.name]; -} - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/generator/types.h b/kjs/bytecode/generator/types.h deleted file mode 100644 index 92c74edd..00000000 --- a/kjs/bytecode/generator/types.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * A utilitity for building various tables and specializations for the - * KJS Frostbyte bytecode - * - * Copyright (C) 2007, 2008 Maks Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef TYPES_H -#define TYPES_H - -#include -#include -#include - -#include "codeprinter.h" - -using std::ostream; -using std::vector; -using std::map; - -enum TypeFlags { - Type_HaveImm = 1, - Type_HaveReg = 2, - Type_Align8 = 4 -}; - -enum ConvFlags { - Conv_NoFlags, - Conv_HaveReg = 2, - Conv_Checked = 4, - Conv_MayThrow = 8 -}; - -struct Type -{ - string name; - string nativeName; - - unsigned flags; - - // may not be the same as Type_Align8 in the feature.. - bool alignTo8() const { - return (flags & Type_Align8) == Type_Align8; - } - - bool hasReg() const { - return (flags & Type_HaveReg) == Type_HaveReg; - } - - bool hasImm() const { - return (flags & Type_HaveImm) == Type_HaveImm; - } - - // field in store cells to access for this type - string field() const { - return ((flags & Type_Align8) ? "wide" : "narrow") + - std::string(".") + name + "Val"; - } - - bool operator==(const Type& other) const { - return name == other.name; - } -}; - -struct ConversionInfo -{ - string name; - string impl; - int cost; // for w/in tile for immediate, for external for reg - unsigned flags; - Type from; - Type to; - int codeLine; - - ConversionInfo(): cost(0), flags(Conv_NoFlags) - {} //Can be called for trivial conversion -}; - -class TableBuilder; - -// This class is responsible for managing types & conversions, and generating -// conversion-selection routines. -class TypeTable -{ -public: - TypeTable(TableBuilder* instrBuilder, CodePrinter& out); - - void generateCode(); - - void handleType(const string& type, const string& nativeName, unsigned flags); - void handleConversion(const string& runtimeRoutine, int codeLine, - unsigned flags, const string& from, const string& to, - int tileCost, int registerCost); - - // issues error if there is a problem.. - vector resolveSignature(const StringList& in); - Type resolveType(const string& type); - - ConversionInfo immConv(const Type& from, const Type& to); -private: - TableBuilder* instrBuilder; - CodePrinter& out; - void printConversionInfo(Array& array, map >& table, bool reg); - - void printConversionRoutine(const ConversionInfo& conversion); - - map types; - StringList typeNames; - - StringList conversionNames; - vector imConversionList; - vector rgConversionList; - - map > imConversions; - map > rgConversions; -}; - -#endif -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/machine.cpp.in b/kjs/bytecode/machine.cpp.in deleted file mode 100644 index a434c363..00000000 --- a/kjs/bytecode/machine.cpp.in +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Main VM dispatch loop and related routines for KJS/Frostbyte - * This file is part of the KDE libraries - * Copyright (C) 2008 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "completion.h" -#include "ExecState.h" -#include "value.h" - -#include "nodes.h" -#include "opcodes.h" -#include "LocalStorage.h" -#include "bytecode/opargs.h" -#include "bytecode/machine.h" -#include "scriptfunction.h" -#include "internal.h" // for printInfo -#include "ustring.h" -#include "debugger.h" - -#include - -// maximum global call stack size. Protects against accidental or -// malicious infinite recursions. Define to -1 if you want no limit. -#if PLATFORM(DARWIN) -// Given OS X stack sizes we run out of stack at about 350 levels. -// If we improve our stack usage, we can bump this number. -#define KJS_MAX_STACK 100 -#else -#define KJS_MAX_STACK 1000 // ### set system specific -#endif - -namespace KJS { - -#if defined(__GNUC__) -#define USE_LABEL_VALS -#endif - -// We can either do jumps via switch or a GCC extension -#ifdef USE_LABEL_VALS - #define handler(X) l##X -#else - #define handler(X) case OpByteCode_##X -#endif - - -// #define COUNT_INSTRS - -// A little profiling aid -- counts the # of dynamic instances of each instruction. -#ifdef COUNT_INSTRS - -static unsigned instrCounts[OpByteCode_NumValues]; - -struct InstrCountPrinter -{ - ~InstrCountPrinter() { - for (int c = 0; c < OpByteCode_NumValues; ++c) { - printf("%9d %s\n", instrCounts[c], OpByteCodeVals[c]); - } - } -}; - -static InstrCountPrinter dumpCounts; -#endif - -// ### Need to consolidate this w/things remaining in nodes.cpp somehow. -static void substitute(UString &string, const UString &substring) -{ - int position = string.find("%s"); - assert(position != -1); - UString newString = string.substr(0, position); - newString.append(substring); - newString.append(string.substr(position + 2)); - string = newString; -} - -NEVER_INLINE void throwUndefinedVariableError(ExecState* exec, const Identifier& ident) -{ - UString msg = "Can't find variable: %s"; - substitute(msg, ident.ustring()); - throwError(exec, ReferenceError, msg); -} - -static JSValue* typeStringForValue(JSValue* v) -{ - switch (v->type()) { - case UndefinedType: - return jsString("undefined"); - case NullType: - return jsString("object"); - case BooleanType: - return jsString("boolean"); - case NumberType: - return jsString("number"); - case StringType: - return jsString("string"); - default: - if (v->isObject()) { - // Return "undefined" for objects that should be treated - // as null when doing comparisons. - if (static_cast(v)->masqueradeAsUndefined()) - return jsString("undefined"); - else if (static_cast(v)->isFunctionType()) - return jsString("function"); - } - - return jsString("object"); - } -} - -template -ALWAYS_INLINE void lookupScopeAndFetch(ExecState* exec, Identifier* varName, JSValue*& scopeOut, JSValue*& valOut) -{ - const ScopeChain& chain = exec->scopeChain(); - ScopeChainIterator iter = chain.begin(); - ScopeChainIterator end = chain.end(); - - // we must always have something in the scope chain - assert(iter != end); - - JSObject *scopeObj = *iter; - if (trySkipOne && !scopeObj->isLocalInjected()) { - // Unless eval introduced new variables dynamically, - // we know this isn't in the top scope - ++iter; - } - - PropertySlot slot; - do { - scopeObj = *iter; - ++iter; - if (scopeObj->getPropertySlot(exec, *varName, slot)) { - if (!replaceActivations) { - scopeOut = scopeObj; - } else { - // Common case: we found it in global object -- no need to check - // if it's an activation - if (iter == end || !scopeObj->isActivation()) - scopeOut = scopeObj; - else - scopeOut = exec->dynamicInterpreter()->globalObject(); - } - valOut = slot.getValue(exec, scopeObj, *varName); - return; - } - } while (iter != end); - - scopeOut = scopeObj; - valOut = jsUndefined(); - if (errorOut) { - throwUndefinedVariableError(exec, *varName); - } -} - -static int depth; - -NEVER_INLINE JSValue* handleStackOverflow(ExecState* exec) { - depth -= 11; //Give the debugger some room.. - JSValue *ret = throwError(exec, RangeError, "Maximum call stack size exceeded."); - depth += 10; //Put it back.. - return ret; -} - -enum Dir { Enter, Exit }; - -NEVER_INLINE void changeDebugContext(Dir d, ExecState* exec, Node* n) { - FunctionBodyNode* body = static_cast(n); - Debugger* dbg = exec->dynamicInterpreter()->debugger(); - List args; - FunctionImp* fn = 0; - - // Find the activation that contains arguments, fn - const ScopeChain& chain = exec->scopeChain(); - for (ScopeChainIterator iter = chain.begin(); iter != chain.end(); ++iter) { - JSObject* scopeObj = *iter; - - if (scopeObj->isActivation()) { - ActivationImp* act = static_cast(scopeObj); - args = act->passedInArguments(); - fn = static_cast(act->function()); - break; - } - } - - if (d == Enter) - dbg->enterContext(exec, body->sourceId(), body->firstLine(), fn, args); - else - dbg->exitContext(exec, body->sourceId(), body->lastLine(), fn); -} - -class ForInState: public JSObject { -public: - PropertyNameArray* array; - int pos; - - ForInState() { - array = new PropertyNameArray; - pos = 0; - } - - ~ForInState() { - delete array; - } -}; - -struct DepthCleanup -{ - ~DepthCleanup() { --depth; } -}; - - -ALWAYS_INLINE_INTO JSValue* -Machine::runBlock(ExecState* exec, const CodeBlock& codeBlock, ExecState* parentExec) { - -#ifdef USE_LABEL_VALS - // Jump table, if needed - @generate -#endif - - ++depth; - if (depth > KJS_MAX_STACK) - return handleStackOverflow(exec); - - DepthCleanup dc; - - const unsigned char* base = codeBlock.data(); - const unsigned char* pc = base; - List workList; - LocalStorageEntry* localStore = exec->localStorage(); - exec->setMachineRegisters(base, &pc, &localStore); - JSObject* globalObject = exec->dynamicInterpreter()->globalObject(); - - while (true) { - begin: -#ifdef COUNT_INSTRS - OpByteCode opCodeLog = *reinterpret_cast(pc); - ++instrCounts[opCodeLog]; -#endif - @generate - } -} - -} - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; hl c++; diff --git a/kjs/bytecode/machine.h b/kjs/bytecode/machine.h deleted file mode 100644 index e8fd7376..00000000 --- a/kjs/bytecode/machine.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Main VM dispatch loop and related routines for KJS/Frostbyte - * This file is part of the KDE libraries - * Copyright (C) 2008 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef KJS_MACHINE_H -#define KJS_MACHINE_H - -#include "completion.h" -#include "ExecState.h" -#include "value.h" - -#include "nodes.h" -#include "opcodes.h" - -namespace KJS { - -class Machine { -public: - static JSValue* runBlock(ExecState* exec, const CodeBlock& block, ExecState* parentExec = 0); -}; - -} - -#endif -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; hl c++; diff --git a/kjs/bytecode/opargs.h b/kjs/bytecode/opargs.h deleted file mode 100644 index eb64ada8..00000000 --- a/kjs/bytecode/opargs.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Opcode argument data structures KJS/Frostbyte - * This file is part of the KDE libraries - * Copyright (C) 2008 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#ifndef OP_ARGS_H -#define OP_ARGS_H - -#include "opcodes.h" - -namespace KJS { - -class Node; -class RegDescriptor; - -// The NarrowArg and WideArg unions correspond to the encoding of -// 4- and 8-byte arguments in the bytecode. -// Note that the union field names should correspond to codes.def types --- -// type foo will be accessed as fooVal - -union NarrowArg -{ - bool boolVal; - int32_t int32Val; - Addr addrVal; - Register regVal; - unsigned char asBytes[4]; -}; - -union WideArg -{ - JSValue* valueVal; - Identifier* identVal; - UString* stringVal; - double numberVal; - Node* nodeVal; - const char* cstrVal; - unsigned char asBytes[8]; -}; - -// This describes where result of evaluating an expression, or an argument -// to a function, is stored. If immediate is true, it is included directly inside -// the structure. Otherwise, it's passed by the register number specified in -// ownedReg->reg() -// Note: there is a difference between values stored in registers, and register names. -// The former have immediate = false, and some type such as OpType_Bool; the latter have -// immediate = true, and type = OpType_reg. -struct OpValue -{ - bool immediate; - OpType type; - RefPtr ownedReg; // Register the lifetime of which we reserve, including the register # - union { - NarrowArg narrow; - WideArg wide; - } value; - - OpValue(); - - // A few helpers for making immediate values... These are actually inside CompileState.h - // due to them touching the ownedTemp; - - static void initImm(OpValue* val, OpType type) { - val->immediate = true; - val->type = type; - } - - // A placeholder address value, will be patched up later - static OpValue* dummyAddr(); - - static OpValue immInt32(int32_t in); - static OpValue immNumber(double in); - static OpValue immValue(JSValue* in); - static OpValue immBool(bool in); - static OpValue immString(UString* in); - static OpValue immIdent(Identifier* in); - static OpValue immNode(Node* in); - static OpValue immCStr(const char* in); - static OpValue immAddr(Addr in); -}; - -} - -#endif - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/bytecode/opcodes.cpp.in b/kjs/bytecode/opcodes.cpp.in deleted file mode 100644 index b90787a7..00000000 --- a/kjs/bytecode/opcodes.cpp.in +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Opcode data structure and selection routines for KJS/Frostbyte - * This file is part of the KDE libraries - * Copyright (C) 2008 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "opcodes.h" -#include "CompileState.h" -#include - -#if PLATFORM(SOLARIS_OS) -using std::printf; -#endif - -// Enable this to dump instruction selection instructions. -// #define TRACE_INSTR_SELECT - -namespace KJS { - -const int Cost_NoConversion = -100000; // small enough so that adding actual costs doesn't - // make it positive -const int Cost_Checked = -2; - -@generate - -// Note: costOut will be negative if no conversion is possible -ConvOp computeCast(const OpValue* in, OpType outType, bool outImmediate, int& costOut, bool exact) -{ - bool inImmediate = (in->immediate != 0); - OpType inType = in->type; - - // Obviously, we can't make a register result into an an immediate value - if (outImmediate && !inImmediate) { - costOut = Cost_NoConversion; - return Conv_NoConversion; - } - - if (exact) { - if (inType == outType) { - costOut = 0; - // We want to prefer these even if they require a spill, - // (since the implementation is more immediate), - // but we do want a slight cost to the spill so we don't do it for no good reason - if (!outImmediate && inImmediate) - costOut = 1; - return Conv_NoOp; - } - - // as a special case, int32 -> number conversion is always safe; otherwise - // exact matching can't happen - if (inType != OpType_int32 || outType != OpType_number) { - costOut = Cost_NoConversion; - return Conv_NoConversion; - } - } - - // In general, if we're converting immediate to register, we first try to - // convert the immediate value to the right type. That will either produce - // a fresh immediate value that be spilled directly, or may even emit the - // conversion for us. If it produces the value --- and hence the basic conversion --- - // all we have to do is spill it. - - // Look up in the table.. - const ConvInfo* inf = getConversionInfo(inImmediate, inType, outType); - - if (inf->costCode == Cost_Checked) { - ASSERT(inImmediate); - ASSERT(outType == OpType_value); - ASSERT(inType == OpType_int32 || inType == OpType_number); - - // Where a conversion is checked, we may not be able to get an - // immediate<->immediate match, so we may have to generate - // a special immediate<->register conversion. - - bool inlineOK = inType == OpType_int32 ? JSImmediate::from(in->value.narrow.int32Val) : - JSImmediate::from(in->value.wide.numberVal); - - if (outImmediate) { - // immediate -> immediate.. - if (inlineOK) - costOut = 0; - else - costOut = Cost_NoConversion; - return inf->routine; - } else { - // immediate -> register. - - // If we know inline op OK, we follow the normal path below which adds in a spill cost. - // Otherwise we emit the op directly. - if (!inlineOK) { - // cost about the same as register int32-> number conversion - costOut = getConversionInfo(false, OpType_int32, OpType_value)->costCode; - return inType == OpType_int32 ? Conv_I_R_Int32_Value : - Conv_I_R_Number_Value; - } - } - } - - costOut = inf->costCode; - // Add some cost for a spill... - if (inImmediate && !outImmediate) - costOut += 25; - - return inf->routine; -} - -void emitConversion(CompileState* comp, bool outImm, - ConvOp convType, OpValue* original, OpValue& out) -{ - if (emitImmediateConversion(convType, original, out)) { - // Emit a spill if needed, after the value gets converted.. - if (!outImm && original->immediate) { // Need both checks since NoOp might get here.. - OpValue spillVal, spillRef; - - comp->requestTemporary(out.type, &spillVal, &spillRef); - CodeGen::emitRegStore(comp, &spillRef, &out); - out = spillVal; - } - - return; - } - - if (emitSimpleRegisterConversion(comp, convType, original, out)) - return; - - switch (convType) { - case Conv_I_R_Int32_Value: - CodeGen::emitOp(comp, Op_RInt32_Value_NonImm, &out, original); - break; - - case Conv_I_R_Number_Value: - CodeGen::emitOp(comp, Op_RNum_Value_NonImm, &out, original); - break; - - default: - fprintf(stderr, "Unable to emit conversion:%s, in:%c, out:%c\n", ConvOpVals[convType], - original->immediate ? 'I' : 'R', outImm ? 'I' : 'R'); - CRASH(); - }; -} - -static inline void setArg(unsigned char* argBase, const OpValue& val) -{ - if (val.immediate) { - if (opTypeIsAlign8[val.type]) { - *reinterpret_cast(argBase) = val.value.wide; - } else { - *reinterpret_cast(argBase) = val.value.narrow; - } - } else { - // For arguments, we actually output the byte offset. - reinterpret_cast(argBase)->regVal = val.ownedReg->reg() * sizeof(LocalStorageEntry); - } -} - -static void emitArg(unsigned char* basePtr, const Op* opDescr, int pos, const OpValue& val) -{ - ASSERT(opDescr->immediateParams[pos] == val.immediate); - ASSERT(opDescr->paramTypes[pos] == val.type); - - unsigned char* argBase = basePtr + opDescr->paramOffsets[pos]; - setArg(argBase, val); -} - -void CodeGen::emitConvertTo(CompileState* comp, OpValue* in, - OpType outType, OpValue* out) -{ - int cost; - ConvOp op = computeCast(in, outType, in->immediate, cost, false); - ASSERT(cost >= 0); - emitConversion(comp, in->immediate, op, in, *out); -} - -void CodeGen::emitRegStore(CompileState* comp, OpValue* regNum, OpValue* val) -{ - ASSERT(regNum->immediate && regNum->type == OpType_reg); - - switch (val->type) { - case OpType_bool: - emitOp(comp, Op_RegPutBool, 0, regNum, val); - break; - case OpType_int32: - emitOp(comp, Op_RegPutInt32, 0, regNum, val); - break; - case OpType_value: - emitOp(comp, Op_RegPutValue, 0, regNum, val); - break; - case OpType_number: - emitOp(comp, Op_RegPutNumber, 0, regNum, val); - break; - default: - fprintf(stderr, "Don't know how to store type to register:%s\n", OpTypeVals[val->type]); - CRASH(); - } -} - -static void printType(const char* prefix, int pos, OpValue* v) { - fprintf(stderr, "%s%d:%s/imm:%d\n", prefix, pos, OpTypeVals[v->type], v->immediate); -} - -Addr CodeGen::emitOp(CompileState* comp, OpName baseInstr, - OpValue* retOut, OpValue* a0, OpValue* a1, OpValue* a2, OpValue* a3) -{ - CodeBlock& block = comp->codeBlock(); - const Op* const* cands = opSpecializations[baseInstr]; - - const Op* cheapest = 0; - int cheapestCost = 0; - ConvOp cheapestConvOps[4] = {Conv_NoConversion, Conv_NoConversion, Conv_NoConversion}; - - // Here, we assume that all methods either return or not. - OpType retType = opRetTypes[baseInstr]; - OpValue retVal, retReg; - if (retType != OpType_void) { - // Add in a register argument.. For now just a dummy #; - // will fill in w/appropriate type later - ASSERT(!a3); - retReg.immediate = true; - retReg.type = OpType_reg; - a3 = a2; - a2 = a1; - a1 = a0; - a0 = &retReg; - } else { - ASSERT(!retOut); - } - - OpValue* args[4] = {a0, a1, a2, a3}; - - int numArgs = 0; - while (numArgs < 4 && args[numArgs]) - ++numArgs; - -#ifdef TRACE_INSTR_SELECT - fprintf(stderr, "\n\nTrying to select variant for:%s\n", OpNameVals[baseInstr]); - for (int i = 0; i < numArgs; ++i) - printType("\targ", i, args[i]); -#endif - - // First, scan through, and determine the cheapest non-align variant. - // We can't select whether to align or not, since we may have to emit - // cast ops, which could change where we are. - for (int c = 0; cands[c]; ++c) { - const Op* cand = cands[c]; - ASSERT(cand->baseInstr == baseInstr); - ASSERT(cand->numParams == numArgs); - - if (cand->padAlign) - continue; - - int costs[4]; - ConvOp convOps[4]; - - int totalCost = cand->cost; - for (int i = 0; i < numArgs; ++i) { - convOps[i] = computeCast(args[i], cand->paramTypes[i], - cand->immediateParams[i], costs[i], cand->exactParams[i]); - - totalCost += costs[i]; - } - -#ifdef TRACE_INSTR_SELECT - fprintf(stderr, "Candidate:%s, totalCost:%d, variant cost:%d\n", OpByteCodeVals[cand->opCode], totalCost, cand->cost); - for (int i = 0; i < numArgs; ++i) { - fprintf(stderr, "\tconv:%s, costs:%d\n", ConvOpVals[convOps[i]], costs[i]); - } -#endif - - if (totalCost < 0) // Cost_NoConversion in the sum... - continue; - - if (totalCost < cheapestCost || !cheapest) { - cheapest = cand; - cheapestCost = totalCost; - cheapestConvOps[0] = convOps[0]; - cheapestConvOps[1] = convOps[1]; - cheapestConvOps[2] = convOps[2]; - cheapestConvOps[3] = convOps[3]; - } - } - - if (!cheapest) { - fprintf(stderr, "Unable to find an acceptable conversion for:%s\n", OpNameVals[baseInstr]); - for (int i = 0; i < numArgs; ++i) - printType("\ta", i, args[i]); - CRASH(); // Should never happen! - } - - if (cheapest->endsBB) - comp->localFlushAll(block); - - // Now that we have a candidate, actually grab a register of the proper return type. - retType = cheapest->retType; - if (retType != OpType_void) { - comp->requestTemporary(retType, &retVal, &retReg); - - // Set return value, if needed - if (retOut) - *retOut = retVal; - } - - OpValue c[4]; // converted version - - for (int i = 0; i < numArgs; ++i) - emitConversion(comp, cheapest->immediateParams[i], cheapestConvOps[i], args[i], c[i]); - - // Now figure out if we need to do align.. We need it if the PC is 8-aligned, since - // the instr will mess that up, and the instruction need it.. - if (cheapest->hasPadVariant && ((block.size() % 8) == 0)) { - // The padded variant of the instruction always preceeds the unpadded one.. - cheapest = &opsForOpCodes[cheapest->opCode - 1]; - } - - // Phewww. Now we can actually write out stuff. - size_t pos = block.size(); - block.resize(pos + cheapest->length); - unsigned char* basePtr = block.data() + pos; - - // Write out the opcode.. - *reinterpret_cast(basePtr) = cheapest->opCode; - - // ... and the args, as needed. - for (int i = 0; i < numArgs; ++i) { - emitArg(basePtr, cheapest, i, c[i]); - } - - return basePtr - block.data(); -} - -Addr CodeGen::nextPC(CompileState* comp) -{ - CodeBlock& block = comp->codeBlock(); - comp->localFlushAll(block); - return block.size(); -} - -void CodeGen::patchOpArgument(CodeBlock& block, Addr baseAddr, int pos, OpValue& newVal) -{ - OpByteCode* base = reinterpret_cast(block.data() + baseAddr); - const Op& variant = opsForOpCodes[*base]; - - // We only permit patching immediate arguments for now.. - ASSERT(variant.immediateParams[pos] && newVal.immediate); - ASSERT(variant.paramTypes[pos] == newVal.type); - ASSERT(pos < variant.numParams); - - unsigned char* argBase = reinterpret_cast(base) + variant.paramOffsets[pos]; - setArg(argBase, newVal); -} - -void CodeGen::patchJumpToNext(CompileState* comp, Addr op, int argNum) -{ - OpValue destAddr = OpValue::immAddr(nextPC(comp)); - patchOpArgument(comp->codeBlock(), op, argNum, destAddr); -} - -static void dumpParam(CodeBlock& block, size_t offset, OpType type, bool wasImm) -{ - switch (type) { - case OpType_bool: - if (reinterpret_cast(block.data() + offset)->boolVal) - std::fprintf(stderr, "true"); - else - std::fprintf(stderr, "false"); - break; - case OpType_int32: - std::fprintf(stderr, "%d", reinterpret_cast(block.data() + offset)->int32Val); - break; - case OpType_value: - // Immediate value -- should go through JSImmediate stuff.. - std::fprintf(stderr, "", reinterpret_cast(block.data() + offset)->valueVal->toString(0).ascii()); - break; - case OpType_ident: - std::fprintf(stderr, "%s", reinterpret_cast(block.data() + offset)->identVal->ustring().ascii()); - break; - case OpType_string: - std::fprintf(stderr, "\"%s\"", reinterpret_cast(block.data() + offset)->stringVal->ascii()); - break; - case OpType_number: - std::fprintf(stderr, "%f", reinterpret_cast(block.data() + offset)->numberVal); - break; - case OpType_addr: - std::fprintf(stderr, "A%08x", reinterpret_cast(block.data() + offset)->addrVal); - break; - case OpType_reg: - std::fprintf(stderr, "r%lu", reinterpret_cast(block.data() + offset)->regVal / (wasImm ? - 1lu : sizeof(LocalStorageEntry))); - break; - case OpType_node: - std::fprintf(stderr,"N%p", (void*)(reinterpret_cast(block.data() + offset)->nodeVal)); - break; - case OpType_cstr: - std::fprintf(stderr, "c\"%s\"", reinterpret_cast(block.data() + offset)->cstrVal); - break; - default: - std::fprintf(stderr, "???:%s", OpTypeVals[type]); - }; - std::fprintf(stderr, " "); -} - -void CodeGen::disassembleBlock(CodeBlock& block) -{ - size_t pc = 0; - while (pc < block.size()) { - OpByteCode opCode = *reinterpret_cast(block.data() + pc); - const Op& opDescr = opsForOpCodes[opCode]; - - std::fprintf(stderr, "%08lx %s ", pc, OpNameVals[opDescr.baseInstr]); - for (int p = 0; p < opDescr.numParams; ++p) { - dumpParam(block, pc + opDescr.paramOffsets[p], - opDescr.immediateParams[p] ? opDescr.paramTypes[p] : OpType_reg, opDescr.immediateParams[p]); - } - - std::fprintf(stderr, "\t\t// %s\n", OpByteCodeVals[opCode]); - pc += opDescr.length; - } -} - -} //namespace KJS -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; hl c++; diff --git a/kjs/bytecode/opcodes.h.in b/kjs/bytecode/opcodes.h.in deleted file mode 100644 index 99e71ae2..00000000 --- a/kjs/bytecode/opcodes.h.in +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Opcode data structure and selection routines for KJS/Frostbyte - * This file is part of the KDE libraries - * Copyright (C) 2008 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include - // be nice to our fruity overlords and their silly assert-unfriendly environment - -#include -#include -#include "value.h" -#include "identifier.h" -#include "ExecState.h" - -#ifndef OPCODES_H -#define OPCODES_H - -namespace KJS { - -typedef unsigned Register; -class CompileState; - -@generate - -/** - There are 2 levels at which instructions exist. First of all, there is - an actual operation name, represent by the OpName enum. This is something like - Op_IfJump. For each one of these, we have multiple bytecode instructions, such as - OpByteCode_IfJump_Ibool_Iaddr and OpByteCode_IfJump_Rbool_Iaddr, with their - names given in the OpByteCode_ enum. - - For each of these bytecode codes, there is an entry in the opsForOpCodes - array, which provides an Op structure, which describes which parameters - go where, and so on. The opSpecializations array lets one look up - all these structures relevant for each OpName, so one can select - the specific operation for each conceptual instruction. - - Besides parameter variants, there is also variation based on padding, with - some bytecodes skipping 4 extra bytes after the opcode to make things 8-aligned. - Those bytecodes are always 1 below their unaligned version -*/ - -struct Op { - OpName baseInstr; - OpByteCode opCode; - int cost; - - int numParams; - OpType paramTypes[4]; - bool immediateParams[4]; - bool exactParams[4]; // if true, we should not perform any - // (non-injective) conversions for the given parameter - - OpType retType; // type of this specialization - - int length; // Length of instruction, including opcode + args - - // This contains offsets of arguments, starting from before the instruction - int paramOffsets[4]; - - // If this is true, this version of the instruction has an - // extra word inserted after the opcode, for alignment reasons. - bool padAlign; - - // If this is true, this version has both padded and unpadded flavors - bool hasPadVariant; - - // If this is true, this instruction performs a jump, and hence - // should flush per-BB info - bool endsBB; -}; - -// The main array of Op instances, mapped by OpByteCode -extern const Op opsForOpCodes[]; - -// Lists all the specialized versions of each Op class, mapped by OpName, -// 0 terminated. -extern const Op* const* const opSpecializations[]; - -// Describes whether the type is align8 or not. -extern const bool opTypeIsAlign8[]; - -struct OpValue; - -typedef Vector CodeBlock; - -class CodeGen { -public: - // All of these emit the instruction of given type, and return its base. - // If retVal isn't 0, the return value will be placed there - static Addr emitOp(CompileState* comp, OpName baseInstr, - OpValue* retOut = 0, OpValue* a0 = 0, OpValue* a1 = 0, - OpValue* a2 = 0, OpValue* a3 = 0); - - static void emitConvertTo(CompileState* comp, OpValue* in, - OpType outType, OpValue* out); - - // Emits a register store of appropriate type - static void emitRegStore(CompileState* comp, OpValue* regNum, OpValue* val); - - static void patchOpArgument(CodeBlock& block, Addr base, int pos, OpValue& newVal); - - // Patches op at address 'op' to jump to next instr. - static void patchJumpToNext(CompileState* comp, Addr op, int argNum); - - // This requests the address of next instruction, for use in control flow, and - // designates a basic block boundary, flushing everything BB-dependent; - static Addr nextPC(CompileState* comp); - - static void disassembleBlock(CodeBlock& block); - -}; - - -} //namespace KJS - -#endif - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; hl c++; - diff --git a/kjs/collector.cpp b/kjs/collector.cpp deleted file mode 100644 index cdd8421d..00000000 --- a/kjs/collector.cpp +++ /dev/null @@ -1,938 +0,0 @@ -// -*- mode: c++; c-basic-offset: 4 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Computer, Inc. - * Copyright (C) 2007 Eric Seidel - * Copyright (C) 2007 Maksim Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "collector.h" -#include - -#include -#include -#include "internal.h" -#include "list.h" -#include "value.h" - -#include -#include -#include - -#if PLATFORM(DARWIN) - -#include -#include -#include -#include -#include -#include - -#elif PLATFORM(WIN_OS) || COMPILER(CYGWIN) - -#include -#include - -#elif PLATFORM(UNIX) - -#include -#include -#include -#include //krazy:exclude=includes (yes, it's duplicate, but in a different #if branch) -#include - -#if PLATFORM(SOLARIS_OS) -#include -#include -using std::memset; -#endif - -#if HAVE(PTHREAD_NP_H) -#include -#endif - -#endif - -#define DEBUG_COLLECTOR 0 - -#if HAVE(VALGRIND_MEMCHECK_H) && !defined(NDEBUG) - #include - #if defined(VALGRIND_MAKE_MEM_DEFINED) - #define VG_DEFINED(p) VALGRIND_MAKE_MEM_DEFINED(&p, sizeof(void*)) - #else - #define VG_DEFINED(p) - #endif -#else - #define VG_DEFINED(p) -#endif - - -using std::max; - -namespace KJS { - -// tunable parameters -const size_t SPARE_EMPTY_BLOCKS = 2; -const size_t MIN_ARRAY_SIZE = 14; -const size_t GROWTH_FACTOR = 2; -const size_t LOW_WATER_FACTOR = 4; -const size_t ALLOCATIONS_PER_COLLECTION = 4000; - - -// A whee bit like a WTF::Vector, but perfectly POD, so can be used in global context -// w/o worries. -struct BlockList { - CollectorBlock** m_data; - size_t m_used; - size_t m_capacity; - - CollectorBlock* operator[](size_t pos) { - return m_data[pos]; - } - - size_t used() const { - return m_used; - } - - void append(CollectorBlock* block) { - if (m_used == m_capacity) { - static const size_t maxNumBlocks = ULONG_MAX / sizeof(CollectorBlock*) / GROWTH_FACTOR; - if (m_capacity > maxNumBlocks) - CRASH(); - m_capacity = max(MIN_ARRAY_SIZE, m_capacity * GROWTH_FACTOR); - m_data = static_cast(fastRealloc(m_data, m_capacity * sizeof(CollectorBlock *))); - } - m_data[m_used] = block; - ++m_used; - } - - void remove(CollectorBlock* block) { - size_t c; - for (c = 0; c < m_used; ++c) - if (m_data[c] == block) - break; - - if (c == m_used) - return; - - // Move things up, and shrink.. - --m_used; - for (; c < m_used; ++c) - m_data[c] = m_data[c+1]; - } -}; - -struct CollectorHeap { - // This contains the list of both normal and oversize blocks - BlockList allBlocks; - - // Just the normal blocks - BlockList blocks; - - size_t firstBlockWithPossibleSpace; - - // The oversize block handling is a bit tricky, since we do not wish to slow down - // the usual paths. Hence, we do the following: - // 1) We set the marked bits for any extension portions of the block. - // this way the stack GC doesn't have to do anything special if a pointer - // happens to go that way. - // 2) We keep track of an allBlocks list to help the stack GC tests things. - // - // The oversize heap itself represents blocks as follows: - // 1) free: marked = false, allocd = false, trailer = false, zeroIfFree = 0 - // 2) alloc'd, head: marked = depends, allocd = true, trailer = false, zeroIfFree is uncertain - // 3) alloc'd, trailer: marked = true (see above), allocd = true, trailer = true, zeroIfFree is uncertain - // - // For now, we don't use a freelist, so performance may be quite bad if - // this is used heavily; this is just because the cell does not have - // back and forward links; which we need since we can pick a non-first cell - // ### actually, it may be possible to shuffle the list. Not now, though - BlockList oversizeBlocks; - - size_t numLiveObjects; - size_t numLiveObjectsAtLastCollect; - size_t extraCost; -}; - -static CollectorHeap heap; - -bool Collector::memoryFull = false; - -static CollectorBlock* allocateBlock() -{ -#if PLATFORM(DARWIN) - vm_address_t address = 0; - vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT); -#elif PLATFORM(WIN_OS) || COMPILER(CYGWIN) - // windows virtual address granularity is naturally 64k - LPVOID address = VirtualAlloc(NULL, BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); -#elif HAVE(POSIX_MEMALIGN) - void* address; - posix_memalign(address, BLOCK_SIZE, BLOCK_SIZE); - memset(reinterpret_cast(address), 0, BLOCK_SIZE); -#else - static size_t pagesize = getpagesize(); - - size_t extra = 0; - if (BLOCK_SIZE > pagesize) - extra = BLOCK_SIZE - pagesize; - - void* mmapResult = mmap(NULL, BLOCK_SIZE + extra, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); - uintptr_t address = reinterpret_cast(mmapResult); - - size_t adjust = 0; - if ((address & BLOCK_OFFSET_MASK) != 0) - adjust = BLOCK_SIZE - (address & BLOCK_OFFSET_MASK); - - if (adjust > 0) - munmap(reinterpret_cast(address), adjust); - - if (adjust < extra) - munmap(reinterpret_cast(address + adjust + BLOCK_SIZE), extra - adjust); - - address += adjust; - memset(reinterpret_cast(address), 0, BLOCK_SIZE); -#endif - CollectorBlock* ptr = reinterpret_cast(address); - heap.allBlocks.append(ptr); // Register with the heap - return ptr; -} - -static void freeBlock(CollectorBlock* block) -{ - // Unregister the block first - heap.allBlocks.remove(block); - -#if PLATFORM(DARWIN) - vm_deallocate(current_task(), reinterpret_cast(block), BLOCK_SIZE); -#elif PLATFORM(WIN_OS) || COMPILER(CYGWIN) - VirtualFree(block, BLOCK_SIZE, MEM_RELEASE); -#elif HAVE(POSIX_MEMALIGN) - free(block); -#else - munmap(block, BLOCK_SIZE); -#endif -} - -void Collector::recordExtraCost(size_t cost) -{ - // Our frequency of garbage collection tries to balance memory use against speed - // by collecting based on the number of newly created values. However, for values - // that hold on to a great deal of memory that's not in the form of other JS values, - // that is not good enough - in some cases a lot of those objects can pile up and - // use crazy amounts of memory without a GC happening. So we track these extra - // memory costs. Only unusually large objects are noted, and we only keep track - // of this extra cost until the next GC. In garbage collected languages, most values - // are either very short lived temporaries, or have extremely long lifetimes. So - // if a large value survives one garbage collection, there is not much point to - // collecting more frequently as long as it stays alive. - - heap.extraCost += cost; -} - -static void* allocOversize(size_t s) -{ - size_t cellsNeeded = (s + (CELL_SIZE - 1)) / CELL_SIZE; - - // printf("allocOversize, size:%d, cellsNeeded:%d\n", s, cellsNeeded); - - // We are not oversize enough to deal with things close to 64K in size - assert(cellsNeeded <= CELLS_PER_BLOCK); - - // Look through the blocks, see if one has enough, and where. - CollectorBlock* sufficientBlock = 0; - size_t startOffset = -1; - for (size_t b = 0; b < heap.oversizeBlocks.used() && !sufficientBlock; ++b) { - CollectorBlock* candidate = heap.oversizeBlocks[b]; - if (cellsNeeded <= CELLS_PER_BLOCK - candidate->usedCells) { - // Well, there is a chance we will fit.. Let's see if we can find a batch long enough.. - for (size_t i = 0; i < CELLS_PER_BLOCK; i++) { - if (i % 32 == 0 && candidate->allocd.bits[i/32] == 0xFFFFFFFF) { - // Can skip this and 31 other cells - i += 31; - continue; - } - - if (candidate->allocd.get(i)) - continue; - - // This cell is free -- are there enough free cells after it? - startOffset = i; - size_t last = i + cellsNeeded - 1; - - if (last >= CELLS_PER_BLOCK) // No way it will fit - break; - - ++i; - while (i <= last && !candidate->allocd.get(i)) - ++i; - - // Did we get through enough? - if (i == last + 1) { - sufficientBlock = candidate; - break; - } - - // Not enough room -- and the current entry has a non-zero zeroIfFree, - // so we should go on at i + 1 on next iteration - - } // for each cell per block. - } // if enough room in block - } // for each block - - if (!sufficientBlock) { - sufficientBlock = allocateBlock(); - startOffset = 0; - heap.oversizeBlocks.append(sufficientBlock); - } - - sufficientBlock->usedCells += cellsNeeded; - - // Set proper bits for trailers and the head - sufficientBlock->allocd.set(startOffset); - for (size_t t = startOffset + 1; t < startOffset + cellsNeeded; ++t) { - sufficientBlock->trailer.set(t); - sufficientBlock->marked.set(t); - sufficientBlock->allocd.set(t); - } - - void* result = sufficientBlock->cells + startOffset; - memset(result, 0, s); - heap.numLiveObjects = heap.numLiveObjects + 1; - return result; -} - -void* Collector::allocate(size_t s) -{ - assert(JSLock::lockCount() > 0); - - // collect if needed - size_t numLiveObjects = heap.numLiveObjects; - size_t numLiveObjectsAtLastCollect = heap.numLiveObjectsAtLastCollect; - size_t numNewObjects = numLiveObjects - numLiveObjectsAtLastCollect; - size_t newCost = numNewObjects + heap.extraCost; - - if (newCost >= ALLOCATIONS_PER_COLLECTION && newCost >= numLiveObjectsAtLastCollect) { - collect(); - numLiveObjects = heap.numLiveObjects; - } - - if (s > CELL_SIZE) { - return allocOversize(s); - } - - // slab allocator - - size_t usedBlocks = heap.blocks.used(); - - size_t i = heap.firstBlockWithPossibleSpace; - CollectorBlock *targetBlock; - size_t targetBlockUsedCells; - if (i != usedBlocks) { - targetBlock = heap.blocks[i]; - targetBlockUsedCells = targetBlock->usedCells; - assert(targetBlockUsedCells <= CELLS_PER_BLOCK); - while (targetBlockUsedCells == CELLS_PER_BLOCK) { - if (++i == usedBlocks) - goto allocateNewBlock; - targetBlock = heap.blocks[i]; - targetBlockUsedCells = targetBlock->usedCells; - assert(targetBlockUsedCells <= CELLS_PER_BLOCK); - } - heap.firstBlockWithPossibleSpace = i; - } else { -allocateNewBlock: - // didn't find one, need to allocate a new block - targetBlock = allocateBlock(); - targetBlock->freeList = targetBlock->cells; - targetBlockUsedCells = 0; - heap.blocks.append(targetBlock); - heap.firstBlockWithPossibleSpace = usedBlocks; // previous usedBlocks -> new one's index - } - - // find a free spot in the block and detach it from the free list - CollectorCell *newCell = targetBlock->freeList; - - // "next" field is a byte offset -- 0 means next cell, so a zeroed block is already initialized - // could avoid the casts by using a cell offset, but this avoids a relatively-slow multiply - targetBlock->freeList = reinterpret_cast(reinterpret_cast(newCell + 1) + newCell->u.freeCell.next); - - targetBlock->usedCells = targetBlockUsedCells + 1; - heap.numLiveObjects = numLiveObjects + 1; - - return newCell; -} - -#if USE(MULTIPLE_THREADS) - -struct Collector::Thread { - Thread(pthread_t pthread, mach_port_t mthread) : posixThread(pthread), machThread(mthread) {} - Thread *next; - pthread_t posixThread; - mach_port_t machThread; -}; - -pthread_key_t registeredThreadKey; -pthread_once_t registeredThreadKeyOnce = PTHREAD_ONCE_INIT; - -Collector::Thread *registeredThreads; - -static void destroyRegisteredThread(void *data) -{ - Collector::Thread *thread = (Collector::Thread *)data; - - if (registeredThreads == thread) { - registeredThreads = registeredThreads->next; - } else { - Collector::Thread *last = registeredThreads; - for (Collector::Thread *t = registeredThreads->next; t != NULL; t = t->next) { - if (t == thread) { - last->next = t->next; - break; - } - last = t; - } - } - - delete thread; -} - -static void initializeRegisteredThreadKey() -{ - pthread_key_create(®isteredThreadKey, destroyRegisteredThread); -} - -void Collector::registerThread() -{ - pthread_once(®isteredThreadKeyOnce, initializeRegisteredThreadKey); - - if (!pthread_getspecific(registeredThreadKey)) { - pthread_t pthread = pthread_self(); - WTF::fastMallocRegisterThread(pthread); - Collector::Thread *thread = new Collector::Thread(pthread, pthread_mach_thread_np(pthread)); - thread->next = registeredThreads; - registeredThreads = thread; - pthread_setspecific(registeredThreadKey, thread); - } -} - -#endif - -#define IS_POINTER_ALIGNED(p) (((intptr_t)(p) & (sizeof(char *) - 1)) == 0) - -// cell size needs to be a power of two for this to be valid -#define IS_CELL_ALIGNED(p) (((intptr_t)(p) & CELL_MASK) == 0) - -void Collector::markStackObjectsConservatively(void *start, void *end) -{ - if (start > end) { - void *tmp = start; - start = end; - end = tmp; - } - - assert(((char *)end - (char *)start) < 0x1000000); - assert(IS_POINTER_ALIGNED(start)); - assert(IS_POINTER_ALIGNED(end)); - - char **p = (char **)start; - char **e = (char **)end; - - // We use allBlocks here since we want to mark oversize cells as well. - // Their trailers will have the mark bit set already, to avoid trouble. - size_t usedBlocks = heap.allBlocks.used(); - CollectorBlock **blocks = heap.allBlocks.m_data; - - const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1); - - while (p != e) { - char *x = *p++; - VG_DEFINED(x); - if (IS_CELL_ALIGNED(x) && x) { - uintptr_t offset = reinterpret_cast(x) & BLOCK_OFFSET_MASK; - CollectorBlock* blockAddr = reinterpret_cast(x - offset); - for (size_t block = 0; block < usedBlocks; block++) { - if ((blocks[block] == blockAddr) && (offset <= lastCellOffset)) { - if (((CollectorCell *)x)->u.freeCell.zeroIfFree != 0) { - JSCell *imp = reinterpret_cast(x); - if (!imp->marked()) - imp->mark(); - } - } // if valid block - } // for each block - } // if cell-aligned - } // for each pointer -} - -static inline void* currentThreadStackBase() -{ -#if PLATFORM(DARWIN) - pthread_t thread = pthread_self(); - void *stackBase = pthread_get_stackaddr_np(thread); -#elif (PLATFORM(WIN_OS) || COMPILER(CYGWIN)) - // tested with mingw32, mingw64, msvc2008, cygwin - NT_TIB *pTib = (NT_TIB*)NtCurrentTeb(); - void *stackBase = (void *)pTib->StackBase; -#elif PLATFORM(SOLARIS_OS) - stack_t s; - thr_stksegment(&s); - return s.ss_sp; - // NOTREACHED - void *stackBase = 0; -#elif PLATFORM(UNIX) - static void *stackBase = 0; - static pthread_t stackThread; - pthread_t thread = pthread_self(); - if (stackBase == 0 || thread != stackThread) { - pthread_attr_t sattr; -#if HAVE(PTHREAD_NP_H) || defined(__NetBSD__) - // e.g. on FreeBSD 5.4, neundorf@kde.org - // also on NetBSD 3 and 4, raphael.langerhorst@kdemail.net - // HIGHLY RECCOMENDED by manpage to allocate storage, avoids - // crashing in JS immediately in FreeBSD. - pthread_attr_init(&sattr); - pthread_attr_get_np(thread, &sattr); -#else - // FIXME: this function is non-portable; other POSIX systems may have different np alternatives - pthread_getattr_np(thread, &sattr); -#endif // picking the _np function to use --- Linux or BSD - - size_t stackSize; - pthread_attr_getstack(&sattr, &stackBase, &stackSize); - stackBase = (char *)stackBase + stackSize; // a matter of interpretation, apparently... - pthread_attr_destroy(&sattr); - assert(stackBase); - stackThread = thread; - } -#else -#error Need a way to get the stack base on this platform -#endif - return stackBase; -} - - -void Collector::markCurrentThreadConservatively() -{ - // setjmp forces volatile registers onto the stack - jmp_buf registers; -#if COMPILER(MSVC) -#pragma warning(push) -#pragma warning(disable: 4611) -#endif - setjmp(registers); -#if COMPILER(MSVC) -#pragma warning(pop) -#endif - - void* dummy; - void* stackPointer = &dummy; - void* stackBase = currentThreadStackBase(); - - markStackObjectsConservatively(stackPointer, stackBase); -} - -#if USE(MULTIPLE_THREADS) - -typedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit - -void Collector::markOtherThreadConservatively(Thread *thread) -{ - thread_suspend(thread->machThread); - -#if PLATFORM(X86) - i386_thread_state_t regs; - unsigned user_count = sizeof(regs)/sizeof(int); - thread_state_flavor_t flavor = i386_THREAD_STATE; -#elif PLATFORM(X86_64) - x86_thread_state64_t regs; - unsigned user_count = x86_THREAD_STATE64_COUNT; - thread_state_flavor_t flavor = x86_THREAD_STATE64; -#elif PLATFORM(PPC) - ppc_thread_state_t regs; - unsigned user_count = PPC_THREAD_STATE_COUNT; - thread_state_flavor_t flavor = PPC_THREAD_STATE; -#elif PLATFORM(PPC64) - ppc_thread_state64_t regs; - unsigned user_count = PPC_THREAD_STATE64_COUNT; - thread_state_flavor_t flavor = PPC_THREAD_STATE64; -#else -#error Unknown Architecture -#endif - // get the thread register state - thread_get_state(thread->machThread, flavor, (thread_state_t)®s, &user_count); - - // scan the registers - markStackObjectsConservatively((void *)®s, (void *)((char *)®s + (user_count * sizeof(usword_t)))); - - // scan the stack -#if PLATFORM(X86) && __DARWIN_UNIX03 - markStackObjectsConservatively((void *)regs.__esp, pthread_get_stackaddr_np(thread->posixThread)); -#elif PLATFORM(X86) - markStackObjectsConservatively((void *)regs.esp, pthread_get_stackaddr_np(thread->posixThread)); -#elif PLATFORM(X86_64) && __DARWIN_UNIX03 - markStackObjectsConservatively((void *)regs.__rsp, pthread_get_stackaddr_np(thread->posixThread)); -#elif PLATFORM(X86_64) - markStackObjectsConservatively((void *)regs.rsp, pthread_get_stackaddr_np(thread->posixThread)); -#elif (PLATFORM(PPC) || PLATFORM(PPC64)) && __DARWIN_UNIX03 - markStackObjectsConservatively((void *)regs.__r1, pthread_get_stackaddr_np(thread->posixThread)); -#elif PLATFORM(PPC) || PLATFORM(PPC64) - markStackObjectsConservatively((void *)regs.r1, pthread_get_stackaddr_np(thread->posixThread)); -#else -#error Unknown Architecture -#endif - - thread_resume(thread->machThread); -} - -#endif - -void Collector::markStackObjectsConservatively() -{ - markCurrentThreadConservatively(); - -#if USE(MULTIPLE_THREADS) - for (Thread *thread = registeredThreads; thread != NULL; thread = thread->next) { - if (thread->posixThread != pthread_self()) { - markOtherThreadConservatively(thread); - } - } -#endif -} - -typedef HashCountedSet ProtectCounts; - -static ProtectCounts& protectedValues() -{ - static ProtectCounts pv; - return pv; -} - -void Collector::protect(JSValue *k) -{ - assert(k); - assert(JSLock::lockCount() > 0); - - if (JSImmediate::isImmediate(k)) - return; - - protectedValues().add(k->asCell()); -} - -void Collector::unprotect(JSValue *k) -{ - assert(k); - assert(JSLock::lockCount() > 0); - - if (JSImmediate::isImmediate(k)) - return; - - protectedValues().remove(k->asCell()); -} - -void Collector::markProtectedObjects() -{ - ProtectCounts& pv = protectedValues(); - ProtectCounts::iterator end = pv.end(); - for (ProtectCounts::iterator it = pv.begin(); it != end; ++it) { - JSCell *val = it->first; - if (!val->marked()) - val->mark(); - } -} - -bool Collector::collect() -{ - assert(JSLock::lockCount() > 0); - -#if USE(MULTIPLE_THREADS) - bool currentThreadIsMainThread = pthread_main_np(); -#else - bool currentThreadIsMainThread = true; -#endif - - Interpreter::markSourceCachedObjects(); - - if (Interpreter::s_hook) { - Interpreter* scr = Interpreter::s_hook; - do { - scr->mark(currentThreadIsMainThread); - scr = scr->next; - } while (scr != Interpreter::s_hook); - } - - // MARK: first mark all referenced objects recursively starting out from the set of root objects - - markStackObjectsConservatively(); - markProtectedObjects(); - List::markProtectedLists(); -#if USE(MULTIPLE_THREADS) - if (!currentThreadIsMainThread) - markMainThreadOnlyObjects(); -#endif - - // SWEEP: delete everything with a zero refcount (garbage) and unmark everything else - - // Note: if a cell has zeroIfFree == 0, it is either free, - // or in the middle of being constructed and has not yet - // had its vtable filled. Hence, such cells should not be cleaned up - - size_t emptyBlocks = 0; - size_t numLiveObjects = heap.numLiveObjects; - - for (size_t block = 0; block < heap.blocks.used(); block++) { - CollectorBlock *curBlock = heap.blocks[block]; - - size_t usedCells = curBlock->usedCells; - CollectorCell *freeList = curBlock->freeList; - - if (usedCells == CELLS_PER_BLOCK) { - // special case with a block where all cells are used -- testing indicates this happens often - for (size_t i = 0; i < CELLS_PER_BLOCK; i++) { - CollectorCell *cell = curBlock->cells + i; - JSCell *imp = reinterpret_cast(cell); - if (!curBlock->marked.get(i) && currentThreadIsMainThread) { - // special case for allocated but uninitialized object - // (We don't need this check earlier because nothing prior this point assumes the object has a valid vptr.) - if (cell->u.freeCell.zeroIfFree == 0) - continue; - imp->~JSCell(); - --usedCells; - --numLiveObjects; - - // put cell on the free list - cell->u.freeCell.zeroIfFree = 0; - cell->u.freeCell.next = reinterpret_cast(freeList) - reinterpret_cast(cell + 1); - freeList = cell; - } - } - } else { - size_t minimumCellsToProcess = usedCells; - for (size_t i = 0; (i < minimumCellsToProcess) & (i < CELLS_PER_BLOCK); i++) { - CollectorCell *cell = curBlock->cells + i; - if (cell->u.freeCell.zeroIfFree == 0) { - ++minimumCellsToProcess; - } else { - JSCell *imp = reinterpret_cast(cell); - if (!curBlock->marked.get(i) && currentThreadIsMainThread) { - imp->~JSCell(); - --usedCells; - --numLiveObjects; - - // put cell on the free list - cell->u.freeCell.zeroIfFree = 0; - cell->u.freeCell.next = reinterpret_cast(freeList) - reinterpret_cast(cell + 1); - freeList = cell; - } - } - } - } - - curBlock->marked.clearAll(); - curBlock->usedCells = usedCells; - curBlock->freeList = freeList; - - if (usedCells == 0) { - emptyBlocks++; - if (emptyBlocks > SPARE_EMPTY_BLOCKS) { -#if !DEBUG_COLLECTOR - freeBlock(curBlock); -#endif - // swap with the last block so we compact as we go - heap.blocks.m_data[block] = heap.blocks[heap.blocks.used() - 1]; - heap.blocks.m_used--; - block--; // Don't move forward a step in this case - } - } - } - - if (heap.numLiveObjects != numLiveObjects) - heap.firstBlockWithPossibleSpace = 0; - - // Now sweep oversize blocks. - emptyBlocks = 0; - for (size_t ob = 0; ob < heap.oversizeBlocks.used(); ++ob) { - CollectorBlock* curBlock = heap.oversizeBlocks[ob]; - CollectorCell *freeList = curBlock->freeList; - size_t usedCells = curBlock->usedCells; - - // Go through the cells - for (size_t i = 0; i < CELLS_PER_BLOCK; i++) { - if (i % 32 == 0 && curBlock->allocd.bits[i/32] == 0) { - // Nothing used around here, skip this and 31 next cells - i += 31; - continue; - } - - CollectorCell *cell = curBlock->cells + i; - if (cell->u.freeCell.zeroIfFree == 0) - continue; - - if (!curBlock->allocd.get(i)) - continue; - - JSCell *imp = reinterpret_cast(cell); - - // Live and trailer cells will all have the mark set, - // so we only have to collect with it clear -- - // and we already took care of those that are - // already free (or being initialized) above - if (!curBlock->marked.get(i)) { - // Free this block... - imp->~JSCell(); - --numLiveObjects; - --usedCells; - - // Mark the block and the trailers as available - cell->u.freeCell.zeroIfFree = 0; - curBlock->allocd.clear(i); - - ++i; // Go to the potential trailer.. - while (curBlock->trailer.get(i) && i < CELLS_PER_BLOCK) { - --usedCells; - curBlock->allocd.clear(i); - curBlock->trailer.clear(i); - curBlock->marked.clear (i); - curBlock->cells[i].u.freeCell.zeroIfFree = 0; - ++i; - } - --i; // Last item we processed. - } else { - // If this is not a trailer cell, clear the mark - if (!curBlock->trailer.get(i)) - curBlock->marked.clear(i); - } - } // each cell - curBlock->usedCells = usedCells; - curBlock->freeList = freeList; - if (usedCells == 0) { - emptyBlocks++; - if (emptyBlocks > SPARE_EMPTY_BLOCKS) { - freeBlock(curBlock); - - // swap with the last block so we compact as we go - heap.oversizeBlocks.m_data[ob] = heap.oversizeBlocks[heap.oversizeBlocks.used() - 1]; - heap.oversizeBlocks.m_used--; - ob--; // Don't move forward a step in this case - } - } - } // each oversize block - - bool deleted = heap.numLiveObjects != numLiveObjects; - - heap.numLiveObjects = numLiveObjects; - heap.numLiveObjectsAtLastCollect = numLiveObjects; - heap.extraCost = 0; - - bool newMemoryFull = (numLiveObjects >= KJS_MEM_LIMIT); - if (newMemoryFull && newMemoryFull != memoryFull) - reportOutOfMemoryToAllInterpreters(); - memoryFull = newMemoryFull; - - return deleted; -} - -size_t Collector::size() -{ - return heap.numLiveObjects; -} - -#ifdef KJS_DEBUG_MEM -void Collector::finalCheck() -{ -} -#endif - -size_t Collector::numInterpreters() -{ - size_t count = 0; - if (Interpreter::s_hook) { - Interpreter* scr = Interpreter::s_hook; - do { - ++count; - scr = scr->next; - } while (scr != Interpreter::s_hook); - } - return count; -} - -size_t Collector::numProtectedObjects() -{ - return protectedValues().size(); -} - -static const char *typeName(JSCell *val) -{ - const char *name = "???"; - switch (val->type()) { - case UnspecifiedType: - break; - case UndefinedType: - name = "undefined"; - break; - case NullType: - name = "null"; - break; - case BooleanType: - name = "boolean"; - break; - case StringType: - name = "string"; - break; - case NumberType: - name = "number"; - break; - case ObjectType: { - const ClassInfo *info = static_cast(val)->classInfo(); - name = info ? info->className : "Object"; - break; - } - case GetterSetterType: - name = "gettersetter"; - break; - } - return name; -} - -HashCountedSet* Collector::rootObjectTypeCounts() -{ - HashCountedSet* counts = new HashCountedSet; - - ProtectCounts& pv = protectedValues(); - ProtectCounts::iterator end = pv.end(); - for (ProtectCounts::iterator it = pv.begin(); it != end; ++it) - counts->add(typeName(it->first)); - - return counts; -} - -void Collector::reportOutOfMemoryToAllInterpreters() -{ - if (!Interpreter::s_hook) - return; - - Interpreter* interpreter = Interpreter::s_hook; - do { - ExecState* exec = interpreter->execState(); - - exec->setException(Error::create(exec, GeneralError, "Out of memory")); - - interpreter = interpreter->next; - } while(interpreter != Interpreter::s_hook); -} - -} // namespace KJS diff --git a/kjs/collector.h b/kjs/collector.h deleted file mode 100644 index 9f8b0d7f..00000000 --- a/kjs/collector.h +++ /dev/null @@ -1,192 +0,0 @@ -// -*- 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) - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2007 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef KJSCOLLECTOR_H_ -#define KJSCOLLECTOR_H_ - -#include -#include -#include - -#define KJS_MEM_LIMIT 500000 - -namespace KJS { - class JSCell; - class JSValue; - class CollectorBlock; - - /** - * @short Garbage collector. - */ - class KJS_EXPORT Collector { - // disallow direct construction/destruction - Collector(); - public: - /** - * Register an object with the collector. The following assumptions are - * made: - * @li the operator new() of the object class is overloaded. - * @li operator delete() has been overloaded as well and does not free - * the memory on its own. - * - * @param s Size of the memory to be registered. - * @return A pointer to the allocated memory. - */ - static void* allocate(size_t s); - /** - * Run the garbage collection. This involves calling the delete operator - * on each object and freeing the used memory. - */ - static bool collect(); - - static const size_t minExtraCostSize = 256; - - static void reportExtraMemoryCost(size_t cost); - - static size_t size(); - static bool isOutOfMemory() { return memoryFull; } - -#ifdef KJS_DEBUG_MEM - /** - * Check that nothing is left when the last interpreter gets deleted - */ - static void finalCheck(); -#endif - - static void protect(JSValue *); - static void unprotect(JSValue *); - - static size_t numInterpreters(); - static size_t numProtectedObjects(); - static HashCountedSet* rootObjectTypeCounts(); - - class Thread; - static void registerThread(); - - static bool isCellMarked(const JSCell*); - static void markCell(JSCell*); - - private: - static const CollectorBlock* cellBlock(const JSCell*); - static CollectorBlock* cellBlock(JSCell*); - static size_t cellOffset(const JSCell*); - - static void recordExtraCost(size_t); - static void markProtectedObjects(); - static void markCurrentThreadConservatively(); - static void markOtherThreadConservatively(Thread*); - static void markStackObjectsConservatively(); - static void markStackObjectsConservatively(void *start, void *end); - - static bool memoryFull; - static void reportOutOfMemoryToAllInterpreters(); - }; - - // tunable parameters - template struct CellSize; - - // cell size needs to be a power of two for certain optimizations in collector.cpp - // below also assume it's divisible by 8, and that block size is divisible by it - template<> struct CellSize<4> { static const size_t m_value = 32; }; // 32-bit - template<> struct CellSize<8> { static const size_t m_value = 64; }; // 64-bit - const size_t BLOCK_SIZE = 16 * 4096; // 64k - - const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1; - const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK; - - const size_t CELL_SIZE = CellSize::m_value; - const size_t CELL_ARRAY_LENGTH = (CELL_SIZE / sizeof(double)); - const size_t CELL_MASK = CELL_SIZE - 1; - - // For each block, we can have at /most/ BLOCK_SIZE/CELL_SIZE entries. - // Sice the bitmap accordingly, don't try to be fancy - const size_t BITMAP_SIZE = (BLOCK_SIZE / CELL_SIZE + 7) / 8; - const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t); - - // In each block, we have 3 bitmaps (mark for all blocks, extension + allocd for oversize cell blocks), - // as well as an int and a pointer - const size_t BLOCK_METADATA_SIZE = 3 * 4 * BITMAP_WORDS + sizeof(uint32_t) + sizeof(void*); - const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - BLOCK_METADATA_SIZE) / CELL_SIZE; - - struct CollectorBitmap { - uint32_t bits[BITMAP_WORDS]; - bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); } - void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); } - void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); } - void clearAll() { std::memset(bits, 0, sizeof(bits)); } - }; - - struct CollectorCell { - union { - double memory[CELL_ARRAY_LENGTH]; - struct { - void* zeroIfFree; - ptrdiff_t next; - } freeCell; - } u; - }; - - class CollectorBlock { - public: - CollectorCell cells[CELLS_PER_BLOCK]; - uint32_t usedCells; - CollectorCell* freeList; - CollectorBitmap marked; - CollectorBitmap allocd; - CollectorBitmap trailer; - }; - - inline const CollectorBlock* Collector::cellBlock(const JSCell* cell) - { - return reinterpret_cast(reinterpret_cast(cell) & BLOCK_MASK); - } - - inline CollectorBlock* Collector::cellBlock(JSCell* cell) - { - return const_cast(cellBlock(const_cast(cell))); - } - - inline size_t Collector::cellOffset(const JSCell* cell) - { - return (reinterpret_cast(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE; - } - - inline bool Collector::isCellMarked(const JSCell* cell) - { - return cellBlock(cell)->marked.get(cellOffset(cell)); - } - - inline void Collector::markCell(JSCell* cell) - { - cellBlock(cell)->marked.set(cellOffset(cell)); - } - - inline void Collector::reportExtraMemoryCost(size_t cost) - { - if (cost > minExtraCostSize) - recordExtraCost(cost / (CELL_SIZE * 2)); - } -} - -#endif /* _KJSCOLLECTOR_H_ */ diff --git a/kjs/commonunicode.h b/kjs/commonunicode.h deleted file mode 100644 index ad14cff0..00000000 --- a/kjs/commonunicode.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2003 Apple Computer, Inc. - * Copyright (C) 2012 Bernd Buschinski (b.buschinski@googlemail.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef COMMONUNICODE_H_ -#define COMMONUNICODE_H_ - -namespace KJS { - namespace CommonUnicode { - - inline bool isLineTerminator(unsigned short c) - { - switch (c) { - case 0x000A: // LINE FEED - case 0x000D: // CARRIAGE RETURN - case 0x2028: // LINE SEPARATOR - case 0x2029: // PARAGRAPH SEPARATOR - return true; - default: - return false; - } - } - - inline bool isWhiteSpace(unsigned short c) - { - switch (c) { - case 0x0009: - case 0x000B: - case 0x000C: - // Unicode category Zs - case 0x0020: // SPACE - case 0x00A0: // NO-BREAK SPACE - case 0x1680: // OGHAM SPACE MARK - case 0x180E: // MONGOLIAN VOWEL SEPARATOR - case 0x2000: // EN QUAD - case 0x2001: // EM QUAD - case 0x2002: // EN SPACE - case 0x2003: // EM SPACE - case 0x2004: // THREE-PER-EM SPACE - case 0x2005: // FOUR-PER-EM SPACE - case 0x2006: // SIX-PER-EM SPACE - case 0x2007: // FIGURE SPACE - case 0x2008: // PUNCTUATION SPACE - case 0x2009: // THIN SPACE - case 0x200A: // HAIR SPACE - case 0x202F: // NARROW NO-BREAK SPACE - case 0x205F: // MEDIUM MATHEMATICAL SPACE - case 0x3000: // IDEOGRAPHIC SPACE - // Unicode Byte-Order-Mark, Ecmascript 5.1r6 - 7.2 - case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE, BOM - return true; - default: - return false; - } - } - - inline bool isStrWhiteSpace(unsigned short c) - { - return isWhiteSpace(c) || isLineTerminator(c); - } - - } //namespace CommonUnicode -} //namespace KJS - -#endif //COMMONUNICODE_H_ diff --git a/kjs/completion.h b/kjs/completion.h deleted file mode 100644 index 5dde3b1f..00000000 --- a/kjs/completion.h +++ /dev/null @@ -1,85 +0,0 @@ -// -*- 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) - * Copyright (C) 2003 Apple Computer, Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _KJS_COMPLETION_H_ -#define _KJS_COMPLETION_H_ - -#include "CommonIdentifiers.h" - -namespace KJS { - - typedef unsigned Addr; // ### should there be some separare types h? - - class Node; - class JSValue; - - /** - * Completion types. - */ - enum ComplType { Normal, Break, Continue, ReturnValue, Throw, Interrupted }; - - /** - * Completion objects are used to convey the return status and value - * from functions. - * - * See FunctionImp::execute() - * - * @see FunctionImp - * - * @short Handle for a Completion type. - */ - class KJS_EXPORT Completion { - public: - explicit Completion(ComplType c = Normal, JSValue *v = NULL, Addr t = 0 ) - : comp(c), val(v), tar(t) { } - - /** - * Returns the type of this completion. - */ - ComplType complType() const { return comp; } - - /** - * Returns the value of this completion if it is of type - * value-completion, 0 otherwise. - */ - JSValue *value() const { return val; } - - /** - * Returns the address a break or a continue statement targets - */ - Addr target() const { return tar; } - - /** - * Returns true if this is a value completion, false otherwise. - */ - bool isValueCompletion() const { return !!val; } - private: - ComplType comp; - JSValue *val; - Addr tar; - }; - -} - -#endif diff --git a/kjs/config-kjs.h.cmake b/kjs/config-kjs.h.cmake deleted file mode 100644 index f6445282..00000000 --- a/kjs/config-kjs.h.cmake +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2002 David Faure (faure@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "../config.h" -#cmakedefine HAVE_PTHREAD_ATTR_GET_NP 1 -#cmakedefine HAVE_PTHREAD_GETATTR_NP 1 -#cmakedefine HAVE_PCREPOSIX 1 -#cmakedefine HAVE_SYS_TIMEB_H 1 -#cmakedefine HAVE_FLOAT_H 1 -#cmakedefine HAVE_IEEEFP_H 1 -#cmakedefine HAVE_PTHREAD_NP_H 1 -#cmakedefine HAVE_MEMCHECK_H 1 -#cmakedefine HAVE_FUNC__FINITE 1 -#cmakedefine HAVE_FUNC_FINITE 1 -#cmakedefine HAVE_FUNC_ISINF 1 -#cmakedefine HAVE_FUNC_ISNAN 1 -#cmakedefine HAVE_FUNC_POSIX_MEMALIGN 1 - -/* Defined to 1 if you have a tm_gmtoff member in struct tm */ -#cmakedefine HAVE_TM_GMTOFF 1 diff --git a/kjs/context.h b/kjs/context.h deleted file mode 100644 index 6d7231cd..00000000 --- a/kjs/context.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/kjs/create_hash_table b/kjs/create_hash_table deleted file mode 100755 index 94f3e435..00000000 --- a/kjs/create_hash_table +++ /dev/null @@ -1,274 +0,0 @@ -#! /usr/bin/perl -w -# -# Static Hashtable Generator -# -# (c) 2000-2002 by Harri Porten and -# David Faure -# Modified (c) 2004 by Nikolas Zimmermann -# -# Part of the KJS library. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# - -use strict; - -my $file = $ARGV[0]; -shift; -my $findSize = 0; -my $includelookup = 0; -my $useNameSpace; - -# Use -s as second argument to make it try many hash sizes -if (defined($ARGV[0]) && $ARGV[0] eq "-s") { $findSize = 1; shift; } - -# Use -i as second argument to make it include "lookup.h" -if (defined($ARGV[0]) && $ARGV[0] eq "-i") { $includelookup = 1; shift; } - -# Use -n as second argument to make it use the third argument as namespace parameter ie. -n KDOM -if (defined($ARGV[0]) && $ARGV[0] eq "-n") { $useNameSpace = $ARGV[1]; shift; shift; } - -open(IN, $file) or die "No such file $file"; - -my @keys = (); -my @values = (); -my @attrs = (); -my @params = (); -my @hashes = (); -my @table = (); -my @links = (); - -my $inside = 0; -my $name; -my $size; -my $hashsize; -my $banner = 0; -sub calcTable(); -sub output(); -sub hashValue($); - -while () { - chop; - s/^\s*//g; - if (/^\#|^$/) { - # comment. do nothing - } elsif (/^\@begin/ && !$inside) { - if (/^\@begin\s*([:_\w]+)\s*(\d+)\s*$/) { - $inside = 1; - $name = $1; - $hashsize = $2; - } else { - printf STDERR "WARNING: \@begin without table name and hashsize, skipping $_\n"; - } - } elsif (/^\@end\s*$/ && $inside) { - - if($findSize) { - my $entriesnum=@keys; - print STDERR "Table: $name $entriesnum entries\n"; - for( my $i=3 ; $i<79 ; ++$i) { $hashsize=$i ; calcTable(); } - } else { - calcTable(); - } - - output(); - @keys = (); - @values = (); - @attrs = (); - @params = (); - @table = (); - @links = (); - @hashes = (); - $inside = 0; - } elsif (/^(\S+)\s*(\S+)\s*([\w\|]*)\s*(\w*)\s*$/ && $inside) { - my $key = $1; - my $val = $2; - my $att = $3; - my $param = $4; - push(@keys, $key); - push(@values, $val); - push(@hashes, hashValue($key)); - 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() { - $size = $hashsize; - my $collisions = 0; - my $maxdepth = 0; - my $i = 0; - foreach my $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++; - } - } - #print STDERR "table[$h] = $i\n"; - $table[$h] = $i; - $i++; - $maxdepth = $depth if ( $depth > $maxdepth); - } - - # Ensure table is big enough (in case of undef entries at the end) - if ( $#table+1 < $size ) { - $#table = $size-1; - } - #print STDERR "After loop: size=$size table=".($#table+1)."\n"; - - if ($findSize) { - my $emptycount = 0; - foreach my $entry (@table) { - $emptycount++ if (!defined($entry)); - } - print STDERR "Hashsize: $hashsize Total Size: $size Empty: $emptycount MaxDepth: $maxdepth Collisions: $collisions\n"; - } -# my $debugtable = 0; -# foreach my $entry (@table) { -# print STDERR "$debugtable " . (defined $entry ? $entry : ''); -# print STDERR " -> " . $links[$debugtable] if (defined($links[$debugtable])); -# print STDERR "\n"; -# $debugtable++; -# } -} - -sub leftShift($$) { - my ($value, $distance) = @_; - return (($value << $distance) & 0xFFFFFFFF); -} - -# Paul Hsieh's SuperFastHash -# http://www.azillionmonkeys.com/qed/hash.html -# Ported from UString.. -sub hashValue($) { - my @chars = split(/ */, $_[0]); - - # This hash is designed to work on 16-bit chunks at a time. But since the normal case - # (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they - # were 16-bit chunks, which should give matching results - - my $EXP2_32 = 4294967296; - - my $hash = 0x9e3779b9; - my $l = scalar @chars; #I wish this was in Ruby --- Maks - my $rem = $l & 1; - $l = $l >> 1; - - my $s = 0; - - # Main loop - for (; $l > 0; $l--) { - $hash += ord($chars[$s]); - my $tmp = leftShift(ord($chars[$s+1]), 11) ^ $hash; - $hash = (leftShift($hash, 16)% $EXP2_32) ^ $tmp; - $s += 2; - $hash += $hash >> 11; - $hash %= $EXP2_32; - } - - # Handle end case - if ($rem !=0) { - $hash += ord($chars[$s]); - $hash ^= (leftShift($hash, 11)% $EXP2_32); - $hash += $hash >> 17; - } - - # Force "avalanching" of final 127 bits - $hash ^= leftShift($hash, 3); - $hash += ($hash >> 5); - $hash = ($hash% $EXP2_32); - $hash ^= (leftShift($hash, 2)% $EXP2_32); - $hash += ($hash >> 15); - $hash = $hash% $EXP2_32; - $hash ^= (leftShift($hash, 10)% $EXP2_32); - - # this avoids ever returning a hash code of 0, since that is used to - # signal "hash not computed yet", using a value that is likely to be - # effectively the same as 0 when the low bits are masked - $hash = 0x80000000 if ($hash == 0); - - return $hash; -} - -sub output() { - if (!$banner) { - $banner = 1; - print "/* Automatically generated from $file using $0. DO NOT EDIT ! */\n"; - } - - my $nameEntries = "${name}Entries"; - $nameEntries =~ s/:/_/g; - - print "\n#include \"lookup.h\"\n" if ($includelookup); - if ($useNameSpace) { - print "\nnamespace ${useNameSpace}\n{\n"; - } else { - print "\nnamespace KJS {\n"; - } - print "\nstatic const struct KJS::HashEntry ".$nameEntries."[] = {\n"; - my $i = 0; - #print STDERR "writing out table with ".($#table+1)." entries\n"; - - if ($hashsize eq 0) { - # To make the hash table lookup code fast, we don't allow tables of size 0. - # That way it can do a modulo by the size without a special case to avoid division by 0. - print " \{ 0, 0, 0, 0, 0 \}\n"; - $hashsize = 1; - $size = 1; - } else { - foreach my $entry (@table) { - if (defined($entry)) { - my $key = $keys[$entry]; - print " \{ \"" . $key . "\""; - print ", " . $values[$entry]; - my $kjsattrs = $attrs[$entry]; - if ($kjsattrs ne "0") { - $kjsattrs =~ s/([^|]+)/KJS::$1/g; # DontDelete|Function -> KJS::DontDelete|KJS::Function - } - print ", " . $kjsattrs; - print ", " . $params[$entry]; - print ", "; - if (defined($links[$i])) { - print "&" . $nameEntries . "[" . $links[$i] . "]" . " \}"; - } else { - print "0 \}" - } - print "/* " . $hashes[$entry] . " */ "; - } else { - print " \{ 0, 0, 0, 0, 0 \}"; - } - print "," unless ($i == $size - 1); - print "\n"; - $i++; - } - } - print "};\n\n"; - print "const struct KJS::HashTable $name = "; - print "\{ 2, $size, ".$nameEntries.", $hashsize \};\n\n"; - print "} // namespace\n"; -} diff --git a/kjs/create_parser b/kjs/create_parser deleted file mode 100755 index 8e23fbc2..00000000 --- a/kjs/create_parser +++ /dev/null @@ -1,16 +0,0 @@ - -#!/bin/sh - -# -# A replacement for the make parser target until someone figures out -# how to do that in CMake. -# - -bison -d -p kjsyy grammar.y && mv grammar.tab.c grammar.cpp; -if test -f grammar.tab.h; -then -if cmp -s grammar.tab.h grammar.h; then rm -f grammar.tab.h; -else mv grammar.tab.h grammar.h; -fi -else :; -fi diff --git a/kjs/date_object.cpp b/kjs/date_object.cpp deleted file mode 100644 index 10424fac..00000000 --- a/kjs/date_object.cpp +++ /dev/null @@ -1,1491 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2004 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "date_object.h" -#include -#include "date_object.lut.h" -#include "internal.h" - -#if HAVE(ERRNO_H) -#include -#endif - -#if HAVE(SYS_PARAM_H) -#include -#endif - -#if HAVE(SYS_TIME_H) -#include -#endif - -#if HAVE(SYS_TIMEB_H) -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#if PLATFORM(SOLARIS_OS) -#include -#endif - -#include "error_object.h" -#include "operations.h" - -#if PLATFORM(MAC) -#include -#endif - -#if PLATFORM(WIN_OS) -#include -#define copysign(x, y) _copysign(x, y) -#define snprintf _snprintf -#if !COMPILER(GCC) -#define isfinite(x) _finite(x) -#ifndef strncasecmp -#define strncasecmp(x, y, z) strnicmp(x, y, z) -#endif -#endif -#endif - -#include "wtf/DisallowCType.h" -#include "wtf/ASCIICType.h" - -// GCC cstring uses these automatically, but not all implementations do. -using std::strlen; -using std::strcpy; -using std::strncpy; -using std::memset; -using std::memcpy; - -using namespace WTF; - - -inline int gmtoffset(const tm& t) -{ -#if PLATFORM(WIN_OS) - // Time is supposed to be in the current timezone. - // FIXME: Use undocumented _dstbias? - return -(_timezone / 60 - (t.tm_isdst > 0 ? 60 : 0 )) * 60; -#else -#ifdef HAVE_TM_GMTOFF - return t.tm_gmtoff; -#else - return - timezone; -#endif -#endif -} - -namespace KJS { - -/** - * @internal - * - * Class to implement all methods that are properties of the - * Date object - */ -class DateObjectFuncImp : public InternalFunctionImp { -public: - DateObjectFuncImp(ExecState *, FunctionPrototype *, int i, int len, const Identifier& ); - - virtual JSValue *callAsFunction(ExecState *, JSObject *thisObj, const List &args); - - enum { Parse, UTC, Now }; - -private: - int id; -}; - -// some constants -const double hoursPerDay = 24; -const double minutesPerHour = 60; -const double secondsPerMinute = 60; -const double msPerSecond = 1000; -const double msPerMinute = 60 * 1000; -const double msPerHour = 60 * 60 * 1000; -const double msPerDay = 24 * 60 * 60 * 1000; - -static const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; -static const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - -static double makeTime(tm *, double ms, bool utc); -static double parseDate(const UString &); -static double timeClip(double); -static void millisecondsToTM(double milli, bool utc, tm *t); - -#if PLATFORM(MAC) - -static CFDateFormatterStyle styleFromArgString(const UString& string, CFDateFormatterStyle defaultStyle) -{ - if (string == "short") - return kCFDateFormatterShortStyle; - if (string == "medium") - return kCFDateFormatterMediumStyle; - if (string == "long") - return kCFDateFormatterLongStyle; - if (string == "full") - return kCFDateFormatterFullStyle; - return defaultStyle; -} - -static UString formatLocaleDate(ExecState *exec, double time, bool includeDate, bool includeTime, const List &args) -{ - CFDateFormatterStyle dateStyle = (includeDate ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle); - CFDateFormatterStyle timeStyle = (includeTime ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle); - - bool useCustomFormat = false; - UString customFormatString; - - JSValue* arg0 = args[0]; - JSValue* arg1 = args[1]; - UString arg0String = arg0->toString(exec); - if (arg0String == "custom" && !arg1->isUndefined()) { - useCustomFormat = true; - customFormatString = arg1->toString(exec); - } else if (includeDate && includeTime && !arg1->isUndefined()) { - dateStyle = styleFromArgString(arg0String, dateStyle); - timeStyle = styleFromArgString(arg1->toString(exec), timeStyle); - } else if (includeDate && !arg0->isUndefined()) { - dateStyle = styleFromArgString(arg0String, dateStyle); - } else if (includeTime && !arg0->isUndefined()) { - timeStyle = styleFromArgString(arg0String, timeStyle); - } - - CFLocaleRef locale = CFLocaleCopyCurrent(); - CFDateFormatterRef formatter = CFDateFormatterCreate(0, locale, dateStyle, timeStyle); - CFRelease(locale); - - if (useCustomFormat) { - CFStringRef customFormatCFString = CFStringCreateWithCharacters(0, (UniChar *)customFormatString.data(), customFormatString.size()); - CFDateFormatterSetFormat(formatter, customFormatCFString); - CFRelease(customFormatCFString); - } - - CFStringRef string = CFDateFormatterCreateStringWithAbsoluteTime(0, formatter, time - kCFAbsoluteTimeIntervalSince1970); - - CFRelease(formatter); - - // We truncate the string returned from CFDateFormatter if it's absurdly long (> 200 characters). - // That's not great error handling, but it just won't happen so it doesn't matter. - UChar buffer[200]; - const size_t bufferLength = sizeof(buffer) / sizeof(buffer[0]); - size_t length = CFStringGetLength(string); - assert(length <= bufferLength); - if (length > bufferLength) - length = bufferLength; - CFStringGetCharacters(string, CFRangeMake(0, length), reinterpret_cast(buffer)); - - CFRelease(string); - - return UString(buffer, length); -} - -#endif // PLATFORM(MAC) - -static UString formatDate(const tm &t) -{ - char buffer[100]; - int len = snprintf(buffer, sizeof(buffer), "%s %s %02d %04d", - weekdayName[(t.tm_wday + 6) % 7], - monthName[t.tm_mon], t.tm_mday, t.tm_year + 1900); - return UString(buffer, len); -} - -static UString formatDateUTCVariant(const tm &t) -{ - char buffer[100]; - int len = snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d", - weekdayName[(t.tm_wday + 6) % 7], - t.tm_mday, monthName[t.tm_mon], t.tm_year + 1900); - return UString(buffer, len); -} - -static UString formatDateISOVariant(const tm &t, bool utc, double absoluteMS) -{ - char buffer[100]; - // YYYY-MM-DD - int len; - if (utc) { - len = snprintf(buffer, sizeof(buffer), "%04d-%02d-%02d", - t.tm_year + 1900, t.tm_mon+1, t.tm_mday); - } else { - int offset = gmtoffset(t); - tm t_fixed; - millisecondsToTM(absoluteMS - offset*1000, true, &t_fixed); - len = snprintf(buffer, sizeof(buffer), "%04d-%02d-%02d", - t_fixed.tm_year + 1900, t_fixed.tm_mon+1, t_fixed.tm_mday); - } - return UString(buffer, len); -} - -static UString formatTime(const tm &t, bool utc) -{ - char buffer[100]; - int len; - if (utc) { - // FIXME: why not on windows? -#if !PLATFORM(WIN_OS) - ASSERT(gmtoffset(t) == 0); -#endif - len = snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.tm_hour, t.tm_min, t.tm_sec); - } else { - int offset = abs(gmtoffset(t)); - len = snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d", - t.tm_hour, t.tm_min, t.tm_sec, - gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60); - } - return UString(buffer, len); -} - -static UString formatTimeISOVariant(const tm &t, bool utc, double absoluteMS, double ms) -{ - char buffer[100]; - // HH:mm:ss.sss - int len; - if (utc) { - len = snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%03d", - t.tm_hour, t.tm_min, t.tm_sec, int(ms)); - } else { - int offset = gmtoffset(t); - tm t_fixed; - millisecondsToTM(absoluteMS - offset*1000, true, &t_fixed); - len = snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%03d", - t_fixed.tm_hour, t_fixed.tm_min, t_fixed.tm_sec, int(ms)); - } - return UString(buffer, len); -} - -static int day(double t) -{ - return int(floor(t / msPerDay)); -} - -static double dayFromYear(int year) -{ - return 365.0 * (year - 1970) - + floor((year - 1969) / 4.0) - - floor((year - 1901) / 100.0) - + floor((year - 1601) / 400.0); -} - -// based on the rule for whether it's a leap year or not -static int daysInYear(int year) -{ - if (year % 4 != 0) - return 365; - if (year % 400 == 0) - return 366; - if (year % 100 == 0) - return 365; - return 366; -} - -// time value of the start of a year -static double timeFromYear(int year) -{ - return msPerDay * dayFromYear(year); -} - -// year determined by time value -static int yearFromTime(double t) -{ - // ### there must be an easier way - - // initial guess - int y = 1970 + int(t / (365.25 * msPerDay)); - - // adjustment - if (timeFromYear(y) > t) { - do - --y; - while (timeFromYear(y) > t); - } else { - while (timeFromYear(y + 1) < t) - ++y; - } - - return y; -} - -// 0: Sunday, 1: Monday, etc. -static int weekDay(double t) -{ - int wd = (day(t) + 4) % 7; - if (wd < 0) - wd += 7; - return wd; -} - -// Converts a list of arguments sent to a Date member function into milliseconds, updating -// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately. -// -// Format of member function: f([hour,] [min,] [sec,] [ms]) -static double setTimeFields(ExecState* exec, const List& args, int id, double ms, tm* t) -{ - assert(DateProtoFunc::SetSeconds - DateProtoFunc::SetMilliSeconds + 1 == 2); - assert(DateProtoFunc::SetMinutes - DateProtoFunc::SetMilliSeconds + 1 == 3); - assert(DateProtoFunc::SetHours - DateProtoFunc::SetMilliSeconds + 1 == 4); - - assert(id == DateProtoFunc::SetMilliSeconds || id == DateProtoFunc::SetSeconds || - id == DateProtoFunc::SetMinutes || id == DateProtoFunc::SetHours); - - int maxArgs = id - DateProtoFunc::SetMilliSeconds + 1; - double milliseconds = 0; - int idx = 0; - int numArgs = args.size(); - - // JS allows extra trailing arguments -- ignore them - if (numArgs > maxArgs) - numArgs = maxArgs; - - // hours - if (maxArgs >= 4 && idx < numArgs) { - t->tm_hour = 0; - milliseconds += args[idx++]->toInt32(exec) * msPerHour; - } - - // minutes - if (maxArgs >= 3 && idx < numArgs) { - t->tm_min = 0; - milliseconds += args[idx++]->toInt32(exec) * msPerMinute; - } - - // seconds - if (maxArgs >= 2 && idx < numArgs) { - t->tm_sec = 0; - milliseconds += args[idx++]->toInt32(exec) * msPerSecond; - } - - // milliseconds - if (idx < numArgs) { - milliseconds += roundValue(exec, args[idx]); - } else { - milliseconds += ms; - } - - return milliseconds; -} - -// Converts a list of arguments sent to a Date member function into years, months, and milliseconds, updating -// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately. -// -// Format of member function: f([years,] [months,] [days]) -static double setDateFields(ExecState* exec, const List& args, int id, double ms, tm* t) -{ - assert(DateProtoFunc::SetMonth - DateProtoFunc::SetDate + 1 == 2); - assert(DateProtoFunc::SetFullYear - DateProtoFunc::SetDate + 1 == 3); - - assert(id == DateProtoFunc::SetDate || id == DateProtoFunc::SetMonth || id == DateProtoFunc::SetFullYear); - - int maxArgs = id - DateProtoFunc::SetDate + 1; - int idx = 0; - int numArgs = args.size(); - - // JS allows extra trailing arguments -- ignore them - if (numArgs > maxArgs) - numArgs = maxArgs; - - // years - if (maxArgs >= 3 && idx < numArgs) - t->tm_year = args[idx++]->toInt32(exec) - 1900; - - // months - if (maxArgs >= 2 && idx < numArgs) - t->tm_mon = args[idx++]->toInt32(exec); - - // days - if (idx < numArgs) { - t->tm_mday = 0; - ms += args[idx]->toInt32(exec) * msPerDay; - } - - return ms; -} - -// ------------------------------ DateInstance ------------------------------ - -const ClassInfo DateInstance::info = {"Date", 0, 0, 0}; - -DateInstance::DateInstance(JSObject *proto) - : JSWrapperObject(proto) -{ -} - -JSObject* DateInstance::valueClone(Interpreter* targetCtx) const -{ - DateInstance* copy = new DateInstance(targetCtx->builtinDatePrototype()); - copy->setInternalValue(internalValue()); - return copy; -} - -bool DateInstance::getTime(tm &t, int &offset) const -{ - double milli = internalValue()->getNumber(); - if (isNaN(milli)) - return false; - - millisecondsToTM(milli, false, &t); - offset = gmtoffset(t); - return true; -} - -bool DateInstance::getUTCTime(tm &t) const -{ - double milli = internalValue()->getNumber(); - if (isNaN(milli)) - return false; - - millisecondsToTM(milli, true, &t); - return true; -} - -bool DateInstance::getTime(double &milli, int &offset) const -{ - milli = internalValue()->getNumber(); - if (isNaN(milli)) - return false; - - tm t; - millisecondsToTM(milli, false, &t); - offset = gmtoffset(t); - return true; -} - -bool DateInstance::getUTCTime(double &milli) const -{ - milli = internalValue()->getNumber(); - if (isNaN(milli)) - return false; - - return true; -} - -static inline bool isTime_tSigned() -{ - time_t minusOne = (time_t)(-1); - return minusOne < 0; -} - -static void millisecondsToTM(double milli, bool utc, tm *t) -{ - // check whether time value is outside time_t's usual range - // make the necessary transformations if necessary - static bool time_tIsSigned = isTime_tSigned(); -#if PLATFORM(WIN_OS) - static double time_tMin = 0; //on windows localtime/gmtime returns NULL for pre 1970 dates -#else - static double time_tMin = (time_tIsSigned ? - (double)(1ULL << (8 * sizeof(time_t) - 1)) : 0); -#endif - static double time_tMax = (time_tIsSigned ? (1ULL << (8 * sizeof(time_t) - 1)) - 1 : 2 * (double)(1ULL << (8 * sizeof(time_t) - 1)) - 1); - int realYearOffset = 0; - double milliOffset = 0.0; - double secs = floor(milli / msPerSecond); - - if (secs < time_tMin || secs > time_tMax) { - // ### ugly and probably not very precise - int realYear = yearFromTime(milli); - int base = daysInYear(realYear) == 365 ? 2001 : 2000; - milliOffset = timeFromYear(base) - timeFromYear(realYear); - milli += milliOffset; - realYearOffset = realYear - base; - } - - time_t tv = (time_t) floor(milli / msPerSecond); - - *t = *(utc ? gmtime(&tv) : localtime(&tv)); - // We had an out of range year. Restore the year (plus/minus offset - // found by calculating tm_year) and fix the week day calculation. - if (realYearOffset != 0) { - t->tm_year += realYearOffset; - milli -= milliOffset; - // Do our own weekday calculation. Use time zone offset to handle local time. - double m = milli; - if (!utc) - m += gmtoffset(*t) * msPerSecond; - t->tm_wday = weekDay(m); - } -} - -static bool isNaNorInf(double value) -{ - return isNaN(value) || isInf(value); -} - -// ------------------------------ DatePrototype ----------------------------- - -const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, &dateTable, 0}; - -/* Source for date_object.lut.h - We use a negative ID to denote the "UTC" variant. -@begin dateTable 61 - toString DateProtoFunc::ToString DontEnum|Function 0 - toUTCString -DateProtoFunc::ToUTCString DontEnum|Function 0 - toDateString DateProtoFunc::ToDateString DontEnum|Function 0 - toTimeString DateProtoFunc::ToTimeString DontEnum|Function 0 - toISOString DateProtoFunc::ToISOString DontEnum|Function 0 - toJSON DateProtoFunc::ToJSON DontEnum|Function 1 - toLocaleString DateProtoFunc::ToLocaleString DontEnum|Function 0 - toLocaleDateString DateProtoFunc::ToLocaleDateString DontEnum|Function 0 - toLocaleTimeString DateProtoFunc::ToLocaleTimeString DontEnum|Function 0 - valueOf DateProtoFunc::ValueOf DontEnum|Function 0 - getTime DateProtoFunc::GetTime DontEnum|Function 0 - getFullYear DateProtoFunc::GetFullYear DontEnum|Function 0 - getUTCFullYear -DateProtoFunc::GetFullYear DontEnum|Function 0 - toGMTString -DateProtoFunc::ToGMTString DontEnum|Function 0 - getMonth DateProtoFunc::GetMonth DontEnum|Function 0 - getUTCMonth -DateProtoFunc::GetMonth DontEnum|Function 0 - getDate DateProtoFunc::GetDate DontEnum|Function 0 - getUTCDate -DateProtoFunc::GetDate DontEnum|Function 0 - getDay DateProtoFunc::GetDay DontEnum|Function 0 - getUTCDay -DateProtoFunc::GetDay DontEnum|Function 0 - getHours DateProtoFunc::GetHours DontEnum|Function 0 - getUTCHours -DateProtoFunc::GetHours DontEnum|Function 0 - getMinutes DateProtoFunc::GetMinutes DontEnum|Function 0 - getUTCMinutes -DateProtoFunc::GetMinutes DontEnum|Function 0 - getSeconds DateProtoFunc::GetSeconds DontEnum|Function 0 - getUTCSeconds -DateProtoFunc::GetSeconds DontEnum|Function 0 - getMilliseconds DateProtoFunc::GetMilliSeconds DontEnum|Function 0 - getUTCMilliseconds -DateProtoFunc::GetMilliSeconds DontEnum|Function 0 - getTimezoneOffset DateProtoFunc::GetTimezoneOffset DontEnum|Function 0 - setTime DateProtoFunc::SetTime DontEnum|Function 1 - setMilliseconds DateProtoFunc::SetMilliSeconds DontEnum|Function 1 - setUTCMilliseconds -DateProtoFunc::SetMilliSeconds DontEnum|Function 1 - setSeconds DateProtoFunc::SetSeconds DontEnum|Function 2 - setUTCSeconds -DateProtoFunc::SetSeconds DontEnum|Function 2 - setMinutes DateProtoFunc::SetMinutes DontEnum|Function 3 - setUTCMinutes -DateProtoFunc::SetMinutes DontEnum|Function 3 - setHours DateProtoFunc::SetHours DontEnum|Function 4 - setUTCHours -DateProtoFunc::SetHours DontEnum|Function 4 - setDate DateProtoFunc::SetDate DontEnum|Function 1 - setUTCDate -DateProtoFunc::SetDate DontEnum|Function 1 - setMonth DateProtoFunc::SetMonth DontEnum|Function 2 - setUTCMonth -DateProtoFunc::SetMonth DontEnum|Function 2 - setFullYear DateProtoFunc::SetFullYear DontEnum|Function 3 - setUTCFullYear -DateProtoFunc::SetFullYear DontEnum|Function 3 - setYear DateProtoFunc::SetYear DontEnum|Function 1 - getYear DateProtoFunc::GetYear DontEnum|Function 0 -@end -*/ -// ECMA 15.9.4 - -DatePrototype::DatePrototype(ExecState *, ObjectPrototype *objectProto) - : DateInstance(objectProto) -{ - setInternalValue(jsNaN()); - // The constructor will be added later, after DateObjectImp has been built. -} - -bool DatePrototype::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) -{ - return getStaticFunctionSlot(exec, &dateTable, this, propertyName, slot); -} - -// ------------------------------ DateProtoFunc ----------------------------- - -DateProtoFunc::DateProtoFunc(ExecState *exec, int i, int len, const Identifier& name) - : InternalFunctionImp(static_cast(exec->lexicalInterpreter()->builtinFunctionPrototype()), name) - , id(abs(i)) - , utc(i < 0) - // We use a negative ID to denote the "UTC" variant. -{ - putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); -} - -JSValue *DateProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) -{ - if (id == ToJSON) { - JSValue* tv = thisObj->toPrimitive(exec, NumberType); - if (tv->isNumber()) { - double ms = tv->toNumber(exec); - if (isNaN(ms)) - return jsNull(); - } - - JSValue *toISO = thisObj->get(exec, exec->propertyNames().toISOString); - if (!toISO->implementsCall()) - return throwError(exec, TypeError, "toISOString is not callable"); - JSObject* toISOobj = toISO->toObject(exec); - if (!toISOobj) - return throwError(exec, TypeError, "toISOString is not callable"); - return toISOobj->call(exec, thisObj, List::empty()); - } - - if (!thisObj->inherits(&DateInstance::info)) - return throwError(exec, TypeError); - - DateInstance* thisDateObj = static_cast(thisObj); - - JSValue *result = 0; -#if !PLATFORM(MAC) - const int bufsize=100; - char timebuffer[bufsize]; - CString oldlocale = setlocale(LC_TIME, 0); - if (!oldlocale.size()) - oldlocale = setlocale(LC_ALL, 0); - // FIXME: Where's the code to set the locale back to oldlocale? -#endif - JSValue *v = thisDateObj->internalValue(); - double milli = v->toNumber(exec); - if (isNaN(milli)) { - switch (id) { - case ToString: - case ToDateString: - case ToTimeString: - case ToGMTString: - case ToUTCString: - case ToLocaleString: - case ToLocaleDateString: - case ToLocaleTimeString: - return jsString("Invalid Date", 12); - case ValueOf: - case GetTime: - case GetYear: - case GetFullYear: - case GetMonth: - case GetDate: - case GetDay: - case GetHours: - case GetMinutes: - case GetSeconds: - case GetMilliSeconds: - case GetTimezoneOffset: - case SetMilliSeconds: - case SetSeconds: - case SetMinutes: - case SetHours: - case SetDate: - case SetMonth: - case SetFullYear: - return jsNaN(); - case ToISOString: - return throwError(exec, RangeError, "Invalid Date"); - } - } - - if (id == SetTime) { - double milli = roundValue(exec, args[0]); - result = jsNumber(timeClip(milli)); - thisDateObj->setInternalValue(result); - return result; - } - - double secs = floor(milli / msPerSecond); - double ms = milli - secs * msPerSecond; - - tm t; - millisecondsToTM(milli, utc, &t); - - switch (id) { - case ToString: - return jsString(formatDate(t).append(' ').append(formatTime(t, utc))); - - case ToDateString: - return jsString(formatDate(t)); - - case ToTimeString: - return jsString(formatTime(t, utc)); - - case ToGMTString: - case ToUTCString: - return jsString(formatDateUTCVariant(t).append(' ').append(formatTime(t, utc))); - case ToISOString: - return jsString(formatDateISOVariant(t, utc, milli).append('T').append(formatTimeISOVariant(t, utc, milli, ms)).append('Z')); - -#if PLATFORM(MAC) - case ToLocaleString: - return jsString(formatLocaleDate(exec, secs, true, true, args)); - - case ToLocaleDateString: - return jsString(formatLocaleDate(exec, secs, true, false, args)); - - case ToLocaleTimeString: - return jsString(formatLocaleDate(exec, secs, false, true, args)); - -#else - case ToLocaleString: - return jsString(timebuffer, strftime(timebuffer, bufsize, "%c", &t)); - - case ToLocaleDateString: - return jsString(timebuffer, strftime(timebuffer, bufsize, "%x", &t)); - - case ToLocaleTimeString: - return jsString(timebuffer, strftime(timebuffer, bufsize, "%X", &t)); - -#endif - case ValueOf: - case GetTime: - return jsNumber(milli); - case GetYear: - // IE returns the full year even in getYear. - if (exec->dynamicInterpreter()->compatMode() == Interpreter::IECompat) - return jsNumber(1900 + t.tm_year); - return jsNumber(t.tm_year); - case GetFullYear: - return jsNumber(1900 + t.tm_year); - case GetMonth: - return jsNumber(t.tm_mon); - case GetDate: - return jsNumber(t.tm_mday); - case GetDay: - return jsNumber(t.tm_wday); - case GetHours: - return jsNumber(t.tm_hour); - case GetMinutes: - return jsNumber(t.tm_min); - case GetSeconds: - return jsNumber(t.tm_sec); - case GetMilliSeconds: - return jsNumber(ms); - case GetTimezoneOffset: - return jsNumber(-gmtoffset(t) / 60); - - case SetMilliSeconds: - case SetSeconds: - case SetMinutes: - case SetHours: - ms = args.size() > 0 ? setTimeFields(exec, args, id, ms, &t) : NaN; - break; - - case SetDate: - case SetMonth: - case SetFullYear: - ms = args.size() > 0 ? setDateFields(exec, args, id, ms, &t) : NaN; - break; - - case SetYear: { - int32_t year = args[0]->toInt32(exec); - t.tm_year = (year > 99 || year < 0) ? year - 1900 : year; - break; - } - } - - if (id == SetYear || id == SetMilliSeconds || id == SetSeconds || - id == SetMinutes || id == SetHours || id == SetDate || - id == SetMonth || id == SetFullYear ) { - result = jsNumber(isnan(ms) ? ms : timeClip(makeTime(&t, ms, utc))); - thisDateObj->setInternalValue(result); - } - - return result; -} - -// ------------------------------ DateObjectImp -------------------------------- - -DateObjectImp::DateObjectImp(ExecState *exec, - FunctionPrototype *funcProto, - DatePrototype *dateProto) - : InternalFunctionImp(funcProto) -{ - // ECMA 15.9.4.1 Date.prototype - static const Identifier* parsePropertyName = new Identifier("parse"); - static const Identifier* UTCPropertyName = new Identifier("UTC"); - static const Identifier* nowPropertyName = new Identifier("now"); - - putDirect(exec->propertyNames().prototype, dateProto, DontEnum|DontDelete|ReadOnly); - putDirectFunction(new DateObjectFuncImp(exec, funcProto, DateObjectFuncImp::Parse, 1, *parsePropertyName), DontEnum); - putDirectFunction(new DateObjectFuncImp(exec, funcProto, DateObjectFuncImp::UTC, 7, *UTCPropertyName), DontEnum); - putDirectFunction(new DateObjectFuncImp(exec, funcProto, DateObjectFuncImp::Now, 0, *nowPropertyName), DontEnum); - - // no. of arguments for constructor - putDirect(exec->propertyNames().length, 7, ReadOnly|DontDelete|DontEnum); -} - -bool DateObjectImp::implementsConstruct() const -{ - return true; -} - -static double getCurrentUTCTime() -{ -#if PLATFORM(WIN_OS) -#if COMPILER(BORLAND) - struct timeb timebuffer; - ftime(&timebuffer); -#else - struct _timeb timebuffer; - _ftime(&timebuffer); -#endif - double utc = timebuffer.time * msPerSecond + timebuffer.millitm; -#else - struct timeval tv; - gettimeofday(&tv, 0); - double utc = floor(tv.tv_sec * msPerSecond + tv.tv_usec / 1000); -#endif - return utc; -} - -static double makeTimeFromList(ExecState *exec, const List &args, bool utc) -{ - const int numArgs = args.size(); - if (isNaNorInf(args[0]->toNumber(exec)) - || isNaNorInf(args[1]->toNumber(exec)) - || (numArgs >= 3 && isNaNorInf(args[2]->toNumber(exec))) - || (numArgs >= 4 && isNaNorInf(args[3]->toNumber(exec))) - || (numArgs >= 5 && isNaNorInf(args[4]->toNumber(exec))) - || (numArgs >= 6 && isNaNorInf(args[5]->toNumber(exec))) - || (numArgs >= 7 && isNaNorInf(args[6]->toNumber(exec)))) { - return NaN; - } - - tm t; - memset(&t, 0, sizeof(t)); - int year = args[0]->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; - if (!utc) - t.tm_isdst = -1; - double ms = (numArgs >= 7) ? roundValue(exec, args[6]) : 0; - return makeTime(&t, ms, utc); -} - -// ECMA 15.9.3 -JSObject *DateObjectImp::construct(ExecState *exec, const List &args) -{ - int numArgs = args.size(); - double value; - - if (numArgs == 0) { // new Date() ECMA 15.9.3.3 - value = getCurrentUTCTime(); - } else if (numArgs == 1) { - JSValue* arg0 = args[0]; - if (arg0->isObject(&DateInstance::info)) - value = static_cast(arg0)->internalValue()->toNumber(exec); - else { - JSValue* primitive = arg0->toPrimitive(exec); - if (primitive->isString()) - value = parseDate(primitive->getString()); - else - value = primitive->toNumber(exec); - } - } else { - value = makeTimeFromList(exec, args, false); - } - - DateInstance *ret = new DateInstance(exec->lexicalInterpreter()->builtinDatePrototype()); - ret->setInternalValue(jsNumber(timeClip(value))); - return ret; -} - -// ECMA 15.9.2 -JSValue *DateObjectImp::callAsFunction(ExecState * /*exec*/, JSObject * /*thisObj*/, const List &/*args*/) -{ - time_t t = time(0); - tm ts = *localtime(&t); - return jsString(formatDate(ts).append(' ').append(formatTime(ts, false))); -} - -// ------------------------------ DateObjectFuncImp ---------------------------- - -DateObjectFuncImp::DateObjectFuncImp(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) - : InternalFunctionImp(funcProto, name), id(i) -{ - putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); -} - -// ECMA 15.9.4.2 - 3 -JSValue *DateObjectFuncImp::callAsFunction(ExecState* exec, JSObject*, const List& args) -{ - if (id == Parse) { - return jsNumber(parseDate(args[0]->toString(exec))); - } else if (id == Now) { - return jsNumber(getCurrentUTCTime()); - } else { // UTC - return jsNumber(makeTimeFromList(exec, args, true)); - } -} - -// ----------------------------------------------------------------------------- - -// Code originally from krfcdate.cpp, but we don't want to use kdecore, and we want double range. - -static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, double second) -{ - // in which case is the floor() needed? breaks day value of - // "new Date('Thu Nov 5 2065 18:15:30 GMT+0500')" -#if 0 - double days = (day - 32075) - + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4) - + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12 - - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4) - - 2440588; -#else - double days = (day - 32075) - + 1461 * (year + 4800 + (mon - 14) / 12) / 4 - + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12 - - 3 * ((year + 4900 + (mon - 14) / 12) / 100) / 4 - - 2440588; -#endif - return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerMinute + second; -} - -// We follow the recommendation of RFC 2822 to consider all -// obsolete time zones not listed here equivalent to "-0000". -static const struct KnownZone { -#if !PLATFORM(WIN_OS) - const -#endif - char tzName[4]; - int tzOffset; -} known_zones[] = { - { "UT", 0 }, - { "GMT", 0 }, - { "EST", -300 }, - { "EDT", -240 }, - { "CST", -360 }, - { "CDT", -300 }, - { "MST", -420 }, - { "MDT", -360 }, - { "PST", -480 }, - { "PDT", -420 } -}; - -#if PLATFORM(WIN_OS) -void FileTimeToUnixTime(LPFILETIME pft, double* pt) -{ - ULARGE_INTEGER ull; - ull.LowPart = pft->dwLowDateTime; - ull.HighPart = pft->dwHighDateTime; - *pt = (double)(ull.QuadPart / 10000000ULL) - 11644473600ULL; -} - -void SystemTimeToUnixTime(LPSYSTEMTIME pst, double* pt) -{ - FILETIME ft; - SystemTimeToFileTime(pst, &ft); - FileTimeToUnixTime(&ft, pt); -} -#endif - -static double makeTime(tm *t, double ms, bool utc) -{ - int utcOffset; - if (utc) { - time_t zero = 0; -#if PLATFORM(WIN_OS) - // FIXME: not thread safe - (void)localtime(&zero); -#if COMPILER(BORLAND) || COMPILER(CYGWIN) - utcOffset = - _timezone; -#else - utcOffset = - timezone; -#endif - t->tm_isdst = 0; -#elif PLATFORM(DARWIN) - utcOffset = 0; - t->tm_isdst = 0; -#else - tm t3; - localtime_r(&zero, &t3); - utcOffset = gmtoffset(t3); - t->tm_isdst = t3.tm_isdst; -#endif - } else { - utcOffset = 0; - t->tm_isdst = -1; - } - -#if !PLATFORM(WIN_OS) - double yearOffset = 0.0; - if (t->tm_year < (1971 - 1900) || t->tm_year > (2037 - 1900)) { - // we'll fool mktime() into believing that this year is within - // its normal, portable range (1970-2038) by setting tm_year to - // 2000 or 2001 and adding the difference in milliseconds later. - // choice between offset will depend on whether the year is a - // leap year or not. - int y = t->tm_year + 1900; - int baseYear = daysInYear(y) == 365 ? 2001 : 2000; - double baseTime = timeFromYear(baseYear); - yearOffset = timeFromYear(y) - baseTime; - t->tm_year = baseYear - 1900; - } - - // Determine whether DST is in effect. mktime() can't do this for us because - // it doesn't know about ms and yearOffset. - // NOTE: Casting values of large magnitude to time_t (long) will - // produce incorrect results, but there's no other option when calling localtime_r(). - if (!utc) { - time_t tval = mktime(t) + (time_t)((ms + yearOffset) / 1000); - tm t3 = *localtime(&tval); - t->tm_isdst = t3.tm_isdst; - } - - return (mktime(t) + utcOffset) * msPerSecond + ms + yearOffset; -#else - SYSTEMTIME st, dt; - double tval; - - st.wYear = 1900 + t->tm_year; - st.wMonth = t->tm_mon + 1; - st.wDayOfWeek = t->tm_wday; - st.wDay = t->tm_mday; - st.wHour = t->tm_hour; - st.wMinute = t->tm_min; - st.wSecond = t->tm_sec; - st.wMilliseconds = 0; - - TzSpecificLocalTimeToSystemTime(0, &st, &dt); - SystemTimeToUnixTime(&dt, &tval); - - return (tval + utcOffset) * msPerSecond + ms; -#endif -} - -inline static bool isSpaceLike(char c) -{ - return isASCIISpace(c) || c == ',' || c == ':' || c == '-'; -} - -static const char* skipSpacesAndComments(const char* s) -{ - int nesting = 0; - char ch; - while ((ch = *s)) { - // interpret - before a number as a sign rather than a comment char - if (ch == '-' && isASCIIDigit(*(s+1))) - break; - if (!isSpaceLike(ch)) { - if (ch == '(') - nesting++; - else if (ch == ')' && nesting > 0) - nesting--; - else if (nesting == 0) - break; - } - s++; - } - return s; -} - -// returns 0-11 (Jan-Dec); -1 on failure -static int findMonth(const char *monthStr) -{ - assert(monthStr); - char needle[4]; - for (int i = 0; i < 3; ++i) { - if (!*monthStr) - return -1; - needle[i] = toASCIILower(*monthStr++); - } - needle[3] = '\0'; - const char *haystack = "janfebmaraprmayjunjulaugsepoctnovdec"; - const char *str = strstr(haystack, needle); - if (str) { - int position = str - haystack; - if (position % 3 == 0) - return position / 3; - } - return -1; -} - -static bool isTwoDigits (const char* str) -{ - return isASCIIDigit(str[0]) && isASCIIDigit(str[1]); -} - -static int twoDigit (const char* str) -{ - return (str[0] - '0') * 10 + str[1] - '0'; -} - -static double parseDate(const UString &date) -{ - // This parses a date in the form: - // Tuesday, 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 formats, added for Javascript: - // [Wednesday] January 09 1999 23:12:40 GMT - // [Wednesday] January 09 23:12:40 GMT 1999 - // - // We ignore the weekday. - - CString dateCString = date.UTF8String(); - const char *dateString = dateCString.c_str(); - if(!dateString) - return NaN; - - // Skip leading space - dateString = skipSpacesAndComments(dateString); - - // ISO 8601: "YYYY-MM-DD('T'|'t')hh:mm:ss[.S+]['Z']" - // e.g. "2006-06-15T23:12:10.207830Z" - if (isTwoDigits(dateString) && - isTwoDigits(dateString + 2) && - dateString[4] == '-' && - isTwoDigits(dateString + 5) && - dateString[7] == '-' && - isTwoDigits(dateString + 8)) - { - int year = twoDigit(dateString) * 100 + twoDigit(dateString + 2); - int month = twoDigit(dateString + 5) - 1; - int day = twoDigit(dateString + 8); - if (month > 11 || day < 1 || day > 31) - return NaN; - int hour = 0, minute = 0; - double second = 0; - dateString += 10; - if ((dateString[0] | 0x20) == 't' && - isTwoDigits(dateString + 1) && - dateString[3] == ':' && - isTwoDigits(dateString + 4)) - { - hour = twoDigit(dateString + 1); - minute = twoDigit(dateString + 4); - if (hour > 23 || minute > 59) - return NaN; - dateString += 6; - if (dateString[0] == ':' && - isTwoDigits(dateString + 1)) - { - second = twoDigit(dateString + 1); - if (second > 59) - return NaN; - dateString += 3; - if (dateString[0] == '.' && - isASCIIDigit(dateString[1])) - { - dateString++; - double div = 10; - do { - second += (dateString[0] - '0') / div; - div *= 10; - } while (isASCIIDigit(*++dateString)); - } - } - } - - if (dateString[0] == 'Z') - { - tm t; - memset(&t, 0, sizeof(tm)); - int secs = int(second); - t.tm_sec = secs; - t.tm_min = minute; - t.tm_hour = hour; - t.tm_mday = day; - t.tm_mon = month; - t.tm_year = year - 1900; - // t.tm_isdst = -1; - - // Use our makeTime() rather than mktime() as the latter can't handle the full year range. - return makeTime(&t, (second - secs) * 1000, true); - } - - int offset = 0; - return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond; - } - - long month = -1; - const char *wordStart = dateString; - // Check contents of first words if not number - while (*dateString && !isASCIIDigit(*dateString)) { - if (isASCIISpace(*dateString) || *dateString == '(') { - if (dateString - wordStart >= 3) - month = findMonth(wordStart); - dateString = skipSpacesAndComments(dateString); - wordStart = dateString; - } else - dateString++; - } - - // Missing delimiter between month and day (like "January29")? - if (month == -1 && wordStart != dateString) - month = findMonth(wordStart); - - dateString = skipSpacesAndComments(dateString); - - if (!*dateString) - return NaN; - - // ' 09-Nov-99 23:12:40 GMT' - char *newPosStr; - errno = 0; - long day = strtol(dateString, &newPosStr, 10); - dateString = newPosStr; - - if (errno || day < 0 || !*dateString) - return NaN; - - long year = 0; - if (day > 31) { - // ### where is the boundary and what happens below? - if (*dateString != '/') - return NaN; - // looks like a YYYY/MM/DD date - if (!*++dateString) - return NaN; - year = day; - month = strtol(dateString, &newPosStr, 10) - 1; - if (errno) - return NaN; - dateString = newPosStr; - if (*dateString++ != '/' || !*dateString) - return NaN; - day = strtol(dateString, &newPosStr, 10); - if (errno) - return NaN; - dateString = newPosStr; - } else if (*dateString == '/' && month == -1) { - dateString++; - // This looks like a MM/DD/YYYY date, not an RFC date. - month = day - 1; // 0-based - day = strtol(dateString, &newPosStr, 10); - if (errno) - return NaN; - dateString = newPosStr; - if (*dateString == '/') - dateString++; - if (!*dateString) - return NaN; - } else { - if (*dateString == '-') - dateString++; - - dateString = skipSpacesAndComments(dateString); - - if (*dateString == ',') - dateString++; - - if (month == -1) { // not found yet - month = findMonth(dateString); - if (month == -1) - return NaN; - - while (*dateString && (*dateString != '-') && !isASCIISpace(*dateString)) - dateString++; - - if (!*dateString) - return NaN; - - // '-99 23:12:40 GMT' - if (*dateString != '-' && *dateString != '/' && !isASCIISpace(*dateString)) - return NaN; - dateString++; - } - - if (month < 0 || month > 11) - return NaN; - } - - // '99 23:12:40 GMT' - if (year <= 0 && *dateString) { - year = strtol(dateString, &newPosStr, 10); - if (errno) - return NaN; - } - - // Don't fail if the time is missing. - long hour = 0; - long minute = 0; - long second = 0; - if (!*newPosStr) - dateString = newPosStr; - else { - // ' 23:12:40 GMT' - if (*newPosStr == ':') { - // There was no year; the number was the hour. - year = -1; - } else if (isSpaceLike(*newPosStr)) { - // in the normal case (we parsed the year), advance to the next number - dateString = skipSpacesAndComments(newPosStr + 1); - } else { - return NaN; - } - - hour = strtol(dateString, &newPosStr, 10); - // Do not check for errno here since we want to continue - // even if errno was set because we are still looking - // for the timezone! - - // Read a number? If not, this might be a timezone name. - if (newPosStr != dateString) { - dateString = newPosStr; - - if (hour < 0 || hour > 23) - return NaN; - - if (!*dateString) - return NaN; - - // ':12:40 GMT' - if (*dateString++ != ':') - return NaN; - - minute = strtol(dateString, &newPosStr, 10); - if (errno) - return NaN; - dateString = newPosStr; - - if (minute < 0 || minute > 59) - return NaN; - - // ':40 GMT' - if (*dateString && *dateString != ':' && !isASCIISpace(*dateString)) - return NaN; - - // seconds are optional in rfc822 + rfc2822 - if (*dateString ==':') { - dateString++; - - second = strtol(dateString, &newPosStr, 10); - if (errno) - return NaN; - dateString = newPosStr; - - if (second < 0 || second > 59) - return NaN; - - // disallow trailing colon seconds - if (*dateString == ':') - return NaN; - } - - dateString = skipSpacesAndComments(dateString); - - if (strncasecmp(dateString, "AM", 2) == 0) { - if (hour > 12) - return NaN; - if (hour == 12) - hour = 0; - dateString = skipSpacesAndComments(dateString + 2); - } else if (strncasecmp(dateString, "PM", 2) == 0) { - if (hour > 12) - return NaN; - if (hour != 12) - hour += 12; - dateString = skipSpacesAndComments(dateString + 2); - } - } - } - - bool haveTZ = false; - int offset = 0; - - // Don't fail if the time zone is missing. - // Some websites omit the time zone (4275206). - if (*dateString) { - if (strncasecmp(dateString, "GMT", 3) == 0 || - strncasecmp(dateString, "UTC", 3) == 0) { - dateString += 3; - haveTZ = true; - } - - if (*dateString == '+' || *dateString == '-') { - long o = strtol(dateString, &newPosStr, 10); - if (errno) - return NaN; - dateString = newPosStr; - - if (o < -9959 || o > 9959) - return NaN; - - int sgn = (o < 0) ? -1 : 1; - o = abs(o); - if (*dateString != ':') { - offset = ((o / 100) * 60 + (o % 100)) * sgn; - } else { // GMT+05:00 - dateString++; - long o2 = strtol(dateString, &newPosStr, 10); - if (errno) - return NaN; - dateString = newPosStr; - offset = (o * 60 + o2) * sgn; - } - haveTZ = true; - } else { - for (int i = 0; i < int(sizeof(known_zones) / sizeof(KnownZone)); i++) { - if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) { - offset = known_zones[i].tzOffset; - dateString += strlen(known_zones[i].tzName); - haveTZ = true; - break; - } - } - } - } - - dateString = skipSpacesAndComments(dateString); - - if (*dateString && year == -1) { - year = strtol(dateString, &newPosStr, 10); - if (errno) - return NaN; - dateString = newPosStr; - } - - dateString = skipSpacesAndComments(dateString); - - // Trailing garbage - if (*dateString) - return NaN; - - // Y2K: Handle 2 digit years. - if (year >= 0 && year < 100) { - if (year < 50) - year += 2000; - else - year += 1900; - } - - // fall back to local timezone - if (!haveTZ) { - tm t; - memset(&t, 0, sizeof(tm)); - t.tm_mday = day; - t.tm_mon = month; - t.tm_year = year - 1900; - t.tm_isdst = -1; - t.tm_sec = second; - t.tm_min = minute; - t.tm_hour = hour; - - // Use our makeTime() rather than mktime() as the latter can't handle the full year range. - return makeTime(&t, 0, false); - } - - return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond; -} - -double timeClip(double t) -{ - if (isnan(t) || isInf(t)) - return NaN; - double at = fabs(t); - if (at > 8.64E15) - return NaN; - return copysign(floor(at), t); -} - -} // namespace KJS diff --git a/kjs/date_object.h b/kjs/date_object.h deleted file mode 100644 index 3af2f413..00000000 --- a/kjs/date_object.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef DATE_OBJECT_H -#define DATE_OBJECT_H - -#include "function.h" -#include "JSWrapperObject.h" - -struct tm; - -namespace KJS { - - class FunctionPrototype; - class ObjectPrototype; - - class DateInstance : public JSWrapperObject { - public: - DateInstance(JSObject *proto); - - bool getTime(tm &t, int &gmtoffset) const; - bool getUTCTime(tm &t) const; - bool getTime(double &ms, int &gmtoffset) const; - bool getUTCTime(double &ms) const; - - virtual const ClassInfo *classInfo() const { return &info; } - static const ClassInfo info; - - virtual JSObject* valueClone(Interpreter* targetCtx) const; - }; - - /** - * @internal - * - * The initial value of Date.prototype (and thus all objects created - * with the Date constructor - */ - class DatePrototype : public DateInstance { - public: - DatePrototype(ExecState *, ObjectPrototype *); - using KJS::JSObject::getOwnPropertySlot; - virtual bool getOwnPropertySlot(ExecState *, const Identifier &, PropertySlot&); - 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 DateProtoFunc : public InternalFunctionImp { - public: - DateProtoFunc(ExecState *, int i, int len, const Identifier& date); - - virtual JSValue *callAsFunction(ExecState *, JSObject *thisObj, const List &args); - - 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, ToISOString, ToJSON, - // non-normative properties (Appendix B) - GetYear, SetYear, ToGMTString }; - private: - short id; - bool utc; - }; - - /** - * @internal - * - * The initial value of the global variable's "Date" property - */ - class DateObjectImp : public InternalFunctionImp { - using InternalFunctionImp::construct; - public: - DateObjectImp(ExecState *, FunctionPrototype *, DatePrototype *); - - virtual bool implementsConstruct() const; - virtual JSObject *construct(ExecState *, const List &args); - virtual JSValue *callAsFunction(ExecState *, JSObject *thisObj, const List &args); - - Completion execute(const List &); - JSObject *construct(const List &); - }; - -} // namespace - -#endif diff --git a/kjs/debugger.cpp b/kjs/debugger.cpp deleted file mode 100644 index b021fc6a..00000000 --- a/kjs/debugger.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// -*- 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 - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "debugger.h" -#include "nodes.h" -#include -#include "ustring.h" - -#include "internal.h" - -using namespace KJS; - -// ------------------------------ Debugger ------------------------------------- - -namespace KJS { - struct AttachedInterpreter - { - AttachedInterpreter(Interpreter *i, AttachedInterpreter *ai) : interp(i), next(ai) { ++Debugger::debuggersPresent; } - ~AttachedInterpreter() { --Debugger::debuggersPresent; } - Interpreter *interp; - AttachedInterpreter *next; - }; - -} - -int Debugger::debuggersPresent = 0; - -Debugger::Debugger() -{ - lastLineRan = 0; - rep = new DebuggerImp(); - lastSourceParsed = -1; -} - -Debugger::~Debugger() -{ - detach(0); - delete rep; -} - -void Debugger::attach(Interpreter* interp) -{ - Debugger *other = interp->debugger(); - if (other == this) - return; - if (other) - other->detach(interp); - interp->setDebugger(this); - rep->interps = new AttachedInterpreter(interp, rep->interps); -} - -void Debugger::detach(Interpreter* interp) -{ - // iterate the addresses where AttachedInterpreter pointers are stored - // so we can unlink items from the list - AttachedInterpreter **p = &rep->interps; - AttachedInterpreter *q; - while ((q = *p)) { - if (!interp || q->interp == interp) { - *p = q->next; - q->interp->setDebugger(0); - delete q; - } else - p = &q->next; - } - - if (interp) - latestExceptions.remove(interp); - else - latestExceptions.clear(); -} - -bool Debugger::hasHandledException(ExecState *exec, JSValue *exception) -{ - if (latestExceptions.get(exec->dynamicInterpreter()).get() == exception) - return true; - - latestExceptions.set(exec->dynamicInterpreter(), exception); - return false; -} - -bool Debugger::sourceParsed(ExecState * /*exec*/, int /*sourceId*/, const UString &/*sourceURL*/, - const UString &/*source*/, int /*startingLineNumber*/, int /*errorLine*/, const UString & /*errorMsg*/) -{ - return true; -} - -bool Debugger::exception(ExecState * /*exec*/, int /*sourceId*/, int /*lineno*/, - JSValue * /*exception*/) -{ - return true; -} - -bool Debugger::atStatement(ExecState * /*exec*/, int /*sourceId*/, int /*firstLine*/, - int /*lastLine*/) -{ - return true; -} - -void Debugger::reportAtStatement(ExecState *exec, int sourceId, int firstLine, int lastLine) -{ - lastLineRan = firstLine; - atStatement(exec, sourceId, firstLine, lastLine); -} - -void Debugger::reportException(ExecState *exec, JSValue *exceptionVal) -{ - if (!hasHandledException(exec, exceptionVal)) - exception(exec, exec->currentBody() ? exec->currentBody()->sourceId() : lastSourceParsed, lastLineRan, exceptionVal); -} - -bool Debugger::enterContext(ExecState * /*exec*/, int /*sourceId*/, int /*lineno*/, - JSObject * /*function*/, const List & /*args*/) -{ - return true; -} - -bool Debugger::exitContext(ExecState * /*exec*/, int /*sourceId*/, int /*lineno*/, - JSObject * /*function*/) -{ - return true; -} - -bool Debugger::shouldReindentSources() const -{ - return false; -} - -bool Debugger::shouldReportCaught() const -{ - return false; -} - -void Debugger::reportSourceParsed(ExecState *exec, FunctionBodyNode *body, - int sourceId, UString sourceURL, const UString &source, - int startingLineNumber, int errorLine, const UString &errorMsg) -{ - lastSourceParsed = sourceId; - UString code = source; - if (shouldReindentSources() && body) - code = body->reindent(startingLineNumber); - sourceParsed(exec, sourceId, sourceURL, code, startingLineNumber, errorLine, errorMsg); -} diff --git a/kjs/debugger.h b/kjs/debugger.h deleted file mode 100644 index 3819cbca..00000000 --- a/kjs/debugger.h +++ /dev/null @@ -1,240 +0,0 @@ -// -*- 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 - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef _KJSDEBUGGER_H_ -#define _KJSDEBUGGER_H_ - -#include "global.h" -#include -#include "protect.h" - -namespace KJS { - - class DebuggerImp; - class Interpreter; - class ExecState; - class JSObject; - class JSValue; - class UString; - class List; - class FunctionBodyNode; - - /** - * @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 - * officially 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 KJS_EXPORT Debugger { - public: - - /** - * Creates a new debugger - */ - Debugger(); - - /** - * 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 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() - */ - virtual void attach(Interpreter *interp); - - /** - * 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() - */ - virtual void detach(Interpreter *interp); - - /** - * 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 atStatement() - * @param sourceURL Where the source code that was parsed came from - * @param source The source code that was parsed - * @param startingLineNumber The line number at which parsing started - * @param errorLine The line number at which parsing encountered an - * error, or -1 if the source code was valid and parsed successfully - * @param errorMsg The error description, or null if the source code - was valid and parsed successfully - * @return true if execution should be continue, false if it should - * be aborted - */ - virtual bool sourceParsed(ExecState *exec, int sourceId, const UString &sourceURL, - const UString &source, int startingLineNumber, int errorLine, const UString &errorMsg); - - /** - * 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 exception 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, - JSValue *exception); - - bool hasHandledException(ExecState *, JSValue *); - - /** - * 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 lastLine 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 when the interpreter enters a new execution context (stack - * frame). This can happen in three situations: - * - *
    - *
  • A call to Interpreter::evaluate(). This has a codeType of - * GlobalCode
  • - *
  • A call to the builtin eval() function. The sourceId corresponds to - * the code passed in to eval. This has a codeType of EvalCode. The - * lineno here is always 0 since execution starts at the beginning of - * the script.
  • - *
  • A function call. This only occurs for functions defined in - * ECMAScript code, whether via the normal function() { ... } syntax or - * a call to the built-in Function() constructor (anonymous functions). - * In the former case, the sourceId and lineno indicate the location at - * which the function was defined. For anonymous functions, the sourceId - * corresponds to the code passed into the Function() constructor.
  • - *
- * - * enterContext() is not called for functions implemented in the native - * code, since these do not use an execution context. - * - * @param exec The current execution state (corresponding to the new stack) - * @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. 0 in non-function context. - * @param args The arguments that were passed to the function - * line is being executed. Empty in non-function contexts. - * - * @return true if execution should be continued, false if it should - * be aborted - */ - virtual bool enterContext(ExecState *exec, int sourceId, int lineno, - JSObject *function, const List &args); - - /** - * Called when the inteprreter exits an execution context. This always - * corresponds to a previous call to enterContext() - * - * 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 returned from, if there is one - * @return true if execution should be continue, false if it should - * be aborted - */ - virtual bool exitContext(ExecState *exec, int sourceId, int lineno, - JSObject *function); - - - // Override this and return true if you want the debugger to report - // pretty-printed versions of the source. - virtual bool shouldReindentSources() const; - - // Override this to return true if the debugger should report - // exceptions even if there is a try block waiting for it. - virtual bool shouldReportCaught() const; - - // The two methods below call the events but also keep track/use of line # information - // so we can associate it with exceptions - void reportAtStatement(ExecState *exec, int sourceId, int firstLine, int lastLine); - void reportException (ExecState *exec, JSValue *exception); - - // This notifies the debugger of source being parsed, reindenting it if need be. - void reportSourceParsed(ExecState *exec, FunctionBodyNode *body, int sourceId, UString sourceURL, - const UString &source, int startingLineNumber, int errorLine, const UString &errorMsg); - private: - DebuggerImp *rep; - HashMap > latestExceptions; - int lastLineRan; - int lastSourceParsed; // Needed for attributing syntax exceptions at top-level - public: - static int debuggersPresent; - }; - -} - -#endif - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/dtoa.cpp b/kjs/dtoa.cpp deleted file mode 100644 index fc2ba82f..00000000 --- a/kjs/dtoa.cpp +++ /dev/null @@ -1,3204 +0,0 @@ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* Please send bug reports to - David M. Gay - Bell Laboratories, Room 2C-463 - 600 Mountain Avenue - Murray Hill, NJ 07974-0636 - U.S.A. - dmg@bell-labs.com - */ - -/* On a machine with IEEE extended-precision registers, it is - * necessary to specify double-precision (53-bit) rounding precision - * before invoking strtod or dtoa. If the machine uses (the equivalent - * of) Intel 80x87 arithmetic, the call - * _control87(PC_53, MCW_PC); - * does this with many compilers. Whether this or another call is - * appropriate depends on the compiler; for this to work, it may be - * necessary to #include "float.h" or another system-dependent header - * file. - */ - -/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. - * - * This strtod returns a nearest machine number to the input decimal - * string (or sets errno to ERANGE). With IEEE arithmetic, ties are - * broken by the IEEE round-even rule. Otherwise ties are broken by - * biased rounding (add half and chop). - * - * Inspired loosely by William D. Clinger's paper "How to Read Floating - * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). - */ - -/* - * #define IEEE_8087 for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_MC68k for IEEE-arithmetic machines where the most - * significant byte has the lowest address. - * #define Long int on machines with 32-bit ints and 64-bit longs. - * #define IBM for IBM mainframe-style floating-point arithmetic. - * #define VAX for VAX-style floating-point arithmetic (D_floating). - * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. - * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and strtod and dtoa should round accordingly. - * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and Honor_FLT_ROUNDS is not #defined. - * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding. - * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. - * #define NO_LONG_LONG on machines that do not have a "long long" - * integer type (of >= 64 bits). On such machines, you can - * #define Just_16 to store 16 bits per 32-bit Long when doing - * high-precision integer arithmetic. Whether this speeds things - * up or slows things down depends on the machine and the number - * being converted. If long long is available and the name is - * something other than "long long", #define Llong to be the name, - * and if "unsigned Llong" does not work as an unsigned version of - * Llong, #define #ULLong to be the corresponding unsigned type. - * #define KR_headers for old-style C function headers. - * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. - * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making - * memory allocations from a private pool of memory when possible. - * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, - * unless #defined to be a different length. This default length - * suffices to get rid of MALLOC calls except for unusual cases, - * such as decimal-to-binary conversion of a very long string of - * digits. The longest string dtoa can return is about 751 bytes - * long. For conversions by strtod of strings of 800 digits and - * all dtoa conversions in single-threaded executions with 8-byte - * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte - * pointers, PRIVATE_MEM >= 7112 appears adequate. - * #define INFNAN_CHECK on IEEE systems to cause strtod to check for - * Infinity and NaN (case insensitively). On some systems (e.g., - * some HP systems), it may be necessary to #define NAN_WORD0 - * appropriately -- to the most significant word of a quiet NaN. - * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) - * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, - * strtod also accepts (case insensitively) strings of the form - * NaN(x), where x is a string of hexadecimal digits and spaces; - * if there is only one string of hexadecimal digits, it is taken - * for the 52 fraction bits of the resulting NaN; if there are two - * or more strings of hex digits, the first is for the high 20 bits, - * the second and subsequent for the low 32 bits, with intervening - * white space ignored; but if this results in none of the 52 - * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 - * and NAN_WORD1 are used instead. - * #define MULTIPLE_THREADS if the system offers preemptively scheduled - * multiple threads. In this case, you must provide (or suitably - * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed - * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed - * in pow5mult, ensures lazy evaluation of only one copy of high - * powers of 5; omitting this lock would introduce a small - * probability of wasting memory, but would otherwise be harmless.) - * You must also invoke freedtoa(s) to free the value s returned by - * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. - * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that - * avoids underflows on inputs whose result does not underflow. - * If you #define NO_IEEE_Scale on a machine that uses IEEE-format - * floating-point numbers and flushes underflows to zero rather - * than implementing gradual underflow, then you must also #define - * Sudden_Underflow. - * #define YES_ALIAS to permit aliasing certain double values with - * arrays of ULongs. This leads to slightly better code with - * some compilers and was always used prior to 19990916, but it - * is not strictly legal and can cause trouble with aggressively - * optimizing compilers (e.g., gcc 2.95.1 under -O2). - * #define USE_LOCALE to use the current locale's decimal_point value. - * #define SET_INEXACT if IEEE arithmetic is being used and extra - * computation should be done to set the inexact flag when the - * result is inexact and avoid setting inexact when the result - * is exact. In this case, dtoa.c must be compiled in - * an environment, perhaps provided by #include "dtoa.c" in a - * suitable wrapper, that defines two functions, - * int get_inexact(void); - * void clear_inexact(void); - * such that get_inexact() returns a nonzero value if the - * inexact bit is already set, and clear_inexact() sets the - * inexact bit to 0. When SET_INEXACT is #defined, strtod - * also does extra computations to set the underflow and overflow - * flags when appropriate (i.e., when the result is tiny and - * inexact or when it is a numeric value rounded to +-infinity). - * #define NO_ERRNO if strtod should not assign errno = ERANGE when - * the result overflows to +-Infinity or underflows to 0. - */ - -#include "dtoa.h" -#include - -#include "global.h" - -#if PLATFORM(BIG_ENDIAN) -#define IEEE_MC68k -#else -#define IEEE_8087 -#endif -#define INFNAN_CHECK - - - -#ifndef Long -#define Long int -#endif -#ifndef ULong -typedef unsigned Long ULong; -#endif - -#ifdef DEBUG -#include -#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} -#endif - -#include -#include - -#ifdef USE_LOCALE -#include -#endif - -#ifdef MALLOC -extern void *MALLOC(size_t); -#else -#define MALLOC malloc -#endif - -#ifndef Omit_Private_Memory -#ifndef PRIVATE_MEM -#define PRIVATE_MEM 2304 -#endif -#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) -static double private_mem[PRIVATE_mem], *pmem_next = private_mem; -#endif - -#undef IEEE_Arith -#undef Avoid_Underflow -#ifdef IEEE_MC68k -#define IEEE_Arith -#endif -#ifdef IEEE_8087 -#define IEEE_Arith -#endif - -#include - -#ifdef Bad_float_h - -#ifdef IEEE_Arith -#define DBL_DIG 15 -#define DBL_MAX_10_EXP 308 -#define DBL_MAX_EXP 1024 -#define FLT_RADIX 2 -#endif /*IEEE_Arith*/ - -#ifdef IBM -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 75 -#define DBL_MAX_EXP 63 -#define FLT_RADIX 16 -#define DBL_MAX 7.2370055773322621e+75 -#endif - -#ifdef VAX -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 38 -#define DBL_MAX_EXP 127 -#define FLT_RADIX 2 -#define DBL_MAX 1.7014118346046923e+38 -#endif - -#ifndef LONG_MAX -#define LONG_MAX 2147483647 -#endif - -#else /* ifndef Bad_float_h */ -#include -#endif /* Bad_float_h */ - -#ifndef __MATH_H__ -#include -#endif - -#define strtod kjs_strtod -#define dtoa kjs_dtoa -#define freedtoa kjs_freedtoa - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef CONST -#define CONST const -#endif - -#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 -Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. -#endif - -typedef union { double d; ULong L[2]; } U; - -#define dval(x) (x).d -#ifdef IEEE_8087 -#define word0(x) (x).L[1] -#define word1(x) (x).L[0] -#else -#define word0(x) (x).L[0] -#define word1(x) (x).L[1] -#endif - -/* The following definition of Storeinc is appropriate for MIPS processors. - * An alternative that might be better on some machines is - */ -#define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) - -/* #define P DBL_MANT_DIG */ -/* Ten_pmax = floor(P*log(2)/log(5)) */ -/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ -/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ -/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ - -#ifdef IEEE_Arith -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Bias 1023 -#define Emin (-1022) -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 -#ifndef NO_IEEE_Scale -#define Avoid_Underflow -#ifdef Flush_Denorm /* debugging option */ -#undef Sudden_Underflow -#endif -#endif - -#ifndef Flt_Rounds -#ifdef FLT_ROUNDS -#define Flt_Rounds FLT_ROUNDS -#else -#define Flt_Rounds 1 -#endif -#endif /*Flt_Rounds*/ - -#ifdef Honor_FLT_ROUNDS -#define Rounding rounding -#undef Check_FLT_ROUNDS -#define Check_FLT_ROUNDS -#else -#define Rounding Flt_Rounds -#endif - -#else /* ifndef IEEE_Arith */ -#undef Check_FLT_ROUNDS -#undef Honor_FLT_ROUNDS -#undef SET_INEXACT -#undef Sudden_Underflow -#define Sudden_Underflow -#ifdef IBM -#undef Flt_Rounds -#define Flt_Rounds 0 -#define Exp_shift 24 -#define Exp_shift1 24 -#define Exp_msk1 0x1000000 -#define Exp_msk11 0x1000000 -#define Exp_mask 0x7f000000 -#define P 14 -#define Bias 65 -#define Exp_1 0x41000000 -#define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ -#define Frac_mask 0xffffff -#define Frac_mask1 0xffffff -#define Bletch 4 -#define Ten_pmax 22 -#define Bndry_mask 0xefffff -#define Bndry_mask1 0xffffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 4 -#define Tiny0 0x100000 -#define Tiny1 0 -#define Quick_max 14 -#define Int_max 15 -#else /* VAX */ -#undef Flt_Rounds -#define Flt_Rounds 1 -#define Exp_shift 23 -#define Exp_shift1 7 -#define Exp_msk1 0x80 -#define Exp_msk11 0x800000 -#define Exp_mask 0x7f80 -#define P 56 -#define Bias 129 -#define Exp_1 0x40800000 -#define Exp_11 0x4080 -#define Ebits 8 -#define Frac_mask 0x7fffff -#define Frac_mask1 0xffff007f -#define Ten_pmax 24 -#define Bletch 2 -#define Bndry_mask 0xffff007f -#define Bndry_mask1 0xffff007f -#define LSB 0x10000 -#define Sign_bit 0x8000 -#define Log2P 1 -#define Tiny0 0x80 -#define Tiny1 0 -#define Quick_max 15 -#define Int_max 15 -#endif /* IBM, VAX */ -#endif /* IEEE_Arith */ - -#ifndef IEEE_Arith -#define ROUND_BIASED -#endif - -#ifdef RND_PRODQUOT -#define rounded_product(a,b) a = rnd_prod(a, b) -#define rounded_quotient(a,b) a = rnd_quot(a, b) -extern double rnd_prod(double, double), rnd_quot(double, double); -#else -#define rounded_product(a,b) a *= b -#define rounded_quotient(a,b) a /= b -#endif - -#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) -#define Big1 0xffffffff - -#ifndef Pack_32 -#define Pack_32 -#endif - -#define FFFFFFFF 0xffffffffUL - -#ifdef NO_LONG_LONG -#undef ULLong -#ifdef Just_16 -#undef Pack_32 -/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. - * This makes some inner loops simpler and sometimes saves work - * during multiplications, but it often seems to make things slightly - * slower. Hence the default is now to store 32 bits per Long. - */ -#endif -#else /* long long available */ -#ifndef Llong -#define Llong long long -#endif -#ifndef ULLong -#define ULLong unsigned Llong -#endif -#endif /* NO_LONG_LONG */ - -#ifndef MULTIPLE_THREADS -#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ -#define FREE_DTOA_LOCK(n) /*nothing*/ -#endif - -#define Kmax (sizeof(size_t) << 3) - - struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; - }; - - typedef struct Bigint Bigint; - - static Bigint *freelist[Kmax+1]; - - static Bigint * -Balloc - (int k) -{ - int x; - Bigint *rv; -#ifndef Omit_Private_Memory - unsigned int len; -#endif - - ACQUIRE_DTOA_LOCK(0); - if ((rv = freelist[k])) { - freelist[k] = rv->next; - } - else { - x = 1 << k; -#ifdef Omit_Private_Memory - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); -#else - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - if (pmem_next - private_mem + len <= (unsigned)PRIVATE_mem) { - rv = (Bigint*)pmem_next; - pmem_next += len; - } - else - rv = (Bigint*)MALLOC(len*sizeof(double)); -#endif - rv->k = k; - rv->maxwds = x; - } - FREE_DTOA_LOCK(0); - rv->sign = rv->wds = 0; - return rv; - } - - static void -Bfree - (Bigint *v) -{ - if (v) { - ACQUIRE_DTOA_LOCK(0); - v->next = freelist[v->k]; - freelist[v->k] = v; - FREE_DTOA_LOCK(0); - } - } - -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ -y->wds*sizeof(Long) + 2*sizeof(int)) - - static Bigint * -multadd - (Bigint *b, int m, int a) /* multiply by m and add a */ -{ - int i, wds; -#ifdef ULLong - ULong *x; - ULLong carry, y; -#else - ULong carry, *x, y; -#ifdef Pack_32 - ULong xi, z; -#endif -#endif - Bigint *b1; - - wds = b->wds; - x = b->x; - i = 0; - carry = a; - do { -#ifdef ULLong - y = *x * (ULLong)m + carry; - carry = y >> 32; - *x++ = (ULong)y & FFFFFFFF; -#else -#ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + carry; - z = (xi >> 16) * m + (y >> 16); - carry = z >> 16; - *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + carry; - carry = y >> 16; - *x++ = y & 0xffff; -#endif -#endif - } - while(++i < wds); - if (carry) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = (ULong)carry; - b->wds = wds; - } - return b; - } - - static Bigint * -s2b - (CONST char *s, int nd0, int nd, ULong y9) -{ - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; -#ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); - s++; - } - else - s += 10; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; - } - - static int -hi0bits - (register ULong x) -{ - register int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; - } - - static int -lo0bits - (ULong *y) -{ - register int k; - register ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x & 1) - return 32; - } - *y = x; - return k; - } - - static Bigint * -i2b - (int i) -{ - Bigint *b; - - b = Balloc(1); - b->x[0] = i; - b->wds = 1; - return b; - } - - static Bigint * -mult - (Bigint *a, Bigint *b) -{ - Bigint *c; - int k, wa, wb, wc; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; - ULong y; -#ifdef ULLong - ULLong carry, z; -#else - ULong carry, z; -#ifdef Pack_32 - ULong z2; -#endif -#endif - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; -#ifdef ULLong - for(; xb < xbe; xc0++) { - if ((y = *xb++)) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * (ULLong)y + *xc + carry; - carry = z >> 32; - *xc++ = (ULong)z & FFFFFFFF; - } - while(x < xae); - *xc = (ULong)carry; - } - } -#else -#ifdef Pack_32 - for(; xb < xbe; xb++, xc0++) { - if (y = *xb & 0xffff) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } - while(x < xae); - *xc = carry; - } - if (y = *xb >> 16) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } - while(x < xae); - *xc = z2; - } - } -#else - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; - } - - static Bigint *p5s; - - static Bigint * -pow5mult - (Bigint *b, int k) -{ - Bigint *b1, *p5, *p51; - int i; - static int p05[3] = { 5, 25, 125 }; - - if ((i = k & 3)) - b = multadd(b, p05[i-1], 0); - - if (!(k >>= 2)) - return b; - if (!(p5 = p5s)) { - /* first time */ -#ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p5 = p5s)) { - p5 = p5s = i2b(625); - p5->next = 0; - } - FREE_DTOA_LOCK(1); -#else - p5 = p5s = i2b(625); - p5->next = 0; -#endif - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - if (!(p51 = p5->next)) { -#ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - FREE_DTOA_LOCK(1); -#else - p51 = p5->next = mult(p5,p5); - p51->next = 0; -#endif - } - p5 = p51; - } - return b; - } - - static Bigint * -lshift - (Bigint *b, int k) -{ - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; - -#ifdef Pack_32 - n = k >> 5; -#else - n = k >> 4; -#endif - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; -#ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if ((*x1 = z)) - ++n1; - } -#else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#endif - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; - } - - static int -cmp - (Bigint *a, Bigint *b) -{ - ULong *xa, *xa0, *xb, *xb0; - int i, j; - - i = a->wds; - j = b->wds; -#ifdef DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; - } - - static Bigint * -diff - (Bigint *a, Bigint *b) -{ - Bigint *c; - int i, wa, wb; - ULong *xa, *xae, *xb, *xbe, *xc; -#ifdef ULLong - ULLong borrow, y; -#else - ULong borrow, y; -#ifdef Pack_32 - ULong z; -#endif -#endif - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; -#ifdef ULLong - do { - y = (ULLong)*xa++ - *xb++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = (ULong)y & FFFFFFFF; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = (ULong)y & FFFFFFFF; - } -#else -#ifdef Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } -#else - do { - y = *xa++ - *xb++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } -#endif -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; - } - - static double -ulp - (double dx) -{ - register Long L; - U x, a; - - dval(x) = dx; - L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - if (L > 0) { -#endif -#endif -#ifdef IBM - L |= Exp_msk1 >> 4; -#endif - word0(a) = L; - word1(a) = 0; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - } - else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - word0(a) = 0x80000 >> L; - word1(a) = 0; - } - else { - word0(a) = 0; - L -= Exp_shift; - word1(a) = L >= 31 ? 1 : 1 << 31 - L; - } - } -#endif -#endif - return dval(a); - } - - static double -b2d - (Bigint *a, int *e) -{ - ULong *xa, *xa0, w, y, z; - int k; - U d; -#ifdef VAX - ULong d0, d1; -#else -#define d0 word0(d) -#define d1 word1(d) -#endif - - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; -#ifdef DEBUG - if (!y) Bug("zero y in b2d"); -#endif - k = hi0bits(y); - *e = 32 - k; -#ifdef Pack_32 - if (k < Ebits) { - d0 = Exp_1 | y >> (Ebits - k); - w = xa > xa0 ? *--xa : 0; - d1 = y << (32-Ebits + k) | w >> (Ebits - k); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> (32 - k); - y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> (32 - k); - } - else { - d0 = Exp_1 | y; - d1 = z; - } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; - y = xa > xa0 ? *--xa : 0; - d1 = w << k + 16 | y << k; -#endif - ret_d: -#ifdef VAX - word0(d) = d0 >> 16 | d0 << 16; - word1(d) = d1 >> 16 | d1 << 16; -#else -#undef d0 -#undef d1 -#endif - return dval(d); - } - - static Bigint * -d2b - (double dd, int *e, int *bits) -{ - U d; - Bigint *b; - int de, k; - ULong *x, y, z; -#ifndef Sudden_Underflow - int i; -#endif -#ifdef VAX - ULong d0, d1; -#endif - dval(d) = dd; -#ifdef VAX - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; -#else -#define d0 word0(d) -#define d1 word1(d) -#endif - -#ifdef Pack_32 - b = Balloc(1); -#else - b = Balloc(2); -#endif - x = b->x; - - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ -#ifdef Sudden_Underflow - de = (int)(d0 >> Exp_shift); -#ifndef IBM - z |= Exp_msk11; -#endif -#else - if ((de = (int)(d0 >> Exp_shift))) - z |= Exp_msk1; -#endif -#ifdef Pack_32 - if ((y = d1)) { - if ((k = lo0bits(&y))) { - x[0] = y | z << (32 - k); - z >>= k; - } - else - x[0] = y; -#ifndef Sudden_Underflow - i = -#endif - b->wds = (x[1] = z) ? 2 : 1; - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - x[0] = z; -#ifndef Sudden_Underflow - i = -#endif - b->wds = 1; - k += 32; - } -#else - if (y = d1) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while(!x[i]) - --i; - b->wds = i + 1; -#endif -#ifndef Sudden_Underflow - if (de) { -#endif -#ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); -#else - *e = de - Bias - (P-1) + k; - *bits = P - k; -#endif -#ifndef Sudden_Underflow - } - else { - *e = de - Bias - (P-1) + 1 + k; -#ifdef Pack_32 - *bits = 32*i - hi0bits(x[i-1]); -#else - *bits = (i+2)*16 - hi0bits(x[i]); -#endif - } -#endif - return b; - } -#undef d0 -#undef d1 - - static double -ratio - (Bigint *a, Bigint *b) -{ - U da, db; - int k, ka, kb; - - dval(da) = b2d(a, &ka); - dval(db) = b2d(b, &kb); -#ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); -#else - k = ka - kb + 16*(a->wds - b->wds); -#endif -#ifdef IBM - if (k > 0) { - word0(da) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(da) *= 1 << k; - } - else { - k = -k; - word0(db) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(db) *= 1 << k; - } -#else - if (k > 0) - word0(da) += k*Exp_msk1; - else { - k = -k; - word0(db) += k*Exp_msk1; - } -#endif - return dval(da) / dval(db); - } - - static CONST double -tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 -#ifdef VAX - , 1e23, 1e24 -#endif - }; - - static CONST double -#ifdef IEEE_Arith -bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, -#ifdef Avoid_Underflow - 9007199254740992.*9007199254740992.e-256 - /* = 2^106 * 1e-53 */ -#else - 1e-256 -#endif - }; -/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ -/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ -#define Scale_Bit 0x10 -#define n_bigtens 5 -#else -#ifdef IBM -bigtens[] = { 1e16, 1e32, 1e64 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; -#define n_bigtens 3 -#else -bigtens[] = { 1e16, 1e32 }; -static CONST double tinytens[] = { 1e-16, 1e-32 }; -#define n_bigtens 2 -#endif -#endif - -#ifndef IEEE_Arith -#undef INFNAN_CHECK -#endif - -#ifdef INFNAN_CHECK - -#ifndef NAN_WORD0 -#define NAN_WORD0 0x7ff80000 -#endif - -#ifndef NAN_WORD1 -#define NAN_WORD1 0 -#endif - - static int -match - (CONST char **sp, CONST char *t) -{ - int c, d; - CONST char *s = *sp; - - while((d = *t++)) { - if ((c = *++s) >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != d) - return 0; - } - *sp = s + 1; - return 1; - } - -#ifndef No_Hex_NaN - static void -hexnan - (U *rvp, CONST char **sp) -{ - ULong c, x[2]; - CONST char *s; - int havedig, udx0, xshift; - - x[0] = x[1] = 0; - havedig = xshift = 0; - udx0 = 1; - s = *sp; - while((c = *(CONST unsigned char*)++s)) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'a' && c <= 'f') - c += 10 - 'a'; - else if (c >= 'A' && c <= 'F') - c += 10 - 'A'; - else if (c <= ' ') { - if (udx0 && havedig) { - udx0 = 0; - xshift = 1; - } - continue; - } - else if (/*(*/ c == ')' && havedig) { - *sp = s + 1; - break; - } - else - return; /* invalid form: don't change *sp */ - havedig = 1; - if (xshift) { - xshift = 0; - x[0] = x[1]; - x[1] = 0; - } - if (udx0) - x[0] = (x[0] << 4) | (x[1] >> 28); - x[1] = (x[1] << 4) | c; - } - if ((x[0] &= 0xfffff) || x[1]) { - word0(*rvp) = Exp_mask | x[0]; - word1(*rvp) = x[1]; - } - } -#endif /*No_Hex_NaN*/ -#endif /* INFNAN_CHECK */ - - double -strtod - (CONST char *s00, char **se) -{ -#ifdef Avoid_Underflow - int scale; -#endif - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, - e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - CONST char *s, *s0, *s1; - double aadj, aadj1, adj; - U aadj2, rv, rv0; - Long L; - ULong y, z; - Bigint *bb = NULL, *bb1 = NULL, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL; -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif -#ifdef Honor_FLT_ROUNDS - int rounding; -#endif -#ifdef USE_LOCALE - CONST char *s2; -#endif - - sign = nz0 = nz = 0; - dval(rv) = 0.; - for(s = s00;;s++) switch(*s) { - case '-': - sign = 1; - /* no break */ - case '+': - if (*++s) - goto break2; - /* no break */ - case 0: - goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; - default: - goto break2; - } - break2: - if (*s == '0') { - nz0 = 1; - while(*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < 16) - z = 10*z + c - '0'; - nd0 = nd; -#ifdef USE_LOCALE - s1 = localeconv()->decimal_point; - if (c == *s1) { - c = '.'; - if (*++s1) { - s2 = s; - for(;;) { - if (*++s2 != *s1) { - c = 0; - break; - } - if (!*++s1) { - s = s2; - break; - } - } - } - } -#endif - if (c == '.') { - c = *++s; - if (!nd) { - for(; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for(; c >= '0' && c <= '9'; c = *++s) { - have_dig: - nz++; - if (c -= '0') { - nf += nz; - for(i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 1) - z = 10*z + c; - nz = 0; - } - } - } - dig_done: - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - goto ret0; - } - s00 = s; - esign = 0; - switch(c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while(c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) { -#ifdef INFNAN_CHECK - /* Check for Nan and Infinity */ - switch(c) { - case 'i': - case 'I': - if (match(&s,"nf")) { - --s; - if (!match(&s,"inity")) - ++s; - word0(rv) = 0x7ff00000; - word1(rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(rv) = NAN_WORD0; - word1(rv) = NAN_WORD1; -#ifndef No_Hex_NaN - if (*s == '(') /*)*/ - hexnan(&rv, &s); -#endif - goto ret; - } - } -#endif /* INFNAN_CHECK */ - ret0: - s = s00; - sign = 0; - } - goto ret; - } - e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv) = y; - if (k > 9) { -#ifdef SET_INEXACT - if (k > DBL_DIG) - oldinexact = get_inexact(); -#endif - dval(rv) = tens[k - 9] * dval(rv) + z; - } - bd0 = 0; - if (nd <= DBL_DIG -#ifndef RND_PRODQUOT -#ifndef Honor_FLT_ROUNDS - && Flt_Rounds == 1 -#endif -#endif - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { -#ifdef VAX - goto vax_ovfl_check; -#else -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv = -rv; - sign = 0; - } -#endif - /* rv = */ rounded_product(dval(rv), tens[e]); - goto ret; -#endif - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv = -rv; - sign = 0; - } -#endif - e -= i; - dval(rv) *= tens[i]; -#ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ - vax_ovfl_check: - word0(rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(rv), tens[e]); - if ((word0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - word0(rv) += P*Exp_msk1; -#else - /* rv = */ rounded_product(dval(rv), tens[e]); -#endif - goto ret; - } - } -#ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv = -rv; - sign = 0; - } -#endif - /* rv = */ rounded_quotient(dval(rv), tens[-e]); - goto ret; - } -#endif - } - e1 += nd - k; - -#ifdef IEEE_Arith -#ifdef SET_INEXACT - inexact = 1; - if (k <= DBL_DIG) - oldinexact = get_inexact(); -#endif -#ifdef Avoid_Underflow - scale = 0; -#endif -#ifdef Honor_FLT_ROUNDS - if ((rounding = Flt_Rounds) >= 2) { - if (sign) - rounding = rounding == 2 ? 0 : 2; - else - if (rounding != 2) - rounding = 0; - } -#endif -#endif /*IEEE_Arith*/ - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if ((i = e1 & 15)) - dval(rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - /* Can't trust HUGE_VAL */ -#ifdef IEEE_Arith -#ifdef Honor_FLT_ROUNDS - switch(rounding) { - case 0: /* toward 0 */ - case 3: /* toward -infinity */ - word0(rv) = Big0; - word1(rv) = Big1; - break; - default: - word0(rv) = Exp_mask; - word1(rv) = 0; - } -#else /*Honor_FLT_ROUNDS*/ - word0(rv) = Exp_mask; - word1(rv) = 0; -#endif /*Honor_FLT_ROUNDS*/ -#ifdef SET_INEXACT - /* set overflow bit */ - dval(rv0) = 1e300; - dval(rv0) *= dval(rv0); -#endif -#else /*IEEE_Arith*/ - word0(rv) = Big0; - word1(rv) = Big1; -#endif /*IEEE_Arith*/ - if (bd0) - goto retfree; - goto ret; - } - e1 >>= 4; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(rv) -= P*Exp_msk1; - dval(rv) *= bigtens[j]; - if ((z = word0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(rv) = Big0; - word1(rv) = Big1; - } - else - word0(rv) += P*Exp_msk1; - } - } - else if (e1 < 0) { - e1 = -e1; - if ((i = e1 & 15)) - dval(rv) /= tens[i]; - if (e1 >>= 4) { - if (e1 >= 1 << n_bigtens) - goto undfl; -#ifdef Avoid_Underflow - if (e1 & Scale_Bit) - scale = 2*P; - for(j = 0; e1 > 0; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= tinytens[j]; - if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) - >> Exp_shift)) > 0) { - /* scaled rv is denormal; zap j low bits */ - if (j >= 32) { - word1(rv) = 0; - if (j >= 53) - word0(rv) = (P+2)*Exp_msk1; - else - word0(rv) &= 0xffffffff << (j-32); - } - else - word1(rv) &= 0xffffffff << j; - } -#else - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= tinytens[j]; - /* The last multiplication could underflow. */ - dval(rv0) = dval(rv); - dval(rv) *= tinytens[j]; - if (!dval(rv)) { - dval(rv) = 2.*dval(rv0); - dval(rv) *= tinytens[j]; -#endif - if (!dval(rv)) { - undfl: - dval(rv) = 0.; -#ifndef NO_ERRNO - errno = ERANGE; -#endif - if (bd0) - goto retfree; - goto ret; - } -#ifndef Avoid_Underflow - word0(rv) = Tiny0; - word1(rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } -#endif - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bd0 = s2b(s0, nd0, nd, y); - - for(;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ - bs = i2b(1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; -#ifdef Honor_FLT_ROUNDS - if (rounding != 1) - bs2++; -#endif -#ifdef Avoid_Underflow - j = bbe - scale; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#else /*Avoid_Underflow*/ -#ifdef Sudden_Underflow -#ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); -#else - j = P + 1 - bbbits; -#endif -#else /*Sudden_Underflow*/ - j = bbe; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - bb2 += j; - bd2 += j; -#ifdef Avoid_Underflow - bd2 += scale; -#endif - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - } - if (bb2 > 0) - bb = lshift(bb, bb2); - if (bd5 > 0) - bd = pow5mult(bd, bd5); - if (bd2 > 0) - bd = lshift(bd, bd2); - if (bs2 > 0) - bs = lshift(bs, bs2); - delta = diff(bb, bd); - dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); -#ifdef Honor_FLT_ROUNDS - if (rounding != 1) { - if (i < 0) { - /* Error is less than an ulp */ - if (!delta->x[0] && delta->wds <= 1) { - /* exact */ -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - if (rounding) { - if (dsign) { - adj = 1.; - goto apply_adj; - } - } - else if (!dsign) { - adj = -1.; - if (!word1(rv) - && !(word0(rv) & Frac_mask)) { - y = word0(rv) & Exp_mask; -#ifdef Avoid_Underflow - if (!scale || y > 2*P*Exp_msk1) -#else - if (y) -#endif - { - delta = lshift(delta,Log2P); - if (cmp(delta, bs) <= 0) - adj = -0.5; - } - } - apply_adj: -#ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) - <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= - P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - dval(rv) += adj*ulp(dval(rv)); - word0(rv) -= P*Exp_msk1; - } - else -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - dval(rv) += adj*ulp(dval(rv)); - } - break; - } - adj = ratio(delta, bs); - if (adj < 1.) - adj = 1.; - if (adj <= 0x7ffffffe) { - /* adj = rounding ? ceil(adj) : floor(adj); */ - y = adj; - if (y != adj) { - if (!((rounding>>1) ^ dsign)) - y++; - adj = y; - } - } -#ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - adj *= ulp(dval(rv)); - if (dsign) - dval(rv) += adj; - else - dval(rv) -= adj; - word0(rv) -= P*Exp_msk1; - goto cont; - } -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - adj *= ulp(dval(rv)); - if (dsign) - dval(rv) += adj; - else - dval(rv) -= adj; - goto cont; - } -#endif /*Honor_FLT_ROUNDS*/ - - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask -#ifdef IEEE_Arith -#ifdef Avoid_Underflow - || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 -#else - || (word0(rv) & Exp_mask) <= Exp_msk1 -#endif -#endif - ) { -#ifdef SET_INEXACT - if (!delta->x[0] && delta->wds <= 1) - inexact = 0; -#endif - break; - } - if (!delta->x[0] && delta->wds <= 1) { - /* exact result */ -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - delta = lshift(delta,Log2P); - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (dsign) { - if ((word0(rv) & Bndry_mask1) == Bndry_mask1 - && word1(rv) == ( -#ifdef Avoid_Underflow - (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : -#endif - 0xffffffff)) { - /*boundary case -- increment exponent*/ - word0(rv) = (word0(rv) & Exp_mask) - + Exp_msk1 -#ifdef IBM - | Exp_msk1 >> 4 -#endif - ; - word1(rv) = 0; -#ifdef Avoid_Underflow - dsign = 0; -#endif - break; - } - } - else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { - drop_down: - /* boundary case -- decrement exponent */ -#ifdef Sudden_Underflow /*{{*/ - L = word0(rv) & Exp_mask; -#ifdef IBM - if (L < Exp_msk1) -#else -#ifdef Avoid_Underflow - if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) -#else - if (L <= Exp_msk1) -#endif /*Avoid_Underflow*/ -#endif /*IBM*/ - goto undfl; - L -= Exp_msk1; -#else /*Sudden_Underflow}{*/ -#ifdef Avoid_Underflow - if (scale) { - L = word0(rv) & Exp_mask; - if (L <= (2*P+1)*Exp_msk1) { - if (L > (P+2)*Exp_msk1) - /* round even ==> */ - /* accept rv */ - break; - /* rv = smallest denormal */ - goto undfl; - } - } -#endif /*Avoid_Underflow*/ - L = (word0(rv) & Exp_mask) - Exp_msk1; -#endif /*Sudden_Underflow}}*/ - word0(rv) = L | Bndry_mask1; - word1(rv) = 0xffffffff; -#ifdef IBM - goto cont; -#else - break; -#endif - } -#ifndef ROUND_BIASED - if (!(word1(rv) & LSB)) - break; -#endif - if (dsign) - dval(rv) += ulp(dval(rv)); -#ifndef ROUND_BIASED - else { - dval(rv) -= ulp(dval(rv)); -#ifndef Sudden_Underflow - if (!dval(rv)) - goto undfl; -#endif - } -#ifdef Avoid_Underflow - dsign = 1 - dsign; -#endif -#endif - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (dsign) - aadj = aadj1 = 1.; - else if (word1(rv) || word0(rv) & Bndry_mask) { -#ifndef Sudden_Underflow - if (word1(rv) == Tiny1 && !word0(rv)) - goto undfl; -#endif - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; -#ifdef Check_FLT_ROUNDS - switch(Rounding) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } -#else - if (Flt_Rounds == 0) - aadj1 += 0.5; -#endif /*Check_FLT_ROUNDS*/ - } - y = word0(rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(rv0) = dval(rv); - word0(rv) -= P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; - if ((word0(rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(rv0) == Big0 && word1(rv0) == Big1) - goto ovfl; - word0(rv) = Big0; - word1(rv) = Big1; - goto cont; - } - else - word0(rv) += P*Exp_msk1; - } - else { -#ifdef Avoid_Underflow - if (scale && y <= 2*P*Exp_msk1) { - if (aadj <= 0x7fffffff) { - if ((z = (ULong)aadj) <= 0) - z = 1; - aadj = z; - aadj1 = dsign ? aadj : -aadj; - } - dval(aadj2) = aadj1; - word0(aadj2) += (2*P+1)*Exp_msk1 - y; - aadj1 = dval(aadj2); - } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; -#else -#ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - dval(rv0) = dval(rv); - word0(rv) += P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; -#ifdef IBM - if ((word0(rv) & Exp_mask) < P*Exp_msk1) -#else - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) -#endif - { - if (word0(rv0) == Tiny0 - && word1(rv0) == Tiny1) - goto undfl; - word0(rv) = Tiny0; - word1(rv) = Tiny1; - goto cont; - } - else - word0(rv) -= P*Exp_msk1; - } - else { - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; - } -#else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!dsign) - aadj1 = -aadj1; - } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - } - z = word0(rv) & Exp_mask; -#ifndef SET_INEXACT -#ifdef Avoid_Underflow - if (!scale) -#endif - if (y == z) { - /* Can we stop now? */ - L = (Long)aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } -#endif - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(rv0) = Exp_1 + (70 << Exp_shift); - word1(rv0) = 0; - dval(rv0) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif -#ifdef Avoid_Underflow - if (scale) { - word0(rv0) = Exp_1 - 2*P*Exp_msk1; - word1(rv0) = 0; - dval(rv) *= dval(rv0); -#ifndef NO_ERRNO - /* try to avoid the bug of testing an 8087 register value */ - if (word0(rv) == 0 && word1(rv) == 0) - errno = ERANGE; -#endif - } -#endif /* Avoid_Underflow */ -#ifdef SET_INEXACT - if (inexact && !(word0(rv) & Exp_mask)) { - /* set underflow bit */ - dval(rv0) = 1e-300; - dval(rv0) *= dval(rv0); - } -#endif - retfree: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - ret: - if (se) - *se = (char *)s; - return sign ? -dval(rv) : dval(rv); - } - - static int -quorem - (Bigint *b, Bigint *S) -{ - int n; - ULong *bx, *bxe, q, *sx, *sxe; -#ifdef ULLong - ULLong borrow, carry, y, ys; -#else - ULong borrow, carry, y, ys; -#ifdef Pack_32 - ULong si, z, zs; -#endif -#endif - - n = S->wds; -#ifdef DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ -#ifdef DEBUG - /*debug*/ if (q > 9) - /*debug*/ Bug("oversized quotient in quorem"); -#endif - if (q) { - borrow = 0; - carry = 0; - do { -#ifdef ULLong - ys = *sx++ * (ULLong)q + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = (ULong)y & FFFFFFFF; -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { -#ifdef ULLong - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = (ULong)y & FFFFFFFF; -#else -#ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; - } - -#ifndef MULTIPLE_THREADS - static char *dtoa_result; -#endif - - static char * -rv_alloc(int i) -{ - int j, k, *r; - - j = sizeof(ULong); - for(k = 0; - sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (unsigned)i; - j <<= 1) - k++; - r = (int*)Balloc(k); - *r = k; - return -#ifndef MULTIPLE_THREADS - dtoa_result = -#endif - (char *)(r+1); - } - - static char * -nrv_alloc(CONST char *s, char **rve, int n) -{ - char *rv, *t; - - t = rv = rv_alloc(n); - while((*t = *s++)) t++; - if (rve) - *rve = t; - return rv; - } - -/* freedtoa(s) must be used to free values s returned by dtoa - * when MULTIPLE_THREADS is #defined. It should be used in all cases, - * but for consistency with earlier versions of dtoa, it is optional - * when MULTIPLE_THREADS is not defined. - */ - - void -freedtoa(char *s) -{ - Bigint *b = (Bigint *)((int *)s - 1); - b->maxwds = 1 << (b->k = *(int*)b); - Bfree(b); -#ifndef MULTIPLE_THREADS - if (s == dtoa_result) - dtoa_result = 0; -#endif - } - -/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - - char * -dtoa - (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) -{ - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4,5 ==> similar to 2 and 3, respectively, but (in - round-nearest mode) with the tests of mode 0 to - possibly return a shorter string that rounds to d. - With IEEE arithmetic and compilation with - -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same - as modes 2 and 3 when FLT_ROUNDS != 1. - 6-9 ==> Debugging modes similar to mode - 4: don't try - fast floating-point estimate (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; - Long L; -#ifndef Sudden_Underflow - int denorm; - ULong x; -#endif - Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S; - U d, d2, eps; - double ds; - char *s, *s0; -#ifdef Honor_FLT_ROUNDS - int rounding; -#endif -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif - -#ifndef MULTIPLE_THREADS - if (dtoa_result) { - freedtoa(dtoa_result); - dtoa_result = 0; - } -#endif - - dval(d) = dd; - if (word0(d) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(d) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; - -#if defined(IEEE_Arith) + defined(VAX) -#ifdef IEEE_Arith - if ((word0(d) & Exp_mask) == Exp_mask) -#else - if (word0(d) == 0x8000) -#endif - { - /* Infinity or NaN */ - *decpt = 9999; -#ifdef IEEE_Arith - if (!word1(d) && !(word0(d) & 0xfffff)) - return nrv_alloc("Infinity", rve, 8); -#endif - return nrv_alloc("NaN", rve, 3); - } -#endif -#ifdef IBM - dval(d) += 0; /* normalize */ -#endif - if (!dval(d)) { - *decpt = 1; - return nrv_alloc("0", rve, 1); - } - -#ifdef SET_INEXACT - try_quick = oldinexact = get_inexact(); - inexact = 1; -#endif -#ifdef Honor_FLT_ROUNDS - if ((rounding = Flt_Rounds) >= 2) { - if (*sign) - rounding = rounding == 2 ? 0 : 2; - else - if (rounding != 2) - rounding = 0; - } -#endif - - b = d2b(dval(d), &be, &bbits); -#ifdef Sudden_Underflow - i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); -#else - if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { -#endif - dval(d2) = dval(d); - word0(d2) &= Frac_mask1; - word0(d2) |= Exp_11; -#ifdef IBM - if (j = 11 - hi0bits(word0(d2) & Frac_mask)) - dval(d2) /= 1 << j; -#endif - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; -#ifdef IBM - i <<= 2; - i += j; -#endif -#ifndef Sudden_Underflow - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) - : word1(d) << (32 - i); - dval(d2) = x; - word0(d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (dval(d) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; - -#ifndef SET_INEXACT -#ifdef Check_FLT_ROUNDS - try_quick = Rounding == 1; -#else - try_quick = 1; -#endif -#endif /*SET_INEXACT*/ - - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - switch(mode) { - case 0: - case 1: - ilim = ilim1 = -1; - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - s = s0 = rv_alloc(i); - -#ifdef Honor_FLT_ROUNDS - if (mode > 1 && rounding != 1) - leftright = 0; -#endif - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - dval(d2) = dval(d); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - dval(d) /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - dval(d) /= ds; - } - else if ((j1 = -k)) { - dval(d) *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - dval(d) *= bigtens[i]; - } - } - if (k_check && dval(d) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - dval(d) *= 10.; - ieps++; - } - dval(eps) = ieps*dval(d) + 7.; - word0(eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - dval(d) -= 5.; - if (dval(d) > dval(eps)) - goto one_digit; - if (dval(d) < -dval(eps)) - goto no_digits; - goto fast_failed; - } -#ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - dval(eps) = 0.5/tens[ilim-1] - dval(eps); - for(i = 0;;) { - L = (long int)dval(d); - dval(d) -= L; - *s++ = '0' + (int)L; - if (dval(d) < dval(eps)) - goto ret1; - if (1. - dval(d) < dval(eps)) - goto bump_up; - if (++i >= ilim) - break; - dval(eps) *= 10.; - dval(d) *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - dval(eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d)); - if (!(dval(d) -= L)) - ilim = i; - *s++ = '0' + (int)L; - if (i == ilim) { - if (dval(d) > 0.5 + dval(eps)) - goto bump_up; - else if (dval(d) < 0.5 - dval(eps)) { - while(*--s == '0') - ; - s++; - goto ret1; - } - break; - } - } -#ifndef No_leftright - } -#endif - fast_failed: - s = s0; - dval(d) = dval(d2); - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || dval(d) <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d) / ds); - dval(d) -= L*ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(d) < 0) { - L--; - dval(d) += ds; - } -#endif - *s++ = '0' + (int)L; - if (!dval(d)) { -#ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - if (i == ilim) { -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(rounding) { - case 0: goto ret1; - case 2: goto bump_up; - } -#endif - dval(d) += dval(d); - if (dval(d) > ds || (dval(d) == ds && L & 1)) { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - } - goto ret1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = 0; - if (leftright) { - i = -#ifndef Sudden_Underflow - denorm ? be + (Bias + (P-1) - 1 + 1) : -#endif -#ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); -#else - 1 + P - bbits; -#endif - b2 += i; - s2 += i; - mhi = i2b(1); - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mult(mhi, b); - Bfree(b); - b = b1; - } - if ((j = b5 - m5)) - b = pow5mult(b, j); - } - else - b = pow5mult(b, b5); - } - S = i2b(1); - if (s5 > 0) - S = pow5mult(S, s5); - - /* Check for special case that d is a normalized power of 2. */ - - spec_case = 0; - if ((mode < 2 || leftright) -#ifdef Honor_FLT_ROUNDS - && rounding == 1 -#endif - ) { - if (!word1(d) && !(word0(d) & Bndry_mask) -#ifndef Sudden_Underflow - && word0(d) & (Exp_mask & ~Exp_msk1) -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ -#ifdef Pack_32 - if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)) - i = 32 - i; -#else - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) - i = 16 - i; -#endif - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } - else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - if (b2 > 0) - b = lshift(b, b2); - if (s2 > 0) - S = lshift(S, s2); - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - mhi = multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && (mode == 3 || mode == 5)) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) - mhi = lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); -#ifndef ROUND_BIASED - if (j1 == 0 && mode != 1 && !(word1(d) & 1) -#ifdef Honor_FLT_ROUNDS - && rounding >= 1 -#endif - ) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; -#ifdef SET_INEXACT - else if (!b->x[0] && b->wds <= 1) - inexact = 0; -#endif - *s++ = dig; - goto ret; - } -#endif - if (j < 0 || (j == 0 && mode != 1 -#ifndef ROUND_BIASED - && !(word1(d) & 1) -#endif - )) { - if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif - goto accept_dig; - } -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(rounding) { - case 0: goto accept_dig; - case 2: goto keep_dig; - } -#endif /*Honor_FLT_ROUNDS*/ - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); - if ((j1 > 0 || (j1 == 0 && dig & 1)) - && dig++ == '9') - goto round_9_up; - } - accept_dig: - *s++ = dig; - goto ret; - } - if (j1 > 0) { -#ifdef Honor_FLT_ROUNDS - if (!rounding) - goto accept_dig; -#endif - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } -#ifdef Honor_FLT_ROUNDS - keep_dig: -#endif - *s++ = dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (mlo == mhi) - mlo = mhi = multadd(mhi, 10, 0); - else { - mlo = multadd(mlo, 10, 0); - mhi = multadd(mhi, 10, 0); - } - } - } - else - for(i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; - if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif - goto ret; - } - if (i >= ilim) - break; - b = multadd(b, 10, 0); - } - - /* Round off last digit */ - -#ifdef Honor_FLT_ROUNDS - switch(rounding) { - case 0: goto trimzeros; - case 2: goto roundoff; - } -#endif - b = lshift(b, 1); - j = cmp(b, S); - if (j > 0 || (j == 0 && dig & 1)) { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { -#ifdef Honor_FLT_ROUNDS -trimzeros: -#endif - while(*--s == '0') - ; - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(d) = Exp_1 + (70 << Exp_shift); - word1(d) = 0; - dval(d) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif - Bfree(b); - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; - } -#ifdef __cplusplus -} -#endif diff --git a/kjs/dtoa.h b/kjs/dtoa.h deleted file mode 100644 index 188a4878..00000000 --- a/kjs/dtoa.h +++ /dev/null @@ -1,31 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 2003 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _KJS_DTOA_H_ -#define _KJS_DTOA_H_ - -extern "C" double kjs_strtod(const char *s00, char **se); -extern "C" char *kjs_dtoa(double d, int mode, int ndigits, - int *decpt, int *sign, char **rve); -extern "C" void kjs_freedtoa(char *s); - -#endif /* _KJS_DTOA_H */ diff --git a/kjs/error_object.cpp b/kjs/error_object.cpp deleted file mode 100644 index ea42f47d..00000000 --- a/kjs/error_object.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "error_object.h" -#include - -#include "value.h" -#include "object.h" -#include "types.h" -#include "interpreter.h" -#include "operations.h" -//#include "debugger.h" - -using namespace KJS; - -// ------------------------------ ErrorInstance ---------------------------- - -const ClassInfo ErrorInstance::info = {"Error", 0, 0, 0}; - -ErrorInstance::ErrorInstance(JSObject *proto) -: JSObject(proto) -{ -} - -// ------------------------------ ErrorPrototype ---------------------------- - -// ECMA 15.9.4 -ErrorPrototype::ErrorPrototype(ExecState* exec, - ObjectPrototype* objectProto, - FunctionPrototype* funcProto) - : ErrorInstance(objectProto) -{ - // Interpreter::initGlobalObject sets the constructor property - // on the prototypes for this and the native error types - - put(exec, exec->propertyNames().name, jsString("Error"), DontEnum); - // ECMA Edition 5.1r6 - 15.11.4.3 - // The initial value of Error.prototype.message is the empty String. - put(exec, exec->propertyNames().message, jsString(""), DontEnum); - putDirectFunction(new ErrorProtoFunc(exec, funcProto, exec->propertyNames().toString), DontEnum); -} - -// ------------------------------ ErrorProtoFunc ---------------------------- - -ErrorProtoFunc::ErrorProtoFunc(ExecState* exec, FunctionPrototype* funcProto, const Identifier& name) - : InternalFunctionImp(funcProto, name) -{ - putDirect(exec->propertyNames().length, jsNumber(0), DontDelete|ReadOnly|DontEnum); -} - -JSValue* ErrorProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, const List &/*args*/) -{ - // toString() - UString name; - JSValue* v = thisObj->get(exec, exec->propertyNames().name); - if (!v->isUndefined()) - name = v->toString(exec); - else - name = "Error"; - - UString message; - v = thisObj->get(exec, exec->propertyNames().message); - if (!v->isUndefined()) - message = v->toString(exec); - - if (name.isEmpty()) - return jsString(message); - if (message.isEmpty()) - return jsString(name); - - return jsString(name + ": " + message); -} - -// ------------------------------ ErrorObjectImp ------------------------------- - -ErrorObjectImp::ErrorObjectImp(ExecState* exec, FunctionPrototype* funcProto, ErrorPrototype* errorProto) - : InternalFunctionImp(funcProto) -{ - // ECMA 15.11.3.1 Error.prototype - putDirect(exec->propertyNames().prototype, errorProto, DontEnum|DontDelete|ReadOnly); - putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum); - //putDirect(namePropertyName, jsString(n)); -} - -bool ErrorObjectImp::implementsConstruct() const -{ - return true; -} - -// ECMA 15.9.3 -JSObject* ErrorObjectImp::construct(ExecState* exec, const List& args) -{ - JSObject* proto = static_cast(exec->lexicalInterpreter()->builtinErrorPrototype()); - JSObject* imp = new ErrorInstance(proto); - JSObject* obj(imp); - - if (!args[0]->isUndefined()) - imp->putDirect(exec->propertyNames().message, jsString(args[0]->toString(exec))); - - return obj; -} - -// ECMA 15.9.2 -JSValue* ErrorObjectImp::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const List &args) -{ - // "Error()" gives the sames result as "new Error()" - return construct(exec, args); -} - -// ------------------------------ NativeErrorPrototype ---------------------- - -NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, ErrorPrototype* errorProto, ErrorType et, UString name, UString message) - : JSObject(errorProto) -{ - errType = et; - putDirect(exec->propertyNames().name, jsString(name), 0); - putDirect(exec->propertyNames().message, jsString(message), 0); -} - -// ------------------------------ NativeErrorImp ------------------------------- - -const ClassInfo NativeErrorImp::info = {"Function", &InternalFunctionImp::info, 0, 0}; - -NativeErrorImp::NativeErrorImp(ExecState* exec, FunctionPrototype* funcProto, JSObject* prot) - : InternalFunctionImp(funcProto) - , proto(prot) -{ - putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum); // ECMA 15.11.7.5 - putDirect(exec->propertyNames().prototype, proto, DontDelete|ReadOnly|DontEnum); -} - -bool NativeErrorImp::implementsConstruct() const -{ - return true; -} - -JSObject* NativeErrorImp::construct(ExecState* exec, const List& args) -{ - JSObject* imp = new ErrorInstance(proto); - JSObject* obj(imp); - if (!args[0]->isUndefined()) - imp->putDirect(exec->propertyNames().message, jsString(args[0]->toString(exec))); - return obj; -} - -JSValue* NativeErrorImp::callAsFunction(ExecState* exec, JSObject*, const List& args) -{ - return construct(exec, args); -} - -void NativeErrorImp::mark() -{ - InternalFunctionImp::mark(); - if (proto && !proto->marked()) - proto->mark(); -} diff --git a/kjs/error_object.h b/kjs/error_object.h deleted file mode 100644 index 8c151d48..00000000 --- a/kjs/error_object.h +++ /dev/null @@ -1,90 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ERROR_OBJECT_H_ -#define ERROR_OBJECT_H_ - -#include "function_object.h" - -namespace KJS { - - class ErrorInstance : public JSObject { - public: - ErrorInstance(JSObject *proto); - - virtual const ClassInfo *classInfo() const { return &info; } - static const ClassInfo info; - }; - - class ErrorPrototype : public ErrorInstance { - public: - ErrorPrototype(ExecState *exec, - ObjectPrototype *objectProto, - FunctionPrototype *funcProto); - }; - - class ErrorProtoFunc : public InternalFunctionImp { - public: - ErrorProtoFunc(ExecState*, FunctionPrototype*, const Identifier&); - virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); - }; - - class ErrorObjectImp : public InternalFunctionImp { - public: - ErrorObjectImp(ExecState *exec, FunctionPrototype *funcProto, - ErrorPrototype *errorProto); - - virtual bool implementsConstruct() const; - using KJS::JSObject::construct; - virtual JSObject *construct(ExecState *exec, const List &args); - - virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); - }; - - class NativeErrorPrototype : public JSObject { - public: - NativeErrorPrototype(ExecState *exec, ErrorPrototype *errorProto, - ErrorType et, UString name, UString message); - private: - ErrorType errType; - }; - - class NativeErrorImp : public InternalFunctionImp { - public: - NativeErrorImp(ExecState *exec, FunctionPrototype *funcProto, - JSObject *prot); - - virtual bool implementsConstruct() const; - using KJS::JSObject::construct; - virtual JSObject *construct(ExecState *exec, const List &args); - virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); - - virtual void mark(); - - virtual const ClassInfo *classInfo() const { return &info; } - static const ClassInfo info; - private: - JSObject *proto; - }; - -} // namespace - -#endif diff --git a/kjs/fpconst.cpp b/kjs/fpconst.cpp deleted file mode 100644 index ad0deed7..00000000 --- a/kjs/fpconst.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2003, 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * - */ - -#include -#include "global.h" - -namespace KJS { - -// This file exists because JavaScriptCore needs to define the NaN and Inf globals in a way -// that does not use a static initializer so we don't have a framework initialization routine. - -// The trick is to define the NaN and Inf globals with a different type than the declaration. -// This trick works because the mangled name of the globals does not include the type, although -// I'm not sure that's guaranteed. There could be alignment issues with this, since arrays of -// characters don't necessarily need the same alignment doubles do, but for now it seems to work. -// It would be good to figure out a 100% clean way that still avoids code that runs at init time. - -#if (defined(AVOID_STATIC_CONSTRUCTORS) && !AVOID_STATIC_CONSTRUCTORS) - KJS_EXPORT extern const double NaN = NAN; - KJS_EXPORT extern const double Inf = INFINITY; -#elif PLATFORM(DARWIN) - -#if PLATFORM(BIG_ENDIAN) - KJS_EXPORT extern const unsigned char NaN[sizeof(double)] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; - KJS_EXPORT extern const unsigned char Inf[sizeof(double)] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; -#elif PLATFORM(MIDDLE_ENDIAN) - KJS_EXPORT extern const unsigned char NaN[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 }; - KJS_EXPORT extern const unsigned char Inf[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }; -#else - KJS_EXPORT extern const unsigned char NaN[sizeof(double)] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; - KJS_EXPORT extern const unsigned char Inf[sizeof(double)] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; -#endif // PLATFORM(MIDDLE_ENDIAN) - -#else // !PLATFORM(DARWIN) - -// Note, we have to use union to ensure alignment. Otherwise, NaN_Bytes can start anywhere, -// while NaN_double has to be 4-byte aligned for 32-bits. -// With -fstrict-aliasing enabled, unions are the only safe way to do type masquerading. - -static const union { - struct { - unsigned char NaN_Bytes[8]; - unsigned char Inf_Bytes[8]; - } bytes; - - struct { - double NaN_Double; - double Inf_Double; - } doubles; - -} NaNInf = { { -#if PLATFORM(BIG_ENDIAN) - { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }, - { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } -#elif PLATFORM(MIDDLE_ENDIAN) - { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 }, - { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } -#else - { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }, - { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } -#endif -} } ; - - KJS_EXPORT extern const double NaN = NaNInf.doubles.NaN_Double; - KJS_EXPORT extern const double Inf = NaNInf.doubles.Inf_Double; - -#endif // !PLATFORM(DARWIN) - - -} // namespace KJS diff --git a/kjs/function.cpp b/kjs/function.cpp deleted file mode 100644 index 85b4acc3..00000000 --- a/kjs/function.cpp +++ /dev/null @@ -1,1216 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003 Apple Computer, Inc. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2007 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "function.h" -#include -#include "scriptfunction.h" -#include "dtoa.h" -#include "internal.h" -#include "function_object.h" -#include "lexer.h" -#include "nodes.h" -#include "operations.h" -#include "debugger.h" -#include "PropertyNameArray.h" -#include "commonunicode.h" - -#include -#include -#include -#include -#include -#include -#include "wtf/DisallowCType.h" -#include "wtf/ASCIICType.h" -#include "bytecode/machine.h" - -using namespace WTF; - -//#define KJS_VERBOSE - -namespace KJS { - -// ----------------------------- FunctionImp ---------------------------------- - -const ClassInfo FunctionImp::info = {"Function", &InternalFunctionImp::info, 0, 0}; - -FunctionImp::FunctionImp(ExecState* exec, const Identifier& n, FunctionBodyNode* b, const ScopeChain& sc) - : InternalFunctionImp(static_cast - (exec->lexicalInterpreter()->builtinFunctionPrototype()), n) - , body(b) - , _scope(sc) -{ -} - -void FunctionImp::mark() -{ - InternalFunctionImp::mark(); - _scope.mark(); -} - -FunctionImp::~FunctionImp() -{ -} - -void FunctionImp::initialCompile(ExecState* newExec) -{ - FunctionBodyNode* body = this->body.get(); - - // Reserve various slots needed for the activation object. We do it only once, - // --- isCompiled() would return true even if debugging state changed - body->reserveSlot(ActivationImp::LengthSlot, false); - body->reserveSlot(ActivationImp::TearOffNeeded, false); - body->reserveSlot(ActivationImp::ScopeLink, false /* will mark via ScopeChain::mark() */); - body->reserveSlot(ActivationImp::FunctionSlot, true); - body->reserveSlot(ActivationImp::ArgumentsObjectSlot, true); - - // Create declarations for parameters, and allocate the symbols. - // We always just give them sequential positions, to make passInParameters - // simple (though perhaps wasting memory in the trivial case) - for (size_t i = 0; i < body->numParams(); ++i) - body->addSymbolOverwriteID(i + ActivationImp::NumReservedSlots, body->paramName(i), DontDelete); - - body->processDecls(newExec); - body->compile(FunctionCode, newExec->dynamicInterpreter()->debugger() ? Debug : Release); -} - - -#ifdef KJS_VERBOSE -static int callDepth; -static std::string callIndent; - -static const char* ind() -{ - callIndent = ""; - for (int i = 0; i < callDepth; ++i) - callIndent += " "; - return callIndent.c_str(); -} - -// Multiline print adding indentation -static void printInd(const char* str) -{ - fprintf(stderr, "%s", ind()); - for (const char* c = str; *c; ++c) { - if (*c != '\n') - fprintf(stderr, "%c", *c); - else - fprintf(stderr, "\n%s", ind()); - } -} - -#endif - -JSValue* FunctionImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) -{ - assert(thisObj); - -#ifdef KJS_VERBOSE - ++callDepth; -#endif - - Debugger* dbg = exec->dynamicInterpreter()->debugger(); - - // enter a new execution context - FunctionExecState newExec(exec->dynamicInterpreter(), thisObj, body.get(), exec, this); - if (exec->hadException()) - newExec.setException(exec->exception()); - - FunctionBodyNode* body = this->body.get(); - - // The first time we're called, compute the set of local variables, - // and compile the body. (note that parameters have been collected - // during the AST build) - CompileType currentState = body->compileState(); - if (currentState == NotCompiled) { - initialCompile(&newExec); - } else { - // Otherwise, we may still need to recompile due to debug... - CompileType desiredState = dbg ? Debug : Release; - if (desiredState != currentState) - body->compile(FunctionCode, desiredState); - } - - size_t stackSize = 0; - LocalStorageEntry* stackSpace = 0; - - // We always allocate on stack initially, and tearoff only after we're done. - int regs = body->numLocalsAndRegisters(); - stackSize = sizeof(LocalStorageEntry) * regs; - stackSpace = (LocalStorageEntry*)exec->dynamicInterpreter()->stackAlloc(stackSize); - - ActivationImp* activation = static_cast(newExec.activationObject()); - activation->setup(&newExec, this, &args, stackSpace); - activation->tearOffNeededSlot() = body->tearOffAtEnd(); - - newExec.initLocalStorage(stackSpace, regs); - - JSValue* result = Machine::runBlock(&newExec, body->code(), exec); - - // If we need to tear off now --- either due to static flag above, or - // if execution requested it dynamically --- do so now. - if (activation->tearOffNeededSlot()) { - activation->performTearOff(); - } else { - // Otherwise, we recycle the activation object; we must clear its - // data pointer, though, since that may become dead. - // (we also unlink it from the scope chain at this time) - activation->scopeLink().deref(); - activation->localStorage = 0; - exec->dynamicInterpreter()->recycleActivation(activation); - } - - // Now free the stack space.. - exec->dynamicInterpreter()->stackFree(stackSize); - -#ifdef KJS_VERBOSE - fprintf(stderr, "%s", ind()); - if (exec->exception()) - printInfo(exec,"throwing", exec->exception()); - else - printInfo(exec,"returning", result); - - --callDepth; -#endif - - return result; -} - -JSValue *FunctionImp::argumentsGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) -{ - FunctionImp *thisObj = static_cast(slot.slotBase()); - ExecState *context = exec; - while (context) { - if (context->function() == thisObj) { - return static_cast(context->activationObject())->get(exec, propertyName); - } - context = context->callingExecState(); - } - return jsNull(); -} - -JSValue *FunctionImp::callerGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot) -{ - FunctionImp* thisObj = static_cast(slot.slotBase()); - ExecState* context = exec; - while (context) { - if (context->function() == thisObj) - break; - context = context->callingExecState(); - } - - if (!context) - return jsNull(); - - ExecState* callingContext = context->callingExecState(); - if (!callingContext) - return jsNull(); - - FunctionImp* callingFunction = callingContext->function(); - if (!callingFunction) - return jsNull(); - - return callingFunction; -} - -JSValue *FunctionImp::lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot) -{ - FunctionImp *thisObj = static_cast(slot.slotBase()); - return jsNumber(thisObj->body->numParams()); -} - -JSValue* FunctionImp::nameGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot) -{ - FunctionImp* thisObj = static_cast(slot.slotBase()); - return jsString(thisObj->functionName().ustring()); -} - -bool FunctionImp::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) -{ - // Find the arguments from the closest context. - if (propertyName == exec->propertyNames().arguments) { - slot.setCustom(this, argumentsGetter); - return true; - } - - // Compute length of parameters. - if (propertyName == exec->propertyNames().length) { - slot.setCustom(this, lengthGetter); - return true; - } - - // Calling function (Mozilla-extension) - if (propertyName == exec->propertyNames().caller) { - slot.setCustom(this, callerGetter); - return true; - } - - // Function name (Mozilla-extension) - if (propertyName == exec->propertyNames().name) { - slot.setCustom(this, nameGetter); - return true; - } - - return InternalFunctionImp::getOwnPropertySlot(exec, propertyName, slot); -} - -bool FunctionImp::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& desc) -{ - if (propertyName == exec->propertyNames().length) { - desc.setPropertyDescriptorValues(exec, jsNumber(body->numParams()), ReadOnly|DontDelete|DontEnum); - return true; - } - - return KJS::JSObject::getOwnPropertyDescriptor(exec, propertyName, desc); -} - -void FunctionImp::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) -{ - if (propertyName == exec->propertyNames().arguments || - propertyName == exec->propertyNames().length || - propertyName == exec->propertyNames().name) - return; - InternalFunctionImp::put(exec, propertyName, value, attr); -} - -bool FunctionImp::deleteProperty(ExecState *exec, const Identifier &propertyName) -{ - if (propertyName == exec->propertyNames().arguments || - propertyName == exec->propertyNames().length || - propertyName == exec->propertyNames().name) - return false; - return InternalFunctionImp::deleteProperty(exec, propertyName); -} - -/* Returns the parameter name corresponding to the given index. eg: - * function f1(x, y, z): getParameterName(0) --> x - * - * If a name appears more than once, only the last index at which - * it appears associates with it. eg: - * function f2(x, x): getParameterName(0) --> null - */ -Identifier FunctionImp::getParameterName(size_t index) -{ - if (index >= body->numParams()) - return CommonIdentifiers::shared()->nullIdentifier; - - Identifier name = body->paramName(index); - - // Are there any subsequent parameters with the same name? - for (size_t pos = index + 1; pos < body->numParams(); ++pos) - if (body->paramName(pos) == name) - return CommonIdentifiers::shared()->nullIdentifier; - - return name; -} - -bool FunctionImp::implementsConstruct() const -{ - return true; -} - -// ECMA 13.2.2 [[Construct]] -JSObject *FunctionImp::construct(ExecState *exec, const List &args) -{ - JSObject *proto; - JSValue *p = get(exec, exec->propertyNames().prototype); - if (p->isObject()) - proto = static_cast(p); - else - proto = exec->lexicalInterpreter()->builtinObjectPrototype(); - - JSObject *obj(new JSObject(proto)); - - JSValue *res = call(exec,obj,args); - - if (res->isObject()) - return static_cast(res); - else - return obj; -} - -// ------------------------------ Thrower --------------------------------- - -Thrower::Thrower(ErrorType type) - : JSObject(), - m_type(type) -{ -} - -JSValue* Thrower::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const List& /*args*/) -{ - return throwError(exec, m_type); -} - - -// ------------------------------ BoundFunction --------------------------------- - -BoundFunction::BoundFunction(ExecState* exec, JSObject* targetFunction, JSObject* boundThis, KJS::List boundArgs) - : InternalFunctionImp(static_cast(exec->lexicalInterpreter()->builtinFunctionPrototype())), - m_targetFunction(targetFunction), - m_boundThis(boundThis), - m_boundArgs(boundArgs) -{ -} - -// ECMAScript Edition 5.1r6 - 15.3.4.5.2 -JSObject* BoundFunction::construct(ExecState* exec, const List& extraArgs) -{ - JSObject* target = m_targetFunction; - if (!target->implementsConstruct()) - return throwError(exec, TypeError); - List boundArgs = m_boundArgs; - - List args; - for (int i = 0; i < boundArgs.size(); ++i) - args.append(boundArgs.at(i)); - for (int i = 0; i < extraArgs.size(); ++i) - args.append(extraArgs.at(i)); - - return target->construct(exec, args); -} - -// ECMAScript Edition 5.1r6 - 15.3.4.5.1 -JSValue* BoundFunction::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const List& extraArgs) -{ - List boundArgs = m_boundArgs; - JSObject* boundThis = m_boundThis; - JSObject* target = m_targetFunction; - - List args; - for (int i = 0; i < boundArgs.size(); ++i) - args.append(boundArgs.at(i)); - for (int i = 0; i < extraArgs.size(); ++i) - args.append(extraArgs.at(i)); - - return target->callAsFunction(exec, boundThis, args); -} - -// ECMAScript Edition 5.1r6 - 15.3.4.5.3 -bool BoundFunction::hasInstance(ExecState* exec, JSValue* value) -{ - JSObject* target = m_targetFunction; - if (!target->implementsHasInstance()) - return throwError(exec, TypeError); - - return target->hasInstance(exec, value); -} - -void BoundFunction::setTargetFunction(JSObject* targetFunction) -{ - m_targetFunction = targetFunction; -} - -void BoundFunction::setBoundArgs(const List& boundArgs) -{ - m_boundArgs = boundArgs; -} - -void BoundFunction::setBoundThis(JSObject* boundThis) -{ - m_boundThis = boundThis; -} - - -// ------------------------------ IndexToNameMap --------------------------------- - -// We map indexes in the arguments array to their corresponding argument names. -// Example: function f(x, y, z): arguments[0] = x, so we map 0 to Identifier("x"). - -// Once we have an argument name, we can get and set the argument's value in the -// activation object. - -// We use Identifier::null to indicate that a given argument's value -// isn't stored in the activation object. - -IndexToNameMap::IndexToNameMap(FunctionImp *func, const List &args) -{ - _map = new Identifier[args.size()]; - this->_size = args.size(); - - size_t i = 0; - ListIterator iterator = args.begin(); - for (; iterator != args.end(); i++, iterator++) - _map[i] = func->getParameterName(i); // null if there is no corresponding parameter -} - -IndexToNameMap::~IndexToNameMap() { - delete [] _map; -} - -bool IndexToNameMap::isMapped(const Identifier &index) const -{ - bool indexIsNumber; - int indexAsNumber = index.toStrictUInt32(&indexIsNumber); - - if (!indexIsNumber) - return false; - - if (indexAsNumber >= _size) - return false; - - if (_map[indexAsNumber].isNull()) - return false; - - return true; -} - -void IndexToNameMap::unMap(const Identifier &index) -{ - bool indexIsNumber; - int indexAsNumber = index.toStrictUInt32(&indexIsNumber); - - assert(indexIsNumber && indexAsNumber < _size); - - _map[indexAsNumber] = CommonIdentifiers::shared()->nullIdentifier;; -} - -int IndexToNameMap::size() const -{ - return _size; -} - -Identifier& IndexToNameMap::operator[](int index) -{ - return _map[index]; -} - -Identifier& IndexToNameMap::operator[](const Identifier &index) -{ - bool indexIsNumber; - int indexAsNumber = index.toStrictUInt32(&indexIsNumber); - - assert(indexIsNumber && indexAsNumber < _size); - - return (*this)[indexAsNumber]; -} - -// ------------------------------ Arguments --------------------------------- - -const ClassInfo Arguments::info = {"Arguments", 0, 0, 0}; - -// ECMA 10.1.8 -Arguments::Arguments(ExecState *exec, FunctionImp *func, const List &args, ActivationImp *act) -: JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()), -_activationObject(act), -indexToNameMap(func, args) -{ - putDirect(exec->propertyNames().callee, func, DontEnum); - putDirect(exec->propertyNames().length, args.size(), DontEnum); - - int i = 0; - ListIterator iterator = args.begin(); - for (; iterator != args.end(); i++, iterator++) { - if (!indexToNameMap.isMapped(Identifier::from(i))) { - //ECMAScript Edition 5.1r6 - 10.6.11.b, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true - JSObject::put(exec, Identifier::from(i), *iterator, None); - } - } -} - -void Arguments::mark() -{ - JSObject::mark(); - if (_activationObject && !_activationObject->marked()) - _activationObject->mark(); -} - -JSValue *Arguments::mappedIndexGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) -{ - Arguments *thisObj = static_cast(slot.slotBase()); - return thisObj->_activationObject->get(exec, thisObj->indexToNameMap[propertyName]); -} - -bool Arguments::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) -{ - if (indexToNameMap.isMapped(propertyName)) { - slot.setCustom(this, mappedIndexGetter); - return true; - } - - return JSObject::getOwnPropertySlot(exec, propertyName, slot); -} - -void Arguments::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) -{ - if (indexToNameMap.isMapped(propertyName)) { - unsigned attr = 0; - JSObject::getPropertyAttributes(propertyName, attr); - if (attr & ReadOnly) - return; - - _activationObject->put(exec, indexToNameMap[propertyName], value, attr); - } else { - JSObject::put(exec, propertyName, value, attr); - } -} - -bool Arguments::deleteProperty(ExecState *exec, const Identifier &propertyName) -{ - if (indexToNameMap.isMapped(propertyName)) { - bool result = JSObject::deleteProperty(exec, propertyName); - if (result) { - _activationObject->deleteProperty(exec, indexToNameMap[propertyName]); - indexToNameMap.unMap(propertyName); - } - return true; - } else { - return JSObject::deleteProperty(exec, propertyName); - } -} - -void Arguments::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, PropertyMap::PropertyMode mode) -{ - unsigned int length = indexToNameMap.size(); - unsigned attr; - for (unsigned int i = 0; i < length; ++i) { - attr = 0; - Identifier ident = Identifier::from(i); - - if (indexToNameMap.isMapped(ident) && - _activationObject->getPropertyAttributes(indexToNameMap[ident], attr)) { - if (PropertyMap::checkEnumerable(attr, mode)) { - propertyNames.add(ident); - } - } - } - - JSObject::getOwnPropertyNames(exec, propertyNames, mode); -} - -bool Arguments::defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& desc, bool shouldThrow) -{ - bool isMapped = indexToNameMap.isMapped(propertyName); - - Identifier mappedName; - if (isMapped) - mappedName = indexToNameMap[propertyName]; - else - mappedName = propertyName; - - bool allowed = JSObject::defineOwnProperty(exec, propertyName, desc, false); - - if (!allowed) { - if (shouldThrow) - throwError(exec, TypeError); - return false; - } - if (isMapped) { - if (desc.isAccessorDescriptor()) { - indexToNameMap.unMap(propertyName); - } else { - if (desc.value()) { - _activationObject->putDirect(mappedName, desc.value(), desc.attributes()); - } - if (desc.writableSet() && desc.writable() == false) { - indexToNameMap.unMap(propertyName); - } - } - } - - return true; -} - -// ------------------------------ ActivationImp -------------------------------- - -const ClassInfo ActivationImp::info = {"Activation", 0, 0, 0}; - -// ECMA 10.1.6 -void ActivationImp::setup(ExecState* exec, FunctionImp *function, - const List* arguments, LocalStorageEntry* entries) -{ - FunctionBodyNode* body = function->body.get(); - - size_t total = body->numLocalsAndRegisters(); - localStorage = entries; - lengthSlot() = total; - - // we can now link ourselves into the scope, which will also fix up our scopeLink(). - exec->pushVariableObjectScope(this); - - const FunctionBodyNode::SymbolInfo* symInfo = body->getLocalInfo(); - - // Setup our fields - this->arguments = arguments; - functionSlot() = function; - argumentsObjectSlot() = jsUndefined(); - symbolTable = &body->symbolTable(); - - // Set the mark/don't mark flags and attributes for everything - for (size_t p = 0; p < total; ++p) - entries[p].attributes = symInfo[p].attr; - - // Pass in the parameters (ECMA 10.1.3q) -#ifdef KJS_VERBOSE - fprintf(stderr, "%s---------------------------------------------------\n" - "%sprocessing parameters for %s call\n", ind(), ind(), - function->functionName().isEmpty() ? "(internal)" : function->functionName().ascii()); -#endif - size_t numParams = body->numParams(); - size_t numPassedIn = min(numParams, static_cast(arguments->size())); - - size_t pos = 0; - for (; pos < numPassedIn; ++pos) { - size_t symNum = pos + ActivationImp::NumReservedSlots; - JSValue* v = arguments->atUnchecked(pos); - - entries[symNum].val.valueVal = v; - -#ifdef KJS_VERBOSE - fprintf(stderr, "%s setting parameter %s", ind(), body->paramName(pos).ascii()); - printInfo(exec, "to", v); -#endif - } - - for (; pos < numParams; ++pos) { - size_t symNum = pos + ActivationImp::NumReservedSlots; - entries[symNum].val.valueVal = jsUndefined(); - -#ifdef KJS_VERBOSE - fprintf(stderr, "%s setting parameter %s to undefined (not passed in)", ind(), body->paramName(pos).ascii()); -#endif - } - -#ifdef KJS_VERBOSE - fprintf(stderr, "\n%s---------------------------------\n", ind()); - fprintf(stderr, "%sBody:\n", ind()); - fprintf(stderr, "%s---------------------------------\n", ind()); - printInd(body->toString().ascii()); - fprintf(stderr, "\n%s---------------------------------\n\n", ind()); -#endif - - // Initialize the rest of the locals to 'undefined' - for (size_t pos = numParams + ActivationImp::NumReservedSlots; pos < total; ++pos) - entries[pos].val.valueVal = jsUndefined(); - - // Finally, put in the functions. Note that this relies on above - // steps to have completed, since it can trigger a GC. - size_t numFuns = body->numFunctionLocals(); - size_t* funsData = body->getFunctionLocalInfo(); - for (size_t fun = 0; fun < numFuns; ++fun) { - size_t id = funsData[fun]; - entries[id].val.valueVal = symInfo[id].funcDecl->makeFunctionObject(exec); - } -} - -void ActivationImp::performTearOff() -{ - // Create a new local array, copy stuff over - size_t total = lengthSlot(); - LocalStorageEntry* entries = new LocalStorageEntry[total]; - std::memcpy(entries, localStorage, total*sizeof(LocalStorageEntry)); - localStorage = entries; -} - -void ActivationImp::requestTearOff() -{ - tearOffNeededSlot() = true; -} - -JSValue *ActivationImp::argumentsGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot) -{ - ActivationImp* thisObj = static_cast(slot.slotBase()); - - if (thisObj->argumentsObjectSlot() == jsUndefined()) - thisObj->createArgumentsObject(exec); - - return thisObj->argumentsObjectSlot(); -} - - -PropertySlot::GetValueFunc ActivationImp::getArgumentsGetter() -{ - return ActivationImp::argumentsGetter; -} - -bool ActivationImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) -{ - if (symbolTableGet(propertyName, slot)) - return true; - - if (JSValue** location = getDirectLocation(propertyName)) { - slot.setValueSlot(this, location); - return true; - } - - // Only return the built-in arguments object if it wasn't overridden above. - if (propertyName == exec->propertyNames().arguments) { - slot.setCustom(this, getArgumentsGetter()); - return true; - } - - // We don't call through to JSObject because there's no way to give an - // activation object getter properties or a prototype. - ASSERT(!_prop.hasGetterSetterProperties()); - ASSERT(prototype() == jsNull()); - return false; -} - -bool ActivationImp::deleteProperty(ExecState *exec, const Identifier &propertyName) -{ - if (propertyName == exec->propertyNames().arguments) - return false; - - return JSVariableObject::deleteProperty(exec, propertyName); -} - -void ActivationImp::putDirect(const Identifier& propertyName, JSValue* value, int attr) -{ - size_t index = symbolTable->get(propertyName.ustring().rep()); - if (index != missingSymbolMarker()) { - LocalStorageEntry& entry = localStorage[index]; - entry.val.valueVal = value; - entry.attributes = attr; - return; - } - - JSVariableObject::putDirect(propertyName, value, attr); -} - -JSValue* ActivationImp::getDirect(const Identifier& propertyName) const -{ - size_t index = symbolTable->get(propertyName.ustring().rep()); - if (index != missingSymbolMarker()) { - LocalStorageEntry& entry = localStorage[index]; - return entry.val.valueVal; - } - - return JSVariableObject::getDirect(propertyName); -} - -bool ActivationImp::getPropertyAttributes(const Identifier& propertyName, unsigned int& attributes) const -{ - size_t index = symbolTable->get(propertyName.ustring().rep()); - if (index != missingSymbolMarker()) { - LocalStorageEntry& entry = localStorage[index]; - attributes = entry.attributes; - return true; - } - - return JSVariableObject::getPropertyAttributes(propertyName, attributes); -} - -void ActivationImp::put(ExecState*, const Identifier& propertyName, JSValue* value, int attr) -{ - // If any bits other than DontDelete are set, then we bypass the read-only check. - bool checkReadOnly = !(attr & ~DontDelete); - if (symbolTablePut(propertyName, value, checkReadOnly)) - return; - - // We don't call through to JSObject because __proto__ and getter/setter - // properties are non-standard extensions that other implementations do not - // expose in the activation object. - ASSERT(!_prop.hasGetterSetterProperties()); - _prop.put(propertyName, value, attr, checkReadOnly); -} - -void ActivationImp::createArgumentsObject(ExecState *exec) -{ - requestTearOff(); - argumentsObjectSlot() = new Arguments(exec, static_cast(functionSlot()), - *arguments, const_cast(this)); -} - -// ------------------------------ GlobalFunc ----------------------------------- - - -GlobalFuncImp::GlobalFuncImp(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) - : InternalFunctionImp(funcProto, name) - , id(i) -{ - putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum); -} - -static JSValue *encode(ExecState *exec, const List &args, const char *do_not_escape) -{ - UString r = "", s, str = args[0]->toString(exec); - CString cstr = str.UTF8String(); - const char *p = cstr.c_str(); - for (size_t k = 0; k < cstr.size(); k++, p++) { - char c = *p; - if (c && strchr(do_not_escape, c)) { - r.append(c); - } else { - char tmp[4]; - sprintf(tmp, "%%%02X", (unsigned char)c); - r += tmp; - } - } - return jsString(r); -} - -static JSValue *decode(ExecState *exec, const List &args, const char *do_not_unescape) -{ - UString s = "", str = args[0]->toString(exec); - int k = 0, len = str.size(); - const UChar *d = str.data(); - UChar u; - while (k < len) { - const UChar *p = d + k; - UChar c = *p; - if (c == '%') { - int charLen = 0; - if (k <= len - 3 && isASCIIHexDigit(p[1].uc) && isASCIIHexDigit(p[2].uc)) { - const char b0 = Lexer::convertHex(p[1].uc, p[2].uc); - const int sequenceLen = UTF8SequenceLength(b0); - if (sequenceLen != 0 && k <= len - sequenceLen * 3) { - charLen = sequenceLen * 3; - char sequence[5]; - sequence[0] = b0; - for (int i = 1; i < sequenceLen; ++i) { - const UChar *q = p + i * 3; - if (q[0] == '%' && isASCIIHexDigit(q[1].uc) && isASCIIHexDigit(q[2].uc)) - sequence[i] = Lexer::convertHex(q[1].uc, q[2].uc); - else { - charLen = 0; - break; - } - } - if (charLen != 0) { - sequence[sequenceLen] = 0; - const int character = decodeUTF8Sequence(sequence); - if (character < 0 || character >= 0x110000) { - charLen = 0; - } else if (character >= 0x10000) { - // Convert to surrogate pair. - s.append(static_cast(0xD800 | ((character - 0x10000) >> 10))); - u = static_cast(0xDC00 | ((character - 0x10000) & 0x3FF)); - } else { - u = static_cast(character); - } - } - } - } - if (charLen == 0) - return throwError(exec, URIError); - if (u.uc == 0 || u.uc >= 128 || !strchr(do_not_unescape, u.low())) { - c = u; - k += charLen - 1; - } - } - k++; - s.append(c); - } - return jsString(s); -} - -static int parseDigit(unsigned short c, int radix) -{ - int digit = -1; - - if (c >= '0' && c <= '9') { - digit = c - '0'; - } else if (c >= 'A' && c <= 'Z') { - digit = c - 'A' + 10; - } else if (c >= 'a' && c <= 'z') { - digit = c - 'a' + 10; - } - - if (digit >= radix) - return -1; - return digit; -} - -double parseIntOverflow(const char* s, int length, int radix) -{ - double number = 0.0; - double radixMultiplier = 1.0; - - for (const char* p = s + length - 1; p >= s; p--) { - if (radixMultiplier == Inf) { - if (*p != '0') { - number = Inf; - break; - } - } else { - int digit = parseDigit(*p, radix); - number += digit * radixMultiplier; - } - - radixMultiplier *= radix; - } - - return number; -} - -double parseInt(const UString &s, int radix) -{ - int length = s.size(); - int p = 0; - - while (p < length && CommonUnicode::isStrWhiteSpace(s[p].uc)) { - ++p; - } - - double sign = 1; - if (p < length) { - if (s[p] == '+') { - ++p; - } else if (s[p] == '-') { - sign = -1; - ++p; - } - } - - if ((radix == 0 || radix == 16) && length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) { - radix = 16; - p += 2; - } else if (radix == 0) { - // ECMAscript test262 S15.1.2.2_A5.1_T1 says we should no longer accept octal. To fix remove next 3 lines. - if (p < length && s[p] == '0') - radix = 8; - else - radix = 10; - } - - if (radix < 2 || radix > 36) - return NaN; - - int firstDigitPosition = p; - bool sawDigit = false; - double number = 0; - while (p < length) { - int digit = parseDigit(s[p].uc, radix); - if (digit == -1) - break; - sawDigit = true; - number *= radix; - number += digit; - ++p; - } - - if (number >= mantissaOverflowLowerBound) { - if (radix == 10) - number = kjs_strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0); - else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32) - number = parseIntOverflow(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), p - firstDigitPosition, radix); - } - - if (!sawDigit) - return NaN; - - return sign * number; -} - -double parseFloat(const UString &s) -{ - // Check for 0x prefix here, because toDouble allows it, but we must treat it as 0. - // Need to skip any whitespace and then one + or - sign. - int length = s.size(); - int p = 0; - while (p < length && CommonUnicode::isStrWhiteSpace(s[p].uc)) { - ++p; - } - if (p < length && (s[p] == '+' || s[p] == '-')) { - ++p; - } - if (length - p >= 2 && s[p] == '0' && (s[p + 1] == 'x' || s[p + 1] == 'X')) { - return 0; - } - - return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ ); -} - -JSValue *GlobalFuncImp::callAsFunction(ExecState *exec, JSObject * /*thisObj*/, const List &args) -{ - JSValue *res = jsUndefined(); - - static const char do_not_escape[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "*+-./@_"; - - static const char do_not_escape_when_encoding_URI_component[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "!'()*-._~"; - static const char do_not_escape_when_encoding_URI[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "!#$&'()*+,-./:;=?@_~"; - static const char do_not_unescape_when_decoding_URI[] = - "#$&+,/:;=?@"; - - switch (id) { - case Eval: { // eval() - JSValue *x = args[0]; - if (!x->isString()) - return x; - else { - UString s = x->toString(exec); - - int sourceId; - int errLine; - UString errMsg; - RefPtr progNode(parser().parseProgram(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg)); - - Debugger *dbg = exec->dynamicInterpreter()->debugger(); - if (dbg) { - dbg->reportSourceParsed(exec, progNode.get(), sourceId, UString(), s, 0, errLine, errMsg); - } - - // no program node means a syntax occurred - if (!progNode) - return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL); - - // If the variable object we're working with is an activation, we better - // tear it off since stuff inside eval can capture it in a closure - if (exec->variableObject()->isActivation()) - static_cast(exec->variableObject())->requestTearOff(); - - // enter a new execution context - EvalExecState newExec(exec->dynamicInterpreter(), - exec->dynamicInterpreter()->globalObject(), - progNode.get(), - exec); - - if (exec->hadException()) - newExec.setException(exec->exception()); - - if (dbg) { - bool cont = dbg->enterContext(&newExec, sourceId, 0, 0, List::empty()); - if (!cont) { - dbg->imp()->abort(); - return jsUndefined(); - } - } - - // execute the code - progNode->processDecls(&newExec); - Completion c = progNode->execute(&newExec); - - dbg = exec->dynamicInterpreter()->debugger(); - if (dbg) { - bool cont = dbg->exitContext(&newExec, sourceId, 0, 0); - if (!cont) { - dbg->imp()->abort(); - return jsUndefined(); - } - } - - // if an exception occurred, propagate it back to the previous execution object - if (newExec.hadException()) - exec->setException(newExec.exception()); - - res = jsUndefined(); - if (c.complType() == Throw) - exec->setException(c.value()); - else if (c.isValueCompletion()) - res = c.value(); - } - break; - } - case ParseInt: - res = jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec))); - break; - case ParseFloat: - res = jsNumber(parseFloat(args[0]->toString(exec))); - break; - case IsNaN: - res = jsBoolean(isNaN(args[0]->toNumber(exec))); - break; - case IsFinite: { - double n = args[0]->toNumber(exec); - res = jsBoolean(!isNaN(n) && !isInf(n)); - break; - } - case DecodeURI: - res = decode(exec, args, do_not_unescape_when_decoding_URI); - break; - case DecodeURIComponent: - res = decode(exec, args, ""); - break; - case EncodeURI: - res = encode(exec, args, do_not_escape_when_encoding_URI); - break; - case EncodeURIComponent: - res = encode(exec, args, do_not_escape_when_encoding_URI_component); - break; - case 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->uc; - if (u > 255) { - char tmp[7]; - sprintf(tmp, "%%u%04X", u); - s = UString(tmp); - } else if (u != 0 && strchr(do_not_escape, (char)u)) { - s = UString(c, 1); - } else { - char tmp[4]; - sprintf(tmp, "%%%02X", u); - s = UString(tmp); - } - r += s; - } - res = jsString(r); - break; - } - case 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')) { - if (Lexer::isHexDigit((c+2)->uc) && Lexer::isHexDigit((c+3)->uc) && - Lexer::isHexDigit((c+4)->uc) && Lexer::isHexDigit((c+5)->uc)) { - u = Lexer::convertUnicode((c+2)->uc, (c+3)->uc, - (c+4)->uc, (c+5)->uc); - c = &u; - k += 5; - } - } else if (*c == UChar('%') && k <= len - 3 && - Lexer::isHexDigit((c+1)->uc) && Lexer::isHexDigit((c+2)->uc)) { - u = UChar(Lexer::convertHex((c+1)->uc, (c+2)->uc)); - c = &u; - k += 2; - } - k++; - s += UString(c, 1); - } - res = jsString(s); - break; - } -#ifndef NDEBUG - case KJSPrint: - puts(args[0]->toString(exec).ascii()); - break; -#endif - } - - return res; -} - -} // namespace - -// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/function.h b/kjs/function.h deleted file mode 100644 index ca9c4fea..00000000 --- a/kjs/function.h +++ /dev/null @@ -1,235 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2007, 2008 Maksim Orlovich - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJS_FUNCTION_H -#define KJS_FUNCTION_H - -#include "SymbolTable.h" -#include "LocalStorage.h" -#include "JSVariableObject.h" -#include "object.h" -#include - -namespace KJS { - - class ActivationImp; - class FunctionPrototype; - - class KJS_EXPORT InternalFunctionImp : public JSObject { - public: - InternalFunctionImp(); - InternalFunctionImp(FunctionPrototype*); - InternalFunctionImp(FunctionPrototype*, const Identifier&); - - virtual bool implementsCall() const; - virtual JSValue* callAsFunction(ExecState*, JSObject* thisObjec, const List& args) = 0; - virtual bool implementsHasInstance() const; - - virtual const ClassInfo* classInfo() const { return &info; } - static const ClassInfo info; - const Identifier& functionName() const { return m_name; } - void setFunctionName(const Identifier& name) { m_name = name; } - - private: - Identifier m_name; -#ifdef WIN32 - InternalFunctionImp(const InternalFunctionImp&); - InternalFunctionImp& operator=(const InternalFunctionImp&); -#endif - }; - - /** - * A minimal object that just throws an exception if executed. - */ - class Thrower : public JSObject { - public: - Thrower(ErrorType type); - - virtual JSValue *callAsFunction(ExecState* exec, JSObject*, const List& args); - virtual bool implementsCall() const { return true; }; - private: - ErrorType m_type; - }; - - class BoundFunction : public InternalFunctionImp { - public: - explicit BoundFunction(ExecState* exec, JSObject* targetFunction, JSObject* boundThis, List boundArgs); - - void setTargetFunction(JSObject* targetFunction); - void setBoundThis(JSObject* boundThis); - void setBoundArgs(const List& boundArgs); - - virtual JSValue *callAsFunction(ExecState* exec, JSObject* thisObj, const List& extraArgs); - virtual bool implementsCall() const { return true; }; - - using KJS::JSObject::construct; - virtual JSObject* construct(ExecState* exec, const List& extraArgs); - virtual bool implementsConstruct() const { return true; }; - - virtual bool hasInstance(ExecState *exec, JSValue *value); - virtual bool implementsHasInstance() const { return true; }; - - private: - ProtectedPtr m_targetFunction; - ProtectedPtr m_boundThis; - List m_boundArgs; - }; - - /** - * @internal - * - * The initial value of Function.prototype (and thus all objects created - * with the Function constructor) - */ - class FunctionPrototype : public InternalFunctionImp { - public: - FunctionPrototype(ExecState *exec); - virtual ~FunctionPrototype(); - - virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); - }; - - class IndexToNameMap { - public: - IndexToNameMap(FunctionImp *func, const List &args); - ~IndexToNameMap(); - - Identifier& operator[](int index); - Identifier& operator[](const Identifier &indexIdentifier); - bool isMapped(const Identifier &index) const; - void unMap(const Identifier &index); - int size() const; - - private: - IndexToNameMap(); // prevent construction w/o parameters - int _size; - Identifier * _map; - }; - - class Arguments : public JSObject { - public: - Arguments(ExecState *exec, FunctionImp *func, const List &args, ActivationImp *act); - virtual void mark(); - using KJS::JSObject::getOwnPropertySlot; - virtual bool getOwnPropertySlot(ExecState *, const Identifier &, PropertySlot&); - using KJS::JSObject::put; - virtual void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None); - using KJS::JSObject::deleteProperty; - virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, PropertyMap::PropertyMode mode); - - virtual bool defineOwnProperty(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& desc, bool shouldThrow); - - virtual const ClassInfo *classInfo() const { return &info; } - static const ClassInfo info; - private: - static JSValue *mappedIndexGetter(ExecState *exec, JSObject *, const Identifier &, const PropertySlot& slot); - - ActivationImp *_activationObject; - mutable IndexToNameMap indexToNameMap; - }; - - class ActivationImp : public JSVariableObject { - public: - enum { - FunctionSlot = NumVarObjectSlots, - ArgumentsObjectSlot, - NumReservedSlots = ArgumentsObjectSlot + 1 - }; - - void setup(ExecState* exec, FunctionImp *function, const List* arguments, - LocalStorageEntry* stackSpace); - - // Request that this activation be torn off when the code using it stops running - void requestTearOff(); - void performTearOff(); - - using KJS::JSObject::getOwnPropertySlot; - virtual bool getOwnPropertySlot(ExecState *exec, const Identifier &, PropertySlot&); - using KJS::JSObject::put; - virtual void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None); - using KJS::JSObject::deleteProperty; - virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); - - virtual void putDirect(const Identifier &propertyName, JSValue *value, int attr = 0); - using JSObject::putDirect; - virtual JSValue *getDirect(const Identifier& propertyName) const; - virtual bool getPropertyAttributes(const Identifier& propertyName, unsigned& attributes) const; - - bool isLocalReadOnly(int propertyID) const { - return (localStorage[propertyID].attributes & ReadOnly) == ReadOnly; - } - - virtual const ClassInfo *classInfo() const { return &info; } - static const ClassInfo info; - - virtual bool isActivation() const { return true; } - void setupLocals(FunctionBodyNode* fbody); - void setupFunctionLocals(FunctionBodyNode* fbody, ExecState *exec); - - const List& passedInArguments() const { return *arguments; } - - // really FunctionImp, but type isn't declared yet - JSValue* function() { return functionSlot(); } - private: - JSValue*& functionSlot() { - return localStorage[FunctionSlot].val.valueVal; - } - - JSValue*& argumentsObjectSlot() { - return localStorage[ArgumentsObjectSlot].val.valueVal; - } - - static PropertySlot::GetValueFunc getArgumentsGetter(); - static JSValue *argumentsGetter(ExecState *exec, JSObject *, const Identifier &, const PropertySlot& slot); - void createArgumentsObject(ExecState *exec); - - int numLocals() const { return lengthSlot(); } - bool validLocal(int id) const { return 0 <= id && id < numLocals(); } - const List* arguments; - }; - - class GlobalFuncImp : public InternalFunctionImp { - public: - GlobalFuncImp(ExecState*, FunctionPrototype*, int i, int len, const Identifier&); - virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); - enum { Eval, ParseInt, ParseFloat, IsNaN, IsFinite, Escape, UnEscape, - DecodeURI, DecodeURIComponent, EncodeURI, EncodeURIComponent -#ifndef NDEBUG - , KJSPrint -#endif -}; - private: - int id; - }; - - static const double mantissaOverflowLowerBound = 9007199254740992.0; - double parseIntOverflow(const char* s, int length, int radix); - - double parseInt(const UString &s, int radix); - double parseFloat(const UString &s); - -} // namespace - -#endif diff --git a/kjs/function_object.cpp b/kjs/function_object.cpp deleted file mode 100644 index 232b3c1c..00000000 --- a/kjs/function_object.cpp +++ /dev/null @@ -1,307 +0,0 @@ -// -*- c-basic-offset: 2 -*- -// krazy:excludeall=doublequote_chars (UStrings aren't QStrings) -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "function_object.h" -#include -#include "internal.h" -#include "function.h" -#include "scriptfunction.h" -#include "array_object.h" -#include "nodes.h" -#include "lexer.h" -#include "debugger.h" -#include "object.h" - -#include -#include -#include - -using namespace KJS; - -// ------------------------------ FunctionPrototype ------------------------- - -FunctionPrototype::FunctionPrototype(ExecState *exec) -{ - static const Identifier* applyPropertyName = new Identifier("apply"); - static const Identifier* callPropertyName = new Identifier("call"); - static const Identifier* bindPropertyName = new Identifier("bind"); - - putDirect(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum); - putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum); - putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Apply, 2, *applyPropertyName), DontEnum); - putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Call, 1, *callPropertyName), DontEnum); - putDirectFunction(new FunctionProtoFunc(exec, this, FunctionProtoFunc::Bind, 1, *bindPropertyName), DontEnum); -} - -FunctionPrototype::~FunctionPrototype() -{ -} - -// ECMA 15.3.4 -JSValue *FunctionPrototype::callAsFunction(ExecState * /*exec*/, JSObject * /*thisObj*/, const List &/*args*/) -{ - return jsUndefined(); -} - -// ------------------------------ FunctionProtoFunc ------------------------- - -FunctionProtoFunc::FunctionProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name) - : InternalFunctionImp(funcProto, name) - , id(i) -{ - putDirect(exec->propertyNames().length, len, DontDelete | ReadOnly | DontEnum); -} - -JSValue* FunctionProtoFunc::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args) -{ - JSValue* result = NULL; - - switch (id) { - case ToString: - if (!thisObj || !thisObj->inherits(&InternalFunctionImp::info)) { -#ifndef NDEBUG - fprintf(stderr,"attempted toString() call on null or non-function object\n"); -#endif - return throwError(exec, TypeError); - } - if (thisObj->inherits(&FunctionImp::info)) { - return jsString(static_cast(thisObj)->toSource()); - } else if (thisObj->inherits(&InternalFunctionImp::info) && - !static_cast(thisObj)->functionName().isNull()) { - result = jsString("\nfunction " + static_cast(thisObj)->functionName().ustring() + "() {\n" - " [native code]\n}\n"); - } else { - result = jsString("[function]"); - } - break; - case Apply: { - JSValue *thisArg = args[0]; - JSValue *argArray = args[1]; - JSObject *func = thisObj; - - if (!func->implementsCall()) - return throwError(exec, TypeError); - - JSObject *applyThis; - if (thisArg->isUndefinedOrNull()) - applyThis = exec->dynamicInterpreter()->globalObject(); - else - applyThis = thisArg->toObject(exec); - - List applyArgs; - if (!argArray->isUndefinedOrNull()) { - if (argArray->isObject() && - (static_cast(argArray)->inherits(&ArrayInstance::info) || - static_cast(argArray)->inherits(&Arguments::info))) { - - JSObject *argArrayObj = static_cast(argArray); - unsigned int length = argArrayObj->get(exec, exec->propertyNames().length)->toUInt32(exec); - for (unsigned int i = 0; i < length; i++) - applyArgs.append(argArrayObj->get(exec,i)); - } - else - return throwError(exec, TypeError); - } - result = func->call(exec,applyThis,applyArgs); - } - break; - case Call: { - JSValue *thisArg = args[0]; - JSObject *func = thisObj; - - if (!func->implementsCall()) - return throwError(exec, TypeError); - - JSObject *callThis; - if (thisArg->isUndefinedOrNull()) - callThis = exec->dynamicInterpreter()->globalObject(); - else - callThis = thisArg->toObject(exec); - - result = func->call(exec,callThis,args.copyTail()); - } - break; - case Bind: { //ECMA Edition 5.1r6 - 15.3.4.5 - JSObject* target(thisObj); - if (!target->implementsCall()) - return throwError(exec, TypeError, "object is not callable"); - - List newArgs; - for (int i = 1; i < args.size(); ++i) - newArgs.append(args[i]); - - JSObject* boundThis = 0; - - // As call does not accept JSValue(undefined/null), - // do it like in call and use the global object - if (args[0]->isUndefinedOrNull()) - boundThis = exec->dynamicInterpreter()->globalObject(); - else - boundThis = args[0]->toObject(exec); - - BoundFunction* bfunc = new BoundFunction(exec, target, boundThis, newArgs); - - unsigned length; - if (target->inherits(&FunctionImp::info)) { - double L = target->get(exec, exec->propertyNames().length)->getNumber() - newArgs.size(); - length = (unsigned)std::max((int)L, 0); - } else { - length = 0; - } - bfunc->put(exec, exec->propertyNames().length, jsNumber(length), ReadOnly|DontEnum|DontDelete); - - JSObject *thrower = new Thrower(TypeError); - PropertyDescriptor callerDesc; - - GetterSetterImp* gs = new GetterSetterImp(); - gs->setGetter(thrower); - gs->setSetter(thrower); - - callerDesc.setPropertyDescriptorValues(exec, gs, DontEnum|DontDelete); - bfunc->defineOwnProperty(exec, exec->propertyNames().caller, callerDesc, false); - - PropertyDescriptor argumentsDesc; - argumentsDesc.setPropertyDescriptorValues(exec, gs, DontEnum|DontDelete); - bfunc->defineOwnProperty(exec, exec->propertyNames().arguments, argumentsDesc, false); - - return bfunc; - } - break; - } - - return result; -} - -// ------------------------------ FunctionObjectImp ---------------------------- - -FunctionObjectImp::FunctionObjectImp(ExecState* exec, FunctionPrototype* funcProto) - : InternalFunctionImp(funcProto) -{ - putDirect(exec->propertyNames().prototype, funcProto, DontEnum|DontDelete|ReadOnly); - - // no. of arguments for constructor - putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum); -} - -FunctionObjectImp::~FunctionObjectImp() -{ -} - -bool FunctionObjectImp::implementsConstruct() const -{ - return true; -} - -// ECMA 15.3.2 The Function Constructor -JSObject* FunctionObjectImp::construct(ExecState* exec, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber) -{ - UString p(""); - UString body; - int argsSize = args.size(); - if (argsSize == 0) { - body = ""; - } else if (argsSize == 1) { - body = args[0]->toString(exec); - } else { - p = args[0]->toString(exec); - for (int k = 1; k < argsSize - 1; k++) - p += "," + args[k]->toString(exec); - body = args[argsSize-1]->toString(exec); - } - - // parse the source code - int sourceId; - int errLine; - UString errMsg; - RefPtr functionBody = parser().parseFunctionBody(sourceURL, lineNumber, body.data(), body.size(), &sourceId, &errLine, &errMsg); - - // notify debugger that source has been parsed - Debugger *dbg = exec->dynamicInterpreter()->debugger(); - if (dbg) { - // make sure to pass in sourceURL, since it's useful for lazy event listeners, and empty for actual function ctor - dbg->reportSourceParsed(exec, functionBody.get(), sourceId, sourceURL, body, lineNumber, errLine, errMsg); - } - - // no program node == syntax error - throw a syntax error - if (!functionBody) - // we can't return a Completion(Throw) here, so just set the exception - // and return it - return throwError(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL); - - ScopeChain scopeChain; - scopeChain.push(exec->lexicalInterpreter()->globalObject()); - - FunctionImp* fimp = new FunctionImp(exec, functionName, functionBody.get(), scopeChain); - - // parse parameter list. throw syntax error on illegal identifiers - int len = p.size(); - const UChar *c = p.data(); - int i = 0, params = 0; - UString param; - while (i < len) { - while (*c == ' ' && i < len) - c++, i++; - if (Lexer::isIdentStart(c->uc)) { // else error - param = UString(c, 1); - c++, i++; - while (i < len && (Lexer::isIdentPart(c->uc))) { - param += UString(c, 1); - c++, i++; - } - while (i < len && *c == ' ') - c++, i++; - if (i == len) { - functionBody->addParam(Identifier(param)); - params++; - break; - } else if (*c == ',') { - functionBody->addParam(Identifier(param)); - params++; - c++, i++; - continue; - } // else error - } - return throwError(exec, SyntaxError, "Syntax error in parameter list"); - } - - List consArgs; - - JSObject* objCons = exec->lexicalInterpreter()->builtinObject(); - JSObject* prototype = objCons->construct(exec,List::empty()); - prototype->put(exec, exec->propertyNames().constructor, fimp, DontEnum|DontDelete|ReadOnly); - // ECMA Edition 5.1r6 - 15.3.5.2 - [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false - fimp->put(exec, exec->propertyNames().prototype, prototype, Internal|DontDelete|DontEnum); - return fimp; -} - -// ECMA 15.3.2 The Function Constructor -JSObject* FunctionObjectImp::construct(ExecState* exec, const List& args) -{ - return construct(exec, args, "anonymous", UString(), 0); -} - -// ECMA 15.3.1 The Function Constructor Called as a Function -JSValue* FunctionObjectImp::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const List &args) -{ - return construct(exec, args); -} diff --git a/kjs/function_object.h b/kjs/function_object.h deleted file mode 100644 index a9c2e71a..00000000 --- a/kjs/function_object.h +++ /dev/null @@ -1,66 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef FUNCTION_OBJECT_H_ -#define FUNCTION_OBJECT_H_ - -#include "object_object.h" -#include "function.h" - -namespace KJS { - - /** - * @internal - * - * Class to implement all methods that are properties of the - * Function.prototype object - */ - class FunctionProtoFunc : public InternalFunctionImp { - public: - FunctionProtoFunc(ExecState*, FunctionPrototype*, int i, int len, const Identifier&); - - virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args); - - enum { ToString, Apply, Call, Bind }; - private: - int id; - }; - - /** - * @internal - * - * The initial value of the global variable's "Function" property - */ - class FunctionObjectImp : public InternalFunctionImp { - public: - FunctionObjectImp(ExecState*, FunctionPrototype*); - virtual ~FunctionObjectImp(); - - virtual bool implementsConstruct() const; - virtual JSObject* construct(ExecState*, const List& args); - virtual JSObject* construct(ExecState*, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber); - virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args); - }; - -} // namespace - -#endif // _FUNCTION_OBJECT_H_ diff --git a/kjs/global.h.cmake b/kjs/global.h.cmake deleted file mode 100644 index c8ed39dd..00000000 --- a/kjs/global.h.cmake +++ /dev/null @@ -1,92 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 2002 David Faure (faure@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJS_GLOBAL_H -#define KJS_GLOBAL_H - -#include - -// we don't want any padding between UChars (ARM processor) -#if defined(__GNUC__) || defined(__INTEL_COMPILER) -#define KJS_PACKED __attribute__((__packed__)) -#else -#define KJS_PACKED -#endif - -#if defined(_MSC_VER) -#pragma warning(disable: 4355) -#endif - -#cmakedefine __KDE_HAVE_GCC_VISIBILITY - -#ifndef KJS_EXPORT -# ifdef __KDE_HAVE_GCC_VISIBILITY -# define KJS_EXPORT __attribute__ ((visibility("default"))) -# elif defined(_WIN32) || defined(_WIN64) -# ifdef MAKE_KJS_LIB -# define KJS_EXPORT __declspec(dllexport) -# else -# define KJS_EXPORT __declspec(dllimport) -# endif -# else -# define KJS_EXPORT -# endif -#endif - -// some methods are declared inside kjs and defined outside (currently only in khtml) -// KJS_EXTERNAL_EXPORT should be prefixed to each related method -#ifndef KJS_EXTERNAL_EXPORT -# if defined(MAKE_KJS_LIB) -# define KJS_EXTERNAL_EXPORT -# elif (defined(_WIN32) || defined(_WIN64)) && defined(__GNUC__) -# if defined(MAKE_KHTML_LIB) || defined(MAKE_KJSEMBED_LIB) || defined(MAKE_KATEPART_LIB) -# define KJS_EXTERNAL_EXPORT __declspec(dllexport) -# else -# define KJS_EXTERNAL_EXPORT -# endif -# else -# define KJS_EXTERNAL_EXPORT -# endif -#endif - -#ifndef NDEBUG // protection against problems if committing with KJS_VERBOSE on - -// Uncomment this to enable very verbose output from KJS -//#define KJS_VERBOSE -// Uncomment this to debug memory allocation and garbage collection -//#define KJS_DEBUG_MEM - -#endif - -// Apple feature which we don't use -#define KJS_MULTIPLE_THREADS 0 -// Debugging features, turned off by default -#define DEBUG_COLLECTOR 0 - -#ifndef HAVE_STDINT_H -#cmakedefine HAVE_STDINT_H 1 -#endif - -/* Valgrind memcheck presence */ -#cmakedefine HAVE_VALGRIND_MEMCHECK_H 1 - -#endif diff --git a/kjs/grammar.cpp b/kjs/grammar.cpp deleted file mode 100644 index 6a400a41..00000000 --- a/kjs/grammar.cpp +++ /dev/null @@ -1,4398 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.7.12-4996. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.7.12-4996" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - -/* Substitute the variable and function names. */ -#define yyparse kjsyyparse -#define yylex kjsyylex -#define yyerror kjsyyerror -#define yylval kjsyylval -#define yychar kjsyychar -#define yydebug kjsyydebug -#define yynerrs kjsyynerrs -#define yylloc kjsyylloc - -/* Copy the first part of user declarations. */ -/* Line 371 of yacc.c */ -#line 1 "grammar.y" - - -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include - -#include -#include -#include -#include "value.h" -#include "object.h" -#include "types.h" -#include "interpreter.h" -#include "nodes.h" -#include "makenodes.h" -#include "lexer.h" -#include "internal.h" - -// Not sure why, but yacc doesn't add this define along with the others. -#define yylloc kjsyylloc - -/* default values for bison */ -#define YYDEBUG 0 // Set to 1 to debug a parse error. -#define kjsyydebug 0 // Set to 1 to debug a parse error. -#if !PLATFORM(DARWIN) - // avoid triggering warnings in older bison -#define YYERROR_VERBOSE -#endif - -extern int kjsyylex(); -int kjsyyerror(const char *); -static bool allowAutomaticSemicolon(); - -#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon()) YYABORT; } while (0) -#define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line) - -#ifndef __GNUC__ -# define __attribute__(x) -#endif - -using namespace KJS; - - -/* Line 371 of yacc.c */ -#line 139 "grammar.tab.c" - -# ifndef YY_NULL -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr -# else -# define YY_NULL 0 -# endif -# endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "grammar.tab.h". */ -#ifndef YY_KJSYY_GRAMMAR_TAB_H_INCLUDED -# define YY_KJSYY_GRAMMAR_TAB_H_INCLUDED -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int kjsyydebug; -#endif - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - NULLTOKEN = 258, - TRUETOKEN = 259, - FALSETOKEN = 260, - BREAK = 261, - CASE = 262, - DEFAULT = 263, - FOR = 264, - NEW = 265, - VAR = 266, - CONSTTOKEN = 267, - CONTINUE = 268, - FUNCTION = 269, - RETURN = 270, - VOIDTOKEN = 271, - DELETETOKEN = 272, - IF = 273, - THISTOKEN = 274, - DO = 275, - WHILE = 276, - INTOKEN = 277, - INSTANCEOF = 278, - TYPEOF = 279, - SWITCH = 280, - WITH = 281, - RESERVED = 282, - THROW = 283, - TRY = 284, - CATCH = 285, - FINALLY = 286, - DEBUGGER = 287, - IMPORT = 288, - IF_WITHOUT_ELSE = 289, - ELSE = 290, - EQEQ = 291, - NE = 292, - STREQ = 293, - STRNEQ = 294, - LE = 295, - GE = 296, - OR = 297, - AND = 298, - PLUSPLUS = 299, - MINUSMINUS = 300, - LSHIFT = 301, - RSHIFT = 302, - URSHIFT = 303, - PLUSEQUAL = 304, - MINUSEQUAL = 305, - MULTEQUAL = 306, - DIVEQUAL = 307, - LSHIFTEQUAL = 308, - RSHIFTEQUAL = 309, - URSHIFTEQUAL = 310, - ANDEQUAL = 311, - MODEQUAL = 312, - XOREQUAL = 313, - OREQUAL = 314, - NUMBER = 315, - STRING = 316, - IDENT = 317, - AUTOPLUSPLUS = 318, - AUTOMINUSMINUS = 319 - }; -#endif - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ -/* Line 387 of yacc.c */ -#line 64 "grammar.y" - - int ival; - double dval; - UString *ustr; - Identifier *ident; - Node *node; - StatementNode *stat; - ParameterNode *param; - FunctionBodyNode *body; - FuncDeclNode *func; - FuncExprNode *funcExpr; - ProgramNode *prog; - AssignExprNode *init; - SourceElementsNode *srcs; - ArgumentsNode *args; - ArgumentListNode *alist; - VarDeclNode *decl; - VarDeclListNode *vlist; - CaseBlockNode *cblk; - ClauseListNode *clist; - CaseClauseNode *ccl; - ElementNode *elm; - Operator op; - PropertyListNode *plist; - PropertyNode *pnode; - PropertyNameNode *pname; - PackageNameNode *pkgn; - - -/* Line 387 of yacc.c */ -#line 276 "grammar.tab.c" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE kjsyylval; -extern YYLTYPE kjsyylloc; -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int kjsyyparse (void *YYPARSE_PARAM); -#else -int kjsyyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int kjsyyparse (void); -#else -int kjsyyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - -#endif /* !YY_KJSYY_GRAMMAR_TAB_H_INCLUDED */ - -/* Copy the second part of user declarations. */ - -/* Line 390 of yacc.c */ -#line 317 "grammar.tab.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if (! defined __GNUC__ || __GNUC__ < 2 \ - || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) -# define __attribute__(Spec) /* empty */ -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(N) (N) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 212 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1718 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 89 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 114 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 352 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 589 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 319 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 78, 2, 2, 2, 80, 83, 2, - 67, 68, 79, 75, 69, 76, 74, 65, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 66, 88, - 81, 87, 82, 86, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 72, 2, 73, 84, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 70, 85, 71, 77, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 5, 7, 9, 11, 13, 15, 17, - 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, - 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, - 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, - 79, 81, 83, 85, 87, 89, 93, 94, 101, 102, - 110, 112, 116, 118, 121, 125, 130, 132, 134, 136, - 138, 142, 146, 150, 156, 159, 164, 165, 167, 169, - 172, 174, 176, 181, 185, 189, 191, 196, 200, 204, - 206, 209, 211, 214, 217, 220, 225, 229, 232, 235, - 240, 244, 247, 251, 253, 257, 259, 261, 263, 265, - 267, 270, 273, 275, 278, 281, 284, 287, 290, 293, - 296, 299, 302, 305, 308, 311, 314, 316, 318, 320, - 322, 324, 328, 332, 336, 338, 342, 346, 350, 352, - 356, 360, 362, 366, 370, 372, 376, 380, 384, 386, - 390, 394, 398, 400, 404, 408, 412, 416, 420, 424, - 426, 430, 434, 438, 442, 446, 448, 452, 456, 460, - 464, 468, 472, 474, 478, 482, 486, 490, 492, 496, - 500, 504, 508, 510, 514, 518, 522, 526, 528, 532, - 534, 538, 540, 544, 546, 550, 552, 556, 558, 562, - 564, 568, 570, 574, 576, 580, 582, 586, 588, 592, - 594, 598, 600, 604, 606, 610, 612, 616, 618, 624, - 626, 632, 634, 640, 642, 646, 648, 652, 654, 658, - 660, 662, 664, 666, 668, 670, 672, 674, 676, 678, - 680, 682, 684, 688, 690, 694, 696, 700, 702, 704, - 706, 708, 710, 712, 714, 716, 718, 720, 722, 724, - 726, 728, 730, 732, 734, 737, 741, 745, 749, 751, - 755, 757, 761, 763, 766, 768, 771, 775, 779, 781, - 785, 787, 790, 793, 796, 798, 801, 804, 810, 818, - 826, 834, 840, 850, 861, 869, 878, 888, 889, 891, - 892, 894, 897, 900, 904, 908, 911, 914, 918, 922, - 925, 928, 932, 936, 942, 948, 952, 958, 959, 961, - 963, 966, 970, 975, 978, 982, 986, 990, 994, 999, - 1007, 1017, 1020, 1023, 1025, 1029, 1035, 1041, 1045, 1049, - 1055, 1061, 1062, 1069, 1070, 1078, 1079, 1085, 1086, 1093, - 1094, 1101, 1102, 1110, 1112, 1116, 1119, 1123, 1124, 1126, - 1128, 1131, 1133 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int16 yyrhs[] = -{ - 200, 0, -1, 6, -1, 7, -1, 8, -1, 9, - -1, 10, -1, 11, -1, 12, -1, 13, -1, 14, - -1, 15, -1, 16, -1, 17, -1, 18, -1, 19, - -1, 20, -1, 21, -1, 22, -1, 23, -1, 24, - -1, 25, -1, 26, -1, 28, -1, 29, -1, 30, - -1, 31, -1, 32, -1, 33, -1, 3, -1, 4, - -1, 5, -1, 35, -1, 62, -1, 90, -1, 3, - -1, 4, -1, 5, -1, 60, -1, 61, -1, 65, - -1, 52, -1, 91, -1, 61, -1, 60, -1, 93, - 66, 149, -1, -1, 62, 91, 67, 68, 95, 199, - -1, -1, 62, 91, 67, 198, 68, 96, 199, -1, - 94, -1, 97, 69, 94, -1, 99, -1, 70, 71, - -1, 70, 97, 71, -1, 70, 97, 69, 71, -1, - 19, -1, 92, -1, 100, -1, 62, -1, 67, 153, - 68, -1, 72, 102, 73, -1, 72, 101, 73, -1, - 72, 101, 69, 102, 73, -1, 102, 149, -1, 101, - 69, 102, 149, -1, -1, 103, -1, 69, -1, 103, - 69, -1, 98, -1, 193, -1, 104, 72, 153, 73, - -1, 104, 74, 91, -1, 10, 104, 110, -1, 99, - -1, 105, 72, 153, 73, -1, 105, 74, 91, -1, - 10, 104, 110, -1, 104, -1, 10, 106, -1, 105, - -1, 10, 106, -1, 104, 110, -1, 108, 110, -1, - 108, 72, 153, 73, -1, 108, 74, 91, -1, 105, - 110, -1, 109, 110, -1, 109, 72, 153, 73, -1, - 109, 74, 91, -1, 67, 68, -1, 67, 111, 68, - -1, 149, -1, 111, 69, 149, -1, 106, -1, 108, - -1, 107, -1, 109, -1, 112, -1, 112, 44, -1, - 112, 45, -1, 113, -1, 113, 44, -1, 113, 45, - -1, 17, 117, -1, 16, 117, -1, 24, 117, -1, - 44, 117, -1, 63, 117, -1, 45, 117, -1, 64, - 117, -1, 75, 117, -1, 76, 117, -1, 77, 117, - -1, 78, 117, -1, 114, -1, 116, -1, 115, -1, - 116, -1, 117, -1, 119, 79, 117, -1, 119, 65, - 117, -1, 119, 80, 117, -1, 118, -1, 120, 79, - 117, -1, 120, 65, 117, -1, 120, 80, 117, -1, - 119, -1, 121, 75, 119, -1, 121, 76, 119, -1, - 120, -1, 122, 75, 119, -1, 122, 76, 119, -1, - 121, -1, 123, 46, 121, -1, 123, 47, 121, -1, - 123, 48, 121, -1, 122, -1, 124, 46, 121, -1, - 124, 47, 121, -1, 124, 48, 121, -1, 123, -1, - 125, 81, 123, -1, 125, 82, 123, -1, 125, 40, - 123, -1, 125, 41, 123, -1, 125, 23, 123, -1, - 125, 22, 123, -1, 123, -1, 126, 81, 123, -1, - 126, 82, 123, -1, 126, 40, 123, -1, 126, 41, - 123, -1, 126, 23, 123, -1, 124, -1, 127, 81, - 123, -1, 127, 82, 123, -1, 127, 40, 123, -1, - 127, 41, 123, -1, 127, 23, 123, -1, 127, 22, - 123, -1, 125, -1, 128, 36, 125, -1, 128, 37, - 125, -1, 128, 38, 125, -1, 128, 39, 125, -1, - 126, -1, 129, 36, 126, -1, 129, 37, 126, -1, - 129, 38, 126, -1, 129, 39, 126, -1, 127, -1, - 130, 36, 125, -1, 130, 37, 125, -1, 130, 38, - 125, -1, 130, 39, 125, -1, 128, -1, 131, 83, - 128, -1, 129, -1, 132, 83, 129, -1, 130, -1, - 133, 83, 128, -1, 131, -1, 134, 84, 131, -1, - 132, -1, 135, 84, 132, -1, 133, -1, 136, 84, - 131, -1, 134, -1, 137, 85, 134, -1, 135, -1, - 138, 85, 135, -1, 136, -1, 139, 85, 134, -1, - 137, -1, 140, 43, 137, -1, 138, -1, 141, 43, - 138, -1, 139, -1, 142, 43, 137, -1, 140, -1, - 143, 42, 140, -1, 141, -1, 144, 42, 141, -1, - 142, -1, 145, 42, 140, -1, 143, -1, 143, 86, - 149, 66, 149, -1, 144, -1, 144, 86, 150, 66, - 150, -1, 145, -1, 145, 86, 149, 66, 149, -1, - 146, -1, 112, 152, 149, -1, 147, -1, 112, 152, - 150, -1, 148, -1, 113, 152, 149, -1, 87, -1, - 49, -1, 50, -1, 51, -1, 52, -1, 53, -1, - 54, -1, 55, -1, 56, -1, 58, -1, 59, -1, - 57, -1, 149, -1, 153, 69, 149, -1, 150, -1, - 154, 69, 150, -1, 151, -1, 155, 69, 149, -1, - 157, -1, 158, -1, 163, -1, 168, -1, 169, -1, - 170, -1, 171, -1, 174, -1, 175, -1, 176, -1, - 177, -1, 178, -1, 184, -1, 185, -1, 186, -1, - 187, -1, 189, -1, 70, 71, -1, 70, 201, 71, - -1, 11, 159, 88, -1, 11, 159, 1, -1, 161, - -1, 159, 69, 161, -1, 162, -1, 160, 69, 162, - -1, 62, -1, 62, 166, -1, 62, -1, 62, 167, - -1, 12, 164, 88, -1, 12, 164, 1, -1, 165, - -1, 164, 69, 165, -1, 62, -1, 62, 166, -1, - 87, 149, -1, 87, 150, -1, 88, -1, 155, 88, - -1, 155, 1, -1, 18, 67, 153, 68, 156, -1, - 18, 67, 153, 68, 156, 35, 156, -1, 20, 156, - 21, 67, 153, 68, 88, -1, 20, 156, 21, 67, - 153, 68, 1, -1, 21, 67, 153, 68, 156, -1, - 9, 67, 173, 88, 172, 88, 172, 68, 156, -1, - 9, 67, 11, 160, 88, 172, 88, 172, 68, 156, - -1, 9, 67, 112, 22, 153, 68, 156, -1, 9, - 67, 11, 62, 22, 153, 68, 156, -1, 9, 67, - 11, 62, 167, 22, 153, 68, 156, -1, -1, 153, - -1, -1, 154, -1, 13, 88, -1, 13, 1, -1, - 13, 62, 88, -1, 13, 62, 1, -1, 6, 88, - -1, 6, 1, -1, 6, 62, 88, -1, 6, 62, - 1, -1, 15, 88, -1, 15, 1, -1, 15, 153, - 88, -1, 15, 153, 1, -1, 26, 67, 153, 68, - 156, -1, 25, 67, 153, 68, 179, -1, 70, 180, - 71, -1, 70, 180, 183, 180, 71, -1, -1, 181, - -1, 182, -1, 181, 182, -1, 7, 153, 66, -1, - 7, 153, 66, 201, -1, 8, 66, -1, 8, 66, - 201, -1, 62, 66, 156, -1, 28, 153, 88, -1, - 28, 153, 1, -1, 29, 157, 31, 157, -1, 29, - 157, 30, 67, 62, 68, 157, -1, 29, 157, 30, - 67, 62, 68, 157, 31, 157, -1, 32, 88, -1, - 32, 1, -1, 62, -1, 188, 74, 62, -1, 33, - 188, 74, 79, 88, -1, 33, 188, 74, 79, 1, - -1, 33, 188, 88, -1, 33, 188, 1, -1, 33, - 62, 87, 188, 88, -1, 33, 62, 87, 188, 1, - -1, -1, 14, 62, 67, 68, 191, 199, -1, -1, - 14, 62, 67, 198, 68, 192, 199, -1, -1, 14, - 67, 68, 194, 199, -1, -1, 14, 67, 198, 68, - 195, 199, -1, -1, 14, 62, 67, 68, 196, 199, - -1, -1, 14, 62, 67, 198, 68, 197, 199, -1, - 62, -1, 198, 69, 62, -1, 70, 71, -1, 70, - 201, 71, -1, -1, 201, -1, 202, -1, 201, 202, - -1, 190, -1, 156, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 192, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 226, 227, 231, 232, 233, 234, 235, - 236, 242, 251, 252, 253, 257, 258, 258, 262, 262, - 269, 270, 274, 275, 276, 278, 282, 283, 284, 285, - 286, 291, 292, 293, 297, 298, 303, 304, 308, 309, - 313, 314, 315, 316, 317, 321, 322, 323, 324, 328, - 329, 333, 334, 338, 339, 340, 341, 345, 346, 347, - 348, 352, 353, 357, 358, 362, 363, 367, 368, 372, - 373, 374, 378, 379, 380, 384, 385, 386, 387, 388, - 389, 390, 391, 392, 393, 394, 397, 398, 402, 403, - 407, 408, 409, 410, 414, 415, 417, 419, 424, 425, - 426, 430, 431, 433, 438, 439, 440, 441, 445, 446, - 447, 448, 452, 453, 454, 455, 456, 457, 458, 462, - 463, 464, 465, 466, 467, 472, 473, 474, 475, 476, - 477, 479, 483, 484, 485, 486, 487, 491, 492, 494, - 496, 498, 503, 504, 506, 507, 509, 514, 515, 519, - 520, 525, 526, 530, 531, 535, 536, 541, 542, 547, - 548, 552, 553, 558, 559, 564, 565, 569, 570, 575, - 576, 581, 582, 586, 587, 592, 593, 597, 598, 603, - 604, 609, 610, 615, 616, 621, 622, 627, 628, 633, - 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, - 644, 648, 649, 653, 654, 658, 659, 663, 664, 665, - 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, - 676, 677, 678, 679, 683, 684, 688, 689, 693, 694, - 699, 700, 705, 706, 710, 711, 715, 716, 721, 722, - 727, 728, 732, 736, 740, 744, 745, 749, 751, 756, - 757, 758, 759, 761, 763, 771, 773, 778, 779, 783, - 784, 788, 789, 790, 791, 795, 796, 797, 798, 802, - 803, 804, 805, 809, 813, 817, 818, 823, 824, 828, - 829, 833, 834, 838, 839, 843, 847, 848, 852, 853, - 854, 859, 860, 864, 865, 869, 871, 873, 875, 877, - 879, 884, 884, 885, 885, 890, 890, 893, 893, 896, - 896, 897, 897, 903, 904, 908, 909, 913, 914, 918, - 919, 923, 924 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || 0 -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "NULLTOKEN", "TRUETOKEN", "FALSETOKEN", - "BREAK", "CASE", "DEFAULT", "FOR", "NEW", "VAR", "CONSTTOKEN", - "CONTINUE", "FUNCTION", "RETURN", "VOIDTOKEN", "DELETETOKEN", "IF", - "THISTOKEN", "DO", "WHILE", "INTOKEN", "INSTANCEOF", "TYPEOF", "SWITCH", - "WITH", "RESERVED", "THROW", "TRY", "CATCH", "FINALLY", "DEBUGGER", - "IMPORT", "IF_WITHOUT_ELSE", "ELSE", "EQEQ", "NE", "STREQ", "STRNEQ", - "LE", "GE", "OR", "AND", "PLUSPLUS", "MINUSMINUS", "LSHIFT", "RSHIFT", - "URSHIFT", "PLUSEQUAL", "MINUSEQUAL", "MULTEQUAL", "DIVEQUAL", - "LSHIFTEQUAL", "RSHIFTEQUAL", "URSHIFTEQUAL", "ANDEQUAL", "MODEQUAL", - "XOREQUAL", "OREQUAL", "NUMBER", "STRING", "IDENT", "AUTOPLUSPLUS", - "AUTOMINUSMINUS", "'/'", "':'", "'('", "')'", "','", "'{'", "'}'", "'['", - "']'", "'.'", "'+'", "'-'", "'~'", "'!'", "'*'", "'%'", "'<'", "'>'", - "'&'", "'^'", "'|'", "'?'", "'='", "';'", "$accept", "Keywords", - "IdentifierName", "Literal", "PropertyName", "Property", "$@1", "$@2", - "PropertyList", "PrimaryExpr", "PrimaryExprNoBrace", "ArrayLiteral", - "ElementList", "ElisionOpt", "Elision", "MemberExpr", "MemberExprNoBF", - "NewExpr", "NewExprNoBF", "CallExpr", "CallExprNoBF", "Arguments", - "ArgumentList", "LeftHandSideExpr", "LeftHandSideExprNoBF", - "PostfixExpr", "PostfixExprNoBF", "UnaryExprCommon", "UnaryExpr", - "UnaryExprNoBF", "MultiplicativeExpr", "MultiplicativeExprNoBF", - "AdditiveExpr", "AdditiveExprNoBF", "ShiftExpr", "ShiftExprNoBF", - "RelationalExpr", "RelationalExprNoIn", "RelationalExprNoBF", - "EqualityExpr", "EqualityExprNoIn", "EqualityExprNoBF", "BitwiseANDExpr", - "BitwiseANDExprNoIn", "BitwiseANDExprNoBF", "BitwiseXORExpr", - "BitwiseXORExprNoIn", "BitwiseXORExprNoBF", "BitwiseORExpr", - "BitwiseORExprNoIn", "BitwiseORExprNoBF", "LogicalANDExpr", - "LogicalANDExprNoIn", "LogicalANDExprNoBF", "LogicalORExpr", - "LogicalORExprNoIn", "LogicalORExprNoBF", "ConditionalExpr", - "ConditionalExprNoIn", "ConditionalExprNoBF", "AssignmentExpr", - "AssignmentExprNoIn", "AssignmentExprNoBF", "AssignmentOperator", "Expr", - "ExprNoIn", "ExprNoBF", "Statement", "Block", "VariableStatement", - "VariableDeclarationList", "VariableDeclarationListNoIn", - "VariableDeclaration", "VariableDeclarationNoIn", "ConstStatement", - "ConstDeclarationList", "ConstDeclaration", "Initializer", - "InitializerNoIn", "EmptyStatement", "ExprStatement", "IfStatement", - "IterationStatement", "ExprOpt", "ExprNoInOpt", "ContinueStatement", - "BreakStatement", "ReturnStatement", "WithStatement", "SwitchStatement", - "CaseBlock", "CaseClausesOpt", "CaseClauses", "CaseClause", - "DefaultClause", "LabelledStatement", "ThrowStatement", "TryStatement", - "DebuggerStatement", "PackageName", "ImportStatement", - "FunctionDeclaration", "$@3", "$@4", "FunctionExpr", "$@5", "$@6", "$@7", - "$@8", "FormalParameterList", "FunctionBody", "Program", - "SourceElements", "SourceElement", YY_NULL -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 47, 58, 40, 41, 44, - 123, 125, 91, 93, 46, 43, 45, 126, 33, 42, - 37, 60, 62, 38, 94, 124, 63, 61, 59 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 89, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 91, 91, 92, 92, 92, 92, 92, - 92, 92, 93, 93, 93, 94, 95, 94, 96, 94, - 97, 97, 98, 98, 98, 98, 99, 99, 99, 99, - 99, 100, 100, 100, 101, 101, 102, 102, 103, 103, - 104, 104, 104, 104, 104, 105, 105, 105, 105, 106, - 106, 107, 107, 108, 108, 108, 108, 109, 109, 109, - 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, - 114, 114, 115, 115, 115, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 117, 117, 118, 118, - 119, 119, 119, 119, 120, 120, 120, 120, 121, 121, - 121, 122, 122, 122, 123, 123, 123, 123, 124, 124, - 124, 124, 125, 125, 125, 125, 125, 125, 125, 126, - 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, - 127, 127, 128, 128, 128, 128, 128, 129, 129, 129, - 129, 129, 130, 130, 130, 130, 130, 131, 131, 132, - 132, 133, 133, 134, 134, 135, 135, 136, 136, 137, - 137, 138, 138, 139, 139, 140, 140, 141, 141, 142, - 142, 143, 143, 144, 144, 145, 145, 146, 146, 147, - 147, 148, 148, 149, 149, 150, 150, 151, 151, 152, - 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, - 152, 153, 153, 154, 154, 155, 155, 156, 156, 156, - 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, - 156, 156, 156, 156, 157, 157, 158, 158, 159, 159, - 160, 160, 161, 161, 162, 162, 163, 163, 164, 164, - 165, 165, 166, 167, 168, 169, 169, 170, 170, 171, - 171, 171, 171, 171, 171, 171, 171, 172, 172, 173, - 173, 174, 174, 174, 174, 175, 175, 175, 175, 176, - 176, 176, 176, 177, 178, 179, 179, 180, 180, 181, - 181, 182, 182, 183, 183, 184, 185, 185, 186, 186, - 186, 187, 187, 188, 188, 189, 189, 189, 189, 189, - 189, 191, 190, 192, 190, 194, 193, 195, 193, 196, - 193, 197, 193, 198, 198, 199, 199, 200, 200, 201, - 201, 202, 202 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 0, 6, 0, 7, - 1, 3, 1, 2, 3, 4, 1, 1, 1, 1, - 3, 3, 3, 5, 2, 4, 0, 1, 1, 2, - 1, 1, 4, 3, 3, 1, 4, 3, 3, 1, - 2, 1, 2, 2, 2, 4, 3, 2, 2, 4, - 3, 2, 3, 1, 3, 1, 1, 1, 1, 1, - 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, - 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, - 3, 1, 3, 3, 1, 3, 3, 3, 1, 3, - 3, 3, 1, 3, 3, 3, 3, 3, 3, 1, - 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, - 3, 3, 1, 3, 3, 3, 3, 1, 3, 3, - 3, 3, 1, 3, 3, 3, 3, 1, 3, 1, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 3, 1, 3, 1, 3, 1, 5, 1, - 5, 1, 5, 1, 3, 1, 3, 1, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 1, 3, 1, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 3, 3, 3, 1, 3, - 1, 3, 1, 2, 1, 2, 3, 3, 1, 3, - 1, 2, 2, 2, 1, 2, 2, 5, 7, 7, - 7, 5, 9, 10, 7, 8, 9, 0, 1, 0, - 1, 2, 2, 3, 3, 2, 2, 3, 3, 2, - 2, 3, 3, 5, 5, 3, 5, 0, 1, 1, - 2, 3, 4, 2, 3, 3, 3, 3, 4, 7, - 9, 2, 2, 1, 3, 5, 5, 3, 3, 5, - 5, 0, 6, 0, 7, 0, 5, 0, 6, 0, - 6, 0, 7, 1, 3, 2, 3, 0, 1, 1, - 2, 1, 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint16 yydefact[] = -{ - 347, 35, 36, 37, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 41, 38, 39, - 59, 0, 0, 40, 0, 0, 66, 0, 0, 0, - 0, 274, 57, 75, 58, 81, 97, 98, 102, 118, - 119, 124, 131, 138, 155, 172, 181, 187, 193, 199, - 205, 211, 217, 235, 0, 352, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 351, 0, 348, 349, 296, 0, 295, - 289, 0, 0, 59, 0, 70, 52, 79, 82, 71, - 262, 0, 258, 270, 0, 268, 292, 0, 291, 0, - 300, 299, 79, 95, 96, 99, 116, 117, 120, 128, - 134, 142, 162, 177, 183, 189, 195, 201, 207, 213, - 231, 0, 99, 106, 105, 0, 0, 0, 107, 0, - 0, 0, 0, 322, 321, 323, 0, 108, 110, 0, - 109, 111, 0, 254, 0, 68, 0, 0, 67, 112, - 113, 114, 115, 0, 0, 0, 87, 0, 0, 88, - 103, 104, 220, 221, 222, 223, 224, 225, 226, 227, - 230, 228, 229, 219, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, - 0, 275, 1, 350, 298, 297, 0, 99, 149, 167, - 179, 185, 191, 197, 203, 209, 215, 233, 290, 0, - 79, 80, 0, 0, 29, 30, 31, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 32, 44, 43, 33, 53, 34, - 42, 0, 50, 0, 0, 0, 78, 0, 263, 257, - 0, 256, 271, 267, 0, 266, 294, 293, 0, 83, - 0, 0, 84, 100, 101, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 302, 0, 301, 0, 0, 0, 0, 0, 317, 316, - 0, 0, 0, 328, 0, 327, 315, 60, 255, 66, - 62, 61, 64, 69, 91, 0, 93, 0, 33, 77, - 0, 90, 218, 126, 125, 127, 132, 133, 139, 140, - 141, 161, 160, 158, 159, 156, 157, 173, 174, 175, - 176, 182, 188, 194, 200, 206, 0, 236, 264, 0, - 260, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 287, - 74, 0, 343, 335, 0, 0, 0, 0, 54, 0, - 73, 272, 259, 269, 331, 0, 0, 86, 214, 122, - 121, 123, 129, 130, 135, 136, 137, 148, 147, 145, - 146, 143, 144, 163, 164, 165, 166, 178, 184, 190, - 196, 202, 0, 232, 0, 0, 0, 0, 0, 0, - 318, 323, 0, 324, 0, 0, 92, 0, 76, 89, - 0, 0, 0, 265, 0, 287, 0, 99, 216, 154, - 152, 153, 150, 151, 168, 169, 170, 171, 180, 186, - 192, 198, 204, 0, 234, 288, 0, 339, 0, 0, - 337, 0, 0, 45, 55, 51, 72, 0, 333, 85, - 0, 277, 0, 281, 307, 304, 303, 0, 330, 0, - 329, 326, 325, 63, 65, 94, 212, 0, 273, 0, - 264, 261, 0, 0, 0, 287, 0, 341, 0, 336, - 0, 344, 46, 0, 332, 0, 208, 0, 0, 0, - 0, 308, 309, 0, 0, 0, 265, 287, 284, 210, - 0, 340, 0, 345, 0, 338, 0, 48, 334, 278, - 280, 279, 0, 0, 305, 307, 310, 319, 285, 0, - 0, 0, 342, 346, 47, 0, 311, 313, 0, 0, - 286, 0, 282, 49, 312, 314, 306, 320, 283 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 269, 270, 42, 271, 272, 556, 575, 273, 95, - 96, 44, 156, 157, 158, 112, 45, 113, 46, 114, - 47, 166, 345, 132, 48, 116, 49, 117, 118, 51, - 119, 52, 120, 53, 121, 54, 122, 219, 55, 123, - 220, 56, 124, 221, 57, 125, 222, 58, 126, 223, - 59, 127, 224, 60, 128, 225, 61, 129, 226, 62, - 130, 227, 63, 382, 485, 228, 64, 65, 66, 67, - 101, 379, 102, 380, 68, 104, 105, 278, 463, 69, - 70, 71, 72, 486, 229, 73, 74, 75, 76, 77, - 505, 540, 541, 542, 565, 78, 79, 80, 81, 146, - 82, 83, 497, 535, 99, 489, 530, 526, 552, 404, - 529, 84, 85, 86 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -424 -static const yytype_int16 yypact[] = -{ - 1118, -424, -424, -424, 7, 15, 320, 17, 44, 25, - 58, 718, 1502, 1502, 37, -424, 1198, 64, 1502, 116, - 137, 1502, 152, 67, 145, 1502, 1502, -424, -424, -424, - 175, 1502, 1502, -424, 1502, 798, 189, 1502, 1502, 1502, - 1502, -424, -424, -424, -424, 40, -424, 117, 555, -424, - -424, -424, 115, 71, 46, 165, 217, 161, 193, 209, - 242, 5, -424, -424, 39, -424, -424, -424, -424, -424, - -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, - -424, -424, -424, -424, 295, 1118, -424, -424, 74, -424, - 226, 320, -4, -424, 1578, -424, -424, 149, -424, -424, - 210, 63, -424, 210, 69, -424, -424, 75, -424, 232, - -424, -424, 149, -424, 153, 699, -424, -424, -424, 135, - 157, 233, 170, 228, 224, 216, 241, 268, 13, -424, - -424, 87, 204, -424, -424, 1502, 301, 1502, -424, 1502, - 1502, 89, 231, -424, -424, 246, 27, -424, -424, 1198, - -424, -424, 200, -424, 878, -424, 36, 1274, 259, -424, - -424, -424, -424, 1350, 1502, 656, -424, 1502, 656, -424, - -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, - -424, -424, -424, -424, 1502, 1502, 1502, 1502, 1502, 1502, - 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, - 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, -424, - 1502, -424, -424, -424, -424, -424, 286, 362, 233, 178, - 236, 271, 280, 273, 322, 14, -424, -424, 297, 279, - 149, -424, 302, 16, -424, -424, -424, -424, -424, -424, - -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, - -424, -424, -424, -424, -424, -424, -424, -424, -424, -424, - -424, -424, -424, -424, -424, -424, -424, 656, -424, -424, - -424, 304, -424, 90, 1502, 656, -424, 1502, -424, -424, - 17, -424, -424, -424, 44, -424, -424, -424, 35, -424, - 1502, 656, -424, -424, -424, 1502, 1502, 1502, 1502, 1502, - 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, - 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, - -424, 1502, -424, 215, 306, 237, 247, 267, -424, -424, - 307, 152, 309, -424, 4, -424, -424, -424, -424, 189, - -424, -424, -424, -424, -424, 269, -424, 112, -424, -424, - 113, -424, -424, -424, -424, -424, 135, 135, 157, 157, - 157, 233, 233, 233, 233, 233, 233, 170, 170, 170, - 170, 228, 224, 216, 241, 268, 312, -424, 23, -15, - -424, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, - 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502, - -424, 55, -424, -424, 272, 308, 1502, 1647, -424, 155, - -424, -424, -424, -424, -424, 274, 166, -424, -424, -424, - -424, -424, 135, 135, 157, 157, 157, 233, 233, 233, - 233, 233, 233, 170, 170, 170, 170, 228, 224, 216, - 241, 268, 313, -424, 1198, 1502, 1198, 298, 1198, 315, - -424, -424, 79, -424, 76, 1426, -424, 1502, -424, -424, - 1502, 1502, 1502, 364, 326, 1502, 276, 699, -424, 233, - 233, 233, 233, 233, 178, 178, 178, 178, 236, 271, - 280, 273, 322, 323, -424, 324, 303, -424, 278, 325, - -424, 332, 134, -424, -424, -424, -424, 325, -424, -424, - 1502, 361, 282, -424, 390, -424, -424, 330, -424, 337, - -424, -424, -424, -424, -424, -424, -424, 284, -424, 1502, - 316, -424, 317, 1198, 1502, 1502, 325, -424, 958, -424, - 325, -424, -424, 292, -424, 325, -424, 1198, 80, 1502, - 45, 390, -424, 152, 1198, 294, -424, 1502, -424, -424, - 336, -424, 325, -424, 1038, -424, 325, -424, -424, -424, - -424, -424, 56, 342, -424, 390, -424, 378, -424, 1198, - 354, 1198, -424, -424, -424, 325, 1118, 1118, 339, 152, - -424, 1198, -424, -424, 1118, 1118, -424, -424, -424 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -424, -424, -156, -424, -424, 18, -424, -424, -424, -424, - 0, -424, -424, 84, -424, 42, -424, 83, -424, -424, - -424, -40, -424, 192, -424, -424, -424, 11, 12, -424, - -155, -424, -173, -424, 311, -424, -140, -70, -424, -193, - 32, -424, -189, 33, -424, -176, 34, -424, -174, 41, - -424, -168, 31, -424, -424, -424, -424, -424, -424, -424, - -143, -376, -424, -17, 2, -424, -424, -13, -18, -424, - -424, -424, 150, -35, -424, -424, 148, 331, -82, -424, - -424, -424, -424, -423, -424, -424, -424, -424, -424, -424, - -424, -128, -424, -102, -424, -424, -424, -424, -424, 108, - -424, -424, -424, -424, -424, -424, -424, -424, -424, -283, - -318, -424, -34, -83 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint16 yytable[] = -{ - 43, 154, 213, 136, 142, 415, 468, 169, 87, 349, - 371, 50, 351, 131, 342, 372, 43, 358, 359, 360, - 346, 483, 484, 141, 133, 134, 106, 50, 333, 373, - 138, 184, 374, 356, 357, 43, 152, 147, 148, 375, - 209, 352, 522, 150, 151, 461, 50, 207, 97, 159, - 160, 161, 162, 563, 464, 318, 396, 276, 232, 367, - 368, 369, 370, 233, 279, 376, 453, 377, 143, 88, - 283, 213, 289, 465, 292, 214, 286, 511, 402, 100, - 508, 560, 90, 454, 403, 43, 518, 107, 320, 98, - 328, 208, 190, 191, 192, 89, 50, 402, 295, 319, - 397, 334, 550, 414, 135, 339, 103, 163, 210, 340, - 462, 405, 164, 108, 165, 335, 564, 402, 488, 410, - 109, 437, 576, 487, 570, 321, 438, 211, 424, 425, - 426, 137, 280, 230, 411, 417, 336, 323, 284, 325, - 439, 326, 327, 440, 422, 423, 188, 189, 549, 43, - 441, 281, 418, 509, 43, 144, 321, 285, 321, 407, - 50, 408, 215, 287, 512, 50, 347, 510, 561, 350, - 433, 434, 435, 436, 231, 322, 442, 329, 443, 534, - 185, 321, 321, 139, 163, 458, 459, 193, 194, 167, - 400, 168, 304, 305, 186, 187, 402, 353, 354, 355, - 296, 383, 532, 115, 140, 195, 196, 145, 551, 533, - 306, 307, 555, 115, 297, 298, 163, 558, 384, 385, - 163, 274, 35, 275, 321, 290, 115, 291, 496, 1, - 2, 3, 299, 300, 572, 321, 91, 216, 574, 499, - 92, 149, 12, 13, 203, 15, 197, 198, 293, 294, - 18, 308, 309, 199, 200, 201, 202, 583, 155, 386, - 387, 330, 331, 493, 310, 311, 312, 313, 337, 321, - 25, 26, 388, 389, 390, 391, 409, 204, 27, 301, - 302, 303, 217, 444, 321, 206, 28, 29, 93, 31, - 32, 33, 416, 34, 205, 212, 94, 277, 36, 288, - 315, 37, 38, 39, 40, 446, 321, 314, 419, 420, - 421, 317, 514, 450, 515, 447, 321, 516, 474, 475, - 476, 477, 324, 1, 2, 3, 316, 115, 343, 115, - 91, 115, 115, 332, 92, 448, 321, 456, 457, 15, - 490, 491, 498, 491, 523, 321, 527, 491, 378, 115, - 538, 321, 544, 321, 392, 115, 115, 536, 394, 115, - 557, 491, 569, 321, 393, 395, 398, 399, 504, 401, - 406, 451, 27, 445, 449, 492, 115, 507, 460, 500, - 28, 29, 93, 466, 381, 33, 519, 34, 520, 524, - 94, 525, 36, 321, 531, 528, 537, 539, 543, 453, - 115, 218, 115, 462, 571, 547, 293, 294, 577, 579, - 586, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 581, 455, 478, 495, 479, 482, 480, 521, - 412, 501, 413, 503, 282, 506, 481, 578, 546, 566, - 452, 0, 0, 0, 43, 0, 43, 502, 43, 183, - 0, 0, 0, 0, 0, 50, 0, 50, 0, 50, - 0, 0, 0, 517, 0, 0, 115, 0, 0, 115, - 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 115, 0, 0, 0, 0, 115, 0, 0, - 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, - 0, 213, 213, 0, 361, 362, 363, 364, 365, 366, - 548, 115, 0, 115, 0, 0, 0, 0, 0, 0, - 0, 545, 0, 43, 559, 567, 0, 0, 43, 0, - 0, 568, 0, 0, 50, 0, 0, 43, 0, 50, - 0, 562, 584, 585, 43, 0, 0, 0, 50, 0, - 0, 0, 0, 0, 43, 50, 580, 0, 582, 0, - 0, 587, 0, 0, 0, 50, 0, 0, 588, 43, - 0, 43, 0, 115, 467, 0, 43, 43, 0, 0, - 50, 43, 50, 0, 43, 43, 0, 50, 50, 467, - 467, 115, 50, 0, 0, 50, 50, 0, 115, 170, - 171, 0, 0, 0, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 427, 428, 429, 430, 431, - 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 115, 0, 0, - 0, 0, 183, 0, 0, 0, 0, 115, 0, 115, - 0, 0, 115, 115, 467, 0, 0, 115, 0, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 0, 258, 259, 260, 261, 262, 263, - 0, 264, 115, 218, 469, 470, 471, 472, 473, 218, - 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, - 0, 115, 0, 0, 0, 0, 467, 115, 348, 110, - 0, 1, 2, 3, 0, 0, 0, 0, 91, 0, - 0, 115, 92, 0, 12, 13, 0, 15, 0, 115, - 0, 0, 18, 293, 294, 0, 0, 0, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 0, - 0, 0, 25, 26, 0, 0, 0, 0, 0, 0, - 27, 0, 0, 218, 0, 0, 0, 0, 28, 29, - 93, 31, 32, 33, 0, 34, 183, 0, 94, 0, - 36, 0, 0, 37, 38, 39, 40, 0, 0, 0, - 0, 1, 2, 3, 4, 0, 111, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 0, 0, 18, 19, 20, 0, 21, 22, 0, 0, - 23, 24, 0, 0, 0, 218, 0, 0, 0, 0, - 0, 0, 25, 26, 0, 0, 0, 0, 0, 0, - 27, 0, 0, 0, 0, 0, 0, 0, 28, 29, - 30, 31, 32, 33, 0, 34, 0, 0, 35, 153, - 36, 0, 0, 37, 38, 39, 40, 0, 0, 0, - 0, 1, 2, 3, 4, 0, 41, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 0, 0, 18, 19, 20, 0, 21, 22, 0, 0, - 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 26, 0, 0, 0, 0, 0, 0, - 27, 0, 0, 0, 0, 0, 0, 0, 28, 29, - 30, 31, 32, 33, 0, 34, 0, 0, 35, 338, - 36, 0, 0, 37, 38, 39, 40, 0, 0, 0, - 0, 1, 2, 3, 4, 0, 41, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 0, 0, 18, 19, 20, 0, 21, 22, 0, 0, - 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 26, 0, 0, 0, 0, 0, 0, - 27, 0, 0, 0, 0, 0, 0, 0, 28, 29, - 30, 31, 32, 33, 0, 34, 0, 0, 35, 553, - 36, 0, 0, 37, 38, 39, 40, 0, 0, 0, - 0, 1, 2, 3, 4, 0, 41, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 0, 0, 18, 19, 20, 0, 21, 22, 0, 0, - 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 26, 0, 0, 0, 0, 0, 0, - 27, 0, 0, 0, 0, 0, 0, 0, 28, 29, - 30, 31, 32, 33, 0, 34, 0, 0, 35, 573, - 36, 0, 0, 37, 38, 39, 40, 0, 0, 0, - 0, 1, 2, 3, 4, 0, 41, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 0, 0, 18, 19, 20, 0, 21, 22, 0, 0, - 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 26, 0, 0, 0, 0, 0, 0, - 27, 0, 0, 0, 0, 0, 0, 0, 28, 29, - 30, 31, 32, 33, 0, 34, 0, 0, 35, 0, - 36, 0, 0, 37, 38, 39, 40, 0, 0, 0, - 0, 1, 2, 3, 4, 0, 41, 5, 6, 7, - 8, 9, 0, 11, 12, 13, 14, 15, 16, 17, - 0, 0, 18, 19, 20, 0, 21, 22, 0, 0, - 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 26, 0, 0, 0, 0, 0, 0, - 27, 0, 0, 0, 0, 0, 0, 0, 28, 29, - 30, 31, 32, 33, 0, 34, 0, 0, 35, 0, - 36, 0, 0, 37, 38, 39, 40, 1, 2, 3, - 0, 0, 0, 0, 91, 0, 41, 0, 92, 0, - 12, 13, 0, 15, 0, 0, 0, 0, 18, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, - 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, - 0, 0, 0, 0, 28, 29, 93, 31, 32, 33, - 0, 34, 0, 0, 94, 0, 36, 341, 0, 37, - 38, 39, 40, 1, 2, 3, 0, 0, 0, 0, - 91, 0, 0, 0, 92, 0, 12, 13, 0, 15, - 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 25, 26, 0, 0, 0, 0, - 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, - 28, 29, 93, 31, 32, 33, 0, 34, 344, 0, - 94, 0, 36, 0, 0, 37, 38, 39, 40, 1, - 2, 3, 0, 0, 0, 0, 91, 0, 0, 0, - 92, 0, 12, 13, 0, 15, 0, 0, 0, 0, - 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 26, 0, 0, 0, 0, 0, 0, 27, 0, - 0, 0, 0, 0, 0, 0, 28, 29, 93, 31, - 32, 33, 0, 34, 0, 0, 94, 0, 36, 513, - 0, 37, 38, 39, 40, 1, 2, 3, 0, 0, - 0, 0, 91, 0, 0, 0, 92, 0, 12, 13, - 0, 15, 0, 0, 0, 0, 18, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 25, 26, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, - 0, 0, 28, 29, 93, 31, 32, 33, 0, 34, - 0, 0, 94, 0, 36, 0, 0, 37, 38, 39, - 40, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 0, 258, 259, 260, 261, - 262, 263, 0, 264, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 265, 266, - 267, 0, 0, 0, 0, 0, 0, 0, 0, 268, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 0, 258, 259, 260, 261, 262, - 263, 0, 264, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 265, 266, 267, - 0, 0, 0, 0, 0, 0, 0, 0, 494 -}; - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-424))) - -#define yytable_value_is_error(Yytable_value) \ - YYID (0) - -static const yytype_int16 yycheck[] = -{ - 0, 35, 85, 16, 22, 288, 382, 47, 1, 165, - 203, 0, 168, 11, 157, 204, 16, 190, 191, 192, - 163, 397, 398, 21, 12, 13, 1, 16, 1, 205, - 18, 48, 206, 188, 189, 35, 34, 25, 26, 207, - 1, 184, 465, 31, 32, 22, 35, 42, 6, 37, - 38, 39, 40, 8, 69, 42, 42, 97, 62, 199, - 200, 201, 202, 67, 1, 208, 62, 210, 1, 62, - 1, 154, 112, 88, 114, 1, 1, 1, 62, 62, - 1, 1, 67, 79, 68, 85, 462, 62, 1, 6, - 1, 86, 46, 47, 48, 88, 85, 62, 115, 86, - 86, 74, 525, 68, 67, 69, 62, 67, 69, 73, - 87, 267, 72, 88, 74, 88, 71, 62, 401, 275, - 62, 314, 66, 68, 547, 69, 315, 88, 301, 302, - 303, 67, 69, 91, 277, 291, 149, 135, 69, 137, - 316, 139, 140, 317, 299, 300, 75, 76, 524, 149, - 318, 88, 295, 74, 154, 88, 69, 88, 69, 69, - 149, 71, 88, 88, 88, 154, 164, 88, 88, 167, - 310, 311, 312, 313, 91, 88, 319, 88, 321, 497, - 65, 69, 69, 67, 67, 73, 73, 22, 23, 72, - 230, 74, 22, 23, 79, 80, 62, 185, 186, 187, - 65, 23, 68, 11, 67, 40, 41, 62, 526, 492, - 40, 41, 530, 21, 79, 80, 67, 535, 40, 41, - 67, 72, 70, 74, 69, 72, 34, 74, 73, 3, - 4, 5, 75, 76, 552, 69, 10, 11, 556, 73, - 14, 66, 16, 17, 83, 19, 81, 82, 44, 45, - 24, 81, 82, 36, 37, 38, 39, 575, 69, 81, - 82, 30, 31, 406, 36, 37, 38, 39, 68, 69, - 44, 45, 36, 37, 38, 39, 274, 84, 52, 46, - 47, 48, 90, 68, 69, 43, 60, 61, 62, 63, - 64, 65, 290, 67, 85, 0, 70, 87, 72, 67, - 84, 75, 76, 77, 78, 68, 69, 83, 296, 297, - 298, 43, 455, 331, 457, 68, 69, 460, 388, 389, - 390, 391, 21, 3, 4, 5, 85, 135, 69, 137, - 10, 139, 140, 87, 14, 68, 69, 68, 69, 19, - 68, 69, 68, 69, 68, 69, 68, 69, 62, 157, - 68, 69, 68, 69, 83, 163, 164, 500, 85, 167, - 68, 69, 68, 69, 84, 43, 69, 88, 70, 67, - 66, 62, 52, 67, 67, 67, 184, 62, 66, 66, - 60, 61, 62, 381, 22, 65, 22, 67, 62, 66, - 70, 88, 72, 69, 62, 70, 35, 7, 68, 62, - 208, 90, 210, 87, 68, 88, 44, 45, 66, 31, - 71, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 68, 339, 392, 407, 393, 396, 394, 464, - 280, 444, 284, 446, 103, 448, 395, 565, 520, 541, - 332, -1, -1, -1, 444, -1, 446, 445, 448, 87, - -1, -1, -1, -1, -1, 444, -1, 446, -1, 448, - -1, -1, -1, 461, -1, -1, 274, -1, -1, 277, - -1, 554, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 290, -1, -1, -1, -1, 295, -1, -1, - -1, -1, -1, -1, 528, -1, -1, -1, -1, -1, - -1, 584, 585, -1, 193, 194, 195, 196, 197, 198, - 523, 319, -1, 321, -1, -1, -1, -1, -1, -1, - -1, 519, -1, 523, 537, 543, -1, -1, 528, -1, - -1, 544, -1, -1, 523, -1, -1, 537, -1, 528, - -1, 539, 576, 577, 544, -1, -1, -1, 537, -1, - -1, -1, -1, -1, 554, 544, 569, -1, 571, -1, - -1, 579, -1, -1, -1, 554, -1, -1, 581, 569, - -1, 571, -1, 381, 382, -1, 576, 577, -1, -1, - 569, 581, 571, -1, 584, 585, -1, 576, 577, 397, - 398, 399, 581, -1, -1, 584, 585, -1, 406, 44, - 45, -1, -1, -1, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 304, 305, 306, 307, 308, - 309, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 445, -1, -1, - -1, -1, 87, -1, -1, -1, -1, 455, -1, 457, - -1, -1, 460, 461, 462, -1, -1, 465, -1, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, -1, 28, 29, 30, 31, 32, 33, - -1, 35, 500, 382, 383, 384, 385, 386, 387, 388, - 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, - -1, 519, -1, -1, -1, -1, 524, 525, 62, 1, - -1, 3, 4, 5, -1, -1, -1, -1, 10, -1, - -1, 539, 14, -1, 16, 17, -1, 19, -1, 547, - -1, -1, 24, 44, 45, -1, -1, -1, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, -1, - -1, -1, 44, 45, -1, -1, -1, -1, -1, -1, - 52, -1, -1, 462, -1, -1, -1, -1, 60, 61, - 62, 63, 64, 65, -1, 67, 87, -1, 70, -1, - 72, -1, -1, 75, 76, 77, 78, -1, -1, -1, - -1, 3, 4, 5, 6, -1, 88, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - -1, -1, 24, 25, 26, -1, 28, 29, -1, -1, - 32, 33, -1, -1, -1, 524, -1, -1, -1, -1, - -1, -1, 44, 45, -1, -1, -1, -1, -1, -1, - 52, -1, -1, -1, -1, -1, -1, -1, 60, 61, - 62, 63, 64, 65, -1, 67, -1, -1, 70, 71, - 72, -1, -1, 75, 76, 77, 78, -1, -1, -1, - -1, 3, 4, 5, 6, -1, 88, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - -1, -1, 24, 25, 26, -1, 28, 29, -1, -1, - 32, 33, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 44, 45, -1, -1, -1, -1, -1, -1, - 52, -1, -1, -1, -1, -1, -1, -1, 60, 61, - 62, 63, 64, 65, -1, 67, -1, -1, 70, 71, - 72, -1, -1, 75, 76, 77, 78, -1, -1, -1, - -1, 3, 4, 5, 6, -1, 88, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - -1, -1, 24, 25, 26, -1, 28, 29, -1, -1, - 32, 33, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 44, 45, -1, -1, -1, -1, -1, -1, - 52, -1, -1, -1, -1, -1, -1, -1, 60, 61, - 62, 63, 64, 65, -1, 67, -1, -1, 70, 71, - 72, -1, -1, 75, 76, 77, 78, -1, -1, -1, - -1, 3, 4, 5, 6, -1, 88, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - -1, -1, 24, 25, 26, -1, 28, 29, -1, -1, - 32, 33, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 44, 45, -1, -1, -1, -1, -1, -1, - 52, -1, -1, -1, -1, -1, -1, -1, 60, 61, - 62, 63, 64, 65, -1, 67, -1, -1, 70, 71, - 72, -1, -1, 75, 76, 77, 78, -1, -1, -1, - -1, 3, 4, 5, 6, -1, 88, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - -1, -1, 24, 25, 26, -1, 28, 29, -1, -1, - 32, 33, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 44, 45, -1, -1, -1, -1, -1, -1, - 52, -1, -1, -1, -1, -1, -1, -1, 60, 61, - 62, 63, 64, 65, -1, 67, -1, -1, 70, -1, - 72, -1, -1, 75, 76, 77, 78, -1, -1, -1, - -1, 3, 4, 5, 6, -1, 88, 9, 10, 11, - 12, 13, -1, 15, 16, 17, 18, 19, 20, 21, - -1, -1, 24, 25, 26, -1, 28, 29, -1, -1, - 32, 33, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 44, 45, -1, -1, -1, -1, -1, -1, - 52, -1, -1, -1, -1, -1, -1, -1, 60, 61, - 62, 63, 64, 65, -1, 67, -1, -1, 70, -1, - 72, -1, -1, 75, 76, 77, 78, 3, 4, 5, - -1, -1, -1, -1, 10, -1, 88, -1, 14, -1, - 16, 17, -1, 19, -1, -1, -1, -1, 24, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 44, 45, - -1, -1, -1, -1, -1, -1, 52, -1, -1, -1, - -1, -1, -1, -1, 60, 61, 62, 63, 64, 65, - -1, 67, -1, -1, 70, -1, 72, 73, -1, 75, - 76, 77, 78, 3, 4, 5, -1, -1, -1, -1, - 10, -1, -1, -1, 14, -1, 16, 17, -1, 19, - -1, -1, -1, -1, 24, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 44, 45, -1, -1, -1, -1, - -1, -1, 52, -1, -1, -1, -1, -1, -1, -1, - 60, 61, 62, 63, 64, 65, -1, 67, 68, -1, - 70, -1, 72, -1, -1, 75, 76, 77, 78, 3, - 4, 5, -1, -1, -1, -1, 10, -1, -1, -1, - 14, -1, 16, 17, -1, 19, -1, -1, -1, -1, - 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 44, 45, -1, -1, -1, -1, -1, -1, 52, -1, - -1, -1, -1, -1, -1, -1, 60, 61, 62, 63, - 64, 65, -1, 67, -1, -1, 70, -1, 72, 73, - -1, 75, 76, 77, 78, 3, 4, 5, -1, -1, - -1, -1, 10, -1, -1, -1, 14, -1, 16, 17, - -1, 19, -1, -1, -1, -1, 24, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 44, 45, -1, -1, - -1, -1, -1, -1, 52, -1, -1, -1, -1, -1, - -1, -1, 60, 61, 62, 63, 64, 65, -1, 67, - -1, -1, 70, -1, 72, -1, -1, 75, 76, 77, - 78, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, -1, 28, 29, 30, 31, - 32, 33, -1, 35, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 60, 61, - 62, -1, -1, -1, -1, -1, -1, -1, -1, 71, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, -1, 28, 29, 30, 31, 32, - 33, -1, 35, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 60, 61, 62, - -1, -1, -1, -1, -1, -1, -1, -1, 71 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 3, 4, 5, 6, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 24, 25, - 26, 28, 29, 32, 33, 44, 45, 52, 60, 61, - 62, 63, 64, 65, 67, 70, 72, 75, 76, 77, - 78, 88, 92, 99, 100, 105, 107, 109, 113, 115, - 116, 118, 120, 122, 124, 127, 130, 133, 136, 139, - 142, 145, 148, 151, 155, 156, 157, 158, 163, 168, - 169, 170, 171, 174, 175, 176, 177, 178, 184, 185, - 186, 187, 189, 190, 200, 201, 202, 1, 62, 88, - 67, 10, 14, 62, 70, 98, 99, 104, 106, 193, - 62, 159, 161, 62, 164, 165, 1, 62, 88, 62, - 1, 88, 104, 106, 108, 112, 114, 116, 117, 119, - 121, 123, 125, 128, 131, 134, 137, 140, 143, 146, - 149, 153, 112, 117, 117, 67, 156, 67, 117, 67, - 67, 153, 157, 1, 88, 62, 188, 117, 117, 66, - 117, 117, 153, 71, 201, 69, 101, 102, 103, 117, - 117, 117, 117, 67, 72, 74, 110, 72, 74, 110, - 44, 45, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 87, 152, 65, 79, 80, 75, 76, - 46, 47, 48, 22, 23, 40, 41, 81, 82, 36, - 37, 38, 39, 83, 84, 85, 43, 42, 86, 1, - 69, 88, 0, 202, 1, 88, 11, 112, 123, 126, - 129, 132, 135, 138, 141, 144, 147, 150, 154, 173, - 104, 106, 62, 67, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, - 30, 31, 32, 33, 35, 60, 61, 62, 71, 90, - 91, 93, 94, 97, 72, 74, 110, 87, 166, 1, - 69, 88, 166, 1, 69, 88, 1, 88, 67, 110, - 72, 74, 110, 44, 45, 152, 65, 79, 80, 75, - 76, 46, 47, 48, 22, 23, 40, 41, 81, 82, - 36, 37, 38, 39, 83, 84, 85, 43, 42, 86, - 1, 69, 88, 153, 21, 153, 153, 153, 1, 88, - 30, 31, 87, 1, 74, 88, 156, 68, 71, 69, - 73, 73, 149, 69, 68, 111, 149, 153, 62, 91, - 153, 91, 149, 117, 117, 117, 119, 119, 121, 121, - 121, 123, 123, 123, 123, 123, 123, 125, 125, 125, - 125, 128, 131, 134, 137, 140, 149, 149, 62, 160, - 162, 22, 152, 23, 40, 41, 81, 82, 36, 37, - 38, 39, 83, 84, 85, 43, 42, 86, 69, 88, - 110, 67, 62, 68, 198, 91, 66, 69, 71, 153, - 91, 149, 161, 165, 68, 198, 153, 91, 149, 117, - 117, 117, 119, 119, 121, 121, 121, 123, 123, 123, - 123, 123, 123, 125, 125, 125, 125, 128, 131, 134, - 137, 140, 149, 149, 68, 67, 68, 68, 68, 67, - 157, 62, 188, 62, 79, 102, 68, 69, 73, 73, - 66, 22, 87, 167, 69, 88, 153, 112, 150, 123, - 123, 123, 123, 123, 126, 126, 126, 126, 129, 132, - 135, 138, 141, 150, 150, 153, 172, 68, 198, 194, - 68, 69, 67, 149, 71, 94, 73, 191, 68, 73, - 66, 156, 153, 156, 70, 179, 156, 62, 1, 74, - 88, 1, 88, 73, 149, 149, 149, 153, 150, 22, - 62, 162, 172, 68, 66, 88, 196, 68, 70, 199, - 195, 62, 68, 198, 199, 192, 149, 35, 68, 7, - 180, 181, 182, 68, 68, 153, 167, 88, 156, 150, - 172, 199, 197, 71, 201, 199, 95, 68, 199, 156, - 1, 88, 153, 8, 71, 183, 182, 157, 156, 68, - 172, 68, 199, 71, 199, 96, 66, 66, 180, 31, - 156, 68, 156, 199, 201, 201, 71, 157, 156 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - -/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - -__attribute__((__unused__)) -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static unsigned -yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -#else -static unsigned -yy_location_print_ (yyo, yylocp) - FILE *yyo; - YYLTYPE const * const yylocp; -#endif -{ - unsigned res = 0; - int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; - if (0 <= yylocp->first_line) - { - res += fprintf (yyo, "%d", yylocp->first_line); - if (0 <= yylocp->first_column) - res += fprintf (yyo, ".%d", yylocp->first_column); - } - if (0 <= yylocp->last_line) - { - if (yylocp->first_line < yylocp->last_line) - { - res += fprintf (yyo, "-%d", yylocp->last_line); - if (0 <= end_col) - res += fprintf (yyo, ".%d", end_col); - } - else if (0 <= end_col && yylocp->first_column < end_col) - res += fprintf (yyo, "-%d", end_col); - } - return res; - } - -# define YY_LOCATION_PRINT(File, Loc) \ - yy_location_print_ (File, &(Loc)) - -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; -#endif -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - if (!yyvaluep) - return; - YYUSE (yylocationp); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - YYUSE (yytype); -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) ); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULL; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - Assume YYFAIL is not used. It's too flawed to consider. See - - for details. YYERROR is fine as it does not invoke this - function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; -#endif -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - YYUSE (yytype); -} - - - - -/* The lookahead symbol. */ -int yychar; - - -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); - -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - = { 1, 1, 1, 1 } -# endif -; - - -/* Number of syntax errors so far. */ -int yynerrs; - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - `yyls': related to locations. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yylsp = yyls = yylsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - yylsp[0] = yylloc; - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -/* Line 1787 of yacc.c */ -#line 192 "grammar.y" - { (yyval.ident) = new Identifier("break"); } - break; - - case 3: -/* Line 1787 of yacc.c */ -#line 193 "grammar.y" - { (yyval.ident) = new Identifier("case"); } - break; - - case 4: -/* Line 1787 of yacc.c */ -#line 194 "grammar.y" - { (yyval.ident) = new Identifier("default"); } - break; - - case 5: -/* Line 1787 of yacc.c */ -#line 195 "grammar.y" - { (yyval.ident) = new Identifier("for"); } - break; - - case 6: -/* Line 1787 of yacc.c */ -#line 196 "grammar.y" - { (yyval.ident) = new Identifier("new"); } - break; - - case 7: -/* Line 1787 of yacc.c */ -#line 197 "grammar.y" - { (yyval.ident) = new Identifier("var"); } - break; - - case 8: -/* Line 1787 of yacc.c */ -#line 198 "grammar.y" - { (yyval.ident) = new Identifier("const"); } - break; - - case 9: -/* Line 1787 of yacc.c */ -#line 199 "grammar.y" - { (yyval.ident) = new Identifier("continue"); } - break; - - case 10: -/* Line 1787 of yacc.c */ -#line 200 "grammar.y" - { (yyval.ident) = new Identifier("function"); } - break; - - case 11: -/* Line 1787 of yacc.c */ -#line 201 "grammar.y" - { (yyval.ident) = new Identifier("return"); } - break; - - case 12: -/* Line 1787 of yacc.c */ -#line 202 "grammar.y" - { (yyval.ident) = new Identifier("void"); } - break; - - case 13: -/* Line 1787 of yacc.c */ -#line 203 "grammar.y" - { (yyval.ident) = new Identifier("delete"); } - break; - - case 14: -/* Line 1787 of yacc.c */ -#line 204 "grammar.y" - { (yyval.ident) = new Identifier("if"); } - break; - - case 15: -/* Line 1787 of yacc.c */ -#line 205 "grammar.y" - { (yyval.ident) = new Identifier("this"); } - break; - - case 16: -/* Line 1787 of yacc.c */ -#line 206 "grammar.y" - { (yyval.ident) = new Identifier("do"); } - break; - - case 17: -/* Line 1787 of yacc.c */ -#line 207 "grammar.y" - { (yyval.ident) = new Identifier("while"); } - break; - - case 18: -/* Line 1787 of yacc.c */ -#line 208 "grammar.y" - { (yyval.ident) = new Identifier("in"); } - break; - - case 19: -/* Line 1787 of yacc.c */ -#line 209 "grammar.y" - { (yyval.ident) = new Identifier("instanceof"); } - break; - - case 20: -/* Line 1787 of yacc.c */ -#line 210 "grammar.y" - { (yyval.ident) = new Identifier("typeof"); } - break; - - case 21: -/* Line 1787 of yacc.c */ -#line 211 "grammar.y" - { (yyval.ident) = new Identifier("switch"); } - break; - - case 22: -/* Line 1787 of yacc.c */ -#line 212 "grammar.y" - { (yyval.ident) = new Identifier("with"); } - break; - - case 23: -/* Line 1787 of yacc.c */ -#line 213 "grammar.y" - { (yyval.ident) = new Identifier("throw"); } - break; - - case 24: -/* Line 1787 of yacc.c */ -#line 214 "grammar.y" - { (yyval.ident) = new Identifier("try"); } - break; - - case 25: -/* Line 1787 of yacc.c */ -#line 215 "grammar.y" - { (yyval.ident) = new Identifier("catch"); } - break; - - case 26: -/* Line 1787 of yacc.c */ -#line 216 "grammar.y" - { (yyval.ident) = new Identifier("finally"); } - break; - - case 27: -/* Line 1787 of yacc.c */ -#line 217 "grammar.y" - { (yyval.ident) = new Identifier("debugger"); } - break; - - case 28: -/* Line 1787 of yacc.c */ -#line 218 "grammar.y" - { (yyval.ident) = new Identifier("import"); } - break; - - case 29: -/* Line 1787 of yacc.c */ -#line 219 "grammar.y" - { (yyval.ident) = new Identifier("null"); } - break; - - case 30: -/* Line 1787 of yacc.c */ -#line 220 "grammar.y" - { (yyval.ident) = new Identifier("true"); } - break; - - case 31: -/* Line 1787 of yacc.c */ -#line 221 "grammar.y" - { (yyval.ident) = new Identifier("false"); } - break; - - case 32: -/* Line 1787 of yacc.c */ -#line 222 "grammar.y" - { (yyval.ident) = new Identifier("else"); } - break; - - case 33: -/* Line 1787 of yacc.c */ -#line 226 "grammar.y" - { (yyval.ident) = (yyvsp[(1) - (1)].ident); } - break; - - case 34: -/* Line 1787 of yacc.c */ -#line 227 "grammar.y" - { (yyval.ident) = (yyvsp[(1) - (1)].ident); } - break; - - case 35: -/* Line 1787 of yacc.c */ -#line 231 "grammar.y" - { (yyval.node) = new NullNode(); } - break; - - case 36: -/* Line 1787 of yacc.c */ -#line 232 "grammar.y" - { (yyval.node) = new BooleanNode(true); } - break; - - case 37: -/* Line 1787 of yacc.c */ -#line 233 "grammar.y" - { (yyval.node) = new BooleanNode(false); } - break; - - case 38: -/* Line 1787 of yacc.c */ -#line 234 "grammar.y" - { (yyval.node) = new NumberNode((yyvsp[(1) - (1)].dval)); } - break; - - case 39: -/* Line 1787 of yacc.c */ -#line 235 "grammar.y" - { (yyval.node) = new StringNode((yyvsp[(1) - (1)].ustr)); } - break; - - case 40: -/* Line 1787 of yacc.c */ -#line 236 "grammar.y" - { - Lexer& l = lexer(); - if (!l.scanRegExp()) - YYABORT; - (yyval.node) = new RegExpNode(l.pattern(), l.flags()); - } - break; - - case 41: -/* Line 1787 of yacc.c */ -#line 242 "grammar.y" - { - Lexer& l = lexer(); - if (!l.scanRegExp()) - YYABORT; - (yyval.node) = new RegExpNode("=" + l.pattern(), l.flags()); - } - break; - - case 42: -/* Line 1787 of yacc.c */ -#line 251 "grammar.y" - { (yyval.pname) = new PropertyNameNode(*(yyvsp[(1) - (1)].ident)); } - break; - - case 43: -/* Line 1787 of yacc.c */ -#line 252 "grammar.y" - { (yyval.pname) = new PropertyNameNode(Identifier(*(yyvsp[(1) - (1)].ustr))); } - break; - - case 44: -/* Line 1787 of yacc.c */ -#line 253 "grammar.y" - { (yyval.pname) = new PropertyNameNode(Identifier(UString::from((yyvsp[(1) - (1)].dval)))); } - break; - - case 45: -/* Line 1787 of yacc.c */ -#line 257 "grammar.y" - { (yyval.pnode) = new PropertyNode((yyvsp[(1) - (3)].pname), (yyvsp[(3) - (3)].node), PropertyNode::Constant); } - break; - - case 46: -/* Line 1787 of yacc.c */ -#line 258 "grammar.y" - {inFuncExpr();} - break; - - case 47: -/* Line 1787 of yacc.c */ -#line 258 "grammar.y" - { - if (!makeGetterOrSetterPropertyNode((yyval.pnode), *(yyvsp[(1) - (6)].ident), *(yyvsp[(2) - (6)].ident), 0, (yyvsp[(6) - (6)].body))) - YYABORT; - } - break; - - case 48: -/* Line 1787 of yacc.c */ -#line 262 "grammar.y" - {inFuncExpr();} - break; - - case 49: -/* Line 1787 of yacc.c */ -#line 262 "grammar.y" - { - if (!makeGetterOrSetterPropertyNode((yyval.pnode), *(yyvsp[(1) - (7)].ident), *(yyvsp[(2) - (7)].ident), (yyvsp[(4) - (7)].param), (yyvsp[(7) - (7)].body))) - YYABORT; - } - break; - - case 50: -/* Line 1787 of yacc.c */ -#line 269 "grammar.y" - { (yyval.plist) = new PropertyListNode((yyvsp[(1) - (1)].pnode)); } - break; - - case 51: -/* Line 1787 of yacc.c */ -#line 270 "grammar.y" - { (yyval.plist) = new PropertyListNode((yyvsp[(3) - (3)].pnode), (yyvsp[(1) - (3)].plist)); } - break; - - case 53: -/* Line 1787 of yacc.c */ -#line 275 "grammar.y" - { (yyval.node) = new ObjectLiteralNode(); } - break; - - case 54: -/* Line 1787 of yacc.c */ -#line 276 "grammar.y" - { (yyval.node) = new ObjectLiteralNode((yyvsp[(2) - (3)].plist)); } - break; - - case 55: -/* Line 1787 of yacc.c */ -#line 278 "grammar.y" - { (yyval.node) = new ObjectLiteralNode((yyvsp[(2) - (4)].plist)); } - break; - - case 56: -/* Line 1787 of yacc.c */ -#line 282 "grammar.y" - { (yyval.node) = new ThisNode(); } - break; - - case 59: -/* Line 1787 of yacc.c */ -#line 285 "grammar.y" - { (yyval.node) = new VarAccessNode(*(yyvsp[(1) - (1)].ident)); } - break; - - case 60: -/* Line 1787 of yacc.c */ -#line 286 "grammar.y" - { (yyval.node) = makeGroupNode((yyvsp[(2) - (3)].node)); } - break; - - case 61: -/* Line 1787 of yacc.c */ -#line 291 "grammar.y" - { (yyval.node) = new ArrayNode((yyvsp[(2) - (3)].ival)); } - break; - - case 62: -/* Line 1787 of yacc.c */ -#line 292 "grammar.y" - { (yyval.node) = new ArrayNode((yyvsp[(2) - (3)].elm)); } - break; - - case 63: -/* Line 1787 of yacc.c */ -#line 293 "grammar.y" - { (yyval.node) = new ArrayNode((yyvsp[(4) - (5)].ival), (yyvsp[(2) - (5)].elm)); } - break; - - case 64: -/* Line 1787 of yacc.c */ -#line 297 "grammar.y" - { (yyval.elm) = new ElementNode((yyvsp[(1) - (2)].ival), (yyvsp[(2) - (2)].node)); } - break; - - case 65: -/* Line 1787 of yacc.c */ -#line 299 "grammar.y" - { (yyval.elm) = new ElementNode((yyvsp[(1) - (4)].elm), (yyvsp[(3) - (4)].ival), (yyvsp[(4) - (4)].node)); } - break; - - case 66: -/* Line 1787 of yacc.c */ -#line 303 "grammar.y" - { (yyval.ival) = 0; } - break; - - case 68: -/* Line 1787 of yacc.c */ -#line 308 "grammar.y" - { (yyval.ival) = 1; } - break; - - case 69: -/* Line 1787 of yacc.c */ -#line 309 "grammar.y" - { (yyval.ival) = (yyvsp[(1) - (2)].ival) + 1; } - break; - - case 71: -/* Line 1787 of yacc.c */ -#line 314 "grammar.y" - { (yyval.node) = (yyvsp[(1) - (1)].funcExpr); } - break; - - case 72: -/* Line 1787 of yacc.c */ -#line 315 "grammar.y" - { (yyval.node) = new BracketAccessorNode((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node)); } - break; - - case 73: -/* Line 1787 of yacc.c */ -#line 316 "grammar.y" - { (yyval.node) = new DotAccessorNode((yyvsp[(1) - (3)].node), *(yyvsp[(3) - (3)].ident)); } - break; - - case 74: -/* Line 1787 of yacc.c */ -#line 317 "grammar.y" - { (yyval.node) = new NewExprNode((yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].args)); } - break; - - case 76: -/* Line 1787 of yacc.c */ -#line 322 "grammar.y" - { (yyval.node) = new BracketAccessorNode((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node)); } - break; - - case 77: -/* Line 1787 of yacc.c */ -#line 323 "grammar.y" - { (yyval.node) = new DotAccessorNode((yyvsp[(1) - (3)].node), *(yyvsp[(3) - (3)].ident)); } - break; - - case 78: -/* Line 1787 of yacc.c */ -#line 324 "grammar.y" - { (yyval.node) = new NewExprNode((yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].args)); } - break; - - case 80: -/* Line 1787 of yacc.c */ -#line 329 "grammar.y" - { (yyval.node) = new NewExprNode((yyvsp[(2) - (2)].node)); } - break; - - case 82: -/* Line 1787 of yacc.c */ -#line 334 "grammar.y" - { (yyval.node) = new NewExprNode((yyvsp[(2) - (2)].node)); } - break; - - case 83: -/* Line 1787 of yacc.c */ -#line 338 "grammar.y" - { (yyval.node) = makeFunctionCallNode((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].args)); } - break; - - case 84: -/* Line 1787 of yacc.c */ -#line 339 "grammar.y" - { (yyval.node) = makeFunctionCallNode((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].args)); } - break; - - case 85: -/* Line 1787 of yacc.c */ -#line 340 "grammar.y" - { (yyval.node) = new BracketAccessorNode((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node)); } - break; - - case 86: -/* Line 1787 of yacc.c */ -#line 341 "grammar.y" - { (yyval.node) = new DotAccessorNode((yyvsp[(1) - (3)].node), *(yyvsp[(3) - (3)].ident)); } - break; - - case 87: -/* Line 1787 of yacc.c */ -#line 345 "grammar.y" - { (yyval.node) = makeFunctionCallNode((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].args)); } - break; - - case 88: -/* Line 1787 of yacc.c */ -#line 346 "grammar.y" - { (yyval.node) = makeFunctionCallNode((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].args)); } - break; - - case 89: -/* Line 1787 of yacc.c */ -#line 347 "grammar.y" - { (yyval.node) = new BracketAccessorNode((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node)); } - break; - - case 90: -/* Line 1787 of yacc.c */ -#line 348 "grammar.y" - { (yyval.node) = new DotAccessorNode((yyvsp[(1) - (3)].node), *(yyvsp[(3) - (3)].ident)); } - break; - - case 91: -/* Line 1787 of yacc.c */ -#line 352 "grammar.y" - { (yyval.args) = new ArgumentsNode(); } - break; - - case 92: -/* Line 1787 of yacc.c */ -#line 353 "grammar.y" - { (yyval.args) = new ArgumentsNode((yyvsp[(2) - (3)].alist)); } - break; - - case 93: -/* Line 1787 of yacc.c */ -#line 357 "grammar.y" - { (yyval.alist) = new ArgumentListNode((yyvsp[(1) - (1)].node)); } - break; - - case 94: -/* Line 1787 of yacc.c */ -#line 358 "grammar.y" - { (yyval.alist) = new ArgumentListNode((yyvsp[(1) - (3)].alist), (yyvsp[(3) - (3)].node)); } - break; - - case 100: -/* Line 1787 of yacc.c */ -#line 373 "grammar.y" - { (yyval.node) = makePostfixNode((yyvsp[(1) - (2)].node), OpPlusPlus); } - break; - - case 101: -/* Line 1787 of yacc.c */ -#line 374 "grammar.y" - { (yyval.node) = makePostfixNode((yyvsp[(1) - (2)].node), OpMinusMinus); } - break; - - case 103: -/* Line 1787 of yacc.c */ -#line 379 "grammar.y" - { (yyval.node) = makePostfixNode((yyvsp[(1) - (2)].node), OpPlusPlus); } - break; - - case 104: -/* Line 1787 of yacc.c */ -#line 380 "grammar.y" - { (yyval.node) = makePostfixNode((yyvsp[(1) - (2)].node), OpMinusMinus); } - break; - - case 105: -/* Line 1787 of yacc.c */ -#line 384 "grammar.y" - { (yyval.node) = makeDeleteNode((yyvsp[(2) - (2)].node)); } - break; - - case 106: -/* Line 1787 of yacc.c */ -#line 385 "grammar.y" - { (yyval.node) = new VoidNode((yyvsp[(2) - (2)].node)); } - break; - - case 107: -/* Line 1787 of yacc.c */ -#line 386 "grammar.y" - { (yyval.node) = makeTypeOfNode((yyvsp[(2) - (2)].node)); } - break; - - case 108: -/* Line 1787 of yacc.c */ -#line 387 "grammar.y" - { (yyval.node) = makePrefixNode((yyvsp[(2) - (2)].node), OpPlusPlus); } - break; - - case 109: -/* Line 1787 of yacc.c */ -#line 388 "grammar.y" - { (yyval.node) = makePrefixNode((yyvsp[(2) - (2)].node), OpPlusPlus); } - break; - - case 110: -/* Line 1787 of yacc.c */ -#line 389 "grammar.y" - { (yyval.node) = makePrefixNode((yyvsp[(2) - (2)].node), OpMinusMinus); } - break; - - case 111: -/* Line 1787 of yacc.c */ -#line 390 "grammar.y" - { (yyval.node) = makePrefixNode((yyvsp[(2) - (2)].node), OpMinusMinus); } - break; - - case 112: -/* Line 1787 of yacc.c */ -#line 391 "grammar.y" - { (yyval.node) = makeUnaryPlusNode((yyvsp[(2) - (2)].node)); } - break; - - case 113: -/* Line 1787 of yacc.c */ -#line 392 "grammar.y" - { (yyval.node) = makeNegateNode((yyvsp[(2) - (2)].node)); } - break; - - case 114: -/* Line 1787 of yacc.c */ -#line 393 "grammar.y" - { (yyval.node) = makeBitwiseNotNode((yyvsp[(2) - (2)].node)); } - break; - - case 115: -/* Line 1787 of yacc.c */ -#line 394 "grammar.y" - { (yyval.node) = makeLogicalNotNode((yyvsp[(2) - (2)].node)); } - break; - - case 121: -/* Line 1787 of yacc.c */ -#line 408 "grammar.y" - { (yyval.node) = makeMultNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpMult); } - break; - - case 122: -/* Line 1787 of yacc.c */ -#line 409 "grammar.y" - { (yyval.node) = makeMultNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpDiv); } - break; - - case 123: -/* Line 1787 of yacc.c */ -#line 410 "grammar.y" - { (yyval.node) = makeMultNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpMod); } - break; - - case 125: -/* Line 1787 of yacc.c */ -#line 416 "grammar.y" - { (yyval.node) = makeMultNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpMult); } - break; - - case 126: -/* Line 1787 of yacc.c */ -#line 418 "grammar.y" - { (yyval.node) = makeMultNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpDiv); } - break; - - case 127: -/* Line 1787 of yacc.c */ -#line 420 "grammar.y" - { (yyval.node) = makeMultNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpMod); } - break; - - case 129: -/* Line 1787 of yacc.c */ -#line 425 "grammar.y" - { (yyval.node) = makeAddNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpPlus); } - break; - - case 130: -/* Line 1787 of yacc.c */ -#line 426 "grammar.y" - { (yyval.node) = makeAddNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpMinus); } - break; - - case 132: -/* Line 1787 of yacc.c */ -#line 432 "grammar.y" - { (yyval.node) = makeAddNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpPlus); } - break; - - case 133: -/* Line 1787 of yacc.c */ -#line 434 "grammar.y" - { (yyval.node) = makeAddNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpMinus); } - break; - - case 135: -/* Line 1787 of yacc.c */ -#line 439 "grammar.y" - { (yyval.node) = makeShiftNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpLShift); } - break; - - case 136: -/* Line 1787 of yacc.c */ -#line 440 "grammar.y" - { (yyval.node) = makeShiftNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpRShift); } - break; - - case 137: -/* Line 1787 of yacc.c */ -#line 441 "grammar.y" - { (yyval.node) = makeShiftNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpURShift); } - break; - - case 139: -/* Line 1787 of yacc.c */ -#line 446 "grammar.y" - { (yyval.node) = makeShiftNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpLShift); } - break; - - case 140: -/* Line 1787 of yacc.c */ -#line 447 "grammar.y" - { (yyval.node) = makeShiftNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpRShift); } - break; - - case 141: -/* Line 1787 of yacc.c */ -#line 448 "grammar.y" - { (yyval.node) = makeShiftNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), OpURShift); } - break; - - case 143: -/* Line 1787 of yacc.c */ -#line 453 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpLess, (yyvsp[(3) - (3)].node)); } - break; - - case 144: -/* Line 1787 of yacc.c */ -#line 454 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpGreater, (yyvsp[(3) - (3)].node)); } - break; - - case 145: -/* Line 1787 of yacc.c */ -#line 455 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpLessEq, (yyvsp[(3) - (3)].node)); } - break; - - case 146: -/* Line 1787 of yacc.c */ -#line 456 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpGreaterEq, (yyvsp[(3) - (3)].node)); } - break; - - case 147: -/* Line 1787 of yacc.c */ -#line 457 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpInstanceOf, (yyvsp[(3) - (3)].node)); } - break; - - case 148: -/* Line 1787 of yacc.c */ -#line 458 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpIn, (yyvsp[(3) - (3)].node)); } - break; - - case 150: -/* Line 1787 of yacc.c */ -#line 463 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpLess, (yyvsp[(3) - (3)].node)); } - break; - - case 151: -/* Line 1787 of yacc.c */ -#line 464 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpGreater, (yyvsp[(3) - (3)].node)); } - break; - - case 152: -/* Line 1787 of yacc.c */ -#line 465 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpLessEq, (yyvsp[(3) - (3)].node)); } - break; - - case 153: -/* Line 1787 of yacc.c */ -#line 466 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpGreaterEq, (yyvsp[(3) - (3)].node)); } - break; - - case 154: -/* Line 1787 of yacc.c */ -#line 468 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpInstanceOf, (yyvsp[(3) - (3)].node)); } - break; - - case 156: -/* Line 1787 of yacc.c */ -#line 473 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpLess, (yyvsp[(3) - (3)].node)); } - break; - - case 157: -/* Line 1787 of yacc.c */ -#line 474 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpGreater, (yyvsp[(3) - (3)].node)); } - break; - - case 158: -/* Line 1787 of yacc.c */ -#line 475 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpLessEq, (yyvsp[(3) - (3)].node)); } - break; - - case 159: -/* Line 1787 of yacc.c */ -#line 476 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpGreaterEq, (yyvsp[(3) - (3)].node)); } - break; - - case 160: -/* Line 1787 of yacc.c */ -#line 478 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpInstanceOf, (yyvsp[(3) - (3)].node)); } - break; - - case 161: -/* Line 1787 of yacc.c */ -#line 479 "grammar.y" - { (yyval.node) = makeRelationalNode((yyvsp[(1) - (3)].node), OpIn, (yyvsp[(3) - (3)].node)); } - break; - - case 163: -/* Line 1787 of yacc.c */ -#line 484 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpEqEq, (yyvsp[(3) - (3)].node)); } - break; - - case 164: -/* Line 1787 of yacc.c */ -#line 485 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpNotEq, (yyvsp[(3) - (3)].node)); } - break; - - case 165: -/* Line 1787 of yacc.c */ -#line 486 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpStrEq, (yyvsp[(3) - (3)].node)); } - break; - - case 166: -/* Line 1787 of yacc.c */ -#line 487 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpStrNEq, (yyvsp[(3) - (3)].node));} - break; - - case 168: -/* Line 1787 of yacc.c */ -#line 493 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpEqEq, (yyvsp[(3) - (3)].node)); } - break; - - case 169: -/* Line 1787 of yacc.c */ -#line 495 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpNotEq, (yyvsp[(3) - (3)].node)); } - break; - - case 170: -/* Line 1787 of yacc.c */ -#line 497 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpStrEq, (yyvsp[(3) - (3)].node)); } - break; - - case 171: -/* Line 1787 of yacc.c */ -#line 499 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpStrNEq, (yyvsp[(3) - (3)].node));} - break; - - case 173: -/* Line 1787 of yacc.c */ -#line 505 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpEqEq, (yyvsp[(3) - (3)].node)); } - break; - - case 174: -/* Line 1787 of yacc.c */ -#line 506 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpNotEq, (yyvsp[(3) - (3)].node)); } - break; - - case 175: -/* Line 1787 of yacc.c */ -#line 508 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpStrEq, (yyvsp[(3) - (3)].node)); } - break; - - case 176: -/* Line 1787 of yacc.c */ -#line 510 "grammar.y" - { (yyval.node) = makeEqualNode((yyvsp[(1) - (3)].node), OpStrNEq, (yyvsp[(3) - (3)].node));} - break; - - case 178: -/* Line 1787 of yacc.c */ -#line 515 "grammar.y" - { (yyval.node) = makeBitOperNode((yyvsp[(1) - (3)].node), OpBitAnd, (yyvsp[(3) - (3)].node)); } - break; - - case 180: -/* Line 1787 of yacc.c */ -#line 521 "grammar.y" - { (yyval.node) = makeBitOperNode((yyvsp[(1) - (3)].node), OpBitAnd, (yyvsp[(3) - (3)].node)); } - break; - - case 182: -/* Line 1787 of yacc.c */ -#line 526 "grammar.y" - { (yyval.node) = makeBitOperNode((yyvsp[(1) - (3)].node), OpBitAnd, (yyvsp[(3) - (3)].node)); } - break; - - case 184: -/* Line 1787 of yacc.c */ -#line 531 "grammar.y" - { (yyval.node) = makeBitOperNode((yyvsp[(1) - (3)].node), OpBitXOr, (yyvsp[(3) - (3)].node)); } - break; - - case 186: -/* Line 1787 of yacc.c */ -#line 537 "grammar.y" - { (yyval.node) = makeBitOperNode((yyvsp[(1) - (3)].node), OpBitXOr, (yyvsp[(3) - (3)].node)); } - break; - - case 188: -/* Line 1787 of yacc.c */ -#line 543 "grammar.y" - { (yyval.node) = makeBitOperNode((yyvsp[(1) - (3)].node), OpBitXOr, (yyvsp[(3) - (3)].node)); } - break; - - case 190: -/* Line 1787 of yacc.c */ -#line 548 "grammar.y" - { (yyval.node) = makeBitOperNode((yyvsp[(1) - (3)].node), OpBitOr, (yyvsp[(3) - (3)].node)); } - break; - - case 192: -/* Line 1787 of yacc.c */ -#line 554 "grammar.y" - { (yyval.node) = makeBitOperNode((yyvsp[(1) - (3)].node), OpBitOr, (yyvsp[(3) - (3)].node)); } - break; - - case 194: -/* Line 1787 of yacc.c */ -#line 560 "grammar.y" - { (yyval.node) = makeBitOperNode((yyvsp[(1) - (3)].node), OpBitOr, (yyvsp[(3) - (3)].node)); } - break; - - case 196: -/* Line 1787 of yacc.c */ -#line 565 "grammar.y" - { (yyval.node) = makeBinaryLogicalNode((yyvsp[(1) - (3)].node), OpAnd, (yyvsp[(3) - (3)].node)); } - break; - - case 198: -/* Line 1787 of yacc.c */ -#line 571 "grammar.y" - { (yyval.node) = makeBinaryLogicalNode((yyvsp[(1) - (3)].node), OpAnd, (yyvsp[(3) - (3)].node)); } - break; - - case 200: -/* Line 1787 of yacc.c */ -#line 577 "grammar.y" - { (yyval.node) = makeBinaryLogicalNode((yyvsp[(1) - (3)].node), OpAnd, (yyvsp[(3) - (3)].node)); } - break; - - case 202: -/* Line 1787 of yacc.c */ -#line 582 "grammar.y" - { (yyval.node) = makeBinaryLogicalNode((yyvsp[(1) - (3)].node), OpOr, (yyvsp[(3) - (3)].node)); } - break; - - case 204: -/* Line 1787 of yacc.c */ -#line 588 "grammar.y" - { (yyval.node) = makeBinaryLogicalNode((yyvsp[(1) - (3)].node), OpOr, (yyvsp[(3) - (3)].node)); } - break; - - case 206: -/* Line 1787 of yacc.c */ -#line 593 "grammar.y" - { (yyval.node) = makeBinaryLogicalNode((yyvsp[(1) - (3)].node), OpOr, (yyvsp[(3) - (3)].node)); } - break; - - case 208: -/* Line 1787 of yacc.c */ -#line 599 "grammar.y" - { (yyval.node) = makeConditionalNode((yyvsp[(1) - (5)].node), (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node)); } - break; - - case 210: -/* Line 1787 of yacc.c */ -#line 605 "grammar.y" - { (yyval.node) = makeConditionalNode((yyvsp[(1) - (5)].node), (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node)); } - break; - - case 212: -/* Line 1787 of yacc.c */ -#line 611 "grammar.y" - { (yyval.node) = makeConditionalNode((yyvsp[(1) - (5)].node), (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node)); } - break; - - case 214: -/* Line 1787 of yacc.c */ -#line 617 "grammar.y" - { (yyval.node) = makeAssignNode((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].node)); } - break; - - case 216: -/* Line 1787 of yacc.c */ -#line 623 "grammar.y" - { (yyval.node) = makeAssignNode((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].node)); } - break; - - case 218: -/* Line 1787 of yacc.c */ -#line 629 "grammar.y" - { (yyval.node) = makeAssignNode((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].node)); } - break; - - case 219: -/* Line 1787 of yacc.c */ -#line 633 "grammar.y" - { (yyval.op) = OpEqual; } - break; - - case 220: -/* Line 1787 of yacc.c */ -#line 634 "grammar.y" - { (yyval.op) = OpPlusEq; } - break; - - case 221: -/* Line 1787 of yacc.c */ -#line 635 "grammar.y" - { (yyval.op) = OpMinusEq; } - break; - - case 222: -/* Line 1787 of yacc.c */ -#line 636 "grammar.y" - { (yyval.op) = OpMultEq; } - break; - - case 223: -/* Line 1787 of yacc.c */ -#line 637 "grammar.y" - { (yyval.op) = OpDivEq; } - break; - - case 224: -/* Line 1787 of yacc.c */ -#line 638 "grammar.y" - { (yyval.op) = OpLShift; } - break; - - case 225: -/* Line 1787 of yacc.c */ -#line 639 "grammar.y" - { (yyval.op) = OpRShift; } - break; - - case 226: -/* Line 1787 of yacc.c */ -#line 640 "grammar.y" - { (yyval.op) = OpURShift; } - break; - - case 227: -/* Line 1787 of yacc.c */ -#line 641 "grammar.y" - { (yyval.op) = OpAndEq; } - break; - - case 228: -/* Line 1787 of yacc.c */ -#line 642 "grammar.y" - { (yyval.op) = OpXOrEq; } - break; - - case 229: -/* Line 1787 of yacc.c */ -#line 643 "grammar.y" - { (yyval.op) = OpOrEq; } - break; - - case 230: -/* Line 1787 of yacc.c */ -#line 644 "grammar.y" - { (yyval.op) = OpModEq; } - break; - - case 232: -/* Line 1787 of yacc.c */ -#line 649 "grammar.y" - { (yyval.node) = new CommaNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; - - case 234: -/* Line 1787 of yacc.c */ -#line 654 "grammar.y" - { (yyval.node) = new CommaNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; - - case 236: -/* Line 1787 of yacc.c */ -#line 659 "grammar.y" - { (yyval.node) = new CommaNode((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); } - break; - - case 254: -/* Line 1787 of yacc.c */ -#line 683 "grammar.y" - { (yyval.stat) = new BlockNode(0); DBG((yyval.stat), (yylsp[(2) - (2)]), (yylsp[(2) - (2)])); } - break; - - case 255: -/* Line 1787 of yacc.c */ -#line 684 "grammar.y" - { (yyval.stat) = new BlockNode((yyvsp[(2) - (3)].srcs)); DBG((yyval.stat), (yylsp[(3) - (3)]), (yylsp[(3) - (3)])); } - break; - - case 256: -/* Line 1787 of yacc.c */ -#line 688 "grammar.y" - { (yyval.stat) = new VarStatementNode((yyvsp[(2) - (3)].vlist)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); } - break; - - case 257: -/* Line 1787 of yacc.c */ -#line 689 "grammar.y" - { (yyval.stat) = new VarStatementNode((yyvsp[(2) - (3)].vlist)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; } - break; - - case 258: -/* Line 1787 of yacc.c */ -#line 693 "grammar.y" - { (yyval.vlist) = new VarDeclListNode((yyvsp[(1) - (1)].decl)); } - break; - - case 259: -/* Line 1787 of yacc.c */ -#line 695 "grammar.y" - { (yyval.vlist) = new VarDeclListNode((yyvsp[(1) - (3)].vlist), (yyvsp[(3) - (3)].decl)); } - break; - - case 260: -/* Line 1787 of yacc.c */ -#line 699 "grammar.y" - { (yyval.vlist) = new VarDeclListNode((yyvsp[(1) - (1)].decl)); } - break; - - case 261: -/* Line 1787 of yacc.c */ -#line 701 "grammar.y" - { (yyval.vlist) = new VarDeclListNode((yyvsp[(1) - (3)].vlist), (yyvsp[(3) - (3)].decl)); } - break; - - case 262: -/* Line 1787 of yacc.c */ -#line 705 "grammar.y" - { (yyval.decl) = new VarDeclNode(*(yyvsp[(1) - (1)].ident), 0, VarDeclNode::Variable); } - break; - - case 263: -/* Line 1787 of yacc.c */ -#line 706 "grammar.y" - { (yyval.decl) = new VarDeclNode(*(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].init), VarDeclNode::Variable); } - break; - - case 264: -/* Line 1787 of yacc.c */ -#line 710 "grammar.y" - { (yyval.decl) = new VarDeclNode(*(yyvsp[(1) - (1)].ident), 0, VarDeclNode::Variable); } - break; - - case 265: -/* Line 1787 of yacc.c */ -#line 711 "grammar.y" - { (yyval.decl) = new VarDeclNode(*(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].init), VarDeclNode::Variable); } - break; - - case 266: -/* Line 1787 of yacc.c */ -#line 715 "grammar.y" - { (yyval.stat) = new VarStatementNode((yyvsp[(2) - (3)].vlist)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); } - break; - - case 267: -/* Line 1787 of yacc.c */ -#line 717 "grammar.y" - { (yyval.stat) = new VarStatementNode((yyvsp[(2) - (3)].vlist)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; } - break; - - case 268: -/* Line 1787 of yacc.c */ -#line 721 "grammar.y" - { (yyval.vlist) = new VarDeclListNode((yyvsp[(1) - (1)].decl)); } - break; - - case 269: -/* Line 1787 of yacc.c */ -#line 723 "grammar.y" - { (yyval.vlist) = new VarDeclListNode((yyvsp[(1) - (3)].vlist), (yyvsp[(3) - (3)].decl)); } - break; - - case 270: -/* Line 1787 of yacc.c */ -#line 727 "grammar.y" - { (yyval.decl) = new VarDeclNode(*(yyvsp[(1) - (1)].ident), 0, VarDeclNode::Constant); } - break; - - case 271: -/* Line 1787 of yacc.c */ -#line 728 "grammar.y" - { (yyval.decl) = new VarDeclNode(*(yyvsp[(1) - (2)].ident), (yyvsp[(2) - (2)].init), VarDeclNode::Constant); } - break; - - case 272: -/* Line 1787 of yacc.c */ -#line 732 "grammar.y" - { (yyval.init) = new AssignExprNode((yyvsp[(2) - (2)].node)); } - break; - - case 273: -/* Line 1787 of yacc.c */ -#line 736 "grammar.y" - { (yyval.init) = new AssignExprNode((yyvsp[(2) - (2)].node)); } - break; - - case 274: -/* Line 1787 of yacc.c */ -#line 740 "grammar.y" - { (yyval.stat) = new EmptyStatementNode(); } - break; - - case 275: -/* Line 1787 of yacc.c */ -#line 744 "grammar.y" - { (yyval.stat) = new ExprStatementNode((yyvsp[(1) - (2)].node)); DBG((yyval.stat), (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); } - break; - - case 276: -/* Line 1787 of yacc.c */ -#line 745 "grammar.y" - { (yyval.stat) = new ExprStatementNode((yyvsp[(1) - (2)].node)); DBG((yyval.stat), (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; } - break; - - case 277: -/* Line 1787 of yacc.c */ -#line 750 "grammar.y" - { (yyval.stat) = makeIfNode((yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].stat), 0); DBG((yyval.stat), (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); } - break; - - case 278: -/* Line 1787 of yacc.c */ -#line 752 "grammar.y" - { (yyval.stat) = makeIfNode((yyvsp[(3) - (7)].node), (yyvsp[(5) - (7)].stat), (yyvsp[(7) - (7)].stat)); DBG((yyval.stat), (yylsp[(1) - (7)]), (yylsp[(4) - (7)])); } - break; - - case 279: -/* Line 1787 of yacc.c */ -#line 756 "grammar.y" - { (yyval.stat) = new DoWhileNode((yyvsp[(2) - (7)].stat), (yyvsp[(5) - (7)].node)); DBG((yyval.stat), (yylsp[(1) - (7)]), (yylsp[(3) - (7)]));} - break; - - case 280: -/* Line 1787 of yacc.c */ -#line 757 "grammar.y" - { (yyval.stat) = new DoWhileNode((yyvsp[(2) - (7)].stat), (yyvsp[(5) - (7)].node)); DBG((yyval.stat), (yylsp[(1) - (7)]), (yylsp[(3) - (7)])); AUTO_SEMICOLON; } - break; - - case 281: -/* Line 1787 of yacc.c */ -#line 758 "grammar.y" - { (yyval.stat) = new WhileNode((yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].stat)); DBG((yyval.stat), (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); } - break; - - case 282: -/* Line 1787 of yacc.c */ -#line 760 "grammar.y" - { (yyval.stat) = new ForNode((yyvsp[(3) - (9)].node), (yyvsp[(5) - (9)].node), (yyvsp[(7) - (9)].node), (yyvsp[(9) - (9)].stat)); DBG((yyval.stat), (yylsp[(1) - (9)]), (yylsp[(8) - (9)])); } - break; - - case 283: -/* Line 1787 of yacc.c */ -#line 762 "grammar.y" - { (yyval.stat) = new ForNode((yyvsp[(4) - (10)].vlist), (yyvsp[(6) - (10)].node), (yyvsp[(8) - (10)].node), (yyvsp[(10) - (10)].stat)); DBG((yyval.stat), (yylsp[(1) - (10)]), (yylsp[(9) - (10)])); } - break; - - case 284: -/* Line 1787 of yacc.c */ -#line 764 "grammar.y" - { - Node *n = (yyvsp[(3) - (7)].node)->nodeInsideAllParens(); - if (!n->isLocation()) - YYABORT; - (yyval.stat) = new ForInNode(n, (yyvsp[(5) - (7)].node), (yyvsp[(7) - (7)].stat)); - DBG((yyval.stat), (yylsp[(1) - (7)]), (yylsp[(6) - (7)])); - } - break; - - case 285: -/* Line 1787 of yacc.c */ -#line 772 "grammar.y" - { (yyval.stat) = new ForInNode(*(yyvsp[(4) - (8)].ident), 0, (yyvsp[(6) - (8)].node), (yyvsp[(8) - (8)].stat)); DBG((yyval.stat), (yylsp[(1) - (8)]), (yylsp[(7) - (8)])); } - break; - - case 286: -/* Line 1787 of yacc.c */ -#line 774 "grammar.y" - { (yyval.stat) = new ForInNode(*(yyvsp[(4) - (9)].ident), (yyvsp[(5) - (9)].init), (yyvsp[(7) - (9)].node), (yyvsp[(9) - (9)].stat)); DBG((yyval.stat), (yylsp[(1) - (9)]), (yylsp[(8) - (9)])); } - break; - - case 287: -/* Line 1787 of yacc.c */ -#line 778 "grammar.y" - { (yyval.node) = 0; } - break; - - case 289: -/* Line 1787 of yacc.c */ -#line 783 "grammar.y" - { (yyval.node) = 0; } - break; - - case 291: -/* Line 1787 of yacc.c */ -#line 788 "grammar.y" - { (yyval.stat) = new ContinueNode(); DBG((yyval.stat), (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); } - break; - - case 292: -/* Line 1787 of yacc.c */ -#line 789 "grammar.y" - { (yyval.stat) = new ContinueNode(); DBG((yyval.stat), (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; } - break; - - case 293: -/* Line 1787 of yacc.c */ -#line 790 "grammar.y" - { (yyval.stat) = new ContinueNode(*(yyvsp[(2) - (3)].ident)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); } - break; - - case 294: -/* Line 1787 of yacc.c */ -#line 791 "grammar.y" - { (yyval.stat) = new ContinueNode(*(yyvsp[(2) - (3)].ident)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; } - break; - - case 295: -/* Line 1787 of yacc.c */ -#line 795 "grammar.y" - { (yyval.stat) = new BreakNode(); DBG((yyval.stat), (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); } - break; - - case 296: -/* Line 1787 of yacc.c */ -#line 796 "grammar.y" - { (yyval.stat) = new BreakNode(); DBG((yyval.stat), (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; } - break; - - case 297: -/* Line 1787 of yacc.c */ -#line 797 "grammar.y" - { (yyval.stat) = new BreakNode(*(yyvsp[(2) - (3)].ident)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); } - break; - - case 298: -/* Line 1787 of yacc.c */ -#line 798 "grammar.y" - { (yyval.stat) = new BreakNode(*(yyvsp[(2) - (3)].ident)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; } - break; - - case 299: -/* Line 1787 of yacc.c */ -#line 802 "grammar.y" - { (yyval.stat) = new ReturnNode(0); DBG((yyval.stat), (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); } - break; - - case 300: -/* Line 1787 of yacc.c */ -#line 803 "grammar.y" - { (yyval.stat) = new ReturnNode(0); DBG((yyval.stat), (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; } - break; - - case 301: -/* Line 1787 of yacc.c */ -#line 804 "grammar.y" - { (yyval.stat) = new ReturnNode((yyvsp[(2) - (3)].node)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); } - break; - - case 302: -/* Line 1787 of yacc.c */ -#line 805 "grammar.y" - { (yyval.stat) = new ReturnNode((yyvsp[(2) - (3)].node)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; } - break; - - case 303: -/* Line 1787 of yacc.c */ -#line 809 "grammar.y" - { (yyval.stat) = new WithNode((yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].stat)); DBG((yyval.stat), (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); } - break; - - case 304: -/* Line 1787 of yacc.c */ -#line 813 "grammar.y" - { (yyval.stat) = new SwitchNode((yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].cblk)); DBG((yyval.stat), (yylsp[(1) - (5)]), (yylsp[(4) - (5)])); } - break; - - case 305: -/* Line 1787 of yacc.c */ -#line 817 "grammar.y" - { (yyval.cblk) = new CaseBlockNode((yyvsp[(2) - (3)].clist), 0, 0); } - break; - - case 306: -/* Line 1787 of yacc.c */ -#line 819 "grammar.y" - { (yyval.cblk) = new CaseBlockNode((yyvsp[(2) - (5)].clist), (yyvsp[(3) - (5)].ccl), (yyvsp[(4) - (5)].clist)); } - break; - - case 307: -/* Line 1787 of yacc.c */ -#line 823 "grammar.y" - { (yyval.clist) = 0; } - break; - - case 309: -/* Line 1787 of yacc.c */ -#line 828 "grammar.y" - { (yyval.clist) = new ClauseListNode((yyvsp[(1) - (1)].ccl)); } - break; - - case 310: -/* Line 1787 of yacc.c */ -#line 829 "grammar.y" - { (yyval.clist) = new ClauseListNode((yyvsp[(1) - (2)].clist), (yyvsp[(2) - (2)].ccl)); } - break; - - case 311: -/* Line 1787 of yacc.c */ -#line 833 "grammar.y" - { (yyval.ccl) = new CaseClauseNode((yyvsp[(2) - (3)].node)); } - break; - - case 312: -/* Line 1787 of yacc.c */ -#line 834 "grammar.y" - { (yyval.ccl) = new CaseClauseNode((yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].srcs)); } - break; - - case 313: -/* Line 1787 of yacc.c */ -#line 838 "grammar.y" - { (yyval.ccl) = new CaseClauseNode(0); } - break; - - case 314: -/* Line 1787 of yacc.c */ -#line 839 "grammar.y" - { (yyval.ccl) = new CaseClauseNode(0, (yyvsp[(3) - (3)].srcs)); } - break; - - case 315: -/* Line 1787 of yacc.c */ -#line 843 "grammar.y" - { (yyval.stat) = makeLabelNode(*(yyvsp[(1) - (3)].ident), (yyvsp[(3) - (3)].stat)); } - break; - - case 316: -/* Line 1787 of yacc.c */ -#line 847 "grammar.y" - { (yyval.stat) = new ThrowNode((yyvsp[(2) - (3)].node)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); } - break; - - case 317: -/* Line 1787 of yacc.c */ -#line 848 "grammar.y" - { (yyval.stat) = new ThrowNode((yyvsp[(2) - (3)].node)); DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(2) - (3)])); AUTO_SEMICOLON; } - break; - - case 318: -/* Line 1787 of yacc.c */ -#line 852 "grammar.y" - { (yyval.stat) = new TryNode((yyvsp[(2) - (4)].stat), CommonIdentifiers::shared()->nullIdentifier, 0, (yyvsp[(4) - (4)].stat)); DBG((yyval.stat), (yylsp[(1) - (4)]), (yylsp[(2) - (4)])); } - break; - - case 319: -/* Line 1787 of yacc.c */ -#line 853 "grammar.y" - { (yyval.stat) = new TryNode((yyvsp[(2) - (7)].stat), *(yyvsp[(5) - (7)].ident), (yyvsp[(7) - (7)].stat), 0); DBG((yyval.stat), (yylsp[(1) - (7)]), (yylsp[(2) - (7)])); } - break; - - case 320: -/* Line 1787 of yacc.c */ -#line 855 "grammar.y" - { (yyval.stat) = new TryNode((yyvsp[(2) - (9)].stat), *(yyvsp[(5) - (9)].ident), (yyvsp[(7) - (9)].stat), (yyvsp[(9) - (9)].stat)); DBG((yyval.stat), (yylsp[(1) - (9)]), (yylsp[(2) - (9)])); } - break; - - case 321: -/* Line 1787 of yacc.c */ -#line 859 "grammar.y" - { (yyval.stat) = new EmptyStatementNode(); DBG((yyval.stat), (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); } - break; - - case 322: -/* Line 1787 of yacc.c */ -#line 860 "grammar.y" - { (yyval.stat) = new EmptyStatementNode(); DBG((yyval.stat), (yylsp[(1) - (2)]), (yylsp[(1) - (2)])); AUTO_SEMICOLON; } - break; - - case 323: -/* Line 1787 of yacc.c */ -#line 864 "grammar.y" - { (yyval.pkgn) = new PackageNameNode(*(yyvsp[(1) - (1)].ident)); } - break; - - case 324: -/* Line 1787 of yacc.c */ -#line 865 "grammar.y" - { (yyval.pkgn) = new PackageNameNode((yyvsp[(1) - (3)].pkgn), *(yyvsp[(3) - (3)].ident)); } - break; - - case 325: -/* Line 1787 of yacc.c */ -#line 869 "grammar.y" - { (yyval.stat) = makeImportNode((yyvsp[(2) - (5)].pkgn), true, 0); - DBG((yyval.stat), (yylsp[(1) - (5)]), (yylsp[(5) - (5)])); } - break; - - case 326: -/* Line 1787 of yacc.c */ -#line 871 "grammar.y" - { (yyval.stat) = makeImportNode((yyvsp[(2) - (5)].pkgn), true, 0); - DBG((yyval.stat), (yylsp[(1) - (5)]), (yylsp[(5) - (5)])); AUTO_SEMICOLON; } - break; - - case 327: -/* Line 1787 of yacc.c */ -#line 873 "grammar.y" - { (yyval.stat) = makeImportNode((yyvsp[(2) - (3)].pkgn), false, 0); - DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); } - break; - - case 328: -/* Line 1787 of yacc.c */ -#line 875 "grammar.y" - { (yyval.stat) = makeImportNode((yyvsp[(2) - (3)].pkgn), false, 0); - DBG((yyval.stat), (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); AUTO_SEMICOLON; } - break; - - case 329: -/* Line 1787 of yacc.c */ -#line 877 "grammar.y" - { (yyval.stat) = makeImportNode((yyvsp[(4) - (5)].pkgn), false, *(yyvsp[(2) - (5)].ident)); - DBG((yyval.stat), (yylsp[(1) - (5)]), (yylsp[(5) - (5)])); } - break; - - case 330: -/* Line 1787 of yacc.c */ -#line 879 "grammar.y" - { (yyval.stat) = makeImportNode((yyvsp[(4) - (5)].pkgn), false, *(yyvsp[(2) - (5)].ident)); - DBG((yyval.stat), (yylsp[(1) - (5)]), (yylsp[(5) - (5)])); AUTO_SEMICOLON; } - break; - - case 331: -/* Line 1787 of yacc.c */ -#line 884 "grammar.y" - {inFuncDecl();} - break; - - case 332: -/* Line 1787 of yacc.c */ -#line 884 "grammar.y" - { (yyval.func) = new FuncDeclNode(*(yyvsp[(2) - (6)].ident), (yyvsp[(6) - (6)].body)); } - break; - - case 333: -/* Line 1787 of yacc.c */ -#line 885 "grammar.y" - {inFuncDecl();} - break; - - case 334: -/* Line 1787 of yacc.c */ -#line 886 "grammar.y" - { (yyval.func) = new FuncDeclNode(*(yyvsp[(2) - (7)].ident), (yyvsp[(4) - (7)].param), (yyvsp[(7) - (7)].body)); } - break; - - case 335: -/* Line 1787 of yacc.c */ -#line 890 "grammar.y" - {inFuncExpr();} - break; - - case 336: -/* Line 1787 of yacc.c */ -#line 890 "grammar.y" - { - (yyval.funcExpr) = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, (yyvsp[(5) - (5)].body)); - } - break; - - case 337: -/* Line 1787 of yacc.c */ -#line 893 "grammar.y" - {inFuncExpr();} - break; - - case 338: -/* Line 1787 of yacc.c */ -#line 893 "grammar.y" - { - (yyval.funcExpr) = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, (yyvsp[(6) - (6)].body), (yyvsp[(3) - (6)].param)); - } - break; - - case 339: -/* Line 1787 of yacc.c */ -#line 896 "grammar.y" - {inFuncExpr();} - break; - - case 340: -/* Line 1787 of yacc.c */ -#line 896 "grammar.y" - { (yyval.funcExpr) = new FuncExprNode(*(yyvsp[(2) - (6)].ident), (yyvsp[(6) - (6)].body)); } - break; - - case 341: -/* Line 1787 of yacc.c */ -#line 897 "grammar.y" - {inFuncExpr();} - break; - - case 342: -/* Line 1787 of yacc.c */ -#line 897 "grammar.y" - { - (yyval.funcExpr) = new FuncExprNode(*(yyvsp[(2) - (7)].ident), (yyvsp[(7) - (7)].body), (yyvsp[(4) - (7)].param)); - } - break; - - case 343: -/* Line 1787 of yacc.c */ -#line 903 "grammar.y" - { (yyval.param) = new ParameterNode(*(yyvsp[(1) - (1)].ident)); } - break; - - case 344: -/* Line 1787 of yacc.c */ -#line 904 "grammar.y" - { (yyval.param) = new ParameterNode((yyvsp[(1) - (3)].param), *(yyvsp[(3) - (3)].ident)); } - break; - - case 345: -/* Line 1787 of yacc.c */ -#line 908 "grammar.y" - { (yyval.body) = new FunctionBodyNode(0); DBG((yyval.body), (yylsp[(1) - (2)]), (yylsp[(2) - (2)])); } - break; - - case 346: -/* Line 1787 of yacc.c */ -#line 909 "grammar.y" - { (yyval.body) = new FunctionBodyNode((yyvsp[(2) - (3)].srcs)); DBG((yyval.body), (yylsp[(1) - (3)]), (yylsp[(3) - (3)])); } - break; - - case 347: -/* Line 1787 of yacc.c */ -#line 913 "grammar.y" - { parser().didFinishParsing(new ProgramNode(0)); } - break; - - case 348: -/* Line 1787 of yacc.c */ -#line 914 "grammar.y" - { parser().didFinishParsing(new ProgramNode((yyvsp[(1) - (1)].srcs))); } - break; - - case 349: -/* Line 1787 of yacc.c */ -#line 918 "grammar.y" - { (yyval.srcs) = new SourceElementsNode((yyvsp[(1) - (1)].stat)); } - break; - - case 350: -/* Line 1787 of yacc.c */ -#line 919 "grammar.y" - { (yyval.srcs) = new SourceElementsNode((yyvsp[(1) - (2)].srcs), (yyvsp[(2) - (2)].stat)); } - break; - - case 351: -/* Line 1787 of yacc.c */ -#line 923 "grammar.y" - { (yyval.stat) = (yyvsp[(1) - (1)].func); } - break; - - case 352: -/* Line 1787 of yacc.c */ -#line 924 "grammar.y" - { (yyval.stat) = (yyvsp[(1) - (1)].stat); } - break; - - -/* Line 1787 of yacc.c */ -#line 4143 "grammar.tab.c" - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - yyerror_range[1] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[1] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, yyerror_range, 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc); - } - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - -/* Line 2050 of yacc.c */ -#line 927 "grammar.y" - - -/* called by yyparse on error */ -int yyerror(const char *) -{ -// fprintf(stderr, "ERROR: %s at line %d\n", s, KJS::Lexer::curr()->lineNo()); - return 1; -} - -/* may we automatically insert a semicolon ? */ -static bool allowAutomaticSemicolon() -{ - return yychar == '}' || yychar == 0 || lexer().prevTerminator(); -} - -// kate: indent-width 2; replace-tabs on; tab-width 4; space-indent on; - diff --git a/kjs/grammar.h b/kjs/grammar.h deleted file mode 100644 index 7ca868d4..00000000 --- a/kjs/grammar.h +++ /dev/null @@ -1,186 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.7.12-4996. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -#ifndef YY_KJSYY_GRAMMAR_TAB_H_INCLUDED -# define YY_KJSYY_GRAMMAR_TAB_H_INCLUDED -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int kjsyydebug; -#endif - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - NULLTOKEN = 258, - TRUETOKEN = 259, - FALSETOKEN = 260, - BREAK = 261, - CASE = 262, - DEFAULT = 263, - FOR = 264, - NEW = 265, - VAR = 266, - CONSTTOKEN = 267, - CONTINUE = 268, - FUNCTION = 269, - RETURN = 270, - VOIDTOKEN = 271, - DELETETOKEN = 272, - IF = 273, - THISTOKEN = 274, - DO = 275, - WHILE = 276, - INTOKEN = 277, - INSTANCEOF = 278, - TYPEOF = 279, - SWITCH = 280, - WITH = 281, - RESERVED = 282, - THROW = 283, - TRY = 284, - CATCH = 285, - FINALLY = 286, - DEBUGGER = 287, - IMPORT = 288, - IF_WITHOUT_ELSE = 289, - ELSE = 290, - EQEQ = 291, - NE = 292, - STREQ = 293, - STRNEQ = 294, - LE = 295, - GE = 296, - OR = 297, - AND = 298, - PLUSPLUS = 299, - MINUSMINUS = 300, - LSHIFT = 301, - RSHIFT = 302, - URSHIFT = 303, - PLUSEQUAL = 304, - MINUSEQUAL = 305, - MULTEQUAL = 306, - DIVEQUAL = 307, - LSHIFTEQUAL = 308, - RSHIFTEQUAL = 309, - URSHIFTEQUAL = 310, - ANDEQUAL = 311, - MODEQUAL = 312, - XOREQUAL = 313, - OREQUAL = 314, - NUMBER = 315, - STRING = 316, - IDENT = 317, - AUTOPLUSPLUS = 318, - AUTOMINUSMINUS = 319 - }; -#endif - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ -/* Line 2053 of yacc.c */ -#line 64 "grammar.y" - - int ival; - double dval; - UString *ustr; - Identifier *ident; - Node *node; - StatementNode *stat; - ParameterNode *param; - FunctionBodyNode *body; - FuncDeclNode *func; - FuncExprNode *funcExpr; - ProgramNode *prog; - AssignExprNode *init; - SourceElementsNode *srcs; - ArgumentsNode *args; - ArgumentListNode *alist; - VarDeclNode *decl; - VarDeclListNode *vlist; - CaseBlockNode *cblk; - ClauseListNode *clist; - CaseClauseNode *ccl; - ElementNode *elm; - Operator op; - PropertyListNode *plist; - PropertyNode *pnode; - PropertyNameNode *pname; - PackageNameNode *pkgn; - - -/* Line 2053 of yacc.c */ -#line 151 "grammar.tab.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE kjsyylval; -extern YYLTYPE kjsyylloc; -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int kjsyyparse (void *YYPARSE_PARAM); -#else -int kjsyyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int kjsyyparse (void); -#else -int kjsyyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - -#endif /* !YY_KJSYY_GRAMMAR_TAB_H_INCLUDED */ diff --git a/kjs/grammar.y b/kjs/grammar.y deleted file mode 100644 index e21bcf16..00000000 --- a/kjs/grammar.y +++ /dev/null @@ -1,942 +0,0 @@ -%{ - -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include - -#include -#include -#include -#include "value.h" -#include "object.h" -#include "types.h" -#include "interpreter.h" -#include "nodes.h" -#include "makenodes.h" -#include "lexer.h" -#include "internal.h" - -// Not sure why, but yacc doesn't add this define along with the others. -#define yylloc kjsyylloc - -/* default values for bison */ -#define YYDEBUG 0 // Set to 1 to debug a parse error. -#define kjsyydebug 0 // Set to 1 to debug a parse error. -#if !PLATFORM(DARWIN) - // avoid triggering warnings in older bison -#define YYERROR_VERBOSE -#endif - -extern int kjsyylex(); -int kjsyyerror(const char *); -static bool allowAutomaticSemicolon(); - -#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon()) YYABORT; } while (0) -#define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line) - -#ifndef __GNUC__ -# define __attribute__(x) -#endif - -using namespace KJS; - -%} - -%union { - int ival; - double dval; - UString *ustr; - Identifier *ident; - Node *node; - StatementNode *stat; - ParameterNode *param; - FunctionBodyNode *body; - FuncDeclNode *func; - FuncExprNode *funcExpr; - ProgramNode *prog; - AssignExprNode *init; - SourceElementsNode *srcs; - ArgumentsNode *args; - ArgumentListNode *alist; - VarDeclNode *decl; - VarDeclListNode *vlist; - CaseBlockNode *cblk; - ClauseListNode *clist; - CaseClauseNode *ccl; - ElementNode *elm; - Operator op; - PropertyListNode *plist; - PropertyNode *pnode; - PropertyNameNode *pname; - PackageNameNode *pkgn; -} - -%start Program - -/* literals */ -%token NULLTOKEN TRUETOKEN FALSETOKEN - -/* keywords */ -%token BREAK CASE DEFAULT FOR NEW VAR CONSTTOKEN CONTINUE -%token FUNCTION RETURN VOIDTOKEN DELETETOKEN -%token IF THISTOKEN DO WHILE INTOKEN INSTANCEOF TYPEOF -%token SWITCH WITH RESERVED -%token THROW TRY CATCH FINALLY -%token DEBUGGER IMPORT - -/* give an if without an else higher precedence than an else to resolve the ambiguity */ -%nonassoc IF_WITHOUT_ELSE -%nonassoc ELSE - -/* punctuators */ -%token EQEQ NE /* == and != */ -%token STREQ STRNEQ /* === and !== */ -%token LE GE /* < and > */ -%token OR AND /* || and && */ -%token PLUSPLUS MINUSMINUS /* ++ and -- */ -%token LSHIFT /* << */ -%token RSHIFT URSHIFT /* >> and >>> */ -%token PLUSEQUAL MINUSEQUAL /* += and -= */ -%token MULTEQUAL DIVEQUAL /* *= and /= */ -%token LSHIFTEQUAL /* <<= */ -%token RSHIFTEQUAL URSHIFTEQUAL /* >>= and >>>= */ -%token ANDEQUAL MODEQUAL /* &= and %= */ -%token XOREQUAL OREQUAL /* ^= and |= */ - -/* terminal types */ -%token NUMBER -%token STRING -%token IDENT - -/* automatically inserted semicolon */ -%token AUTOPLUSPLUS AUTOMINUSMINUS - -/* non-terminal types */ -%type Literal ArrayLiteral - -%type PrimaryExpr PrimaryExprNoBrace -%type MemberExpr MemberExprNoBF /* BF => brace or function */ -%type NewExpr NewExprNoBF -%type CallExpr CallExprNoBF -%type LeftHandSideExpr LeftHandSideExprNoBF -%type PostfixExpr PostfixExprNoBF -%type UnaryExpr UnaryExprNoBF UnaryExprCommon -%type MultiplicativeExpr MultiplicativeExprNoBF -%type AdditiveExpr AdditiveExprNoBF -%type ShiftExpr ShiftExprNoBF -%type RelationalExpr RelationalExprNoIn RelationalExprNoBF -%type EqualityExpr EqualityExprNoIn EqualityExprNoBF -%type BitwiseANDExpr BitwiseANDExprNoIn BitwiseANDExprNoBF -%type BitwiseXORExpr BitwiseXORExprNoIn BitwiseXORExprNoBF -%type BitwiseORExpr BitwiseORExprNoIn BitwiseORExprNoBF -%type LogicalANDExpr LogicalANDExprNoIn LogicalANDExprNoBF -%type LogicalORExpr LogicalORExprNoIn LogicalORExprNoBF -%type ConditionalExpr ConditionalExprNoIn ConditionalExprNoBF -%type AssignmentExpr AssignmentExprNoIn AssignmentExprNoBF -%type Expr ExprNoIn ExprNoBF -%type ExprOpt ExprNoInOpt - -%type Statement Block -%type VariableStatement ConstStatement EmptyStatement ExprStatement -%type IfStatement IterationStatement ContinueStatement -%type BreakStatement ReturnStatement WithStatement -%type SwitchStatement LabelledStatement -%type ThrowStatement TryStatement -%type DebuggerStatement ImportStatement -%type SourceElement - -%type Initializer InitializerNoIn -%type FunctionDeclaration -%type FunctionExpr -%type FunctionBody -%type SourceElements -%type FormalParameterList -%type AssignmentOperator -%type Arguments -%type ArgumentList -%type VariableDeclarationList VariableDeclarationListNoIn ConstDeclarationList -%type VariableDeclaration VariableDeclarationNoIn ConstDeclaration -%type CaseBlock -%type CaseClause DefaultClause -%type CaseClauses CaseClausesOpt -%type Elision ElisionOpt -%type ElementList -%type PropertyName -%type Property -%type PropertyList -%type PackageName -%type Keywords -%type IdentifierName -%% - -Keywords: - BREAK { $$ = new Identifier("break"); } - | CASE { $$ = new Identifier("case"); } - | DEFAULT { $$ = new Identifier("default"); } - | FOR { $$ = new Identifier("for"); } - | NEW { $$ = new Identifier("new"); } - | VAR { $$ = new Identifier("var"); } - | CONSTTOKEN { $$ = new Identifier("const"); } - | CONTINUE { $$ = new Identifier("continue"); } - | FUNCTION { $$ = new Identifier("function"); } - | RETURN { $$ = new Identifier("return"); } - | VOIDTOKEN { $$ = new Identifier("void"); } - | DELETETOKEN { $$ = new Identifier("delete"); } - | IF { $$ = new Identifier("if"); } - | THISTOKEN { $$ = new Identifier("this"); } - | DO { $$ = new Identifier("do"); } - | WHILE { $$ = new Identifier("while"); } - | INTOKEN { $$ = new Identifier("in"); } - | INSTANCEOF { $$ = new Identifier("instanceof"); } - | TYPEOF { $$ = new Identifier("typeof"); } - | SWITCH { $$ = new Identifier("switch"); } - | WITH { $$ = new Identifier("with"); } - | THROW { $$ = new Identifier("throw"); } - | TRY { $$ = new Identifier("try"); } - | CATCH { $$ = new Identifier("catch"); } - | FINALLY { $$ = new Identifier("finally"); } - | DEBUGGER { $$ = new Identifier("debugger"); } - | IMPORT { $$ = new Identifier("import"); } - | NULLTOKEN { $$ = new Identifier("null"); } - | TRUETOKEN { $$ = new Identifier("true"); } - | FALSETOKEN { $$ = new Identifier("false"); } - | ELSE { $$ = new Identifier("else"); } -; - -IdentifierName: - IDENT { $$ = $1; } - | Keywords { $$ = $1; } -; - -Literal: - NULLTOKEN { $$ = new NullNode(); } - | TRUETOKEN { $$ = new BooleanNode(true); } - | FALSETOKEN { $$ = new BooleanNode(false); } - | NUMBER { $$ = new NumberNode($1); } - | STRING { $$ = new StringNode($1); } - | '/' /* regexp */ { - Lexer& l = lexer(); - if (!l.scanRegExp()) - YYABORT; - $$ = new RegExpNode(l.pattern(), l.flags()); - } - | DIVEQUAL /* regexp with /= */ { - Lexer& l = lexer(); - if (!l.scanRegExp()) - YYABORT; - $$ = new RegExpNode("=" + l.pattern(), l.flags()); - } -; - -PropertyName: - IdentifierName { $$ = new PropertyNameNode(*$1); } - | STRING { $$ = new PropertyNameNode(Identifier(*$1)); } - | NUMBER { $$ = new PropertyNameNode(Identifier(UString::from($1))); } -; - -Property: - PropertyName ':' AssignmentExpr { $$ = new PropertyNode($1, $3, PropertyNode::Constant); } - | IDENT IdentifierName '(' ')' {inFuncExpr();} FunctionBody { - if (!makeGetterOrSetterPropertyNode($$, *$1, *$2, 0, $6)) - YYABORT; - } - | IDENT IdentifierName '(' FormalParameterList ')' {inFuncExpr();} FunctionBody { - if (!makeGetterOrSetterPropertyNode($$, *$1, *$2, $4, $7)) - YYABORT; - } -; - -PropertyList: - Property { $$ = new PropertyListNode($1); } - | PropertyList ',' Property { $$ = new PropertyListNode($3, $1); } -; - -PrimaryExpr: - PrimaryExprNoBrace - | '{' '}' { $$ = new ObjectLiteralNode(); } - | '{' PropertyList '}' { $$ = new ObjectLiteralNode($2); } - /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */ - | '{' PropertyList ',' '}' { $$ = new ObjectLiteralNode($2); } -; - -PrimaryExprNoBrace: - THISTOKEN { $$ = new ThisNode(); } - | Literal - | ArrayLiteral - | IDENT { $$ = new VarAccessNode(*$1); } - | '(' Expr ')' { $$ = makeGroupNode($2); } - -; - -ArrayLiteral: - '[' ElisionOpt ']' { $$ = new ArrayNode($2); } - | '[' ElementList ']' { $$ = new ArrayNode($2); } - | '[' ElementList ',' ElisionOpt ']' { $$ = new ArrayNode($4, $2); } -; - -ElementList: - ElisionOpt AssignmentExpr { $$ = new ElementNode($1, $2); } - | ElementList ',' ElisionOpt AssignmentExpr - { $$ = new ElementNode($1, $3, $4); } -; - -ElisionOpt: - /* nothing */ { $$ = 0; } - | Elision -; - -Elision: - ',' { $$ = 1; } - | Elision ',' { $$ = $1 + 1; } -; - -MemberExpr: - PrimaryExpr - | FunctionExpr { $$ = $1; } - | MemberExpr '[' Expr ']' { $$ = new BracketAccessorNode($1, $3); } - | MemberExpr '.' IdentifierName { $$ = new DotAccessorNode($1, *$3); } - | NEW MemberExpr Arguments { $$ = new NewExprNode($2, $3); } -; - -MemberExprNoBF: - PrimaryExprNoBrace - | MemberExprNoBF '[' Expr ']' { $$ = new BracketAccessorNode($1, $3); } - | MemberExprNoBF '.' IdentifierName { $$ = new DotAccessorNode($1, *$3); } - | NEW MemberExpr Arguments { $$ = new NewExprNode($2, $3); } -; - -NewExpr: - MemberExpr - | NEW NewExpr { $$ = new NewExprNode($2); } -; - -NewExprNoBF: - MemberExprNoBF - | NEW NewExpr { $$ = new NewExprNode($2); } -; - -CallExpr: - MemberExpr Arguments { $$ = makeFunctionCallNode($1, $2); } - | CallExpr Arguments { $$ = makeFunctionCallNode($1, $2); } - | CallExpr '[' Expr ']' { $$ = new BracketAccessorNode($1, $3); } - | CallExpr '.' IdentifierName { $$ = new DotAccessorNode($1, *$3); } -; - -CallExprNoBF: - MemberExprNoBF Arguments { $$ = makeFunctionCallNode($1, $2); } - | CallExprNoBF Arguments { $$ = makeFunctionCallNode($1, $2); } - | CallExprNoBF '[' Expr ']' { $$ = new BracketAccessorNode($1, $3); } - | CallExprNoBF '.' IdentifierName { $$ = new DotAccessorNode($1, *$3); } -; - -Arguments: - '(' ')' { $$ = new ArgumentsNode(); } - | '(' ArgumentList ')' { $$ = new ArgumentsNode($2); } -; - -ArgumentList: - AssignmentExpr { $$ = new ArgumentListNode($1); } - | ArgumentList ',' AssignmentExpr { $$ = new ArgumentListNode($1, $3); } -; - -LeftHandSideExpr: - NewExpr - | CallExpr -; - -LeftHandSideExprNoBF: - NewExprNoBF - | CallExprNoBF -; - -PostfixExpr: - LeftHandSideExpr - | LeftHandSideExpr PLUSPLUS { $$ = makePostfixNode($1, OpPlusPlus); } - | LeftHandSideExpr MINUSMINUS { $$ = makePostfixNode($1, OpMinusMinus); } -; - -PostfixExprNoBF: - LeftHandSideExprNoBF - | LeftHandSideExprNoBF PLUSPLUS { $$ = makePostfixNode($1, OpPlusPlus); } - | LeftHandSideExprNoBF MINUSMINUS { $$ = makePostfixNode($1, OpMinusMinus); } -; - -UnaryExprCommon: - DELETETOKEN UnaryExpr { $$ = makeDeleteNode($2); } - | VOIDTOKEN UnaryExpr { $$ = new VoidNode($2); } - | TYPEOF UnaryExpr { $$ = makeTypeOfNode($2); } - | PLUSPLUS UnaryExpr { $$ = makePrefixNode($2, OpPlusPlus); } - | AUTOPLUSPLUS UnaryExpr { $$ = makePrefixNode($2, OpPlusPlus); } - | MINUSMINUS UnaryExpr { $$ = makePrefixNode($2, OpMinusMinus); } - | AUTOMINUSMINUS UnaryExpr { $$ = makePrefixNode($2, OpMinusMinus); } - | '+' UnaryExpr { $$ = makeUnaryPlusNode($2); } - | '-' UnaryExpr { $$ = makeNegateNode($2); } - | '~' UnaryExpr { $$ = makeBitwiseNotNode($2); } - | '!' UnaryExpr { $$ = makeLogicalNotNode($2); } - -UnaryExpr: - PostfixExpr - | UnaryExprCommon -; - -UnaryExprNoBF: - PostfixExprNoBF - | UnaryExprCommon -; - -MultiplicativeExpr: - UnaryExpr - | MultiplicativeExpr '*' UnaryExpr { $$ = makeMultNode($1, $3, OpMult); } - | MultiplicativeExpr '/' UnaryExpr { $$ = makeMultNode($1, $3, OpDiv); } - | MultiplicativeExpr '%' UnaryExpr { $$ = makeMultNode($1, $3, OpMod); } -; - -MultiplicativeExprNoBF: - UnaryExprNoBF - | MultiplicativeExprNoBF '*' UnaryExpr - { $$ = makeMultNode($1, $3, OpMult); } - | MultiplicativeExprNoBF '/' UnaryExpr - { $$ = makeMultNode($1, $3, OpDiv); } - | MultiplicativeExprNoBF '%' UnaryExpr - { $$ = makeMultNode($1, $3, OpMod); } -; - -AdditiveExpr: - MultiplicativeExpr - | AdditiveExpr '+' MultiplicativeExpr { $$ = makeAddNode($1, $3, OpPlus); } - | AdditiveExpr '-' MultiplicativeExpr { $$ = makeAddNode($1, $3, OpMinus); } -; - -AdditiveExprNoBF: - MultiplicativeExprNoBF - | AdditiveExprNoBF '+' MultiplicativeExpr - { $$ = makeAddNode($1, $3, OpPlus); } - | AdditiveExprNoBF '-' MultiplicativeExpr - { $$ = makeAddNode($1, $3, OpMinus); } -; - -ShiftExpr: - AdditiveExpr - | ShiftExpr LSHIFT AdditiveExpr { $$ = makeShiftNode($1, $3, OpLShift); } - | ShiftExpr RSHIFT AdditiveExpr { $$ = makeShiftNode($1, $3, OpRShift); } - | ShiftExpr URSHIFT AdditiveExpr { $$ = makeShiftNode($1, $3, OpURShift); } -; - -ShiftExprNoBF: - AdditiveExprNoBF - | ShiftExprNoBF LSHIFT AdditiveExpr { $$ = makeShiftNode($1, $3, OpLShift); } - | ShiftExprNoBF RSHIFT AdditiveExpr { $$ = makeShiftNode($1, $3, OpRShift); } - | ShiftExprNoBF URSHIFT AdditiveExpr { $$ = makeShiftNode($1, $3, OpURShift); } -; - -RelationalExpr: - ShiftExpr - | RelationalExpr '<' ShiftExpr { $$ = makeRelationalNode($1, OpLess, $3); } - | RelationalExpr '>' ShiftExpr { $$ = makeRelationalNode($1, OpGreater, $3); } - | RelationalExpr LE ShiftExpr { $$ = makeRelationalNode($1, OpLessEq, $3); } - | RelationalExpr GE ShiftExpr { $$ = makeRelationalNode($1, OpGreaterEq, $3); } - | RelationalExpr INSTANCEOF ShiftExpr { $$ = makeRelationalNode($1, OpInstanceOf, $3); } - | RelationalExpr INTOKEN ShiftExpr { $$ = makeRelationalNode($1, OpIn, $3); } -; - -RelationalExprNoIn: - ShiftExpr - | RelationalExprNoIn '<' ShiftExpr { $$ = makeRelationalNode($1, OpLess, $3); } - | RelationalExprNoIn '>' ShiftExpr { $$ = makeRelationalNode($1, OpGreater, $3); } - | RelationalExprNoIn LE ShiftExpr { $$ = makeRelationalNode($1, OpLessEq, $3); } - | RelationalExprNoIn GE ShiftExpr { $$ = makeRelationalNode($1, OpGreaterEq, $3); } - | RelationalExprNoIn INSTANCEOF ShiftExpr - { $$ = makeRelationalNode($1, OpInstanceOf, $3); } -; - -RelationalExprNoBF: - ShiftExprNoBF - | RelationalExprNoBF '<' ShiftExpr { $$ = makeRelationalNode($1, OpLess, $3); } - | RelationalExprNoBF '>' ShiftExpr { $$ = makeRelationalNode($1, OpGreater, $3); } - | RelationalExprNoBF LE ShiftExpr { $$ = makeRelationalNode($1, OpLessEq, $3); } - | RelationalExprNoBF GE ShiftExpr { $$ = makeRelationalNode($1, OpGreaterEq, $3); } - | RelationalExprNoBF INSTANCEOF ShiftExpr - { $$ = makeRelationalNode($1, OpInstanceOf, $3); } - | RelationalExprNoBF INTOKEN ShiftExpr { $$ = makeRelationalNode($1, OpIn, $3); } -; - -EqualityExpr: - RelationalExpr - | EqualityExpr EQEQ RelationalExpr { $$ = makeEqualNode($1, OpEqEq, $3); } - | EqualityExpr NE RelationalExpr { $$ = makeEqualNode($1, OpNotEq, $3); } - | EqualityExpr STREQ RelationalExpr { $$ = makeEqualNode($1, OpStrEq, $3); } - | EqualityExpr STRNEQ RelationalExpr { $$ = makeEqualNode($1, OpStrNEq, $3);} -; - -EqualityExprNoIn: - RelationalExprNoIn - | EqualityExprNoIn EQEQ RelationalExprNoIn - { $$ = makeEqualNode($1, OpEqEq, $3); } - | EqualityExprNoIn NE RelationalExprNoIn - { $$ = makeEqualNode($1, OpNotEq, $3); } - | EqualityExprNoIn STREQ RelationalExprNoIn - { $$ = makeEqualNode($1, OpStrEq, $3); } - | EqualityExprNoIn STRNEQ RelationalExprNoIn - { $$ = makeEqualNode($1, OpStrNEq, $3);} -; - -EqualityExprNoBF: - RelationalExprNoBF - | EqualityExprNoBF EQEQ RelationalExpr - { $$ = makeEqualNode($1, OpEqEq, $3); } - | EqualityExprNoBF NE RelationalExpr { $$ = makeEqualNode($1, OpNotEq, $3); } - | EqualityExprNoBF STREQ RelationalExpr - { $$ = makeEqualNode($1, OpStrEq, $3); } - | EqualityExprNoBF STRNEQ RelationalExpr - { $$ = makeEqualNode($1, OpStrNEq, $3);} -; - -BitwiseANDExpr: - EqualityExpr - | BitwiseANDExpr '&' EqualityExpr { $$ = makeBitOperNode($1, OpBitAnd, $3); } -; - -BitwiseANDExprNoIn: - EqualityExprNoIn - | BitwiseANDExprNoIn '&' EqualityExprNoIn - { $$ = makeBitOperNode($1, OpBitAnd, $3); } -; - -BitwiseANDExprNoBF: - EqualityExprNoBF - | BitwiseANDExprNoBF '&' EqualityExpr { $$ = makeBitOperNode($1, OpBitAnd, $3); } -; - -BitwiseXORExpr: - BitwiseANDExpr - | BitwiseXORExpr '^' BitwiseANDExpr { $$ = makeBitOperNode($1, OpBitXOr, $3); } -; - -BitwiseXORExprNoIn: - BitwiseANDExprNoIn - | BitwiseXORExprNoIn '^' BitwiseANDExprNoIn - { $$ = makeBitOperNode($1, OpBitXOr, $3); } -; - -BitwiseXORExprNoBF: - BitwiseANDExprNoBF - | BitwiseXORExprNoBF '^' BitwiseANDExpr - { $$ = makeBitOperNode($1, OpBitXOr, $3); } -; - -BitwiseORExpr: - BitwiseXORExpr - | BitwiseORExpr '|' BitwiseXORExpr { $$ = makeBitOperNode($1, OpBitOr, $3); } -; - -BitwiseORExprNoIn: - BitwiseXORExprNoIn - | BitwiseORExprNoIn '|' BitwiseXORExprNoIn - { $$ = makeBitOperNode($1, OpBitOr, $3); } -; - -BitwiseORExprNoBF: - BitwiseXORExprNoBF - | BitwiseORExprNoBF '|' BitwiseXORExpr - { $$ = makeBitOperNode($1, OpBitOr, $3); } -; - -LogicalANDExpr: - BitwiseORExpr - | LogicalANDExpr AND BitwiseORExpr { $$ = makeBinaryLogicalNode($1, OpAnd, $3); } -; - -LogicalANDExprNoIn: - BitwiseORExprNoIn - | LogicalANDExprNoIn AND BitwiseORExprNoIn - { $$ = makeBinaryLogicalNode($1, OpAnd, $3); } -; - -LogicalANDExprNoBF: - BitwiseORExprNoBF - | LogicalANDExprNoBF AND BitwiseORExpr - { $$ = makeBinaryLogicalNode($1, OpAnd, $3); } -; - -LogicalORExpr: - LogicalANDExpr - | LogicalORExpr OR LogicalANDExpr { $$ = makeBinaryLogicalNode($1, OpOr, $3); } -; - -LogicalORExprNoIn: - LogicalANDExprNoIn - | LogicalORExprNoIn OR LogicalANDExprNoIn - { $$ = makeBinaryLogicalNode($1, OpOr, $3); } -; - -LogicalORExprNoBF: - LogicalANDExprNoBF - | LogicalORExprNoBF OR LogicalANDExpr { $$ = makeBinaryLogicalNode($1, OpOr, $3); } -; - -ConditionalExpr: - LogicalORExpr - | LogicalORExpr '?' AssignmentExpr ':' AssignmentExpr - { $$ = makeConditionalNode($1, $3, $5); } -; - -ConditionalExprNoIn: - LogicalORExprNoIn - | LogicalORExprNoIn '?' AssignmentExprNoIn ':' AssignmentExprNoIn - { $$ = makeConditionalNode($1, $3, $5); } -; - -ConditionalExprNoBF: - LogicalORExprNoBF - | LogicalORExprNoBF '?' AssignmentExpr ':' AssignmentExpr - { $$ = makeConditionalNode($1, $3, $5); } -; - -AssignmentExpr: - ConditionalExpr - | LeftHandSideExpr AssignmentOperator AssignmentExpr - { $$ = makeAssignNode($1, $2, $3); } -; - -AssignmentExprNoIn: - ConditionalExprNoIn - | LeftHandSideExpr AssignmentOperator AssignmentExprNoIn - { $$ = makeAssignNode($1, $2, $3); } -; - -AssignmentExprNoBF: - ConditionalExprNoBF - | LeftHandSideExprNoBF AssignmentOperator AssignmentExpr - { $$ = makeAssignNode($1, $2, $3); } -; - -AssignmentOperator: - '=' { $$ = OpEqual; } - | PLUSEQUAL { $$ = OpPlusEq; } - | MINUSEQUAL { $$ = OpMinusEq; } - | MULTEQUAL { $$ = OpMultEq; } - | DIVEQUAL { $$ = OpDivEq; } - | LSHIFTEQUAL { $$ = OpLShift; } - | RSHIFTEQUAL { $$ = OpRShift; } - | URSHIFTEQUAL { $$ = OpURShift; } - | ANDEQUAL { $$ = OpAndEq; } - | XOREQUAL { $$ = OpXOrEq; } - | OREQUAL { $$ = OpOrEq; } - | MODEQUAL { $$ = OpModEq; } -; - -Expr: - AssignmentExpr - | Expr ',' AssignmentExpr { $$ = new CommaNode($1, $3); } -; - -ExprNoIn: - AssignmentExprNoIn - | ExprNoIn ',' AssignmentExprNoIn { $$ = new CommaNode($1, $3); } -; - -ExprNoBF: - AssignmentExprNoBF - | ExprNoBF ',' AssignmentExpr { $$ = new CommaNode($1, $3); } -; - -Statement: - Block - | VariableStatement - | ConstStatement - | EmptyStatement - | ExprStatement - | IfStatement - | IterationStatement - | ContinueStatement - | BreakStatement - | ReturnStatement - | WithStatement - | SwitchStatement - | LabelledStatement - | ThrowStatement - | TryStatement - | DebuggerStatement - | ImportStatement -; - -Block: - '{' '}' { $$ = new BlockNode(0); DBG($$, @2, @2); } - | '{' SourceElements '}' { $$ = new BlockNode($2); DBG($$, @3, @3); } -; - -VariableStatement: - VAR VariableDeclarationList ';' { $$ = new VarStatementNode($2); DBG($$, @1, @3); } - | VAR VariableDeclarationList error { $$ = new VarStatementNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; } -; - -VariableDeclarationList: - VariableDeclaration { $$ = new VarDeclListNode($1); } - | VariableDeclarationList ',' VariableDeclaration - { $$ = new VarDeclListNode($1, $3); } -; - -VariableDeclarationListNoIn: - VariableDeclarationNoIn { $$ = new VarDeclListNode($1); } - | VariableDeclarationListNoIn ',' VariableDeclarationNoIn - { $$ = new VarDeclListNode($1, $3); } -; - -VariableDeclaration: - IDENT { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Variable); } - | IDENT Initializer { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Variable); } -; - -VariableDeclarationNoIn: - IDENT { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Variable); } - | IDENT InitializerNoIn { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Variable); } -; - -ConstStatement: - CONSTTOKEN ConstDeclarationList ';' { $$ = new VarStatementNode($2); DBG($$, @1, @3); } - | CONSTTOKEN ConstDeclarationList error - { $$ = new VarStatementNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; } -; - -ConstDeclarationList: - ConstDeclaration { $$ = new VarDeclListNode($1); } - | ConstDeclarationList ',' ConstDeclaration - { $$ = new VarDeclListNode($1, $3); } -; - -ConstDeclaration: - IDENT { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Constant); } - | IDENT Initializer { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Constant); } -; - -Initializer: - '=' AssignmentExpr { $$ = new AssignExprNode($2); } -; - -InitializerNoIn: - '=' AssignmentExprNoIn { $$ = new AssignExprNode($2); } -; - -EmptyStatement: - ';' { $$ = new EmptyStatementNode(); } -; - -ExprStatement: - ExprNoBF ';' { $$ = new ExprStatementNode($1); DBG($$, @1, @2); } - | ExprNoBF error { $$ = new ExprStatementNode($1); DBG($$, @1, @1); AUTO_SEMICOLON; } -; - -IfStatement: - IF '(' Expr ')' Statement %prec IF_WITHOUT_ELSE - { $$ = makeIfNode($3, $5, 0); DBG($$, @1, @4); } - | IF '(' Expr ')' Statement ELSE Statement - { $$ = makeIfNode($3, $5, $7); DBG($$, @1, @4); } -; - -IterationStatement: - DO Statement WHILE '(' Expr ')' ';' { $$ = new DoWhileNode($2, $5); DBG($$, @1, @3);} - | DO Statement WHILE '(' Expr ')' error { $$ = new DoWhileNode($2, $5); DBG($$, @1, @3); AUTO_SEMICOLON; } - | WHILE '(' Expr ')' Statement { $$ = new WhileNode($3, $5); DBG($$, @1, @4); } - | FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement - { $$ = new ForNode($3, $5, $7, $9); DBG($$, @1, @8); } - | FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement - { $$ = new ForNode($4, $6, $8, $10); DBG($$, @1, @9); } - | FOR '(' LeftHandSideExpr INTOKEN Expr ')' Statement - { - Node *n = $3->nodeInsideAllParens(); - if (!n->isLocation()) - YYABORT; - $$ = new ForInNode(n, $5, $7); - DBG($$, @1, @6); - } - | FOR '(' VAR IDENT INTOKEN Expr ')' Statement - { $$ = new ForInNode(*$4, 0, $6, $8); DBG($$, @1, @7); } - | FOR '(' VAR IDENT InitializerNoIn INTOKEN Expr ')' Statement - { $$ = new ForInNode(*$4, $5, $7, $9); DBG($$, @1, @8); } -; - -ExprOpt: - /* nothing */ { $$ = 0; } - | Expr -; - -ExprNoInOpt: - /* nothing */ { $$ = 0; } - | ExprNoIn -; - -ContinueStatement: - CONTINUE ';' { $$ = new ContinueNode(); DBG($$, @1, @2); } - | CONTINUE error { $$ = new ContinueNode(); DBG($$, @1, @1); AUTO_SEMICOLON; } - | CONTINUE IDENT ';' { $$ = new ContinueNode(*$2); DBG($$, @1, @3); } - | CONTINUE IDENT error { $$ = new ContinueNode(*$2); DBG($$, @1, @2); AUTO_SEMICOLON; } -; - -BreakStatement: - BREAK ';' { $$ = new BreakNode(); DBG($$, @1, @2); } - | BREAK error { $$ = new BreakNode(); DBG($$, @1, @1); AUTO_SEMICOLON; } - | BREAK IDENT ';' { $$ = new BreakNode(*$2); DBG($$, @1, @3); } - | BREAK IDENT error { $$ = new BreakNode(*$2); DBG($$, @1, @2); AUTO_SEMICOLON; } -; - -ReturnStatement: - RETURN ';' { $$ = new ReturnNode(0); DBG($$, @1, @2); } - | RETURN error { $$ = new ReturnNode(0); DBG($$, @1, @1); AUTO_SEMICOLON; } - | RETURN Expr ';' { $$ = new ReturnNode($2); DBG($$, @1, @3); } - | RETURN Expr error { $$ = new ReturnNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; } -; - -WithStatement: - WITH '(' Expr ')' Statement { $$ = new WithNode($3, $5); DBG($$, @1, @4); } -; - -SwitchStatement: - SWITCH '(' Expr ')' CaseBlock { $$ = new SwitchNode($3, $5); DBG($$, @1, @4); } -; - -CaseBlock: - '{' CaseClausesOpt '}' { $$ = new CaseBlockNode($2, 0, 0); } - | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}' - { $$ = new CaseBlockNode($2, $3, $4); } -; - -CaseClausesOpt: - /* nothing */ { $$ = 0; } - | CaseClauses -; - -CaseClauses: - CaseClause { $$ = new ClauseListNode($1); } - | CaseClauses CaseClause { $$ = new ClauseListNode($1, $2); } -; - -CaseClause: - CASE Expr ':' { $$ = new CaseClauseNode($2); } - | CASE Expr ':' SourceElements { $$ = new CaseClauseNode($2, $4); } -; - -DefaultClause: - DEFAULT ':' { $$ = new CaseClauseNode(0); } - | DEFAULT ':' SourceElements { $$ = new CaseClauseNode(0, $3); } -; - -LabelledStatement: - IDENT ':' Statement { $$ = makeLabelNode(*$1, $3); } -; - -ThrowStatement: - THROW Expr ';' { $$ = new ThrowNode($2); DBG($$, @1, @3); } - | THROW Expr error { $$ = new ThrowNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; } -; - -TryStatement: - TRY Block FINALLY Block { $$ = new TryNode($2, CommonIdentifiers::shared()->nullIdentifier, 0, $4); DBG($$, @1, @2); } - | TRY Block CATCH '(' IDENT ')' Block { $$ = new TryNode($2, *$5, $7, 0); DBG($$, @1, @2); } - | TRY Block CATCH '(' IDENT ')' Block FINALLY Block - { $$ = new TryNode($2, *$5, $7, $9); DBG($$, @1, @2); } -; - -DebuggerStatement: - DEBUGGER ';' { $$ = new EmptyStatementNode(); DBG($$, @1, @2); } - | DEBUGGER error { $$ = new EmptyStatementNode(); DBG($$, @1, @1); AUTO_SEMICOLON; } -; - -PackageName: - IDENT { $$ = new PackageNameNode(*$1); } - | PackageName '.' IDENT { $$ = new PackageNameNode($1, *$3); } -; - -ImportStatement: - IMPORT PackageName '.' '*' ';' { $$ = makeImportNode($2, true, 0); - DBG($$, @1, @5); } - | IMPORT PackageName '.' '*' error { $$ = makeImportNode($2, true, 0); - DBG($$, @1, @5); AUTO_SEMICOLON; } - | IMPORT PackageName ';' { $$ = makeImportNode($2, false, 0); - DBG($$, @1, @3); } - | IMPORT PackageName error { $$ = makeImportNode($2, false, 0); - DBG($$, @1, @3); AUTO_SEMICOLON; } - | IMPORT IDENT '=' PackageName ';' { $$ = makeImportNode($4, false, *$2); - DBG($$, @1, @5); } - | IMPORT IDENT '=' PackageName error { $$ = makeImportNode($4, false, *$2); - DBG($$, @1, @5); AUTO_SEMICOLON; } -; - -FunctionDeclaration: - FUNCTION IDENT '(' ')' {inFuncDecl();} FunctionBody { $$ = new FuncDeclNode(*$2, $6); } - | FUNCTION IDENT '(' FormalParameterList ')' {inFuncDecl();} FunctionBody - { $$ = new FuncDeclNode(*$2, $4, $7); } -; - -FunctionExpr: - FUNCTION '(' ')' {inFuncExpr();} FunctionBody { - $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $5); - } - | FUNCTION '(' FormalParameterList ')' {inFuncExpr();} FunctionBody { - $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $6, $3); - } - | FUNCTION IDENT '(' ')' {inFuncExpr();} FunctionBody { $$ = new FuncExprNode(*$2, $6); } - | FUNCTION IDENT '(' FormalParameterList ')' {inFuncExpr();} FunctionBody { - $$ = new FuncExprNode(*$2, $7, $4); - } -; - -FormalParameterList: - IDENT { $$ = new ParameterNode(*$1); } - | FormalParameterList ',' IDENT { $$ = new ParameterNode($1, *$3); } -; - -FunctionBody: - '{' '}' /* not in spec */ { $$ = new FunctionBodyNode(0); DBG($$, @1, @2); } - | '{' SourceElements '}' { $$ = new FunctionBodyNode($2); DBG($$, @1, @3); } -; - -Program: - /* not in spec */ { parser().didFinishParsing(new ProgramNode(0)); } - | SourceElements { parser().didFinishParsing(new ProgramNode($1)); } -; - -SourceElements: - SourceElement { $$ = new SourceElementsNode($1); } - | SourceElements SourceElement { $$ = new SourceElementsNode($1, $2); } -; - -SourceElement: - FunctionDeclaration { $$ = $1; } - | Statement { $$ = $1; } -; - -%% - -/* called by yyparse on error */ -int yyerror(const char *) -{ -// fprintf(stderr, "ERROR: %s at line %d\n", s, KJS::Lexer::curr()->lineNo()); - return 1; -} - -/* may we automatically insert a semicolon ? */ -static bool allowAutomaticSemicolon() -{ - return yychar == '}' || yychar == 0 || lexer().prevTerminator(); -} - -// kate: indent-width 2; replace-tabs on; tab-width 4; space-indent on; \ No newline at end of file diff --git a/kjs/identifier.cpp b/kjs/identifier.cpp deleted file mode 100644 index 3a67fa44..00000000 --- a/kjs/identifier.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2003 Apple Computer, Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "identifier.h" -#include - -#include -#include -#include // for strlen -#include // for placement new - -namespace KJS { - -typedef HashSet IdentifierTable; -static IdentifierTable *table; - -static inline IdentifierTable& identifierTable() -{ - if (!table) - table = new IdentifierTable; - return *table; -} - -bool Identifier::equal(const UString::Rep *r, const char *s) -{ - int length = r->len; - const UChar *d = r->data(); - for (int i = 0; i != length; ++i) - if (d[i].uc != (unsigned char)s[i]) - return false; - return s[length] == 0; -} - -bool Identifier::equal(const UString::Rep *r, const UChar *s, int length) -{ - if (r->len != length) - return false; - const UChar *d = r->data(); - for (int i = 0; i != length; ++i) - if (d[i].uc != s[i].uc) - return false; - return true; -} - -struct CStringTranslator -{ - static unsigned hash(const char *c) - { - return UString::Rep::computeHash(c); - } - - static bool equal(UString::Rep *r, const char *s) - { - return Identifier::equal(r, s); - } - - static void translate(UString::Rep*& location, const char *c, unsigned hash) - { - size_t length = strlen(c); - UChar *d = static_cast(fastMalloc(sizeof(UChar) * length)); - for (size_t i = 0; i != length; i++) - d[i] = c[i]; - - UString::Rep *r = UString::Rep::create(d, static_cast(length)).releaseRef(); - r->isIdentifier = 1; - r->rc = 0; - r->_hash = hash; - - location = r; - } -}; - -PassRefPtr Identifier::add(const char *c) -{ - if (!c) { - UString::Rep::null.hash(); - return &UString::Rep::null; - } - - if (!c[0]) { - UString::Rep::empty.hash(); - return &UString::Rep::empty; - } - - return *identifierTable().add(c).first; -} - -struct UCharBuffer { - const UChar *s; - unsigned int length; -}; - -struct UCharBufferTranslator -{ - static unsigned hash(const UCharBuffer& buf) - { - return UString::Rep::computeHash(buf.s, buf.length); - } - - static bool equal(UString::Rep *str, const UCharBuffer& buf) - { - return Identifier::equal(str, buf.s, buf.length); - } - - static void translate(UString::Rep *& location, const UCharBuffer& buf, unsigned hash) - { - UChar *d = static_cast(fastMalloc(sizeof(UChar) * buf.length)); - for (unsigned i = 0; i != buf.length; i++) - d[i] = buf.s[i]; - - UString::Rep *r = UString::Rep::create(d, buf.length).releaseRef(); - r->isIdentifier = 1; - r->rc = 0; - r->_hash = hash; - - location = r; - } -}; - -PassRefPtr Identifier::add(const UChar *s, int length) -{ - if (!length) { - UString::Rep::empty.hash(); - return &UString::Rep::empty; - } - - UCharBuffer buf = {s, static_cast(length)}; - return *identifierTable().add(buf).first; -} - -PassRefPtr Identifier::addSlowCase(UString::Rep *r) -{ - assert(!r->isIdentifier); - - if (r->len == 0) { - UString::Rep::empty.hash(); - return &UString::Rep::empty; - } - - UString::Rep *result = *identifierTable().add(r).first; - if (result == r) - r->isIdentifier = true; - return result; -} - -void Identifier::remove(UString::Rep *r) -{ - identifierTable().remove(r); -} - -} // namespace KJS diff --git a/kjs/identifier.h b/kjs/identifier.h deleted file mode 100644 index 441d1a1c..00000000 --- a/kjs/identifier.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2003 Apple Computer, Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef KJS_IDENTIFIER_H -#define KJS_IDENTIFIER_H - -#include "ustring.h" - -#include -#include - -namespace KJS { - - /** - * Represents an Identifier for a Javascript object. - */ - class KJS_EXPORT Identifier { - friend class PropertyMap; - public: - /** - * Creates an empty identifier - */ - Identifier() { } - /** - * Creates an identifier with the name of the string - * @code - * KJS::Identifier method("someJSMethod"); - * @endcode - */ - Identifier(const char* s) : _ustring(add(s)) { } - Identifier(const UChar* s, int length) : _ustring(add(s, length)) { } - explicit Identifier(UString::Rep* rep) : _ustring(add(rep)) { } - explicit Identifier(const UString& s) : _ustring(add(s.rep())) { } - - - /** - * returns a UString of the identifier - */ - const UString& ustring() const { return _ustring; } - KJS_EXTERNAL_EXPORT DOM::DOMString domString() const; - /** - * returns a QString of the identifier - */ - KJS_EXTERNAL_EXPORT QString qstring() const; - - /** - * returns a UChar pointer to the string of the identifier with a size defined by size(). - */ - const UChar* data() const { return _ustring.data(); } - /** - * The size of the UChar string returned. - */ - int size() const { return _ustring.size(); } - - /** - * Char * of the identifier's string. - */ - const char* ascii() const { return _ustring.ascii(); } - - static Identifier from(unsigned y) { return Identifier(UString::from(y)); } - - /** - * Returns the identfiers state of being unset. - */ - bool isNull() const { return _ustring.isNull(); } - /** - * Returns that the identifiers string is set, but is empty. - */ - bool isEmpty() const { return _ustring.isEmpty(); } - - uint32_t toStrictUInt32(bool* ok) const { return _ustring.toStrictUInt32(ok); } - unsigned toArrayIndex(bool* ok) const { return _ustring.toArrayIndex(ok); } - double toDouble() const { return _ustring.toDouble(); } - - friend bool operator==(const Identifier&, const Identifier&); - friend bool operator!=(const Identifier&, const Identifier&); - - friend bool operator==(const Identifier&, const char*); - - static void remove(UString::Rep*); - static bool equal(const UString::Rep*, const char*); - static bool equal(const UString::Rep*, const UChar*, int length); - - private: - UString _ustring; - - static bool equal(const Identifier& a, const Identifier& b) - { return a._ustring.rep() == b._ustring.rep(); } - static bool equal(const Identifier& a, const char* b) - { return equal(a._ustring.rep(), b); } - - static PassRefPtr add(const char*); - static PassRefPtr add(const UChar*, int length); - static PassRefPtr add(UString::Rep* r) - { - if (r->isIdentifier) - return r; - return addSlowCase(r); - } - static PassRefPtr addSlowCase(UString::Rep *r); - }; - - inline bool operator==(const Identifier& a, const Identifier& b) - { return Identifier::equal(a, b); } - - inline bool operator!=(const Identifier& a, const Identifier& b) - { return !Identifier::equal(a, b); } - - inline bool operator==(const Identifier& a, const char* b) - { return Identifier::equal(a, b); } - -} // namespace KJS - -#endif // KJS_IDENTIFIER_H diff --git a/kjs/internal.cpp b/kjs/internal.cpp deleted file mode 100644 index 49c2ce25..00000000 --- a/kjs/internal.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) - * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2004 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "internal.h" -#include - -#include "array_object.h" -#include "bool_object.h" -#include "collector.h" -#include "date_object.h" -#include "debugger.h" -#include "error_object.h" -#include "function_object.h" -#include "lexer.h" -#include "math_object.h" -#include "nodes.h" -#include "number_object.h" -#include "object.h" -#include "object_object.h" -#include "operations.h" -#include "regexp_object.h" -#include "string_object.h" -#include -#include -#include -#include -#include -#include - -namespace KJS { - -#if PLATFORM(WIN_OS) -#define copysign _copysign -#endif - -static const double D16 = 65536.0; -static const double D32 = 4294967296.0; - - -// ------------------------------ StringImp ------------------------------------ - -JSValue *StringImp::toPrimitive(ExecState *, JSType) const -{ - return const_cast(this); -} - -bool GetterSetterImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value) -{ - ASSERT_NOT_REACHED(); - number = 0; - value = 0; - return true; -} - -bool StringImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value) -{ - value = this; - number = val.toDouble(); - return false; -} - -bool StringImp::toBoolean(ExecState *) const -{ - return (val.size() > 0); -} - -double StringImp::toNumber(ExecState *) const -{ - return val.toDouble(); -} - -UString StringImp::toString(ExecState *) const -{ - return val; -} - -JSObject* StringImp::toObject(ExecState *exec) const -{ - return new StringInstance(exec->lexicalInterpreter()->builtinStringPrototype(), const_cast(this)); -} - -// ------------------------------ NumberImp ------------------------------------ - -JSValue *NumberImp::toPrimitive(ExecState *, JSType) const -{ - return const_cast(this); -} - -bool NumberImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value) -{ - number = val; - value = this; - return true; -} - -bool NumberImp::toBoolean(ExecState *) const -{ - return val < 0.0 || val > 0.0; // false for NaN -} - -double NumberImp::toNumber(ExecState *) const -{ - return val; -} - -UString NumberImp::toString(ExecState *) const -{ - if (val == 0.0) // +0.0 or -0.0 - return "0"; - return UString::from(val); -} - -JSObject *NumberImp::toObject(ExecState *exec) const -{ - List args; - args.append(const_cast(this)); - return static_cast(exec->lexicalInterpreter()->builtinNumber()->construct(exec,args)); -} - -bool NumberImp::getUInt32(uint32_t& uint32) const -{ - uint32 = static_cast(val); - return uint32 == val; -} - -bool NumberImp::getTruncatedInt32(int32_t& int32) const -{ - if (!(val >= -2147483648.0 && val < 2147483648.0)) - return false; - int32 = static_cast(val); - return true; -} - -bool NumberImp::getTruncatedUInt32(uint32_t& uint32) const -{ - if (!(val >= 0.0 && val < 4294967296.0)) - return false; - uint32 = static_cast(val); - return true; -} - -// --------------------------- GetterSetterImp --------------------------------- -void GetterSetterImp::mark() -{ - JSCell::mark(); - - if (getter && !getter->marked()) - getter->mark(); - if (setter && !setter->marked()) - setter->mark(); -} - -JSValue *GetterSetterImp::toPrimitive(ExecState*, JSType) const -{ - assert(false); - return jsNull(); -} - -bool GetterSetterImp::toBoolean(ExecState*) const -{ - assert(false); - return false; -} - -double GetterSetterImp::toNumber(ExecState *) const -{ - assert(false); - return 0.0; -} - -UString GetterSetterImp::toString(ExecState *) const -{ - assert(false); - return UString::null(); -} - -JSObject *GetterSetterImp::toObject(ExecState *exec) const -{ - assert(false); - return jsNull()->toObject(exec); -} - -// ------------------------------ InternalFunctionImp -------------------------- - -const ClassInfo InternalFunctionImp::info = {"Function", 0, 0, 0}; - -InternalFunctionImp::InternalFunctionImp() -{ -} - -InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto) - : JSObject(funcProto) -{ -} - -InternalFunctionImp::InternalFunctionImp(FunctionPrototype* funcProto, const Identifier& name) - : JSObject(funcProto) - , m_name(name) -{ -} - -bool InternalFunctionImp::implementsCall() const -{ - return true; -} - -bool InternalFunctionImp::implementsHasInstance() const -{ - return true; -} - -// ------------------------------ global functions ----------------------------- - -double roundValue(double d) -{ - double ad = fabs(d); - if (ad == 0 || isNaN(d) || isInf(d)) - return d; - return copysign(floor(ad), d); -} - -int32_t toInt32(double d) -{ - if (isNaN(d) || isInf(d)) - return 0; - double d32 = fmod(roundValue(d), D32); - - if (d32 >= D32 / 2) - d32 -= D32; - else if (d32 < -D32 / 2) - d32 += D32; - - return static_cast(d32); -} - -int32_t toInt32(double d, bool &ok) -{ - ok = true; - if (isNaN(d) || isInf(d)) { - ok = false; - return 0; - } - return toInt32(d); -} - -uint32_t toUInt32(double dd) -{ - double d = roundValue(dd); - if (isNaN(d) || isInf(d)) - return 0; - double d32 = fmod(d, D32); - - if (d32 < 0) - d32 += D32; - - return static_cast(d32); -} - -uint16_t toUInt16(double dd) -{ - double d = roundValue(dd); - if (isNaN(d) || isInf(d)) - return 0; - double d16 = fmod(d, D16); - - if (d16 < 0) - d16 += D16; - - return static_cast(d16); -} - -//#ifndef NDEBUG -void printInfo(ExecState *exec, const char *s, JSValue *o, int lineno) -{ - UString vString; - if (!o) - fprintf(stderr, "KJS: %s: (null)", s); - else { - JSValue *v = o; - - unsigned int arrayLength = 0; - bool hadExcep = exec->hadException(); - - UString name; - switch (v->type()) { - case UnspecifiedType: - name = "Unspecified"; - break; - case UndefinedType: - name = "Undefined"; - break; - case NullType: - name = "Null"; - break; - case BooleanType: - name = "Boolean"; - break; - case StringType: - name = "String"; - break; - case NumberType: - name = "Number"; - break; - case ObjectType: { - JSObject* obj = static_cast(v); - name = obj->className(); - if (name.isNull()) - name = "(unknown class)"; - - if ( obj->inherits(&ArrayInstance::info) ) - arrayLength = obj->get(exec, exec->propertyNames().length)->toUInt32(exec); - vString = "[object " + name + "]"; // krazy:exclude=doublequote_chars - break; - } - case GetterSetterType: - name = "GetterSetter"; - break; - } - - // Avoid calling toString on a huge array (e.g. 4 billion elements, in mozilla/js/js1_5/Array/array-001.js) - if ( arrayLength > 100 ) - vString = UString( "[ Array with " ) + UString::from( arrayLength ) + " elements ]"; - else if ( v->type() != ObjectType ) // Don't want to call a user toString function! - vString = v->toString(exec); - if ( !hadExcep ) - exec->clearException(); - - if ( vString.size() > 350 ) - vString = vString.substr( 0, 350 ) + "..."; - - // Can't use two UString::ascii() in the same fprintf call - CString tempString( vString.cstring() ); - - fprintf(stderr, "KJS: %s: %s : %s (%p)", - s, tempString.c_str(), name.ascii(), (void*)v); - - if (lineno >= 0) - fprintf(stderr, ", line %d\n",lineno); - else - fprintf(stderr, "\n"); - } -} -//#endif - -} diff --git a/kjs/internal.h b/kjs/internal.h deleted file mode 100644 index 811a0d0c..00000000 --- a/kjs/internal.h +++ /dev/null @@ -1,131 +0,0 @@ -// -*- 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) - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef INTERNAL_H -#define INTERNAL_H - -#include "JSType.h" -#include "interpreter.h" -#include "object.h" -#include "protect.h" -#include "scope_chain.h" -#include "types.h" -#include "ustring.h" - -#include - -#ifndef I18N_NOOP -#define I18N_NOOP(s) s -#endif - -namespace KJS { - - - // --------------------------------------------------------------------------- - // Primitive impls - // --------------------------------------------------------------------------- - - class StringImp : public JSCell { - public: - StringImp() : val(UString::empty) { } - StringImp(const UString& v) : val(v) { Collector::reportExtraMemoryCost(v.cost()); } - enum HasOtherOwnerType { HasOtherOwner }; // e.g. storage cost already accounted for - StringImp(const UString& value, HasOtherOwnerType) : val(value) { } - StringImp(const char* v) : val(v) { } - StringImp(const char* v, int len) : val(v, len) { } - const UString& value() const { return val; } - - virtual JSType type() const { return StringType; } - - virtual JSValue *toPrimitive(ExecState *exec, JSType preferred = UnspecifiedType) const; - virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value); - virtual bool toBoolean(ExecState *exec) const; - virtual double toNumber(ExecState *exec) const; - virtual UString toString(ExecState *exec) const; - virtual JSObject *toObject(ExecState *exec) const; - - private: - UString val; - }; - - class NumberImp : public JSCell { - friend class ConstantValues; - friend KJS_EXPORT JSValue *jsNumberCell(double); - public: - double value() const { return val; } - - JSType type() const { return NumberType; } - - JSValue *toPrimitive(ExecState *exec, JSType preferred = UnspecifiedType) const; - virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value); - bool toBoolean(ExecState *exec) const; - double toNumber(ExecState *exec) const; - UString toString(ExecState *exec) const; - JSObject *toObject(ExecState *exec) const; - - private: - NumberImp(double v) : val(v) { } - - virtual bool getUInt32(uint32_t&) const; - virtual bool getTruncatedInt32(int32_t&) const; - virtual bool getTruncatedUInt32(uint32_t&) const; - - double val; - }; - - // --------------------------------------------------------------------------- - // Evaluation - // --------------------------------------------------------------------------- - - struct AttachedInterpreter; - class DebuggerImp { - public: - - DebuggerImp() { - interps = 0; - isAborted = false; - } - - void abort() { isAborted = true; } - bool aborted() const { return isAborted; } - - AttachedInterpreter *interps; - bool isAborted; - }; - - // helper function for toInteger, toInt32, toUInt32 and toUInt16 - double roundValue(double d); - inline double roundValue(ExecState *e, JSValue *v) { return roundValue(v->toNumber(e)); } - - int32_t toInt32(double dd); - uint32_t toUInt32(double dd); - uint16_t toUInt16(double dd); - -//#ifndef NDEBUG - void printInfo(ExecState *exec, const char *s, JSValue *, int lineno = -1); -//#endif - -} // namespace - -#endif // INTERNAL_H diff --git a/kjs/interpreter.cpp b/kjs/interpreter.cpp deleted file mode 100644 index bb462925..00000000 --- a/kjs/interpreter.cpp +++ /dev/null @@ -1,1033 +0,0 @@ -// -*- 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) - * Copyright (C) 2003 Apple Computer, Inc. - * Copyright (C) 2008, 2009 Maksim Orlovich (maksim@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "interpreter.h" -#include - -#include "SavedBuiltins.h" -#include "array_object.h" -#include "bool_object.h" -#include "collector.h" -#include "date_object.h" -#include "debugger.h" -#include "error_object.h" -#include "function_object.h" -#include "internal.h" -#include "math_object.h" -#include "nodes.h" -#include "number_object.h" -#include "object.h" -#include "object_object.h" -#include "operations.h" -#include "regexp_object.h" -#include "string_object.h" -#include "types.h" -#include "value.h" -#include "lexer.h" -#include "json_object.h" - -#if USE(BINDINGS) -#include "runtime.h" -#endif - -#if defined _WIN32 || defined _WIN64 -#undef HAVE_SYS_TIME_H // no setitimer in kdewin32 -#endif -#if HAVE(SYS_TIME_H) -#include -#endif - -#include -#include -#include -#include -#include -#if defined(HAVE_UNISTD_H) -#include -#endif - -namespace KJS { - -class TimeoutChecker { -public: - void startTimeoutCheck(Interpreter*); - void stopTimeoutCheck(Interpreter*); - void pauseTimeoutCheck(Interpreter*); - void resumeTimeoutCheck(Interpreter*); - -private: -#if HAVE(SYS_TIME_H) - static Interpreter* s_executingInterpreter; - static void alarmHandler(int); - - Interpreter* m_oldInterpreter; - itimerval m_oldtv; - itimerval m_pausetv; - void (*m_oldAlarmHandler)(int); -#endif -}; - -#if HAVE(SYS_TIME_H) -Interpreter* TimeoutChecker::s_executingInterpreter = 0; -#endif - -void TimeoutChecker::startTimeoutCheck(Interpreter *interpreter) -{ - if (!interpreter->m_timeoutTime) - return; - - interpreter->m_startTimeoutCheckCount++; - -#if HAVE(SYS_TIME_H) - if (s_executingInterpreter == interpreter) - return; - - // Block signals - m_oldAlarmHandler = signal(SIGALRM, SIG_IGN); - - m_oldInterpreter = s_executingInterpreter; - s_executingInterpreter = interpreter; - - itimerval tv = { - { interpreter->m_timeoutTime / 1000, (interpreter->m_timeoutTime % 1000) * 1000 }, - { interpreter->m_timeoutTime / 1000, (interpreter->m_timeoutTime % 1000) * 1000 } - }; - setitimer(ITIMER_REAL, &tv, &m_oldtv); - - // Unblock signals - signal(SIGALRM, alarmHandler); -#endif -} - -void TimeoutChecker::stopTimeoutCheck(Interpreter* interpreter) -{ - if (!interpreter->m_timeoutTime) - return; - - ASSERT(interpreter->m_startTimeoutCheckCount > 0); - - interpreter->m_startTimeoutCheckCount--; - - if (interpreter->m_startTimeoutCheckCount != 0) - return; - -#if HAVE(SYS_TIME_H) - signal(SIGALRM, SIG_IGN); - - s_executingInterpreter = m_oldInterpreter; - - setitimer(ITIMER_REAL, &m_oldtv, 0L); - signal(SIGALRM, m_oldAlarmHandler); -#endif -} - -#if HAVE(SYS_TIME_H) -void TimeoutChecker::alarmHandler(int) -{ - s_executingInterpreter->m_timedOut = true; -} -#endif - -void TimeoutChecker::pauseTimeoutCheck(Interpreter* interpreter) -{ - if (interpreter->m_startTimeoutCheckCount == 0) - return; - -#if HAVE(SYS_TIME_H) - ASSERT(interpreter == s_executingInterpreter); - - void (*currentSignalHandler)(int); - - // Block signal - currentSignalHandler = signal(SIGALRM, SIG_IGN); - - if (currentSignalHandler != alarmHandler) { - signal(SIGALRM, currentSignalHandler); - return; - } - - setitimer(ITIMER_REAL, 0L, &m_pausetv); -#endif - - interpreter->m_pauseTimeoutCheckCount++; -} - -void TimeoutChecker::resumeTimeoutCheck(Interpreter* interpreter) -{ - if (interpreter->m_startTimeoutCheckCount == 0) - return; - -#if HAVE(SYS_TIME_H) - ASSERT(interpreter == s_executingInterpreter); -#endif - - interpreter->m_pauseTimeoutCheckCount--; - - if (interpreter->m_pauseTimeoutCheckCount != 0) - return; - -#if HAVE(SYS_TIME_H) - void (*currentSignalHandler)(int); - - // Check so we have the right handler - currentSignalHandler = signal(SIGALRM, SIG_IGN); - - if (currentSignalHandler != SIG_IGN) { - signal(SIGALRM, currentSignalHandler); - return; - } - - setitimer(ITIMER_REAL, &m_pausetv, 0L); - - // Unblock signal - currentSignalHandler = signal(SIGALRM, alarmHandler); -#endif -} - -Interpreter* Interpreter::s_hook = 0; - - -Interpreter::Interpreter(JSGlobalObject* globalObject) - : m_globalObject(globalObject), - m_globalExec(this, globalObject), - globPkg(0) -{ - init(); -} - -Interpreter::Interpreter() - : m_globalObject(new JSGlobalObject()), - m_globalExec(this, m_globalObject), - globPkg(0) -{ - init(); -} - -void Interpreter::init() -{ - JSLock lock; - - initInternedStringsTable(); - - m_refCount = 0; - m_timeoutTime = 0; - m_recursion = 0; - m_debugger= 0; - m_execState = 0; - m_timedOut = false; - m_timeoutChecker = 0; - m_startTimeoutCheckCount = 0; - m_pauseTimeoutCheckCount = 0; - m_compatMode = NativeMode; - - const int initialStackSize = 8192; - stackBase = (unsigned char*)std::malloc(initialStackSize); - stackPtr = stackBase; - stackEnd = stackBase + initialStackSize; - - m_numCachedActivations = 0; - - m_globalObject->setInterpreter(this); - - if (s_hook) { - prev = s_hook; - next = s_hook->next; - s_hook->next->prev = this; - s_hook->next = this; - } else { - // This is the first interpreter - s_hook = next = prev = this; - } - - initGlobalObject(); -} - -Interpreter::~Interpreter() -{ - JSLock lock; - - ASSERT (m_startTimeoutCheckCount == 0); - ASSERT (m_pauseTimeoutCheckCount == 0); - - delete m_timeoutChecker; - - if (m_debugger) - m_debugger->detach(this); - - std::free(stackBase); - - next->prev = prev; - prev->next = next; - s_hook = next; - if (s_hook == this) { - // This was the last interpreter - s_hook = 0; - } - - m_globalObject->setInterpreter(0); -} - -unsigned char* Interpreter::extendStack(size_t needed) -{ - unsigned char* oldBase = stackBase; // needed for fixing up localStores - - size_t curSize = stackEnd - stackBase; - size_t avail = stackEnd - stackPtr; - size_t extra = needed - avail; - - if (extra < 8192) - extra = 8192; - size_t newSize = curSize + extra; - - //printf("Grow stack:%d -> %d\n", curSize, newSize); - - stackBase = (unsigned char*)std::malloc(newSize); // Not realloc since we need the old stuff - // ### seems optimizeable - std::memcpy(stackBase, oldBase, curSize); - stackPtr = stackBase + (stackPtr - oldBase); - stackEnd = stackBase + newSize; - - // Now go through and fix up activations.. - ExecState* e = m_execState; - while (e) { - if (e->codeType() == FunctionCode) { - ActivationImp* act = static_cast(e->activationObject()); - if (act->localStorage) { - act->localStorage = (LocalStorageEntry*) - (stackBase + ((unsigned char*)act->localStorage - oldBase)); - e->updateLocalStorage(act->localStorage); - } - } - - e = e->savedExecState(); - } - - std::free(oldBase); - - return stackAlloc(needed); -} - -void Interpreter::recycleActivation(ActivationImp* act) -{ - ASSERT(act->localStorage == 0); // Should not refer to anything by now - if (m_numCachedActivations >= MaxCachedActivations) - return; - - act->clearProperties(); - m_cachedActivations[m_numCachedActivations] = act; - ++m_numCachedActivations; -} - -JSGlobalObject* Interpreter::globalObject() const -{ - return m_globalObject; -} - -void Interpreter::putNamedConstructor(const char* name, JSObject* value) -{ - assert(value->implementsCall()); - Identifier i(name); - m_globalObject->put(&m_globalExec, i, value, DontEnum); - static_cast(value)->setFunctionName(i); -} - -void Interpreter::initGlobalObject() -{ - FunctionPrototype *funcProto = new FunctionPrototype(&m_globalExec); - m_FunctionPrototype = funcProto; - ObjectPrototype *objProto = new ObjectPrototype(&m_globalExec, funcProto); - m_ObjectPrototype = objProto; - funcProto->setPrototype(m_ObjectPrototype); - - ArrayPrototype *arrayProto = new ArrayPrototype(&m_globalExec, objProto); - m_ArrayPrototype = arrayProto; - StringPrototype *stringProto = new StringPrototype(&m_globalExec, objProto); - m_StringPrototype = stringProto; - BooleanPrototype *booleanProto = new BooleanPrototype(&m_globalExec, objProto, funcProto); - m_BooleanPrototype = booleanProto; - NumberPrototype *numberProto = new NumberPrototype(&m_globalExec, objProto, funcProto); - m_NumberPrototype = numberProto; - DatePrototype *dateProto = new DatePrototype(&m_globalExec, objProto); - m_DatePrototype = dateProto; - RegExpPrototype *regexpProto = new RegExpPrototype(&m_globalExec, objProto, funcProto); - m_RegExpPrototype = regexpProto; - ErrorPrototype *errorProto = new ErrorPrototype(&m_globalExec, objProto, funcProto); - m_ErrorPrototype = errorProto; - - JSObject* o = m_globalObject; - while (o->prototype()->isObject()) - o = static_cast(o->prototype()); - o->setPrototype(m_ObjectPrototype); - - // Constructors (Object, Array, etc.) - m_Object = new ObjectObjectImp(&m_globalExec, objProto, funcProto); - m_Function = new FunctionObjectImp(&m_globalExec, funcProto); - m_Array = new ArrayObjectImp(&m_globalExec, funcProto, arrayProto); - m_String = new StringObjectImp(&m_globalExec, funcProto, stringProto); - m_Boolean = new BooleanObjectImp(&m_globalExec, funcProto, booleanProto); - m_Number = new NumberObjectImp(&m_globalExec, funcProto, numberProto); - m_Date = new DateObjectImp(&m_globalExec, funcProto, dateProto); - m_RegExp = new RegExpObjectImp(&m_globalExec, funcProto, regexpProto); - m_Error = new ErrorObjectImp(&m_globalExec, funcProto, errorProto); - - // Error object prototypes - m_EvalErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, EvalError, "EvalError", "EvalError"); - m_RangeErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, RangeError, "RangeError", "RangeError"); - m_ReferenceErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, ReferenceError, "ReferenceError", "ReferenceError"); - m_SyntaxErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, SyntaxError, "SyntaxError", "SyntaxError"); - m_TypeErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, TypeError, "TypeError", "TypeError"); - m_UriErrorPrototype = new NativeErrorPrototype(&m_globalExec, errorProto, URIError, "URIError", "URIError"); - - // Error objects - m_EvalError = new NativeErrorImp(&m_globalExec, funcProto, m_EvalErrorPrototype); - m_RangeError = new NativeErrorImp(&m_globalExec, funcProto, m_RangeErrorPrototype); - m_ReferenceError = new NativeErrorImp(&m_globalExec, funcProto, m_ReferenceErrorPrototype); - m_SyntaxError = new NativeErrorImp(&m_globalExec, funcProto, m_SyntaxErrorPrototype); - m_TypeError = new NativeErrorImp(&m_globalExec, funcProto, m_TypeErrorPrototype); - m_UriError = new NativeErrorImp(&m_globalExec, funcProto, m_UriErrorPrototype); - - // ECMA 15.3.4.1 - funcProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Function, DontEnum); - - putNamedConstructor("Object", m_Object); - putNamedConstructor("Function", m_Function); - putNamedConstructor("Array", m_Array); - putNamedConstructor("Boolean", m_Boolean); - putNamedConstructor("String", m_String); - putNamedConstructor("Number", m_Number); - putNamedConstructor("Date", m_Date); - putNamedConstructor("RegExp", m_RegExp); - putNamedConstructor("Error", m_Error); - putNamedConstructor("EvalError",m_EvalError); - putNamedConstructor("RangeError",m_RangeError); - putNamedConstructor("ReferenceError",m_ReferenceError); - putNamedConstructor("SyntaxError",m_SyntaxError); - putNamedConstructor("TypeError",m_TypeError); - putNamedConstructor("URIError",m_UriError); - - // Set the constructorPropertyName property of all builtin constructors - objProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Object, DontEnum); - funcProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Function, DontEnum); - arrayProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Array, DontEnum); - booleanProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Boolean, DontEnum); - stringProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_String, DontEnum); - numberProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Number, DontEnum); - dateProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Date, DontEnum); - regexpProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_RegExp, DontEnum); - errorProto->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_Error, DontEnum); - m_EvalErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_EvalError, DontEnum); - m_RangeErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_RangeError, DontEnum); - m_ReferenceErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_ReferenceError, DontEnum); - m_SyntaxErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_SyntaxError, DontEnum); - m_TypeErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_TypeError, DontEnum); - m_UriErrorPrototype->put(&m_globalExec, m_globalExec.propertyNames().constructor, m_UriError, DontEnum); - - // built-in values - m_globalObject->put(&m_globalExec, "NaN", jsNaN(), DontEnum|DontDelete|ReadOnly); - m_globalObject->put(&m_globalExec, "Infinity", jsNumber(Inf), DontEnum|DontDelete|ReadOnly); - m_globalObject->put(&m_globalExec, "undefined", jsUndefined(), DontEnum|DontDelete|ReadOnly); - - // built-in functions - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::Eval, 1, "eval"), DontEnum); - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum); - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum); - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum); - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum); - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::Escape, 1, "escape"), DontEnum); - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum); - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum); - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum); - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum); - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum); -#ifndef NDEBUG - m_globalObject->putDirectFunction(new GlobalFuncImp(&m_globalExec, funcProto, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum); -#endif - - // built-in objects - m_globalObject->put(&m_globalExec, "Math", new MathObjectImp(&m_globalExec, objProto), DontEnum); - m_globalObject->put(&m_globalExec, "JSON", new JSONObjectImp(&m_globalExec, objProto), DontEnum); -} - -ExecState* Interpreter::globalExec() -{ - return &m_globalExec; -} - -void Interpreter::setGlobalPackage(Package* p) -{ - globPkg = p; -} - -Package* Interpreter::globalPackage() -{ - return globPkg; -} - -Completion Interpreter::checkSyntax(const UString& sourceURL, int startingLineNumber, const UString& code) -{ - return checkSyntax(sourceURL, startingLineNumber, code.data(), code.size()); -} - -Completion Interpreter::checkSyntax(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength) -{ - JSLock lock; - - int errLine; - UString errMsg; - RefPtr progNode = parser().parseProgram(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg); - if (!progNode) - return Completion(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, 0, sourceURL)); - return Completion(Normal); -} - -Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV) -{ - return evaluate(sourceURL, startingLineNumber, code.data(), code.size(), thisV); -} - -Completion Interpreter::evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV) -{ - JSLock lock; - - // prevent against infinite recursion - if (m_recursion >= 20) - return Completion(Throw, Error::create(&m_globalExec, GeneralError, "Recursion too deep")); - - // parse the source code - int sourceId; - int errLine; - UString errMsg; - RefPtr progNode = parser().parseProgram(sourceURL, startingLineNumber, code, codeLength, &sourceId, &errLine, &errMsg); - - // notify debugger that source has been parsed - if (m_debugger) { - m_debugger->reportSourceParsed(&m_globalExec, progNode.get(), sourceId, sourceURL, - UString(code, codeLength), startingLineNumber, errLine, errMsg); - } - - // no program node means a syntax error occurred - if (!progNode) { - Completion res(Throw, Error::create(&m_globalExec, SyntaxError, errMsg, errLine, sourceId, sourceURL)); - if (m_debugger) - m_debugger->reportException(&m_globalExec, res.value()); - - if (shouldPrintExceptions()) - printException(res, sourceURL); - return res; - } - - m_globalExec.clearException(); - - m_recursion++; - - JSGlobalObject* globalObj = m_globalObject; - JSObject* thisObj = globalObj; - - // "this" must be an object... use same rules as Function.prototype.apply() - if (thisV && !thisV->isUndefinedOrNull()) - thisObj = thisV->toObject(&m_globalExec); - - Completion res; - if (m_globalExec.hadException()) - // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it - res = Completion(Throw, m_globalExec.exception()); - else { - // execute the code - InterpreterExecState newExec(this, globalObj, thisObj, progNode.get()); - - if (m_debugger && !m_debugger->enterContext(&newExec, sourceId, startingLineNumber, 0, List::empty())) { - // debugger requested we stop execution. - m_debugger->imp()->abort(); - return Completion(Break); - } - - progNode->processDecls(&newExec); - res = progNode->execute(&newExec); - - if (m_debugger && !m_debugger->exitContext(&newExec, sourceId, startingLineNumber, 0)) { - // debugger requested we stop execution. - m_debugger->imp()->abort(); - return Completion(Break); - } - } - - m_recursion--; - - if (shouldPrintExceptions() && res.complType() == Throw) - printException(res, sourceURL); - - return res; -} - -bool Interpreter::normalizeCode(const UString& codeIn, UString* codeOut, - int* errLine, UString* errMsg) -{ - assert(codeOut); - RefPtr progNode = parser().parseProgram("", // sourceURL - 0, // line - codeIn.data(), - codeIn.size(), - 0, // &sourceId - errLine, errMsg); - if (progNode) { - *codeOut = progNode->toString(); - return true; - } else { - return false; - } -} - -JSObject *Interpreter::builtinObject() const -{ - return m_Object; -} - -JSObject *Interpreter::builtinFunction() const -{ - return m_Function; -} - -JSObject *Interpreter::builtinArray() const -{ - return m_Array; -} - -JSObject *Interpreter::builtinBoolean() const -{ - return m_Boolean; -} - -JSObject *Interpreter::builtinString() const -{ - return m_String; -} - -JSObject *Interpreter::builtinNumber() const -{ - return m_Number; -} - -JSObject *Interpreter::builtinDate() const -{ - return m_Date; -} - -JSObject *Interpreter::builtinRegExp() const -{ - return m_RegExp; -} - -JSObject *Interpreter::builtinError() const -{ - return m_Error; -} - -JSObject *Interpreter::builtinObjectPrototype() const -{ - return m_ObjectPrototype; -} - -JSObject *Interpreter::builtinFunctionPrototype() const -{ - return m_FunctionPrototype; -} - -JSObject *Interpreter::builtinArrayPrototype() const -{ - return m_ArrayPrototype; -} - -JSObject *Interpreter::builtinBooleanPrototype() const -{ - return m_BooleanPrototype; -} - -JSObject *Interpreter::builtinStringPrototype() const -{ - return m_StringPrototype; -} - -JSObject *Interpreter::builtinNumberPrototype() const -{ - return m_NumberPrototype; -} - -JSObject *Interpreter::builtinDatePrototype() const -{ - return m_DatePrototype; -} - -JSObject *Interpreter::builtinRegExpPrototype() const -{ - return m_RegExpPrototype; -} - -JSObject *Interpreter::builtinErrorPrototype() const -{ - return m_ErrorPrototype; -} - -JSObject *Interpreter::builtinEvalError() const -{ - return m_EvalError; -} - -JSObject *Interpreter::builtinRangeError() const -{ - return m_RangeError; -} - -JSObject *Interpreter::builtinReferenceError() const -{ - return m_ReferenceError; -} - -JSObject *Interpreter::builtinSyntaxError() const -{ - return m_SyntaxError; -} - -JSObject *Interpreter::builtinTypeError() const -{ - return m_TypeError; -} - -JSObject *Interpreter::builtinURIError() const -{ - return m_UriError; -} - -JSObject *Interpreter::builtinEvalErrorPrototype() const -{ - return m_EvalErrorPrototype; -} - -JSObject *Interpreter::builtinRangeErrorPrototype() const -{ - return m_RangeErrorPrototype; -} - -JSObject *Interpreter::builtinReferenceErrorPrototype() const -{ - return m_ReferenceErrorPrototype; -} - -JSObject *Interpreter::builtinSyntaxErrorPrototype() const -{ - return m_SyntaxErrorPrototype; -} - -JSObject *Interpreter::builtinTypeErrorPrototype() const -{ - return m_TypeErrorPrototype; -} - -JSObject *Interpreter::builtinURIErrorPrototype() const -{ - return m_UriErrorPrototype; -} - -bool Interpreter::collect() -{ - return Collector::collect(); -} - -void Interpreter::mark(bool) -{ - if (m_execState) - m_execState->mark(); - if (m_globalObject && !m_globalObject->marked()) - m_globalObject->mark(); - if (m_globalExec.exception() && !m_globalExec.exception()->marked()) - m_globalExec.exception()->mark(); - - // Do not let cached activations survive the GC; as they have an unfortunate - // tendenacy to pin blocks, increasing their number and hence spreading out - // the objects somewhat - m_numCachedActivations = 0; -} - -void Interpreter::markSourceCachedObjects() -{ - markInternedStringsTable(); -} - -#ifdef KJS_DEBUG_MEM -void Interpreter::finalCheck() -{ - fprintf(stderr,"Interpreter::finalCheck()\n"); - Collector::collect(); - -// Node::finalCheck(); - Collector::finalCheck(); -} -#endif - -static bool printExceptions = false; - -bool Interpreter::shouldPrintExceptions() -{ - return printExceptions; -} - -void Interpreter::setShouldPrintExceptions(bool print) -{ - printExceptions = print; -} - -void Interpreter::printException(const Completion& c, const UString& sourceURL) -{ - JSLock lock; - ExecState* exec = globalExec(); - CString f = sourceURL.UTF8String(); - CString message = c.value()->toObject(exec)->toString(exec).UTF8String(); - int line = c.value()->toObject(exec)->get(exec, "line")->toUInt32(exec); -#if PLATFORM(WIN_OS) - printf("%s line %d: %s\n", f.c_str(), line, message.c_str()); -#else - printf("[%d] %s line %d: %s\n", getpid(), f.c_str(), line, message.c_str()); -#endif -} - -// bindings are OS X WebKit-only for now -#if USE(BINDINGS) -void *Interpreter::createLanguageInstanceForValue(ExecState *exec, int language, JSObject *value, const Bindings::RootObject *origin, const Bindings::RootObject *current) -{ - return Bindings::Instance::createLanguageInstanceForValue (exec, (Bindings::Instance::BindingLanguage)language, value, origin, current); -} -#endif - -void Interpreter::saveBuiltins (SavedBuiltins& builtins) const -{ - if (!builtins._internal) - builtins._internal = new SavedBuiltinsInternal; - - builtins._internal->m_Object = m_Object; - builtins._internal->m_Function = m_Function; - builtins._internal->m_Array = m_Array; - builtins._internal->m_Boolean = m_Boolean; - builtins._internal->m_String = m_String; - builtins._internal->m_Number = m_Number; - builtins._internal->m_Date = m_Date; - builtins._internal->m_RegExp = m_RegExp; - builtins._internal->m_Error = m_Error; - - builtins._internal->m_ObjectPrototype = m_ObjectPrototype; - builtins._internal->m_FunctionPrototype = m_FunctionPrototype; - builtins._internal->m_ArrayPrototype = m_ArrayPrototype; - builtins._internal->m_BooleanPrototype = m_BooleanPrototype; - builtins._internal->m_StringPrototype = m_StringPrototype; - builtins._internal->m_NumberPrototype = m_NumberPrototype; - builtins._internal->m_DatePrototype = m_DatePrototype; - builtins._internal->m_RegExpPrototype = m_RegExpPrototype; - builtins._internal->m_ErrorPrototype = m_ErrorPrototype; - - builtins._internal->m_EvalError = m_EvalError; - builtins._internal->m_RangeError = m_RangeError; - builtins._internal->m_ReferenceError = m_ReferenceError; - builtins._internal->m_SyntaxError = m_SyntaxError; - builtins._internal->m_TypeError = m_TypeError; - builtins._internal->m_UriError = m_UriError; - - builtins._internal->m_EvalErrorPrototype = m_EvalErrorPrototype; - builtins._internal->m_RangeErrorPrototype = m_RangeErrorPrototype; - builtins._internal->m_ReferenceErrorPrototype = m_ReferenceErrorPrototype; - builtins._internal->m_SyntaxErrorPrototype = m_SyntaxErrorPrototype; - builtins._internal->m_TypeErrorPrototype = m_TypeErrorPrototype; - builtins._internal->m_UriErrorPrototype = m_UriErrorPrototype; -} - -void Interpreter::restoreBuiltins (const SavedBuiltins& builtins) -{ - if (!builtins._internal) - return; - - m_Object = builtins._internal->m_Object; - m_Function = builtins._internal->m_Function; - m_Array = builtins._internal->m_Array; - m_Boolean = builtins._internal->m_Boolean; - m_String = builtins._internal->m_String; - m_Number = builtins._internal->m_Number; - m_Date = builtins._internal->m_Date; - m_RegExp = builtins._internal->m_RegExp; - m_Error = builtins._internal->m_Error; - - m_ObjectPrototype = builtins._internal->m_ObjectPrototype; - m_FunctionPrototype = builtins._internal->m_FunctionPrototype; - m_ArrayPrototype = builtins._internal->m_ArrayPrototype; - m_BooleanPrototype = builtins._internal->m_BooleanPrototype; - m_StringPrototype = builtins._internal->m_StringPrototype; - m_NumberPrototype = builtins._internal->m_NumberPrototype; - m_DatePrototype = builtins._internal->m_DatePrototype; - m_RegExpPrototype = builtins._internal->m_RegExpPrototype; - m_ErrorPrototype = builtins._internal->m_ErrorPrototype; - - m_EvalError = builtins._internal->m_EvalError; - m_RangeError = builtins._internal->m_RangeError; - m_ReferenceError = builtins._internal->m_ReferenceError; - m_SyntaxError = builtins._internal->m_SyntaxError; - m_TypeError = builtins._internal->m_TypeError; - m_UriError = builtins._internal->m_UriError; - - m_EvalErrorPrototype = builtins._internal->m_EvalErrorPrototype; - m_RangeErrorPrototype = builtins._internal->m_RangeErrorPrototype; - m_ReferenceErrorPrototype = builtins._internal->m_ReferenceErrorPrototype; - m_SyntaxErrorPrototype = builtins._internal->m_SyntaxErrorPrototype; - m_TypeErrorPrototype = builtins._internal->m_TypeErrorPrototype; - m_UriErrorPrototype = builtins._internal->m_UriErrorPrototype; -} - -void Interpreter::startTimeoutCheck() -{ - if (!m_timeoutChecker) - m_timeoutChecker = new TimeoutChecker; - - m_timeoutChecker->startTimeoutCheck(this); -} - -void Interpreter::stopTimeoutCheck() -{ - ASSERT(m_timeoutChecker); - - m_timeoutChecker->stopTimeoutCheck(this); -} - -void Interpreter::restartTimeoutCheck() -{ - if (!m_timeoutChecker || !m_startTimeoutCheckCount) - return; - - m_timedOut = false; - m_timeoutChecker->stopTimeoutCheck(this); - m_timeoutChecker->startTimeoutCheck(this); -} - -void Interpreter::pauseTimeoutCheck() -{ - ASSERT(m_timeoutChecker); - - m_timeoutChecker->pauseTimeoutCheck(this); -} - -void Interpreter::resumeTimeoutCheck() -{ - ASSERT(m_timeoutChecker); - - m_timeoutChecker->resumeTimeoutCheck(this); -} - -bool Interpreter::handleTimeout() -{ - m_timedOut = false; - - pauseTimeoutCheck(); - bool retval = shouldInterruptScript(); - resumeTimeoutCheck(); - - return retval; -} - -Interpreter::InternedStringsTable* Interpreter::s_internedStrings; - -void Interpreter::initInternedStringsTable() -{ - if (!s_internedStrings) - s_internedStrings = new InternedStringsTable(); -} - -StringImp* Interpreter::internString(const UString& literal) -{ - InternedStringsTable::iterator i = s_internedStrings->find(literal.rep()); - - if (i == s_internedStrings->end()) { - // Need to add. Note: we can't use ->add() above to avoid a double-hash - // as creation of a StringImp may cause a GC, which in turn may - // rearrange the hashtable, invalidating the iterator. - StringImp* si = static_cast(jsOwnedString(literal)); - s_internedStrings->add(literal.rep(), std::make_pair(si, 1)); - return si; - } else { - ++i.values()->second; // just bump the ref count - return i.values()->first; - } -} - -void Interpreter::releaseInternedString(const UString& literal) -{ - InternedStringsTable::iterator i = s_internedStrings->find(literal.rep()); - - --i.values()->second; - if (i.values()->second == 0) - s_internedStrings->remove(i); -} - -void Interpreter::markInternedStringsTable() -{ - for (InternedStringsTable::iterator i = s_internedStrings->begin(); - i != s_internedStrings->end(); ++i) { - // Note: the StringImp* may be null here if we got called in the middle - // of internString. - if (i.values()->first && !i.values()->first->marked()) - i.values()->first->mark(); - } -} - -SavedBuiltins::SavedBuiltins() : - _internal(0) -{ -} - -SavedBuiltins::~SavedBuiltins() -{ - delete _internal; -} - -UnicodeSupport::UnicodeSupport() -{ -} - -void UnicodeSupport::setIdentStartChecker(bool (*f)(int c)) -{ - Lexer::setIdentStartChecker(f); -} - -void UnicodeSupport::setIdentPartChecker(bool (*f)(int c)) -{ - Lexer::setIdentPartChecker(f); -} - -void UnicodeSupport::setToLowerFunction(StringConversionFunction f) -{ - StringProtoFunc::setToLowerFunction(f); -} - -void UnicodeSupport::setToUpperFunction(StringConversionFunction f) -{ - StringProtoFunc::setToUpperFunction(f); -} - -} - -// kate: indent-width 2; replace-tabs on; tab-width 4; space-indent on; diff --git a/kjs/interpreter.h b/kjs/interpreter.h deleted file mode 100644 index c6ac1dee..00000000 --- a/kjs/interpreter.h +++ /dev/null @@ -1,564 +0,0 @@ -/* - * 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) - * Copyright (C) 2003 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef _KJS_INTERPRETER_H_ -#define _KJS_INTERPRETER_H_ - -#include "ExecState.h" -#include "protect.h" -#include "value.h" -#include "types.h" -#include - -namespace KJS { - class Debugger; - class SavedBuiltins; - class TimeoutChecker; - class Package; - class ActivationImp; - class JSGlobalObject; - class StringImp; - -#if USE(BINDINGS) - namespace Bindings { - class RootObject; - } -#endif - - /** - * Interpreter objects can be used to evaluate ECMAScript code. Each - * interpreter has a global object which is used for the purposes of code - * evaluation, and also provides access to built-in properties such as - * " Object" and "Number". - */ - class KJS_EXPORT Interpreter { - friend class Collector; - friend class TimeoutChecker; - public: - /** - * Creates a new interpreter. The supplied object will be used as the global - * object for all scripts executed with this interpreter. During - * construction, all the standard properties such as "Object" and "Number" - * will be added to the global object. - * - * Note: You should not use the same global object for multiple - * interpreters. - * - * This is due do the fact that the built-in properties are set in the - * constructor, and if these objects have been modified from another - * interpreter (e.g. a script modifying String.prototype), the changes will - * be overridden. - * - * @param globalObject The object to use as the global object for this interpreter - */ - Interpreter(JSGlobalObject* globalObject); - /** - * Creates a new interpreter. A global object will be created and - * initialized with the standard global properties. - */ - Interpreter(); - - /** - * Returns the object that is used as the global object during all script - * execution performed by this interpreter - */ - JSGlobalObject* globalObject() const; - void initGlobalObject(); - - /** - * Returns the execution state object which can be used to execute - * scripts using this interpreter at a the "global" level, i.e. one - * with a execution context that has the global object as the "this" - * value, and who's scope chain contains only the global object. - * - * Note: this pointer remains constant for the life of the interpreter - * and should not be manually deleted. - * - * @return The interpreter global execution state object - */ - virtual ExecState *globalExec(); - - /** - * Sets the package instance that will be used to resolve the - * first level of identifiers of import statements. - * - * If no package is set which will make any "import" script - * statement fail with an error. This is the default in e.g. a - * Web browser where package imports should be disabled for - * security reasons. - */ - void setGlobalPackage(Package* p); - - /** - * Returns the package that was installed to handle top level - * package requests. Returns 0, the default, when no package was - * set. - * - * @return The global package - */ - Package* globalPackage(); - - /** - * Parses the supplied ECMAScript code and checks for syntax errors. - * - * @param code The code to check - * @param sourceURL A URL denoting the origin of the code - * @param startingLineNumber The line offset within an embedding context - * @return A normal completion if there were no syntax errors in the code, - * otherwise a throw completion with the syntax error as its value. - */ - Completion checkSyntax(const UString& sourceURL, int startingLineNumber, const UString& code); - Completion checkSyntax(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength); - - /** - * Evaluates the supplied ECMAScript code. - * - * Since this method returns a Completion, you should check the type of - * completion to detect an error or before attempting to access the returned - * value. For example, if an error occurs during script execution and is not - * caught by the script, the completion type will be Throw. - * - * If the supplied code is invalid, a SyntaxError will be thrown. - * - * @param sourceURL A URL denoting the origin of the code - * @param startingLineNumber The line offset within an embedding context - * @param code The code to evaluate - * @param codeLength The length of the code to evaluate - * @param thisV The value to pass in as the "this" value for the script - * execution. This should either be jsNull() or an Object. - * @return A completion object representing the result of the execution. - */ - Completion evaluate(const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV = 0); - Completion evaluate(const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV = 0); - - /** - * Pretty-prints the supplied ECMAScript code after checking it - * for syntax errors. - * - * @param sourceURL A URL denoting the origin of the code - * @param startingLineNumber The line offset within an embedding context - * @param codeIn The code to check - * @param codeIn Pointer to string that will contain reformatted code - * upon successful parsing. - * @return A normal completion if there were no syntax errors in the code, - * otherwise a throw completion with the syntax error as its value. - */ - static bool normalizeCode(const UString& codeIn, UString* codeOut, - int* errLine = 0, UString* errMsg = 0); - - /** - * Returns the builtin "Object" object. This is the object that was set - * as a property of the global object during construction; if the property - * is replaced by script code, this method will still return the original - * object. - * - * @return The builtin "Object" object - */ - JSObject *builtinObject() const; - - /** - * Returns the builtin "Function" object. - */ - JSObject *builtinFunction() const; - - /** - * Returns the builtin "Array" object. - */ - JSObject *builtinArray() const; - - /** - * Returns the builtin "Boolean" object. - */ - JSObject *builtinBoolean() const; - - /** - * Returns the builtin "String" object. - */ - JSObject *builtinString() const; - - /** - * Returns the builtin "Number" object. - */ - JSObject *builtinNumber() const; - - /** - * Returns the builtin "Date" object. - */ - JSObject *builtinDate() const; - - /** - * Returns the builtin "RegExp" object. - */ - JSObject *builtinRegExp() const; - - /** - * Returns the builtin "Error" object. - */ - JSObject *builtinError() const; - - /** - * Returns the builtin "Object.prototype" object. - */ - JSObject *builtinObjectPrototype() const; - - /** - * Returns the builtin "Function.prototype" object. - */ - JSObject *builtinFunctionPrototype() const; - - /** - * Returns the builtin "Array.prototype" object. - */ - JSObject *builtinArrayPrototype() const; - - /** - * Returns the builtin "Boolean.prototype" object. - */ - JSObject *builtinBooleanPrototype() const; - - /** - * Returns the builtin "String.prototype" object. - */ - JSObject *builtinStringPrototype() const; - - /** - * Returns the builtin "Number.prototype" object. - */ - JSObject *builtinNumberPrototype() const; - - /** - * Returns the builtin "Date.prototype" object. - */ - JSObject *builtinDatePrototype() const; - - /** - * Returns the builtin "RegExp.prototype" object. - */ - JSObject *builtinRegExpPrototype() const; - - /** - * Returns the builtin "Error.prototype" object. - */ - JSObject *builtinErrorPrototype() const; - - /** - * The initial value of "Error" global property - */ - JSObject *builtinEvalError() const; - JSObject *builtinRangeError() const; - JSObject *builtinReferenceError() const; - JSObject *builtinSyntaxError() const; - JSObject *builtinTypeError() const; - JSObject *builtinURIError() const; - - JSObject *builtinEvalErrorPrototype() const; - JSObject *builtinRangeErrorPrototype() const; - JSObject *builtinReferenceErrorPrototype() const; - JSObject *builtinSyntaxErrorPrototype() const; - JSObject *builtinTypeErrorPrototype() const; - JSObject *builtinURIErrorPrototype() const; - - enum CompatMode { NativeMode, IECompat, NetscapeCompat }; - /** - * Call this to enable a compatibility mode with another browser. - * (by default konqueror is in "native mode"). - * Currently, in KJS, this only changes the behavior of Date::getYear() - * which returns the full year under IE. - */ - void setCompatMode(CompatMode mode) { m_compatMode = mode; } - CompatMode compatMode() const { return m_compatMode; } - - /** - * Run the garbage collection. Returns true when at least one object - * was collected; false otherwise. - */ - static bool collect(); - - /** - * Called during the mark phase of the garbage collector. Subclasses - * implementing custom mark methods must make sure to chain to this one. - */ - virtual void mark(bool currentThreadIsMainThread); - - /** - * This marks all GC heap resources stored as optimizations; - * and which have their lifetime managed by the appropriate AST. - * It's static since code can survive the interpreter by a bit. - */ - static void markSourceCachedObjects(); - - /** - * Provides a way to distinguish derived classes. - * Only useful if you reimplement Interpreter and if different kind of - * interpreters are created in the same process. - * The base class returns 0, the ECMA-bindings interpreter returns 1. - */ - virtual int rtti() { return 0; } - - static bool shouldPrintExceptions(); - static void setShouldPrintExceptions(bool); - - void saveBuiltins (SavedBuiltins&) const; - void restoreBuiltins (const SavedBuiltins&); - - /** - * Determine if the it is 'safe' to execute code in the target interpreter from an - * object that originated in this interpreter. This check is used to enforce WebCore - * cross frame security rules. In particular, attempts to access 'bound' objects are - * not allowed unless isSafeScript returns true. - */ - virtual bool isSafeScript(const Interpreter*) { return true; } - -#if USE(BINDINGS) - virtual void *createLanguageInstanceForValue(ExecState*, int language, JSObject* value, const Bindings::RootObject* origin, const Bindings::RootObject* current); -#endif - - // Chained list of interpreters (ring) - static Interpreter* firstInterpreter() { return s_hook; } - Interpreter* nextInterpreter() const { return next; } - Interpreter* prevInterpreter() const { return prev; } - - Debugger* debugger() const { return m_debugger; } - void setDebugger(Debugger* d) { m_debugger = d; } - - void setExecState(ExecState* e) { m_execState = e; } - - // Note: may be 0, if in globalExec - ExecState* execState() { return m_execState ? m_execState : &m_globalExec; } - - void setTimeoutTime(unsigned timeoutTime) { m_timeoutTime = timeoutTime; } - - void startTimeoutCheck(); - void stopTimeoutCheck(); - - // Resets the timer to full time if it's running - void restartTimeoutCheck(); - - void pauseTimeoutCheck(); - void resumeTimeoutCheck(); - - bool checkTimeout(); - - void ref() { ++m_refCount; } - void deref() { if (--m_refCount <= 0) delete this; } - int refCount() const { return m_refCount; } - - unsigned char* stackAlloc(size_t size) { - unsigned char* nextPtr = stackPtr + size; - if (nextPtr <= stackEnd) { - unsigned char* toRet = stackPtr; - stackPtr = nextPtr; - return toRet; - } - return extendStack(size); - } - - void stackFree(size_t size) { stackPtr-= size; } // ### shrink it? - - ActivationImp* getRecycledActivation() { - ActivationImp* out = 0; - if (m_numCachedActivations) { - m_numCachedActivations--; - out = m_cachedActivations[m_numCachedActivations]; - } - return out; - } - - void recycleActivation(ActivationImp* act); - - // Global string table management. This is used from StringNode - // to cache StringImp's for string literals. We keep refcounts - // to permit multiple ones to use the same value. - static StringImp* internString(const UString& literal); - static void releaseInternedString(const UString& literal); - - typedef WTF::HashMap > InternedStringsTable; -private: - static void markInternedStringsTable(); - - // This creates a table if needed - static void initInternedStringsTable(); - - static InternedStringsTable* s_internedStrings; - -protected: - virtual ~Interpreter(); // only deref should delete us - virtual bool shouldInterruptScript() const { return true; } - - long m_timeoutTime; - -private: - bool handleTimeout(); - void init(); - void printException(const Completion& c, const UString& sourceURL); - - /** - * This constructor is not implemented, in order to prevent - * copy-construction of Interpreter objects. You should always pass around - * pointers to an interpreter instance instead. - */ - Interpreter(const Interpreter&); - - /** - * This operator is not implemented, in order to prevent assignment of - * Interpreter objects. You should always pass around pointers to an - * interpreter instance instead. - */ - Interpreter operator=(const Interpreter&); - - int m_refCount; - - JSGlobalObject* m_globalObject; - GlobalExecState m_globalExec; - Package *globPkg; - - // Execution stack stuff for this interpreter. - unsigned char* stackBase; // lowest address in the array - unsigned char* stackPtr; // current top/next to allocate - unsigned char* stackEnd; // last address in the stack - unsigned char* extendStack(size_t needed); - - // A list of cached activations - enum {MaxCachedActivations = 32}; - - ActivationImp* m_cachedActivations[MaxCachedActivations]; - int m_numCachedActivations; - - // Chained list of interpreters (ring) - for collector - static Interpreter* s_hook; - Interpreter *next, *prev; - - int m_recursion; - - Debugger* m_debugger; - ExecState* m_execState; - CompatMode m_compatMode; - - TimeoutChecker* m_timeoutChecker; - bool m_timedOut; - - unsigned m_startTimeoutCheckCount; - unsigned m_pauseTimeoutCheckCount; - - // Helper for setting constructors, making sure their function names are OK - void putNamedConstructor(const char* name, JSObject* value); - - ProtectedPtr m_Object; - ProtectedPtr m_Function; - ProtectedPtr m_Array; - ProtectedPtr m_Boolean; - ProtectedPtr m_String; - ProtectedPtr m_Number; - ProtectedPtr m_Date; - ProtectedPtr m_RegExp; - ProtectedPtr m_Error; - - ProtectedPtr m_ObjectPrototype; - ProtectedPtr m_FunctionPrototype; - ProtectedPtr m_ArrayPrototype; - ProtectedPtr m_BooleanPrototype; - ProtectedPtr m_StringPrototype; - ProtectedPtr m_NumberPrototype; - ProtectedPtr m_DatePrototype; - ProtectedPtr m_RegExpPrototype; - ProtectedPtr m_ErrorPrototype; - - ProtectedPtr m_EvalError; - ProtectedPtr m_RangeError; - ProtectedPtr m_ReferenceError; - ProtectedPtr m_SyntaxError; - ProtectedPtr m_TypeError; - ProtectedPtr m_UriError; - - ProtectedPtr m_EvalErrorPrototype; - ProtectedPtr m_RangeErrorPrototype; - ProtectedPtr m_ReferenceErrorPrototype; - ProtectedPtr m_SyntaxErrorPrototype; - ProtectedPtr m_TypeErrorPrototype; - ProtectedPtr m_UriErrorPrototype; - }; - - inline bool Interpreter::checkTimeout() - { - if (!m_timedOut) - return false; - - return handleTimeout(); - } - - /** - * Interface to set enhanced Unicode support functions. By default - * the interpreter will use the standard C library functions. - * - * @internal - */ - class KJS_EXPORT UnicodeSupport - { - public: - UnicodeSupport(); - - typedef bool (*CharCategoryFunction)(int c); - static void setIdentStartChecker(CharCategoryFunction f); - static void setIdentPartChecker(CharCategoryFunction f); - - typedef int (*StringConversionFunction)(uint16_t* str, int strLength, - uint16_t*& destIfNeeded); - static void setToLowerFunction(StringConversionFunction f); - static void setToUpperFunction(StringConversionFunction f); - }; - - /** - * Define a Qt-based version of the Unicode support functions. - * - * @internal - */ -#define KJS_QT_UNICODE_IMPL \ -namespace KJS { \ - static bool qtIdentStart(int c) { if (c & 0xffff0000) return false; QChar::Category cat = QChar((unsigned short)c).category(); return cat == QChar::Letter_Uppercase || cat == QChar::Letter_Lowercase || cat == QChar::Letter_Titlecase || cat == QChar::Letter_Modifier || cat == QChar::Letter_Other || c == '$' || c == '_'; } \ - static bool qtIdentPart(int c) { if (c & 0xffff0000) return false; QChar::Category cat = QChar((unsigned short)c).category(); return cat == QChar::Letter_Uppercase || cat == QChar::Letter_Lowercase || cat == QChar::Letter_Titlecase || cat == QChar::Letter_Modifier || cat == QChar::Letter_Other || cat == QChar::Mark_NonSpacing || cat == QChar::Mark_SpacingCombining || cat == QChar::Number_DecimalDigit || cat == QChar::Punctuation_Connector || c == '$' || c == '_'; } \ - static int qtToLower(uint16_t* str, int strLength, uint16_t*& destIfNeeded) { \ - destIfNeeded = 0; \ - for (int i = 0; i < strLength; ++i) \ - str[i] = QChar(str[i]).toLower().unicode(); \ - return strLength; } \ - static int qtToUpper(uint16_t* str, int strLength, uint16_t*& destIfNeeded) { \ - destIfNeeded = 0; \ - for (int i = 0; i < strLength; ++i) \ - str[i] = QChar(str[i]).toUpper().unicode(); \ - return strLength; } \ -} - - /** - * Set the Qt-based version of the Unicode support functions. - * - * @internal - */ -#define KJS_QT_UNICODE_SET \ - { KJS::UnicodeSupport::setIdentStartChecker(KJS::qtIdentStart); \ - KJS::UnicodeSupport::setIdentPartChecker(KJS::qtIdentPart); \ - KJS::UnicodeSupport::setToLowerFunction(KJS::qtToLower); \ - KJS::UnicodeSupport::setToUpperFunction(KJS::qtToUpper); } - -} // namespace - -#endif // _KJS_INTERPRETER_H_ diff --git a/kjs/json_object.cpp b/kjs/json_object.cpp deleted file mode 100644 index 12699c42..00000000 --- a/kjs/json_object.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2012 Bernd Buschinski (b.buschinski@googlemail.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "json_object.h" - -#include "jsonlexer.h" -#include -#include "lookup.h" -#include "array_instance.h" -#include "jsonstringify.h" - -#include "json_object.lut.h" - -using namespace KJS; - -// ------------------------------ JSONObjectImp -------------------------------- - -const ClassInfo JSONObjectImp::info = { "JSON", 0, &jsonTable, 0 }; - -/* Source for json_object.lut.h -@begin jsonTable 2 - parse JSONObjectImp::Parse DontEnum|Function 2 - stringify JSONObjectImp::Stringify DontEnum|Function 3 -@end -*/ - - -JSONObjectImp::JSONObjectImp(ExecState*, ObjectPrototype *objProto) - : JSObject(objProto) -{ -} - -bool JSONObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) -{ - // As of ECMA 5.1r6 JSON only has 2 functions, so only functionSlot is needed - return getStaticFunctionSlot(exec, &jsonTable, this, propertyName, slot); -} - -// ------------------------------ JSONFuncImp -------------------------------- - -JSONFuncImp::JSONFuncImp(ExecState* exec, int i, int l, const Identifier& name) - : InternalFunctionImp(static_cast(exec->lexicalInterpreter()->builtinFunctionPrototype()), name), - id(i) -{ - putDirect(exec->propertyNames().length, l, DontDelete|ReadOnly|DontEnum); -} - -static void reviver(ExecState* exec, JSValue* value, JSObject* func) -{ - if (exec->hadException()) - return; - - JSType type = value->type(); - switch (type) { - case ObjectType: { - JSObject* obj = value->getObject(); - bool isArray = obj->inherits(&ArrayInstance::info); - bool validArrayIndex = false; - - PropertyNameArray names; - obj->getOwnPropertyNames(exec, names, KJS::PropertyMap::ExcludeDontEnumProperties); - const int nameSize = names.size(); - for (int i = 0; i < nameSize; ++i) { - // For Array only take properties that are valid Array indexes - if (isArray) { - names[i].toArrayIndex(&validArrayIndex); - if (!validArrayIndex) - continue; - } - - JSValue* val = obj->get(exec, names[i]); - - List args; - args.append(jsString(names[i].ustring())); - args.append(val); - - JSValue* ret = func->call(exec, obj, args); - if (exec->hadException()) - return; - if (ret->isUndefined()) - obj->deleteProperty(exec, names[i]); - else { - obj->put(exec, names[i], ret); - reviver(exec, ret, func); - } - } - break; - } - case NullType: - case NumberType: - case BooleanType: - case StringType: - break; - case UnspecifiedType: - case GetterSetterType: - case UndefinedType: - // should never be reached, as JSON doesn't know them - // and we only have json data here - ASSERT_NOT_REACHED(); - break; - } -} - -JSValue *JSONFuncImp::callAsFunction(ExecState* exec, JSObject* /*thisObj*/, const List& args) -{ - switch (id) { - case JSONObjectImp::Parse: { - if (args.size() < 1) - return throwError(exec, SyntaxError, "Invalid JSON Syntax"); - - JSONParser parser(args[0]->toString(exec)); - if (exec->hadException()) - return jsUndefined(); - JSValue* val = parser.tryParse(exec); - - if (!val) - return throwError(exec, SyntaxError, "Invalid JSON Syntax"); - - if (args.size() < 2) - return val; - - JSValue* func = args[1]; - if (func->implementsCall()) { - JSObject* function = func->getObject(); - - List args; - args.append(jsString("")); - args.append(val); - - JSObject* jsobjectArg = val->toObject(exec); - if (exec->hadException()) - return jsUndefined(); - JSValue* ret = function->call(exec, jsobjectArg, args); - if (ret->isUndefined()) - return ret; - else { - reviver(exec, ret, function); - if (exec->hadException()) - return jsUndefined(); - } - } - - return val; - } - case JSONObjectImp::Stringify: { - JSValue* object = args[0]; - JSONStringify stringifier(exec, args[1], args[2]); - - JSONStringify::StringifyState state; - JSValue* ret = stringifier.stringify(exec, object, state); - switch (state) { - case JSONStringify::Success: - return ret; - case JSONStringify::FailedCyclic: - return throwError(exec, TypeError, "cyclic object value"); - case JSONStringify::FailedStackLimitExceeded: - return throwError(exec, TypeError, "object stack limit exceeded"); - case JSONStringify::FailedException: - //stringify already got an exception - return jsUndefined(); - } - } - default: - ASSERT_NOT_REACHED(); - } - - return jsUndefined(); -} diff --git a/kjs/json_object.h b/kjs/json_object.h deleted file mode 100644 index 047ffe37..00000000 --- a/kjs/json_object.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2012 Bernd Buschinski (b.buschinski@googlemail.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSON_OBJECT_H_ -#define JSON_OBJECT_H_ - -#include "function_object.h" - -namespace KJS { - -class JSONObjectImp : public JSObject { -public: - JSONObjectImp(ExecState *exec, - ObjectPrototype *objProto); - - using KJS::JSObject::getOwnPropertySlot; - bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&); - - virtual const ClassInfo *classInfo() const { return &info; } - static const ClassInfo info; - enum { Parse, Stringify }; -}; - -class JSONFuncImp : public InternalFunctionImp { -public: - JSONFuncImp(ExecState *exec, int i, int l, const Identifier&); - virtual JSValue *callAsFunction(ExecState*, JSObject*, const List&); -private: - int id; -}; - -} // namespace - -#endif // JSON_OBJECT_H diff --git a/kjs/jsonlexer.cpp b/kjs/jsonlexer.cpp deleted file mode 100644 index e2103ad1..00000000 --- a/kjs/jsonlexer.cpp +++ /dev/null @@ -1,642 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2012 Bernd Buschinski (b.buschinski@googlemail.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "jsonlexer.h" - -#include - -#include "lexer.h" -#include "object.h" - -#include "wtf/Assertions.h" - -// #define JSONLEXER_DEBUG_VERBOSE - -namespace KJS { - -using namespace JSONParserState; - -static const unsigned short InvalidJSONUnicode = 0x001F; - -static inline bool isDecimalDigit(const UChar &c) -{ - return (c.uc >= '0' && c.uc <= '9'); -} - -static inline bool isHexDigit(const UChar& c) -{ - return (isDecimalDigit(c) || - (c.uc >= 'a' && c.uc <= 'f') || - (c.uc >= 'A' && c.uc <= 'F')); -} - -static inline bool isJSONWhiteSpace(const UChar& c) -{ - //ECMA Edition 5.1r6 - 15.12.1.1 - Syntax - switch (c.uc) { - case 0x0020: //SP - case 0x0009: //TAB - case 0x000A: //LF - case 0x000D: //CR - return true; - default: - return false; - } -} - -#ifdef JSONLEXER_DEBUG_VERBOSE -static inline UString tokenToString(TokenType type) -{ - switch (type) { - case TokLBracket: return UString("TokLBracket"); - case TokRBracket: return UString("TokRBracket"); - case TokLBrace: return UString("TokLBrace"); - case TokRBrace: return UString("TokRBrace"); - case TokString: return UString("TokString"); - case TokIdentifier: return UString("TokIdentifier"); - case TokNumber: return UString("TokNumber"); - case TokColon: return UString("TokColon"); - case TokLParen: return UString("TokLParen"); - case TokRParen: return UString("TokRParen"); - case TokComma: return UString("TokComma"); - case TokTrue: return UString("TokTrue"); - case TokFalse: return UString("TokFalse"); - case TokNull: return UString("TokNull"); - case TokEnd: return UString("TokEnd"); - case TokError: return UString("TokError"); - } - ASSERT_NOT_REACHED(); - return UString("Default"); -} - -static inline UString parserStateToString(ParserState state) -{ - switch (state) { - case JSONValue: return UString("JSONValue"); - case JSONObject: return UString("JSONObject"); - case JSONArray: return UString("JSONArray"); - } - ASSERT_NOT_REACHED(); - return UString("Default"); -} -#endif - - -// ------------------------------ JSONParser -------------------------------- - -JSONParser::JSONParser(const UString& code) - : m_lexer(code) -{ -#ifdef JSONLEXER_DEBUG_VERBOSE - fprintf(stderr, "=============== new JSONParser ===============\n%s\n===============\n", code.ascii()); -#endif -} - -JSValue* JSONParser::tryParse(ExecState* exec) -{ - JSValue* ret = parse(exec); - // If the syntax is correct, we never see the EOF, the last used token may be '}'. - // But Syntax like "{} xyz" is also invalid, so we have to check if the next(last) token is EOF - if (ret && nextParseIsEOF()) - return ret; - return 0; -} - -// helper function for adding a value to the object. -// the arrayStack saves all added values and gives the correct array position. -// This function will return false for NULL value or on exception. -static inline bool addArrayItem(ExecState* exec, std::stack* arrayStack, JSValue* value, JSObject* object) -{ - if (exec->hadException()) - return false; - - if (!value) - return false; - - arrayStack->push(value); - object->put(exec, arrayStack->size()-1, value); - return true; -} - -JSValue* JSONParser::parse(ExecState* exec, ParserState state) -{ - if (exec->hadException()) - return 0; - - ParserState tState = state; - TokenType type = m_lexer.next(); - - JSObject* object = 0; - std::stack arrayObjectStack; - UString propertyName; - - // For parsing the Object, did we found a propertyName? - // NOTE: empty propertynames are allowed. - bool havePropertyName = false; - // For parsing the Object/Array, checks if we really added/found a propertyName - // before we find the comma ',' - bool propAdded = false; - // For parsing the Array, remember if last found token is Comma - bool lastFoundIsTokComma = false; - - while (type != TokEnd && type != TokError) { -#ifdef JSONLEXER_DEBUG_VERBOSE - fprintf(stderr, "TokenType: %s \t State: %s\n", tokenToString(type).ascii(), parserStateToString(tState).ascii()); -#endif - - switch (tState) { - case JSONValue: - switch (type) { - case TokLBracket: - object = static_cast(exec->lexicalInterpreter()->builtinArray()->construct(exec, List::empty())); - tState = JSONArray; - break; - case TokLBrace: - object = static_cast(exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty())); - tState = JSONObject; - break; - case TokString: - return jsString(m_lexer.currentString()); - case TokNull: - return jsNull(); - case TokTrue: - return jsBoolean(true); - case TokFalse: - return jsBoolean(false); - case TokNumber: - return jsNumber(m_lexer.currentNumber()); - default: - // This can only happen on invalid syntax and with 0 return - // we tell the caller we got a syntax error. - - // ASSERT_NOT_REACHED(); - return 0; - } - break; - case JSONObject: { - // if we got called from JSONArray-TokLBrace we did not create an object. - - // In more detail for the following JSON String "[{}]" - // If we are in parse with type=JSONArray and state=TokLBrace, - // means we just found the "{" in the Array, and call parse(exec, JSONObject), - // now in this call type=JSONObject, state=TokRBrace ("}") and, our new, object=0 (!) - // We will finish the object and return it, but as object is null, we return 0. - // which would be wrong, as empty objects are allowed. - // In this case we just report invalid data. - // But for JSON String like "[{"a":1}]", we end up using object(0)->putDirect - // and crash. - - // In short, remove this line and we will crash. - object = object ? object : static_cast(exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty())); - switch (type) { - case TokString: // PropertyName - if (havePropertyName) - return 0; - propertyName = m_lexer.currentString(); - havePropertyName = true; - break; - case TokColon: { - if (!havePropertyName) - return 0; - JSValue* val = parse(exec, JSONValue); - if (!val) - return 0; - - // use putDirect to by-pass __proto__ - object->putDirect(Identifier(propertyName), val); - propertyName = ""; - havePropertyName = false; - propAdded = true; - break; - } - case TokRBrace: //Finish Object - if (havePropertyName) - return 0; - return object; - case TokComma: // Next Property - if (!propAdded) - return 0; - propAdded = false; - break; - default: - // This can only happen on invalid syntax and with 0 return - // we tell the caller we got a syntax error. - - // ASSERT_NOT_REACHED(); - return 0; - } - break; - } - case JSONArray: { - // if we got called from JSONArray-TokLBracket we did not create an object - object = object ? object : static_cast(exec->lexicalInterpreter()->builtinArray()->construct(exec, List::empty())); - - // Check for invalid Array syntax, like ["1" "2"] - switch (type) { - case TokNumber: - case TokString: - case TokNull: - case TokTrue: - case TokFalse: - case TokLBrace: - case TokLBracket: - if (propAdded) - return 0; - propAdded = true; - lastFoundIsTokComma = false; - break; - default: - break; - } - - switch (type) { - case TokRBracket: // Finish array - // Check for invalid syntax like "[1,]" - if (lastFoundIsTokComma) - return 0; - return object; - case TokNumber: - if (!addArrayItem(exec, &arrayObjectStack, jsNumber(m_lexer.currentNumber()), object)) - return 0; - break; - case TokString: - if (!addArrayItem(exec, &arrayObjectStack, jsString(m_lexer.currentString()), object)) - return 0; - break; - case TokNull: - if (!addArrayItem(exec, &arrayObjectStack, jsNull(), object)) - return 0; - break; - case TokTrue: - if (!addArrayItem(exec, &arrayObjectStack, jsBoolean(true), object)) - return 0; - break; - case TokFalse: - if (!addArrayItem(exec, &arrayObjectStack, jsBoolean(false), object)) - return 0; - break; - case TokLBrace: - if (!addArrayItem(exec, &arrayObjectStack, parse(exec, JSONObject), object)) - return 0; - break; - case TokLBracket: - if (!addArrayItem(exec, &arrayObjectStack, parse(exec, JSONArray), object)) - return 0; - break; - case TokComma: // Skip Comma and parse next Array Element - // if we found a comma without a leading property, this is invalid syntax - if (!propAdded) - return 0; - propAdded = false; - lastFoundIsTokComma = true; - break; - default: - // This can only happen on invalid syntax and with 0 return - // we tell the caller we got a syntax error. - - // ASSERT_NOT_REACHED(); - return 0; - } - break; - } - default: - ASSERT_NOT_REACHED(); - return 0; - } - type = m_lexer.next(); - } - - if (type == TokError) { -#ifdef JSONLEXER_DEBUG_VERBOSE - fprintf(stderr, "WARNING: JSONParse ending with error!\n"); -#endif - return 0; - } - if (type == TokEnd) { -#ifdef JSONLEXER_DEBUG_VERBOSE - fprintf(stderr, "WARNING: JSONParse ending with unexpected END!\n"); -#endif - return 0; - } - ASSERT_NOT_REACHED(); - return 0; -} - - -// ------------------------------ JSONLexer -------------------------------- - -JSONLexer::JSONLexer(const UString& code) - : m_code(code), - m_pos(0) -{ -} - -TokenType JSONLexer::current() -{ - return m_type; -} - -double JSONLexer::currentNumber() const -{ - ASSERT(m_type == TokNumber); - return m_numberToken; -} - -UString JSONLexer::currentString() const -{ - ASSERT(m_type == TokString); - return m_stringToken; -} - -TokenType JSONLexer::lexString() -{ - UString string; - const int codeSize = m_code.size(); - //skip first detected '"' - ++m_pos; - - if (m_pos >= codeSize) { - m_type = TokError; - return m_type; - } - - //while not at the end of the string '"' - while (!(m_code[m_pos] == '"')) { - UChar cur = m_code[m_pos]; - if (cur == UChar('\\')) { - ++m_pos; - bool error = false; - string.append(parseEscapeChar(&error)); - if (error) { - m_type = TokError; - return m_type; - } - } else { - if (cur.uc <= InvalidJSONUnicode) { - m_type = TokError; - return m_type; - } - string.append(cur); - ++m_pos; - } - - if (m_pos >= codeSize) { - m_type = TokError; - return m_type; - } - } - - m_type = TokString; - m_stringToken = string; - ++m_pos; -#ifdef JSONLEXER_DEBUG_VERBOSE - fprintf(stderr, "JSONLexer::lexString: Pos:%d stringlength:%d string:%s\n", m_pos, string.size(), string.ascii()); -#endif - return m_type; -} - -TokenType JSONLexer::lexNumber() -{ - const int start = m_pos; - const int codeSize = m_code.size(); - - // -?(0 | [1-9][0-9]*) ('.' [0-9]+)? ([eE][+-]? [0-9]+)? - - // -? - if (m_pos < codeSize && m_code[m_pos] == '-') - ++m_pos; - - // (0 | [1-9][0-9]*) - if (m_pos < codeSize && m_code[m_pos] == '0') { - ++m_pos; - } else if (m_pos < codeSize) { - while (m_pos < codeSize && isDecimalDigit(m_code[m_pos])) { - ++m_pos; - } - } else { - m_type = TokError; - return m_type; - } - - // ('.' [0-9]+)? - if (m_pos < codeSize && m_code[m_pos] == '.') { - ++m_pos; - // [0-9]+ - if (m_pos >= codeSize || !isDecimalDigit(m_code[m_pos])) { - m_type = TokError; - return m_type; - } - ++m_pos; - - while (m_pos < codeSize && isDecimalDigit(m_code[m_pos])) - ++m_pos; - } - - // ([eE][+-]? [0-9]+)? - if (m_pos < codeSize && (m_code[m_pos] == 'e' || m_code[m_pos] == 'E')) { // [eE] - ++m_pos; - - // [-+]? - if (m_pos < codeSize && (m_code[m_pos] == '-' || m_code[m_pos] == '+')) - ++m_pos; - - // [0-9]+ - if (m_pos >= codeSize || !isDecimalDigit(m_code[m_pos])) { - m_type = TokError; - return m_type; - } - - ++m_pos; - while (m_pos < codeSize && isDecimalDigit(m_code[m_pos])) - ++m_pos; - } - - m_numberToken = m_code.substr(start, m_pos-start).toDouble(false, false); - m_type = TokNumber; -#ifdef JSONLEXER_DEBUG_VERBOSE - fprintf(stderr, "Number: %f\n", m_numberToken); -#endif - return m_type; -} - -UChar JSONLexer::parseEscapeChar(bool* error) -{ - UChar cur = m_code[m_pos]; - switch (cur.uc) { - case '"': - case '\\': - case '/': - ++m_pos; - return cur; - case 'b': - ++m_pos; - return UChar('\b'); - case 'f': - ++m_pos; - return UChar('\f'); - case 'n': - ++m_pos; - return UChar('\n'); - case 'r': - ++m_pos; - return UChar('\r'); - case 't': - ++m_pos; - return UChar('\t'); - case 'u': - { - if ((m_code.size() - (m_pos+1)) < 4) { - *error = true; - return UChar(' '); - } - if (!isHexDigit(m_code[m_pos+1]) || !isHexDigit(m_code[m_pos+2]) || - !isHexDigit(m_code[m_pos+3]) || !isHexDigit(m_code[m_pos+4])) { - *error = true; - return UChar(' '); - } - - UChar next = Lexer::convertUnicode(m_code[m_pos+1].uc, m_code[m_pos+2].uc, m_code[m_pos+3].uc, m_code[m_pos+4].uc); - - *error = false; - m_pos += 5; - return next; - } - default: - *error = true; - return UChar(' '); - } -} - -//helper function, checks if "word" is in the "code" at "pos". -static inline bool isStringSequence(int pos, const UString& code, const UString& word) -{ - const int wordSize = word.size(); - if (pos + wordSize > code.size()) - return false; - - //Skip first, we already checked it - for (int i = 1; i < wordSize; ++i) { - if (code[pos+i].uc != word[i].uc) - return false; - } - return true; -} - -TokenType JSONLexer::next() -{ - while(true) { - if (m_pos >= m_code.size()) { - m_type = TokEnd; - return m_type; - } - - if (!isJSONWhiteSpace(m_code[m_pos])) { - break; - } - ++m_pos; - } - - m_type = TokError; - -#ifdef JSONLEXER_DEBUG_VERBOSE - fprintf(stderr, "JSONLexer::next current: %c \t\t pos: %d/%d\n", char(m_code[m_pos].uc), m_pos, m_code.size()); -#endif - - switch (m_code[m_pos].uc) { - case '[': - m_type = TokLBracket; - ++m_pos; - return m_type; - case ']': - m_type = TokRBracket; - ++m_pos; - return m_type; - case '(': - m_type = TokLParen; - ++m_pos; - return m_type; - case ')': - m_type = TokRParen; - ++m_pos; - return m_type; - case '{': - m_type = TokLBrace; - ++m_pos; - return m_type; - case '}': - m_type = TokRBrace; - ++m_pos; - return m_type; - case ',': - m_type = TokComma; - ++m_pos; - return m_type; - case ':': - m_type = TokColon; - ++m_pos; - return m_type; - case '"': - return lexString(); - - case 't': - if (isStringSequence(m_pos, m_code, "true")) { - m_type = TokTrue; - m_pos += 4; - return m_type; - } - break; - case 'f': - if (isStringSequence(m_pos, m_code, "false")) { - m_type = TokFalse; - m_pos += 5; - return m_type; - } - break; - case 'n': - if (isStringSequence(m_pos, m_code, "null")) { - m_type = TokNull; - m_pos += 4; - return m_type; - } - break; - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return lexNumber(); - } - return m_type; -} - -bool JSONParser::nextParseIsEOF() -{ - return m_lexer.next() == TokEnd; -} - - -} // namespace KJS diff --git a/kjs/jsonlexer.h b/kjs/jsonlexer.h deleted file mode 100644 index b3132580..00000000 --- a/kjs/jsonlexer.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2012 Bernd Buschinski (b.buschinski@googlemail.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSONLEXER_H -#define JSONLEXER_H - -#include "ustring.h" - - -namespace KJS { - -class ExecState; -class JSValue; -class JSObject; -class JSONParser; - -namespace JSONParserState { - enum ParserState { - JSONValue = 1, - JSONObject, - JSONArray - }; - - enum TokenType { - TokLBracket, // [ - TokRBracket, // ] - TokLBrace, // { - TokRBrace, // } - TokString, - TokIdentifier, - TokNumber, - TokColon, - TokLParen, - TokRParen, - TokComma, - TokTrue, - TokFalse, - TokNull, - TokEnd, - TokError }; -}; - - -class JSONLexer { -public: - explicit JSONLexer(const UString& code); - - JSONParserState::TokenType next(); - JSONParserState::TokenType current(); - double currentNumber() const; - UString currentString() const; - -private: - inline JSONParserState::TokenType lexString(); - inline JSONParserState::TokenType lexNumber(); - UChar parseEscapeChar(bool *error); - - UString m_code; - int m_pos; - - //Token Data - JSONParserState::TokenType m_type; - UString m_stringToken; - double m_numberToken; -}; - - -class JSONParser { -public: - explicit JSONParser(const UString& code); - - // Returns the root parsed JSValue* - // or NULL on failure - JSValue* tryParse(ExecState* exec); - -private: - JSValue* parse(ExecState* exec, JSONParserState::ParserState state = JSONParserState::JSONValue); - inline bool nextParseIsEOF(); - - JSONParserState::ParserState m_state; - JSONLexer m_lexer; -}; - - -} // namespace KJS - -#endif // JSONLEXER_H diff --git a/kjs/jsonstringify.cpp b/kjs/jsonstringify.cpp deleted file mode 100644 index e07a7896..00000000 --- a/kjs/jsonstringify.cpp +++ /dev/null @@ -1,409 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2012 Bernd Buschinski (b.buschinski@googlemail.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - - -#include "jsonstringify.h" - -#include - -#include "object.h" -#include "operations.h" -#include "array_instance.h" -#include "number_object.h" -#include "bool_object.h" -#include "string_object.h" -#include "function.h" - -#include "wtf/Assertions.h" - - -namespace KJS { - -static const unsigned int StackObjectLimit = 1500; - -JSONStringify::JSONStringify(ExecState* exec, JSValue* replacer, JSValue* spacer) - : m_state(Success) -{ - m_replacerObject = replacer->getObject(); - - if (!m_replacerObject) - m_replacerType = Invalid; - else if (replacer->implementsCall()) - m_replacerType = Function; - else if (m_replacerObject->inherits(&ArrayInstance::info)) { - //get all whitelist names - m_replacerType = Array; - PropertyNameArray names; - m_replacerObject->getOwnPropertyNames(exec, names, PropertyMap::ExcludeDontEnumProperties); - const int size = names.size(); - bool isValidIndex = false; - for (int i = 0; i < size; ++i) { - names[i].toArrayIndex(&isValidIndex); - if (!isValidIndex) - continue; - m_whitelistNames.add(Identifier(m_replacerObject->get(exec, names[i])->toString(exec))); - if (exec->hadException()) { - m_state = FailedException; - return; - } - } - } else { - m_replacerType = Invalid; - m_replacerObject = 0; - } - - JSObject* spacerObject = spacer->getObject(); - m_emtpySpacer = true; - if (spacer->isString() || (spacerObject && spacerObject->inherits(&StringInstance::info))) { - m_spacer = spacer->toString(exec); - if (exec->hadException()) { - m_state = FailedException; - return; - } - if (!m_spacer.isEmpty()) { - m_spacer = m_spacer.substr(0, 10); - m_emtpySpacer = false; - } - } else if (spacer->isNumber() || (spacerObject && spacerObject->inherits(&NumberInstance::info))) { - double spacesDouble = spacer->toInteger(exec); - if (exec->hadException()) { - m_state = FailedException; - return; - } - - int spaces; - if (isNaN(spacesDouble) || isInf(spacesDouble)) - spaces = 0; - else - spaces = static_cast(spacesDouble); - - if (spaces > 0) { - m_emtpySpacer = false; - int max = std::min(spaces, 10); - for (int i = 0; i < max; ++i) - m_spacer.append(' '); - } - } - m_rootIsUndefined = false; -} - -JSValue* JSONStringify::stringify(ExecState* exec, JSValue* object, StringifyState& state) -{ - JSObject* holder = static_cast(exec->lexicalInterpreter()->builtinObject()->construct(exec, List::empty())); - UString ret = stringifyValue(exec, object, jsString(""), holder); - state = m_state; - - if (m_rootIsUndefined) - return jsUndefined(); - - if (m_state == Success) - return jsString(ret); - return jsUndefined(); -} - -UString JSONStringify::quotedString(ExecState* exec, const UString& string) -{ - //Check if we already failed - if (m_state != Success) - return UString(); - - if (exec->hadException()) { - m_state = FailedException; - return UString(); - } - - const int size = string.size(); - UString ret = "\""; - - for (int i = 0; i < size; ++i) { - int start = i; - static const short unsigned blackSlashUC = '\\'; - static const short unsigned quoteUC = '\"'; - while (i < size && (string[i].uc > 0x001F && string[i].uc != blackSlashUC && string[i].uc != quoteUC)) - ++i; - ret += string.substr(start, i-start); - - if (i >= size) - break; - - switch (string[i].uc) { - case '\t': - ret += "\\t"; - break; - case '\r': - ret += "\\r"; - break; - case '\n': - ret += "\\n"; - break; - case '\f': - ret += "\\f"; - break; - case '\b': - ret += "\\b"; - break; - case '"': - ret += "\\\""; - break; - case '\\': - ret += "\\\\"; - break; - default: - static const char hexDigits[] = "0123456789abcdef"; - short unsigned ch = string[i].uc; - ret.append("\\u"); - ret.append(hexDigits[(ch >> 12) & 0xF]); - ret.append(hexDigits[(ch >> 8) & 0xF]); - ret.append(hexDigits[(ch >> 4) & 0xF]); - ret.append(hexDigits[ch & 0xF]); - break; - } - } - - ret.append('\"'); - return ret; -} - -bool JSONStringify::isWhiteListed(const Identifier& propertyName) -{ - if (m_replacerType != Array) - return true; - - return m_whitelistNames.contains(propertyName); -} - -UString JSONStringify::stringifyObject(KJS::ExecState* exec, KJS::JSValue* object, KJS::JSValue* propertyName, KJS::JSObject* /*holder*/) -{ - if (m_state != Success) - return UString(); - - // As stringifyObject is only called with object->type() == ObhectType, this can't be null - JSObject* jso = object->getObject(); - - if (jso->hasProperty(exec, exec->propertyNames().toJSON)) { - JSObject* toJSONFunc = 0; - toJSONFunc = jso->get(exec, exec->propertyNames().toJSON)->getObject(); - - if (toJSONFunc) { - m_objectStack.push_back(object); - List args; - args.append(propertyName); - JSValue* toJSONCall = toJSONFunc->call(exec, jso, args); - if (exec->hadException()) { - m_state = FailedException; - return UString(); - } - - //Check if the toJSON call returned a function - // we check it here because our stack already contains an object, - // but this is still the root object. - if (m_objectStack.size() == 1 && toJSONCall->implementsCall()) { - m_rootIsUndefined = true; - return UString(); - } - - return stringifyValue(exec, toJSONCall, propertyName, jso); - } - } - - if (jso->inherits(&BooleanInstance::info)) { - return jso->toString(exec); - } else if (jso->inherits(&NumberInstance::info)) { - double val = jso->toNumber(exec); - if (isInf(val) || isNaN(val)) // !isfinite - return UString("null"); - return UString::from(val); - } else if (jso->inherits(&StringInstance::info)) { - return quotedString(exec, jso->toString(exec)); - } else if (jso->implementsCall()) { - return UString("null"); - } else if (jso->inherits(&ArrayInstance::info)) { //stringify array object - m_objectStack.push_back(object); - PropertyNameArray names; - jso->getPropertyNames(exec, names, KJS::PropertyMap::ExcludeDontEnumProperties); - const int size = names.size(); - if (size == 0) - return UString("[]"); - - //filter names - PropertyNameArray whiteListedNames; - bool isValidIndex = false; - for (int i = 0; i < size; ++i) { - if (isWhiteListed(names[i])) { - names[i].toArrayIndex(&isValidIndex); - if (isValidIndex) - whiteListedNames.add(names[i]); - } - } - const int sizeWhitelisted = whiteListedNames.size(); - if (sizeWhitelisted == 0) - return UString("[]"); - - UString ret = "["; - for (int i = 0; i < sizeWhitelisted; ++i) { - JSValue* arrayVal = jso->get(exec, whiteListedNames[i]); - //do not render undefined, ECMA Edition 5.1r6 - 15.12.3 NOTE 2 - if (arrayVal->isUndefined()) - continue; - - if (!m_emtpySpacer) { - ret.append('\n'); - ret += m_spacer; - } - ret += stringifyValue(exec, arrayVal, propertyName, jso); - if (m_state != Success) - return UString(); - if (i != sizeWhitelisted-1) - ret.append(','); - } - - if (!m_emtpySpacer) - ret.append('\n'); - - ret.append(']'); - m_objectStack.pop_back(); - return ret; - } else { //stringify real object - m_objectStack.push_back(object); - PropertyNameArray names; - jso->getPropertyNames(exec, names, KJS::PropertyMap::ExcludeDontEnumProperties); - const int size = names.size(); - if (size == 0) - return UString("{}"); - - //filter names - PropertyNameArray whiteListedNames; - for (int i = 0; i < size; ++i) { - if (isWhiteListed(names[i])) - whiteListedNames.add(names[i]); - } - const int sizeWhitelisted = whiteListedNames.size(); - if (sizeWhitelisted == 0) - return UString("{}"); - - UString ret = "{"; - for (int i = 0; i < sizeWhitelisted; ++i) { - JSValue* objectVal = jso->get(exec, whiteListedNames[i]); - //do not render undefined, ECMA Edition 5.1r6 - 15.12.3 NOTE 2 - if (objectVal->isUndefined()) - continue; - - if (!m_emtpySpacer) { - ret.append('\n'); - ret += m_spacer; - } - ret += quotedString(exec, whiteListedNames[i].ustring()); - ret += ":"; - ret += stringifyValue(exec, objectVal, jsString(whiteListedNames[i].ustring()), jso); - if (m_state != Success) - return UString(); - if (i != sizeWhitelisted-1) - ret.append(','); - } - - if (!m_emtpySpacer) - ret.append('\n'); - - ret.append('}'); - m_objectStack.pop_back(); - return ret; - } - return UString("null"); -} - -UString JSONStringify::stringifyValue(KJS::ExecState* exec, KJS::JSValue* object, KJS::JSValue* propertyName, KJS::JSObject* holder) -{ - //Check if we already failed - if (m_state != Success) - return UString(); - - if (exec->hadException()) { - m_state = FailedException; - return UString(); - } - - if (m_objectStack.size() > StackObjectLimit) { - m_state = FailedStackLimitExceeded; - return UString(); - } - - if (!m_objectStack.empty()) { - std::vector::iterator found = std::find(m_objectStack.begin(), m_objectStack.end(), object); - if (found != m_objectStack.end()) { - m_state = FailedCyclic; - return UString(); - } - } - - if (m_replacerObject && m_replacerType == Function) { - List args; - args.append(propertyName); - args.append(object); - object = m_replacerObject->call(exec, holder, args); - if (exec->hadException()) { - m_state = FailedException; - return UString(); - } - } - - //Check if root object is a function, after replace - if (m_objectStack.empty() && object->implementsCall()) { - m_rootIsUndefined = true; - return UString(); - } - - JSType type = object->type(); - switch (type) { - case ObjectType: - return stringifyObject(exec, object, propertyName, holder); - case NumberType: { - double val = object->getNumber(); - if (isInf(val) || isNaN(val)) // !isfinite - return UString("null"); - // fall through - } - case BooleanType: - return object->toString(exec); - case StringType: - return quotedString(exec, object->toString(exec)); - break; - case UndefinedType: - // Special case: while we normally don't render undefined, - // this is not the case if our "root" object is undefined, - // or replaced to undefined. - // Hence check if root object, AFTER REPLACE, is undefined. - if (m_objectStack.empty()) { - m_rootIsUndefined = true; - return UString(); - } - // beside from root Object we should never render Undefined - ASSERT_NOT_REACHED(); - case NullType: - case UnspecifiedType: - case GetterSetterType: - default: - return UString("null"); - } - ASSERT_NOT_REACHED(); - return UString("null"); -} - -}; diff --git a/kjs/jsonstringify.h b/kjs/jsonstringify.h deleted file mode 100644 index 9415d4f1..00000000 --- a/kjs/jsonstringify.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2012 Bernd Buschinski (b.buschinski@googlemail.com) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef JSONSTRINGIFY_H -#define JSONSTRINGIFY_H - -#include "ustring.h" -#include "identifier.h" -#include "CommonIdentifiers.h" - -#include - -#include - -namespace KJS { - -class JSValue; -class ExecState; -class JSObject; - -class JSONStringify -{ -public: - enum StringifyState { - Success, - FailedCyclic, - FailedException, - FailedStackLimitExceeded - }; - - JSONStringify(ExecState* exec, JSValue* replacer, JSValue* spacer); - - JSValue* stringify(ExecState* exec, JSValue* object, StringifyState& state); - -private: - enum ReplacerType { - Invalid, - Function, - Array - }; - - UString stringifyObject(KJS::ExecState* exec, KJS::JSValue* object, KJS::JSValue* propertyName, KJS::JSObject* holder); - UString quotedString(ExecState* exec, const UString& string); - UString stringifyValue(ExecState* exec, JSValue* object, JSValue* propertyName, JSObject* holder); - - bool isWhiteListed(const Identifier& propertyName); - - StringifyState m_state; - ReplacerType m_replacerType; - JSObject* m_replacerObject; - WTF::HashSet m_whitelistNames; - UString m_spacer; - - //Object Stack for cyclic detection - std::vector m_objectStack; - - bool m_rootIsUndefined; - bool m_emtpySpacer; -}; - -} - -#endif // JSONSTRINGIFY_H diff --git a/kjs/keywords.table b/kjs/keywords.table deleted file mode 100644 index a1f1a853..00000000 --- a/kjs/keywords.table +++ /dev/null @@ -1,72 +0,0 @@ -# main keywords -@begin mainTable 41 - -# types -null NULLTOKEN -true TRUETOKEN -false FALSETOKEN - -# keywords -break BREAK -case CASE -catch CATCH -const CONSTTOKEN -default DEFAULT -finally FINALLY -for FOR -import IMPORT -instanceof INSTANCEOF -new NEW -var VAR -continue CONTINUE -function FUNCTION -return RETURN -void VOIDTOKEN -delete DELETETOKEN -if IF -this THISTOKEN -do DO -while WHILE -else ELSE -in INTOKEN -switch SWITCH -throw THROW -try TRY -typeof TYPEOF -with WITH -debugger DEBUGGER - -# reserved for future use -enum RESERVED -export RESERVED -extends RESERVED -super RESERVED - -# these words are reserved for future use in the ECMA spec, but not in WinIE -# (see http://bugs.webkit.org/show_bug.cgi?id=6179) -# abstract RESERVED -# boolean RESERVED -# byte RESERVED -# char RESERVED -# class RESERVED -# double RESERVED -# final RESERVED -# float RESERVED -# goto RESERVED -# implements RESERVED -# int RESERVED -# interface RESERVED -# long RESERVED -# native RESERVED -# package RESERVED -# private RESERVED -# protected RESERVED -# public RESERVED -# short RESERVED -# static RESERVED -# synchronized RESERVED -# throws RESERVED -# transient RESERVED -# volatile RESERVED -@end - diff --git a/kjs/kjs-devel-gdb b/kjs/kjs-devel-gdb deleted file mode 100644 index 41725379..00000000 --- a/kjs/kjs-devel-gdb +++ /dev/null @@ -1,22 +0,0 @@ -# This file defines handy gdb macros -# To use it, add this line to your ~/.gdbinit : -# source /path/to/kde/sources/kdelibs/kjs/kjs-devel-gdb - -define printucharstar - set $i=0 - while ($i<($arg1)) - p (char)(($arg0)[$i++]) - end -end -document printucharstar - Prints the contents of an UChar [] - for KJS. - Usage: 'printucharstar ' -end - -define printustring - printucharstar ($arg0).rep->dat ($arg0).rep->len -end -document printustring - Prints the contents of an UString - for KJS - Usage: 'printustring ' -end diff --git a/kjs/kjs.cpp b/kjs/kjs.cpp deleted file mode 100644 index c9c65017..00000000 --- a/kjs/kjs.cpp +++ /dev/null @@ -1,290 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* - * This file is part of the KDE libraries - * Copyright (C) 2006 Harri Porten (porten@kde.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "JSLock.h" -#include "interpreter.h" -#include "object.h" -#include "package.h" -#include "function.h" - -#include -#include -#include -#include -#include - -#if PLATFORM(WIN_OS) -# include -# include -#else -# include -#endif - -#include - -enum ExitCode { ErrorNone, - ErrorUnknownSwitch, - ErrorMissingArg, - ErrorReadFile, - ErrorEval -}; - -using std::strcmp; - -using namespace KJS; - -static void printUsage(const char *app) -{ - fprintf(stderr, - "Usage: %s\n" - " [ -h | -help | --help ]\n" - " [ -e |