From cb2627ac03e5dd5270eb1c8e4413fd41436fe310 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 5 Mar 2014 02:00:25 +0100 Subject: [PATCH] Merged branch 'devel' from https://github.com/oliver----/swig-v8 (squashed commit): commit fe10555229b2d2636e16f16a9aa8b4b6ba1f6863 Author: Oliver Buchtala Date: Wed Mar 5 01:51:29 2014 +0100 Add check to skip javascript test-suite if default interpreter is not installed. commit 0e0ac021927d72f59503db91b6a9f57b323beb8b Author: Oliver Buchtala Date: Wed Mar 5 01:50:46 2014 +0100 Activate travis matrix for different Javascript interpreters. commit 89610e984ea3732a7da7bfc6bea1ffed2039201e Author: Oliver Buchtala Date: Wed Mar 5 01:39:26 2014 +0100 Beautified Javascript module. commit b5bc87667d62fa05a31ab85ba0b7894f83d7cdce Author: Oliver Buchtala Date: Wed Mar 5 01:10:55 2014 +0100 Fix regressions. - Adapted to changes in UTL - Fixed detection of setters and getters. commit a234542543088140e4dd925b0060a93960db9eee Merge: 8c05fe3 c99417a Author: Oliver Buchtala Date: Wed Mar 5 01:09:26 2014 +0100 Merge branch 'master' into tmp Conflicts: .travis.yml Examples/Makefile.in Examples/test-suite/director_nspace.i Examples/test-suite/nspace.i Examples/test-suite/nspace_extend.i Source/Modules/lang.cxx configure.ac commit 8c05fe37afcbcd6a2fc2a7d8bbe028e6d8f59239 Author: Oliver Buchtala Date: Tue Mar 4 22:55:32 2014 +0100 Removed obsolete paragraph from Javascript documentation. commit 924f373a2f6a58c4a8d40e6f61434a6e3f6df50b Author: Oliver Buchtala Date: Tue Mar 4 22:51:19 2014 +0100 Fix pandoc filter. And add a script that helps to run pandoc with appropriate command line flags. commit 6b82dff8f35d9ca743670a6131a87d493514c6b6 Author: Oliver Buchtala Date: Tue Mar 4 22:50:23 2014 +0100 Minor tweaks in Javascript documentation. commit 1a7e12911ac96e8b788686076f35771ac248220d Author: Oliver Buchtala Date: Tue Mar 4 12:00:13 2014 +0100 Adding a chapter about Javascript tests and examples. commit a9b8b85c1c1b2bfe5b9b389e6f9406258371d512 Author: Oliver Buchtala Date: Tue Mar 4 11:00:26 2014 +0100 Minor change in Javascript configuration. commit dbd61e40e1c92aa02c3ce5170534687f7ae8d42f Author: Oliver Buchtala Date: Tue Mar 4 10:41:35 2014 +0100 Fix issues that were observed with newer JavascriptCore. commit 70385842df0c68c4e7e7eeb4531f703330edb831 Author: Oliver Buchtala Date: Fri Feb 28 10:40:41 2014 +0100 Add missing copy ctor for Javascript Code Template class. commit b20b0f4e4b1626030c4155f22313af3ee0fd4e00 Author: Oliver Buchtala Date: Thu Feb 27 01:02:06 2014 +0100 Removed CMake. Started a separate project which acts as a CMake shell around SWIG. commit 7e015e4acf3cb6644f2002d4457a589f1d76f69d Author: Oliver Buchtala Date: Wed Feb 26 23:26:19 2014 +0100 Fix regression in Javascript configuration. commit 348cb2026e2edad29003281ed9b0a2f43c10aa54 Author: Oliver Buchtala Date: Wed Feb 26 22:56:31 2014 +0100 Fix regressions in configuration of some Javascript examples. commit 94869c922861adc007e1cfffde279f2c4e554311 Author: Oliver Buchtala Date: Wed Feb 26 22:47:29 2014 +0100 More gitignores filtering Javascript related files. commit 424e3f47123f8a7746d12d02204b896e55b8444d Author: Oliver Buchtala Date: Wed Feb 26 22:46:24 2014 +0100 Fix custom javascript interpreter configuration for OSX. commit 15f12d9b59b9e8522853f010f9d443164774a6a6 Author: Oliver Buchtala Date: Wed Feb 26 22:44:37 2014 +0100 Make examples work with node.js and the custom interpreter. commit b216a739c45cfb595a5b70da7e811b6130148a63 Author: Oliver Buchtala Date: Wed Feb 26 20:51:38 2014 +0100 Introduced an extra Makefile for the custom javascript interpreter. commit bf1606c0f9261dcb4ae8d5c24aebc987a67e7510 Author: Oliver Buchtala Date: Wed Feb 26 11:10:09 2014 +0100 Fix travis configuration. commit 16a702c0aac717462b1eb94fc4640446943d9396 Author: Oliver Buchtala Date: Wed Feb 26 10:48:38 2014 +0100 Added a comment. commit e62c6126e9d6645eaff2b96d7847d4a8c681bb84 Author: Oliver Buchtala Date: Wed Feb 26 10:47:48 2014 +0100 Fix regressions in Javascript example configuration. commit 15550dab450f003c0b42d6a3353b137435793999 Author: Oliver Buchtala Date: Tue Feb 25 20:16:15 2014 +0100 Fix issue with strange constants under OSX. Receiving strange constant nodes before the real tree under OSX 10.8. Not so under Ubuntu 12.04. commit 84ba91dc63d817376486cecfd7188f56303e6e3b Author: Oliver Buchtala Date: Thu Feb 20 12:38:53 2014 +0100 Some fixes in example section of Javascript documentation. commit 1ffacaab5b7635da623de6c49c22684a1c46d549 Author: Oliver Buchtala Date: Thu Feb 20 12:30:57 2014 +0100 Add note about '-node' command line flag for Node.js code generation. commit 462674ea11fc227501a485a878efd1ae9e111126 Author: Oliver Buchtala Date: Thu Feb 20 12:28:06 2014 +0100 Added examples to Javascript module documentation. commit 3f22a3d639a2884b8cd50d57fc22b6df49a85cdf Author: Oliver Buchtala Date: Thu Feb 20 11:37:40 2014 +0100 Simplification in common javascript example Makefile. commit 8e65414a764f390e0db4f8ded0031ecdef16d896 Author: Oliver Buchtala Date: Thu Feb 20 11:37:15 2014 +0100 Add an extra argument for enabling nodejs support. This is essentially using the v8 emitter plus setting a #define. commit 7c1f66c29e4d0fd72e656b4bd27b2010c053b2c7 Author: Oliver Buchtala Date: Thu Feb 20 11:15:46 2014 +0100 Add more notes about how to install node. commit 48e7df8eb2f7cb87e57dd7a890fbaa9ec8598ac7 Author: Oliver Buchtala Date: Thu Feb 20 11:15:18 2014 +0100 Better error message when no Javascript emitter is specified. commit fd0e75843d3ec7816c85a5d1ab84bd9319c9b27e Author: Oliver Buchtala Date: Thu Feb 20 11:14:48 2014 +0100 Deactivated broken JS examples. commit 77ead7017caca778eb3143fa487856ee8dcd4b7b Author: Oliver Buchtala Date: Thu Feb 20 11:13:57 2014 +0100 Refactored configuration for javascript examples. commit 8df34d54d0957552a53fe5f1e6598849c4ac9f81 Author: Oliver Buchtala Date: Fri Feb 14 13:21:52 2014 +0100 Beginning to document v8 integration. commit 05146e2aed5b8e9df390acdd12b6e5cda2ed2e00 Author: Oliver Buchtala Date: Fri Feb 14 13:04:21 2014 +0100 Documented extending Node.js and Webkit's Javascript engine. commit 68472802721264ec8adee4f80ce7576eb3dd1a3e Author: Oliver Buchtala Date: Fri Feb 14 09:02:37 2014 +0100 Pandoc filter detects shell blocks when not explicitely given. Considered as shell if the first character is '$', as in $ swig -javascript Alternatively you can specify the class explicitely: ```shell swig -javascript ``` commit 1fca61c59ad7a825725b76d394de688774f296e8 Author: Oliver Buchtala Date: Fri Feb 14 09:00:04 2014 +0100 Conitnued documenting the Javascript module. commit 915b7094331bf99f5cf6ed31d5747d10ae1bebb9 Author: Oliver Buchtala Date: Fri Feb 14 00:02:05 2014 +0100 Not a real change. Using a macro to reset JSEmitterStates for the sake of readability. commit 8148b017f879f272616c8bb36b6bcd60232f9c4f Author: Oliver Buchtala Date: Fri Feb 14 00:01:15 2014 +0100 Add a pandoc filter to create compatible html. commit e829ea601f573b96efdf0e1ed602d90a7d39e29f Author: Oliver Buchtala Date: Fri Feb 14 00:00:37 2014 +0100 Add Javascript to chapters. commit fa8b350cd67a8850a866ee52250a6955ef17699f Author: Oliver Buchtala Date: Fri Feb 14 00:00:12 2014 +0100 More Javascript module documentation. commit 02c55fc52fb30da3cec7188b64d456c7dcf8fc9f Author: Oliver Buchtala Date: Thu Feb 13 21:18:06 2014 +0100 Next iteration on creating a documentation for the Javascript module. commit 1e34ecdc31c82d30141097f7744617361ebb748c Author: Oliver Buchtala Date: Thu Feb 13 19:25:16 2014 +0100 Next iteration on creating a documentation for the Javascript module. commit 41ec3fb67e65f3448e52c0eb7372d0331bc7b6ca Author: Oliver Buchtala Date: Fri Sep 27 02:54:42 2013 +0200 Travis configuration for Javascript branch. commit 48af60d82904f1eef37b9beac03f8412947e883e Author: Oliver Buchtala Date: Fri Sep 27 02:46:11 2013 +0200 Javascript examples. commit ecf9f96079067386a5f8bc83fadd4ac9e03f551c Author: Oliver Buchtala Date: Fri Sep 27 02:45:22 2013 +0200 Javascript documentation. commit 00053169cd5d69c42b1b1bbf58336776e1820c97 Author: Oliver Buchtala Date: Fri Sep 27 02:44:53 2013 +0200 CMake configuration. commit 6a366cc050f25b3d358d8f4d85e37011ada82726 Author: Oliver Buchtala Date: Fri Sep 27 03:23:37 2013 +0200 Fix regression. commit 6dcbbf07db310a78457d1c00e84a60761502ea5d Merge: 4492a3d c2d3da2 Author: Oliver Buchtala Date: Fri Sep 27 02:29:02 2013 +0200 Conflicts: .gitignore .project .travis.yml Examples/Makefile.in Examples/test-suite/director_nspace.i commit c2d3da2eeca2d1923d9c69dda70a8ce2f1b2cf1e Author: Oliver Buchtala Date: Thu Sep 26 05:14:34 2013 +0200 Fix test configuration. commit 582bd297690605d98ae758d164cc48e299ae34b3 Author: Oliver Buchtala Date: Thu Sep 26 04:55:34 2013 +0200 Trying to install former working version of nodejs. commit 7adf93ef0f86babb564b1458228f5b4666f414dc Author: Oliver Buchtala Date: Thu Sep 26 04:13:32 2013 +0200 Fix test configuration for nodejs. commit 335d926c449d22821eb916d0f862062b925c2ca6 Author: Oliver Buchtala Date: Tue Sep 24 03:56:19 2013 +0200 Add stub std_deque.i files. commit 51b36d1a1f0c9efe3ef3d25c8bd8c3dfecfa4a52 Author: Oliver Buchtala Date: Tue Sep 24 03:55:51 2013 +0200 Add non pretty printing function to Templates. commit dc62a69775f7eff6a11e7ca7f162ae960b53e671 Author: Oliver Buchtala Date: Tue Sep 24 03:55:10 2013 +0200 Fix bug with typedefd function pointers. commit 2efe63ebb2c87e2e8cde445ffdf964f6cc38869e Author: Oliver Buchtala Date: Tue Sep 24 01:50:33 2013 +0200 Add some test runners. commit b9ecf75f17c05bc58d6e6347877b5aedd92d2d28 Author: Oliver Buchtala Date: Tue Sep 24 01:50:13 2013 +0200 Fix emitter for member pointer constants. However, I am not happy with the constant emitter in general. Should not return dynamic values but register constant wrappers statically. commit 8bf966a65c2120d2bf050857587e7e7bd7cafd58 Author: Oliver Buchtala Date: Tue Sep 24 01:47:13 2013 +0200 Fix %nspace support and activated relevant tests. commit d34a6da08c1dd59ad14731f4ea6a7e8b3b6dd8b7 Author: Oliver Buchtala Date: Tue Sep 17 01:53:22 2013 +0200 Disable warnings for some v8 test-cases. commit b3c198ccee3dad34f75c4617900e53e1770f0ee9 Author: Oliver Buchtala Date: Mon Sep 16 22:28:14 2013 +0200 Fix regression. commit b99e8613ad7103bd99d7f6c7e24b774c73467201 Author: Oliver Buchtala Date: Mon Sep 16 21:56:52 2013 +0200 Bugfix in argument marshalling. commit dd4ed7f3d6bc6a13c271ac7ffb629115414113ec Author: Oliver Buchtala Date: Mon Sep 16 11:46:52 2013 +0200 Disable testcase 'typemap_variables' for v8. It uses output typemaps that are not compatible with the v8 API. commit 0528fd3ac3f6205ce642fa6997908df160030608 Author: Oliver Buchtala Date: Mon Sep 16 11:46:00 2013 +0200 Bugfix for Javascript generator. commit 147cec70f1226dead5d93afd711b99bc9e81827f Author: Oliver Buchtala Date: Mon Sep 16 04:54:57 2013 +0200 Replace $symname in generated function wrappers. commit eb9523b5caef732bbd1b259850e16dc8a9e11564 Author: Oliver Buchtala Date: Mon Sep 16 04:12:55 2013 +0200 Add missing macros. commit 3e28d1e28f81688184cf2c362fa01b7efaaad790 Author: Oliver Buchtala Date: Mon Sep 16 04:12:42 2013 +0200 Let v8 generated code include stdlib.h commit b6426bde2501e6304193644ddc6e8c933db4412e Author: Oliver Buchtala Date: Mon Sep 16 04:12:06 2013 +0200 Add cdata.i typemaps. commit 1f07195812f79a20bb1f37178e596dd0bab8ef2e Author: Oliver Buchtala Date: Mon Sep 16 03:53:00 2013 +0200 Rearrange generation of init block to have custom init code within the initializer body. commit 80ce36c445c704a105a70d6820baefb74a7cd0ec Author: Oliver Buchtala Date: Mon Sep 16 02:27:51 2013 +0200 Make JSC inheritance definition more robust. commit 973042302b017111b06305bedafe47798fcfad86 Author: Oliver Buchtala Date: Mon Sep 16 01:57:55 2013 +0200 Removed dead code. commit bf416876ddf24249f75eff9854e551d789dfab42 Author: Oliver Buchtala Date: Mon Sep 16 01:33:19 2013 +0200 Bugfix for JSC %typemap(out) std::string&. commit b7f827e42ce3073d44f163877f7712782740d1bf Author: Oliver Buchtala Date: Mon Sep 16 01:23:03 2013 +0200 Fix typemap declarations for (unsigned) long long. commit 68eff3e81efd46692206dcf2ea762931f94c63ce Merge: bb7bd50 018847b Author: Oliver Buchtala Date: Mon Sep 16 00:55:57 2013 +0200 Merge branch 'devel' of github.com:oliver----/swig-v8 into devel commit bb7bd50eabdf5cc2f07640227713ef75dc1c8fce Author: Oliver Buchtala Date: Mon Sep 16 00:55:43 2013 +0200 Add support for IN/OUTPUT typemaps. commit 018847b0002a445a1e7110e16dd108aac34564a9 Merge: acfed20 325b544 Author: Oliver Buchtala Date: Sun Sep 15 06:00:06 2013 -0700 Merge pull request #28 from whoozle/devel fixed newer v8 compilation commit 325b5445d67ccf60855aac970ecb6ba913e2b32b Author: Vladimir Menshakov Date: Sat Sep 14 16:19:47 2013 +0400 removed Clear before Dispose from newer v8 code, consider the following code: template void Persistent::Dispose() { if (this->IsEmpty()) return; //Clear will trigger this V8::DisposeGlobal(reinterpret_cast(this->val_)); ... } commit 89fd7ed9c1b1c1e0a1a5344018ab9d0a5ce711b0 Author: Vladimir Menshakov Date: Sat Sep 14 16:17:21 2013 +0400 fixed newer v8 compilation commit 477b2393b10f664696b8cf1e49c2b98deab39d79 Author: Oliver Buchtala Date: Thu Sep 12 05:26:22 2013 +0200 Add stub 'typemaps.i' files. commit acfed20eba1c72571f65048c62653bf339d5564b Author: Oliver Buchtala Date: Thu Sep 12 05:10:23 2013 +0200 Bugfix Javascript generator: valid name for dispatcher functions. commit 1a04e488bc5e17de266181f6b39e00e114f9ae8a Author: Oliver Buchtala Date: Thu Sep 12 05:40:59 2013 +0300 Fix Javascript generator for smartpointeraccessed variables. commit 8bf95c4356b61da9f510245310a0bd3c1fafe36f Author: Oliver Buchtala Date: Thu Sep 12 05:09:35 2013 +0300 Bugfix for Javascript generator: avoid duplicate action code generation. commit 09a210e037c8d5ca46ee4edc4c904f11b04cb893 Author: Oliver Buchtala Date: Thu Sep 12 04:09:21 2013 +0300 Bugfix in Javascript generator: detect member setter/getters correctly. commit c53e3e4dab9b6ab61e63880476721c61ec9ff940 Author: Oliver Buchtala Date: Tue Sep 10 14:45:33 2013 +0300 Fix configuration for nodejs based tests. - use $(SWIGOPT) - less verbose commit dd84e6f9e0b67737ca1031cd6bbb4dcc4eb84340 Author: Oliver Buchtala Date: Tue Sep 10 14:16:36 2013 +0300 Some fixes and cleanup in Javascript generator. - v8 generator uses the correct mangled name for class templates - removed symbols for template variables in favor of using the string literals directly, as it is easier to understand when debugging. commit 001f38c6a9ebd19dee26196e9b0ee2421b8cbe5f Author: Oliver Buchtala Date: Tue Sep 10 13:29:16 2013 +0300 Fix settings for building nodejs tests. Removed the `-node` command line flag. Instead one has to use `-v8 -DBUILDING_NODE_EXTENSION=1`. commit be35d94fdb8b274b443e2467d8a1b6d2dd0723c6 Author: Oliver Buchtala Date: Tue Sep 10 11:53:12 2013 +0300 Add support for PackedData to Javascript generator. commit e5ad9cdc0527b21cbabaad02a22efd8418459d99 Author: Oliver Buchtala Date: Mon Sep 9 22:26:30 2013 +0300 Added two more Javascript tests. - `abstract_inherit` - `char_strings` commit 571c516a0b096564b070350c9b90255db3422768 Author: Oliver Buchtala Date: Mon Sep 9 22:25:51 2013 +0300 Some fixes for the Javascript generator. - added missing `exception.i` - added missing generator block `wrappers` for v8 commit 3c5946d998f2bcecc88f04de8df7a6f3da292b32 Author: Oliver Buchtala Date: Mon Sep 9 17:38:44 2013 +0300 Redefined set of Javascript smoke tests. commit 407d8ef5acff62578c701da74cfdf9a752baffd1 Author: Oliver Buchtala Date: Mon Sep 9 17:34:53 2013 +0300 Clean up in `javascripttypemaps.swg`. - following the same layout/order as pytypemaps - added typemaps for `long long` and `unsigned long long`, which are only copies of those for `long` and `unsigned long` and hence are just experimental. commit fc4d9b665c5839df06501e736163bfeadb7503d1 Author: Oliver Buchtala Date: Mon Sep 9 16:28:29 2013 +0300 Fix v8 generator to use a non clashing name for built-in 'equals' method. commit b6c9c97b96bc3039ccb291d76a64d009fc81fbb7 Author: Oliver Buchtala Date: Mon Sep 9 15:05:11 2013 +0300 Fix Javascript generator to use %renamed variable names. commit 108143951da3859e0c056780706b6841231febb3 Author: Oliver Buchtala Date: Mon Sep 9 13:55:08 2013 +0300 Activate Javascript test-cases `rename_simple` and `rename_scope`. These reveal current deficiencies in the Javascript generator with `%rename`ing. commit 64da1173ddf8bd1fe04800e2afbe0f9c5d2dc818 Author: Oliver Buchtala Date: Mon Sep 9 13:23:47 2013 +0300 Activate Javascript testcases `rename1-4`. commit 1438d0cfb45f0f1b740eb8d1d366f694ba99d0b6 Author: Oliver Buchtala Date: Mon Sep 9 13:17:38 2013 +0300 Add `infinity` test-case to list of smoke tests. commit e01e337d752dbbfc58a06b87fe1169d3f6ada76f Author: Eric Wing Date: Thu Sep 5 14:50:15 2013 -0700 Added unit test using C99 INFINITY. This test actually tests a float conversion bug where converting to float imposed overflow checking which should not be there and causes this program to error out. This was seen originally in Javascript, but it turns out Python has the same bug. Lua does not have this bug. Other generators have not been tested. This test also tests the rename feature. The Javascript generator was not renaming the variable correctly. commit 1729fac3605d6649919ee508bcf8b03f904886f4 Author: Oliver Buchtala Date: Mon Sep 9 12:46:07 2013 +0300 Bug-fix for static variables as proposed by Kota Iguchi. Fixes #20. commit 8408e9b19395f9f7ffca586de80012473b6c3a4e Merge: 6b35c2d b49da78 Author: Oliver Buchtala Date: Fri Sep 6 19:50:51 2013 -0700 Merge pull request #19 from whoozle/devel fixed deprecation warnings for v8-3.21 commit 6b35c2d419eac4f71780a939254e8a459c075849 Author: Oliver Buchtala Date: Fri Sep 6 16:26:02 2013 +0300 Let Travis test all three targets. - nodejs: 0.10.12 - libwebgitgtk 1.0 - libv8 3.7.12 We should soon switch to a new v8 version or add an extra runner. commit 0facc7ecf9f48a98a6f66c557917657d3adb2d36 Author: Oliver Buchtala Date: Fri Sep 6 15:59:43 2013 +0300 Allow to run the test suite with our list of smoke tests. The javascript generator can not deal with the whole test-suite. Moreover, during development I want to have immediate feedback using a set of smoke tests. commit 492d3010ff33c1b6af9bca9472ad08e0330ffb42 Author: Oliver Buchtala Date: Fri Sep 6 01:40:23 2013 +0300 Javascript V8 test-cases always create cpp wrappers. commit 26b5acbbe850c3494f4b79c62f678a92f219f61a Author: Oliver Buchtala Date: Fri Sep 6 00:42:56 2013 +0300 Test-suite Makefile now supports testing for all three Javascript variants. - node.js - custom JavascriptCore interpreter - custom V8 interpreter commit 962207e0f33a322af3f9303f1e15ce9e28eb7281 Author: Oliver Buchtala Date: Fri Sep 6 00:41:18 2013 +0300 Rewritten Javascript autoconfiguration. commit 29ccb270afa761d57d6a6728ca49d92fe9d35bc0 Author: Oliver Buchtala Date: Fri Sep 6 00:40:29 2013 +0300 Renamed object provided to JS initializers. JSC initializer create a new module object. V8 initializer fill a provided 'exports' object. commit 4794fa1884215982384535d25bfcc8e37b496629 Author: Oliver Buchtala Date: Fri Sep 6 00:38:07 2013 +0300 Refactored custom javascript engines to support primitive 'require' statements. commit b49da78b0a6ef1d6e9f624c60710f79e709fca2e Author: Vladimir Menshakov Date: Thu Sep 5 19:50:15 2013 +0400 fixed deprecation warnings for v8-3.21 commit 740da9c733e505d52a918742bc0ac559d7e4ccf6 Merge: 8b0ee54 2a39abe Author: Oliver Buchtala Date: Wed Sep 4 09:18:42 2013 -0700 Merge pull request #17 from whoozle/devel fixed v8-3.20+ compilation and deprecation warnings. commit 2a39abebb684e7e5a2bf878b9d74c54de415bae1 Author: Vladimir Menshakov Date: Wed Sep 4 20:10:42 2013 +0400 moved common swig v8 definitions in javascriptruntime.swg, fixed obsoleted api calls commit 8b0ee5491a9f19a57fef83433d755cc0a9e40c40 Author: Oliver Buchtala Date: Wed Sep 4 18:04:40 2013 +0200 Added missing template configuration files for nodejs based tests. commit 315287b6563f4730468e4b882e569fa72893ba71 Author: Oliver Buchtala Date: Wed Sep 4 17:55:44 2013 +0200 Put the SWIG_V8_VERSION macro into "runtime" block. commit 4068f31c6b66f08c24f760f46da5b4a4d7b6f11b Author: Oliver Buchtala Date: Wed Sep 4 17:54:35 2013 +0200 Use a diffent name for the V8_VERSION provided via command line. commit b7db2a84c907b96e3371b8c8301b32421a10fef5 Author: Vladimir Menshakov Date: Wed Sep 4 19:33:48 2013 +0400 fixed return values and added missing newer v8 dtor wrapper. commit fec11a8def1e1bea9626fab8f17d05c253178bec Author: Oliver Buchtala Date: Wed Sep 4 13:07:07 2013 +0200 Allow exceptions in generated example/test node extensions. commit 54dd7e96c0f9623649947f8f6237a8f1be1ac770 Author: Oliver Buchtala Date: Wed Sep 4 12:47:24 2013 +0200 Fix cleanup configuration for javascript test-suite. commit 8778146b4b45d5033bb65701ab881b1edcc51b9b Author: Oliver Buchtala Date: Wed Sep 4 12:10:08 2013 +0200 Relax type check in SWIG_AsVal_int. The array_member test-case revealed that integers come in as `Numbers`. commit 0e78fc0ad7a962f2d3687c1fb32294e174e68dd5 Author: Oliver Buchtala Date: Tue Sep 3 18:50:46 2013 +0200 Fixing travis configuration. commit da48f3307f4ac358ca2d325f8c04b9a5afb90323 Author: Oliver Buchtala Date: Tue Sep 3 18:24:19 2013 +0200 Remove javascript autoconf detection (Temporarily). I want to cut it down to a minimum having only nodejs. We will activate the others (native JSC and V8) later. commit 262aca8ead684a53c4f2029db5f32a3505e348b3 Author: Oliver Buchtala Date: Tue Sep 3 17:16:40 2013 +0200 Fix in travis config. commit 83e6aa85b6e7f8097eb02179bb8f3faaeb06037b Author: Oliver Buchtala Date: Tue Sep 3 17:13:38 2013 +0200 Not a real change. commit 0aabfeb231d74ac997b28e816987fb033d6b2fd9 Author: Oliver Buchtala Date: Tue Sep 3 17:07:49 2013 +0200 Slight modification to travis config. commit fa27ff29769031cef7dbb3b1951ec6adde09b0cf Author: Oliver Buchtala Date: Tue Sep 3 17:03:08 2013 +0200 Add a travis configuration (experimental). commit 8bbd92883101584583e3139e442bc418100b4a45 Author: Oliver Buchtala Date: Tue Sep 3 16:57:40 2013 +0200 Make javascript test-suite work with nodejs. commit cef82c720f4875b9ddf53667e5396d3b80c7eefd Author: Oliver Buchtala Date: Tue Sep 3 14:41:35 2013 +0200 Replace old style v8 version switches. commit d3074ba4c1cc46bfebd3b09671f92965cab533ed Author: Oliver Buchtala Date: Tue Sep 3 14:02:52 2013 +0200 Fix error in SWIG_V8_GetInstancePtr. commit f70c0e16f292e1fab77fb9ae63f56e86c3ae90c4 Author: Kota Iguchi Date: Wed Aug 28 15:08:50 2013 +0900 Add "equals" to compare between pointers Add "getCPtr" to retrieve pointer value commit a29975c69a0bf0628d740232cab722387588eed2 Author: Kota Iguchi Date: Fri Aug 16 16:08:47 2013 +0900 Typemap for natural support for arrays commit 78a3cc9e3e4bdf6d55cb52ab8812c4127e6ad475 Author: Kota Iguchi Date: Fri Aug 16 10:15:37 2013 +0900 Added the finalize callback (JSObjectFinalizeCallback) commit 14a137adca1a101595e103893d7143aa43525791 Author: Oliver Buchtala Date: Tue Sep 3 06:27:14 2013 +0200 Fix regression. commit 5da54ca435741f74a7212d7034b11b9fa17046d7 Author: Oliver Buchtala Date: Tue Sep 3 06:26:54 2013 +0200 Convert javascript examples to nodejs. commit dbf2b1fe945714641322c2f758bde63140db37fa Author: Oliver Buchtala Date: Tue Sep 3 05:46:19 2013 +0200 Ignore javascript Example build files. commit 11e2179dd318d49665fe665022a2a5ea30c59392 Author: Oliver Buchtala Date: Tue Sep 3 05:40:22 2013 +0200 First example that addresses node.js as primary execution environment. commit a48438c562b3f1601e5bbc9cedcf9f124af97975 Author: Oliver Buchtala Date: Tue Sep 3 05:39:37 2013 +0200 Better v8 version handling. You should start to specify a version on command line, e.g., swig -javascript -v8 -DSWIG_V8_VERSION=0x032007 commit 5228c0eeab0e96930d18e1b0b0d732636adc882f Author: Oliver Buchtala Date: Tue Sep 3 05:36:41 2013 +0200 Add a dedicated mode for creating node modules. commit 5aba4c7ea657f086519acb950e19c416d808b74a Author: Oliver Buchtala Date: Tue Sep 3 05:35:03 2013 +0200 Starting from scratch with Examples configuration. commit cb5f4dc47eeac71a0c5f39618027382567cb53d4 Author: Vladimir Menshakov Date: Thu Aug 15 14:33:00 2013 +0400 ported to newer, more efficient v8 api commit c291675ccef1b058ea5e4c642f0f5b2e72b9e006 Merge: 046ca76 0732592 Author: Jason Turner Date: Fri Aug 9 14:09:43 2013 -0600 Merge branch 'devel' of https://github.com/ewmailing/swig-v8 into devel commit 0732592ed99759afab2f05e6be1723659e955464 Author: Kota Iguchi Date: Wed Aug 7 18:10:53 2013 -0700 Patch to support argout typemap for your swig-v8 branch. commit 32f9cce600452a6210b0eebfd1d598219b90d7bc Merge: 4503c53 306b265 Author: Oliver Buchtala Date: Sat Aug 31 03:47:43 2013 +0200 Merged whoozle branch with ewmailing branch. Conflicts: Lib/javascript/v8/javascriptcode.swg commit 306b265af99613948481a60d55fa902ae6a84c17 Merge: 65a0be8 b511e33 Author: Oliver Buchtala Date: Sat Aug 31 03:47:08 2013 +0200 Merge branch 'devel' of git://github.com/oliver----/swig-v8 into devel Conflicts: Lib/javascript/v8/javascriptcode.swg commit 4503c5390304202275a849eaa8473985adf86f02 Author: Eric Wing Date: Wed Aug 7 15:12:36 2013 -0700 Since this code uses assert, #include is needed. commit 65a0be8876959dd9a79bc3d7290af15ab646202d Author: Eric Wing Date: Thu Jul 11 20:04:01 2013 -0700 v8: variable name bug fix in my template modifications for pointers to structs. commit f8feeacb68593063914c58c60e408d8515295b7f Author: Eric Wing Date: Thu Jul 11 19:11:56 2013 -0700 v8: Removed the extern "C" around the initialize function because it makes no sense since it requires a C++ templates object as a parameter. commit ed729f7d3adaf675bbf7f1f800cdcbe17287d987 Author: Eric Wing Date: Thu Jul 11 19:09:17 2013 -0700 This brings over the memory leak fixes for pointers to structs with a %extend destructor from my Neha fork. The generator was not generating and connecting the needed code for the requested destructor to the v8 dtor finalizer. I did not realize this branch has some JavaScriptCore stuff in it too. Unfortunately, it seems to have its own unique problems (like creating C++ files when it should be generating C files). My changes are targeted for v8, and I don't think my JSCore changes fully reach in this JSCore implementation so more work would need to be done to get this branch working. I think my Neha fork is in better shape at the moment. Also, I did port over the 'NULL out the dtor function pointer' in the %nodefaultdtor fix to v8. Usage case: struct MyData { %extend { ~MyData() { FreeData($self); } } }; %newobject CreateData; struct MyData* CreateData(void); %delobject FreeData; void FreeData(struct MyData* the_data); where the use case is something like: var my_data = example.CreateData(); my_data = null; commit 046ca7686b5605fc7e729d5a4afbe28f2d2c6807 Author: Jason Turner Date: Sat Jul 27 12:35:36 2013 -0600 Adjust for v8::Persistent API which was deprecated @ 3.19.16 https://groups.google.com/forum/#!topic/v8-users/oBE_DTpRC08 commit d5df0bb72101d057b6d59cf7d683263e65288884 Author: Eric Wing Date: Wed Aug 7 15:11:49 2013 -0700 Added #if defined guard for V8_3_14 to allow users from the original SWIG v8 implementation to continue using the new changes. It works similarly to the BUILDING_NODE_EXTENSION in all but two places. This define must be explicitly set by users because there is no way to auto detect. (Perhaps a command line switch can be added to generate this on request?) commit cf9b7e89ac52badd89acc2ba2bb5072055837ce0 Author: Jason Turner Date: Sat Jul 27 09:50:03 2013 -0600 Get memory updates working with Node.js again. commit 3af7d543cb52623f962a48f91a129181af29901a Author: Vladimir Menshakov Date: Wed Aug 7 16:11:59 2013 +0400 fixed crash while instantiating generic-wrapped objects from external code, please review commit 9e74bdb97e049511be20322aa85884c1249d3606 Author: Vladimir Menshakov Date: Tue Aug 6 15:50:43 2013 +0400 added virtual dtor to V8ErrorHandler commit 868803ce2ad158326cb70d2e5667baf4014df31a Author: Oliver Buchtala Date: Sat Aug 31 03:44:44 2013 +0200 Merge replayed as done by c778d16abed35829b103d607a53c8f88e3b2d595 commit a190288e663e207375a42bfb7476ab1ca336f2af Author: Vladimir Menshakov Date: Thu Jul 18 21:03:56 2013 +0400 fixed overloaded functions multiplication commit 45bfc97ef437eb919bec2579dd39e3bbb0fd1c12 Author: Vladimir Menshakov Date: Thu Jul 18 19:15:38 2013 +0400 converted function templates to the persistent ones (fixed crash on large wrappers) commit 9b6a4870dd96656f0e9ec731e9b2dea856ae4939 Author: Vladimir Menshakov Date: Thu Jul 18 18:53:15 2013 +0400 added missing scope.Close() commit fe25e2dfc8fd4fa29702685684337444f5948cb1 Author: Vladimir Menshakov Date: Thu Jul 18 18:42:03 2013 +0400 replaced GetInternalField with GetAlignedPointer (it does not work with SetAlignedPointer, btw) commit 9111773400ba10b6b98fea7996d3dcbf53b97ecf Author: Vladimir Menshakov Date: Thu Jul 11 16:41:40 2013 +0400 generate v8-3.19.x compatible code commit 26a4f849485d03fe57ba47435f11953b019ae515 Author: Vladimir Menshakov Date: Thu Jul 11 15:06:08 2013 +0400 added missing javascript/v8 dir commit b511e33121c5167a9a206ddc2f3417f56d39afa9 Author: Oliver Buchtala Date: Fri May 3 18:23:36 2013 +0200 Remove std::iostream relicts from generated v8 wrapper code. commit d3aa8e06fb3d3eb49c05975108acf2c84b716774 Author: Oliver Buchtala Date: Wed Jan 30 18:50:03 2013 +0100 Bugfix: treat persistent V8 references correctly. V8 is somewhat inconvenient regarding invoke of destructors for C++ proxies. commit 827cef75a35ff9ff84c76c46abf483672c4dbcc4 Author: Oliver Buchtala Date: Fri Jan 25 17:09:13 2013 +0100 Add an ifndef-guard to resolve a warning when building nodejs extension. commit 31feff8586c880bf91f7b6bde61b9dbdc6be57c9 Author: Oliver Buchtala Date: Fri Jan 25 17:03:23 2013 +0100 Add missing return statement in v8 code template. commit 5da4f5794c45a09f3e8b641568d38ff650403752 Author: Oliver Buchtala Date: Fri Jan 25 14:20:51 2013 +0100 Add preprocessor define for building node.js extensions. commit 65560a8664f19aaa03392bba33a4ac435867fa35 Author: Oliver Buchtala Date: Fri Jan 25 14:07:06 2013 +0100 Fix v8 string conversion in case of null arguments. commit e3da21ee442913c5554203bf8699cab62a69ed15 Author: Oliver Buchtala Date: Tue Jan 22 19:28:44 2013 +0100 Add more ignores. commit a4036deda841a9894e7228c4fb80cebe86ff8efc Author: Oliver Buchtala Date: Tue Jan 22 19:26:29 2013 +0100 Add pre-processor defines to detect the javascript engine. commit b0cb875ac1a1899c8752b7df33b7c70ab5ff4b3c Merge: 8b10c47 2252524 Author: Oliver Buchtala Date: Tue Jan 22 19:24:12 2013 +0100 Merge branch 'devel' of github.com:oliver----/swig-v8 into devel commit 8b10c47ed80a42c4f47b339820333132188659c0 Author: Oliver Buchtala Date: Tue Jan 22 19:23:11 2013 +0100 Fix regression: add an include for Node.js header. commit 22525249f26e36d6603c7ee7bce58cefd8ff611f Author: Oliver Buchtala Date: Tue Jan 22 15:54:08 2013 +0100 Resolve compile warnings in v8_shell. commit 8eb9aa9e73fca795fbd6a716ba830366a4919405 Author: Oliver Buchtala Date: Tue Jan 22 15:53:39 2013 +0100 Add gitignore file. commit 04c0803f736ef8bd264d7a099a88b4258461547f Author: Oliver Buchtala Date: Fri Jan 18 15:35:45 2013 +0100 Fixes in configuration to detect JavascriptCore on MacOSX correctly. commit 4ac7065c3ba1b73cdf081eaae45ccc28853a4770 Author: Oliver Buchtala Date: Fri Jan 18 15:34:11 2013 +0100 Bugfix: in javascript interpreter load extensions on MacOSX correctly. commit 04cdde05636f22d8504389a3a92a5c39885f04ad Author: Oliver Buchtala Date: Fri Jan 18 15:33:04 2013 +0100 Add test to check javascript unicode strings. commit caa92740d3241e6aa34ee38a6dbcf846d72c3275 Author: Oliver Buchtala Date: Wed Jan 9 00:33:09 2013 +0100 Add an option to deactivate creation of an extra module object in javascript. This is useful, if the extension host calls the initializer with custom local variables. E.g., this is the case with node.js. commit 213c107b7f4762bf58f7d6a7c7f8b463e2068206 Author: Oliver Buchtala Date: Tue Jan 8 22:37:16 2013 +0100 Add a swig macro to register node.js extensions. commit 4fea3a403e5856565d51a5bf0b0a4cec4c03a583 Author: Oliver Buchtala Date: Tue Jan 8 22:36:32 2013 +0100 Generate an extra file part after the initializer for v8 modules. E.g., this is useful for creating node.js modules. commit 31844ac72adfd82c310c239434db579ba7f6670a Author: Oliver Buchtala Date: Tue Jan 8 22:34:38 2013 +0100 Simplify the signature of the v8 module intializer. commit 9d630ab930f83252e75d6e66e2912cbe75ca253f Author: Oliver Buchtala Date: Tue Jan 8 21:48:22 2013 +0100 Fix std::string support for v8. commit 2c4a90a37d7818f792417bfff73a88b9efcbdd01 Author: Oliver Buchtala Date: Tue Dec 4 01:36:51 2012 +0100 Generate defines for initializer function. commit be06ceea2686f65a29a5d46d5d675d4366e5571c Author: Oliver Buchtala Date: Sun Dec 2 23:51:47 2012 +0100 Fixes in std_string for JSC generator. commit 7fffd801e410749c37a818b22c5682375c5f9a1b Author: Oliver Buchtala Date: Sat Dec 1 13:21:22 2012 +0100 Fix std_string.i which generated compile errors in certain cases. commit fb9c4955fb4c39f66ea74dcd714bb34f593b3b40 Author: Oliver Buchtala Date: Thu Nov 29 03:20:49 2012 +0100 Not a real change: removed some trailing spaces. commit f9d6afbdfef0d3ef3fb0d5a1675a0b1f4d2a5630 Author: Oliver Buchtala Date: Thu Nov 29 03:19:00 2012 +0100 Add a missing return statement in JS shell. commit 9d2264456334c88a6b0b74940cc3e96add527325 Author: Oliver Buchtala Date: Thu Nov 29 03:17:27 2012 +0100 Rename a argument variable to avoid errors with overloaded functions. commit bad64925eddf9f78b5bddd6fe559973c51b7f59f Author: Oliver Buchtala Date: Fri Nov 23 01:59:54 2012 +0100 Configuration is now easier for building and running examples and tests using v8. commit caa6827dafc4cc5b0ea3b8c16922905c46bbbf29 Author: Oliver Buchtala Date: Fri Nov 23 01:09:11 2012 +0100 Javascript interpreter supports for JSC and V8 simultaneously. Before, one had to build two different versions. commit 008adca72f5917d8a80cc252572f0b1e80ed4e69 Author: Oliver Buchtala Date: Thu Nov 22 22:50:50 2012 +0100 Provide more control about the target object/namespace where a v8 module is registered to. commit 6754bf2b49862211eb67bc2a31ce79ae31de9034 Author: Oliver Buchtala Date: Sat Nov 17 03:41:22 2012 +0100 Generate cleanup code for %newobject. commit 058a27bf32c6fc082c3753af3aaffb1ab4d85e83 Author: Oliver Buchtala Date: Sat Nov 17 02:12:12 2012 +0100 Simplify creation of a Javascript shell. commit 57980975a0f86961b3a9545fd24f34575609c6c7 Author: Oliver Buchtala Date: Fri Nov 16 22:10:02 2012 +0100 Generate cleanup code. commit 94730dad7a5d00468d4b2798c7cbd04db6b1d30d Author: Oliver Buchtala Date: Sat Sep 8 01:16:54 2012 +0000 Beautify output of v8 emitter. Trimming some of the code templates. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13830 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 86cb62146661f89f9cd3dd76c721ddfed529b99d Author: Oliver Buchtala Date: Sat Sep 8 01:16:42 2012 +0000 Add comments to v8 code templates. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13829 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 217ffb11d0cbcfbcfbaa679bd815a80b897b1c8b Author: Oliver Buchtala Date: Sat Sep 8 01:16:26 2012 +0000 Fix regressions of latest commits. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13828 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 9b06144d39f3f1b820ee90ad0bf1c2cf96cbaf6a Author: Oliver Buchtala Date: Sat Sep 8 01:16:09 2012 +0000 Fix handling of overloaded ctors in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13827 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 131a106204e060ac15bd2474c8a5501f82868284 Author: Oliver Buchtala Date: Sat Sep 8 01:15:51 2012 +0000 Improve names and comments of code templates for javascript emitters. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13826 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8b7a9fec2519aa5faac9c3bb26f7612ee1f5aefb Author: Oliver Buchtala Date: Sat Sep 8 01:15:29 2012 +0000 Add complex support to v8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13825 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 7c7d1cf3b9e8a1dfd92b3ca199e2ee0b8bf1cc6f Author: Oliver Buchtala Date: Sat Sep 8 01:15:12 2012 +0000 Fix errors related to wrapping and destruction of (undefined) SWIG_TYPES. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13824 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 296a5d028547c0a0a013a24e65cdcb9c3086fb52 Author: Oliver Buchtala Date: Sat Sep 8 01:14:48 2012 +0000 Minor change in javascript example Makefile configuration. Propagate global CFLAGS and CXXFLAGS to inner javascript targets. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13823 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 4616f9643ff5ce8aefe0594289c9a97230cabf09 Author: Oliver Buchtala Date: Sat Sep 8 01:14:37 2012 +0000 Adapt test-suite configuration to allow switching between js engines. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13822 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8948360725e853f2232188edd38a834ac1f87666 Author: Oliver Buchtala Date: Sat Sep 8 01:14:23 2012 +0000 Fix configuration_in for detecting v8 include and lib. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13821 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 20927938681c14e4f812879973f8e677c08d77b0 Author: Oliver Buchtala Date: Sat Sep 8 01:14:14 2012 +0000 Make v8 shell more quiet. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13820 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit f814a8e702dcfe2ae2f2480de372e78c5a997eb5 Author: Oliver Buchtala Date: Sat Sep 8 01:14:02 2012 +0000 Fix errors concerning object wrapping and cleanup in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13819 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8db76ddee10085765c41be3c5829ec0cce1e0933 Author: Oliver Buchtala Date: Sat Sep 8 01:13:42 2012 +0000 Remove generated file from repository. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13818 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 5425edc50894d32724b7cde8d11bce9fbd3fcdf8 Author: Oliver Buchtala Date: Sat Sep 8 01:13:29 2012 +0000 Add library flag for building v8 shell. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13817 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit da109ee764b0c48f93554f4cc093997fe530ec28 Author: Oliver Buchtala Date: Sat Sep 8 01:13:17 2012 +0000 Fix input string handling in v8 typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13816 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 91fc0ff205f6f6679a0cb51716adc91a21524929 Author: Oliver Buchtala Date: Sat Sep 8 01:13:03 2012 +0000 Use a throwing default setter in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13815 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit a82e0a6e8f7ba258f29de6f8680e406a8b102ae5 Author: Oliver Buchtala Date: Sat Sep 8 01:12:46 2012 +0000 Fix c++ linking problem in example 'variables'. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13814 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 843c8a408cb76e22efc10ede577f17e2e5b7deb2 Author: Oliver Buchtala Date: Sat Sep 8 01:12:33 2012 +0000 Fix AsVal macros of long and int for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13813 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit d13289cc918061b9ffea6aeb9fe1dba9990727e5 Author: Oliver Buchtala Date: Sat Sep 8 01:12:18 2012 +0000 Fix function dispatching for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13812 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 68f0f859f887f7be4c61d53b37ec8989c02833b9 Author: Oliver Buchtala Date: Sat Sep 8 01:11:51 2012 +0000 Fix name collision in generated v8 initializer. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13811 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit da6307a19ea5668757ab59f95e670f99bd64b61a Author: Oliver Buchtala Date: Sat Sep 8 01:11:32 2012 +0000 Enable overloading ctors for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13810 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 70383a1b61aacfb475f72652cf120515f11de2c1 Author: Oliver Buchtala Date: Sat Sep 8 01:11:11 2012 +0000 Enable string exceptions in v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13809 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 84e5476147cd141d1178cd25be35df6b01c5b92e Author: Oliver Buchtala Date: Sat Sep 8 01:10:57 2012 +0000 Add std::string support to v8 typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13808 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit a4f8e4c1c3bbcd36a771313f2516717aa113b771 Author: Oliver Buchtala Date: Sat Sep 8 01:10:42 2012 +0000 Fix bug in v8 ctor emitter. This bug leaded to flaky crashes of v8 engine. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13807 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 2893df9f7394ef48424f0b88e44af702a11fdd95 Author: Oliver Buchtala Date: Sat Sep 8 01:10:27 2012 +0000 Several fixes in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13806 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit c4ab8790278b8ec1cb96f542985824af84e3144a Author: Oliver Buchtala Date: Sat Sep 8 01:10:10 2012 +0000 Fix string warnings of for char* constants in CPP wrappers. This has been done by changing the implementation of marshalOutputArgs, which now does not create a local result variable in this case, and uses the constant inline in the output typemap. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13805 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 58e4f9703c78052ee60f3021724bc3274f3d329a Author: Oliver Buchtala Date: Sat Sep 8 01:09:57 2012 +0000 Fix handling of Char constants in JSC typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13804 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 915e65135cdf90a484bd1078eb3cfe15f192e50e Author: Oliver Buchtala Date: Sat Sep 8 01:09:43 2012 +0000 Minor fix in v8 shell. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13803 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit c3918f3f822a09b297f30ef060c9269dc97e0f39 Author: Oliver Buchtala Date: Sat Sep 8 01:09:31 2012 +0000 Add string support to v8 typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13802 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit bd752ff86b94a082235d0ff424729c7d5e043715 Author: Oliver Buchtala Date: Sat Sep 8 01:09:18 2012 +0000 In example Makefiles for v8 forward to CPP target. As v8 is C++ it is not possible to build wrappers in C. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13801 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 1862f43cfcd93a3f79cf652da70f22a438de4cf9 Author: Oliver Buchtala Date: Sat Sep 8 01:09:05 2012 +0000 Minor clean up in class example. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13800 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit f1e9b21dfd63df4b694bac471daa1f9359c88378 Author: Oliver Buchtala Date: Sat Sep 8 01:08:50 2012 +0000 Add missing swig_type_info registration in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13799 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 21bdb78f1ca2f016afb73c84b4286312f47d3175 Author: Oliver Buchtala Date: Sat Sep 8 01:08:33 2012 +0000 Activate SwigModuleInitializer for in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13798 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 9a914af2b787b336228f779c519b39147e536a68 Author: Oliver Buchtala Date: Sat Sep 8 01:08:16 2012 +0000 Fix v8 shell to initialize v8 context in proper order. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13797 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 46cff47ada4ec3197798359425c165e09d4498a5 Author: Oliver Buchtala Date: Sat Sep 8 01:08:03 2012 +0000 Several fixes in generator for v8 initializer function. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13796 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 78f5b46381e4c93f3d1227a702761a8eda01f4ca Author: Oliver Buchtala Date: Sat Sep 8 01:07:43 2012 +0000 Fix class example. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13795 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 022c274256d5f61daa6a880d781b903cb82af677 Author: Oliver Buchtala Date: Sat Sep 8 01:07:21 2012 +0000 Minor fixes in v8 javascript shell. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13794 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit cda09239ad4b7f5367ea3382e4497cc8d830338b Author: Oliver Buchtala Date: Sat Sep 8 01:06:58 2012 +0000 Several fixes in v8 emitter and code templates. Achieves first compile of example "class" after re-integration. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13793 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 0cae8fccd0cfdbcc6dc426c75102ac8a08430b5d Author: Oliver Buchtala Date: Sat Sep 8 01:06:39 2012 +0000 Minor refactor of marshalInputArgs for generalization. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13792 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 9b0c8dae839def6e83b447230923630e819b64b4 Author: Oliver Buchtala Date: Sat Sep 8 01:06:26 2012 +0000 Add argcount checking to functions and ctors. Before argument counts were only checked for overloaded functions/ctors. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13791 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit d5c5f7ebeebeef78bb847dea31bda75e65d5d197 Author: Oliver Buchtala Date: Sat Sep 8 01:06:08 2012 +0000 Generalize ctor overloading. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13790 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 72002392770b42c3c1a15a4167426635bf9128db Author: Oliver Buchtala Date: Sat Sep 8 01:05:51 2012 +0000 Fix regression in javascript's test-suite configuration. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13789 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 78442b27647e2a3d7e45516c709632f8419b7fd6 Author: Oliver Buchtala Date: Sat Sep 8 01:05:37 2012 +0000 Several adaptations and fixes on the way to get V8 emitter running. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13788 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8d72616e6598dac37109fce3562c32c31188beb1 Author: Oliver Buchtala Date: Sat Sep 8 01:05:11 2012 +0000 Refactor emitter and code templates to use defined template variables. Also switched from "${...}" to $..., which is swig's common notation of typemap variables. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13787 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit cdd450fbe4b9fa9a756cb464dbb3f54e2791106a Author: Oliver Buchtala Date: Sat Sep 8 01:04:51 2012 +0000 Delete obsolete source file. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13786 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 5fab9c8a3857f2c0499790461160bdb4bc9d3602 Author: Oliver Buchtala Date: Sat Sep 8 01:04:40 2012 +0000 Minor cleanup in javascript shell implementation. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13785 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 0341e6b14c9f118ca2bfe853385df88779f0521b Author: Oliver Buchtala Date: Sat Sep 8 01:04:26 2012 +0000 Clean up example Makefiles. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13784 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 10dc758cadc7e0f27eee867a071ba199678e8a0a Author: Oliver Buchtala Date: Sat Sep 8 01:03:42 2012 +0000 Refactored javascript shell implementation to support JSC and v8. Also changed configuration in examples Makefile.in to allow switching modes. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13783 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 672208d8d20eef3214bf4f48fce009eb3f053a81 Author: Oliver Buchtala Date: Sat Sep 8 01:03:17 2012 +0000 Adapt overload example to reflect changes in module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13782 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit cbb5b711ab8d3038f993dc77f6397419cb7c1f7e Author: Oliver Buchtala Date: Sat Sep 8 01:03:00 2012 +0000 Fix examples after regressions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13781 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 52aef2699700c957015c8ce88c5c75f756ffc86f Author: Oliver Buchtala Date: Sat Sep 8 01:02:30 2012 +0000 Add examples check list for batch runs. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13780 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 07d5ec24cebcaa7a08425fa4780937b3bca9fae5 Author: Oliver Buchtala Date: Sat Sep 8 01:02:16 2012 +0000 Add support for type-based dispatching of overloaded functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13779 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit eff094ef3942c026a0711abad56af9a8a54d9b9a Author: Oliver Buchtala Date: Sat Sep 8 01:01:57 2012 +0000 Add test "constructor_copy". git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13778 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 548287c600e8bd900e6976158ffe9c007a390e5f Author: Oliver Buchtala Date: Sat Sep 8 01:01:41 2012 +0000 Update configuration to detect V8 and allow testing with V8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13777 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 4d9ca620abcfed848785ca4825f6a61648387829 Author: Oliver Buchtala Date: Sat Sep 8 01:00:15 2012 +0000 Refactored JSEmitters to share unified code. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13776 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 387da69e843e7359ba1fb70f0eadbd077e8cf461 Author: Oliver Buchtala Date: Sat Sep 8 00:59:55 2012 +0000 Pull namespace implementation up to be shared between js emitters. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13775 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 66ead9afb2501d02c9ded79309e64a5bc953da5a Author: Oliver Buchtala Date: Sat Sep 8 00:59:43 2012 +0000 Simplify implementation using new issetter flag. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13774 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit d2debe32703c0d1f6b4ca22623b2d13e206be64b Author: Oliver Buchtala Date: Sat Sep 8 00:59:31 2012 +0000 Add more verbose temporary flags for setters in variable wrappers. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13773 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 16077503c86919dbedd3d76318a23323404f4f58 Author: Oliver Buchtala Date: Sat Sep 8 00:59:18 2012 +0000 Fix former workaround by concerning static member functions. "storage" attribute is removed by Language::staticmemberfunctionHandler which was resolved by a workaround before. Now, the implementation relies completely on state flags retrieved at a proper point. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13772 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit c470864d127561d55d36e115ffffffc33cf2ff96 Author: Oliver Buchtala Date: Sat Sep 8 00:59:03 2012 +0000 Remove some dead code and an obsolete member variable from JSEmitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13771 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 46624e24e5b6204ce7fd03be433ec1883fd98f96 Author: Oliver Buchtala Date: Sat Sep 8 00:58:49 2012 +0000 Remove member variable current_wrapper from JSEmitter. Instead each emitting function creates local wrapper instance. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13770 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8577ae41791303471a80fde1384f319ef5ababb9 Author: Oliver Buchtala Date: Sat Sep 8 00:58:37 2012 +0000 Minor clean up. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13769 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit b778c4816b63e12e72cb3c2a97e904411465329a Author: Oliver Buchtala Date: Sat Sep 8 00:58:23 2012 +0000 Remove a global variable from JSEmitter by making use of JSEmitterState. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13768 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 9af3c4879bbd2103548afbfbff200eff6a78418a Author: Oliver Buchtala Date: Sat Sep 8 00:58:11 2012 +0000 Switch to global variable for enabling code template debug information. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13767 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit b39e2bfff0c1082c31149079075faa0999059953 Author: Oliver Buchtala Date: Sat Sep 8 00:57:57 2012 +0000 Refactor JSC emitter to reduce global state variables. Also meld v8 emitter into javascript.cxx (provisional). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13766 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 35e6b73d2acbcc010bd239a83fbf16cecefe7b70 Author: Oliver Buchtala Date: Sat Sep 8 00:57:42 2012 +0000 Add swig configuration files for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13765 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 050219d998c0a518b54366c6c543fa926e601e5b Author: Oliver Buchtala Date: Sat Sep 8 00:56:48 2012 +0000 Merge branch 'devel' of https://github.com/Neha03/gsoc2012-javascript into devel Conflicts: .project COPYRIGHT Doc/Manual/style.css Examples/Makefile.in Examples/test-suite/common.mk Lib/typemaps/strings.swg Makefile.in Source/DOH/fio.c Source/Makefile.am Source/Modules/emit.cxx Source/Modules/javascript.cxx configure.in git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13764 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 360ef44e09e9072702215c46306731ccbbbc1d03 Author: Oliver Buchtala Date: Sat Sep 8 00:52:41 2012 +0000 Clean up in v8 helper functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13763 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 229f2d0fa5ffb71c36201a7c70f86e778d256128 Author: Oliver Buchtala Date: Sat Sep 8 00:52:28 2012 +0000 Add v8 input typemap for cstrings. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13762 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8168750c1b43d42a24efa598a1da14c9f56a95f4 Author: Oliver Buchtala Date: Sat Sep 8 00:52:16 2012 +0000 Add example for string marshalling to v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13761 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 67a3de9a93433585a8daca77d3e300713bf91762 Author: Oliver Buchtala Date: Sat Sep 8 00:52:02 2012 +0000 Add example for inheritance to v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13760 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 32a32633ba1ad9fe12e07f90b1eeaee2665b2631 Author: Oliver Buchtala Date: Sat Sep 8 00:51:47 2012 +0000 Add support for static member variables and functions to v8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13759 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit e8dd979d165faa481b057a1b4cb145b3b789d36e Author: Oliver Buchtala Date: Sat Sep 8 00:51:29 2012 +0000 Update v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13758 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 0fd30dc60f462afa797acf84f0f0ad6cea0077a3 Author: Oliver Buchtala Date: Sat Sep 8 00:51:16 2012 +0000 Add examples to specification of v8 code generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13757 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit badf090cb5f2a3dd396b616ba0b997f562a28496 Author: Oliver Buchtala Date: Sat Sep 8 00:51:00 2012 +0000 Extend and rename v8 helper functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13756 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 65d4769af8792f4193cba47ef56547f9998c247c Author: Oliver Buchtala Date: Sat Sep 8 00:50:41 2012 +0000 Add initial support for argument marshalling using typemaps to v8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13755 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 0e60acfebde30181f93b1acfa57c65b50a13e6c5 Author: Oliver Buchtala Date: Sat Sep 8 00:50:19 2012 +0000 Minor restructuring in v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13754 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 71bee1e78c52a65c5a159768c2f6f02cf3eb903f Author: Oliver Buchtala Date: Sat Sep 8 00:50:06 2012 +0000 Complement variable processing in v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13753 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8e0711cbc63ceb6b0adcc1a2ec4133b0fa198a25 Author: Oliver Buchtala Date: Sat Sep 8 00:49:44 2012 +0000 Fix memory related bug in generalized javascript emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13752 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 285badb95b03a3f1ee7a84fa1b473b06c477f35d Author: Oliver Buchtala Date: Sat Sep 8 00:49:32 2012 +0000 Improve v8 generator regarding registration of function wrappers. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13751 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 7ba26c8a26e52d2f499e20b866b273571c6264b8 Author: Oliver Buchtala Date: Sat Sep 8 00:49:15 2012 +0000 Minor change in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13750 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 9a599be8ab6c3426362beb3dd572cd399620da8d Author: Oliver Buchtala Date: Sat Sep 8 00:49:02 2012 +0000 Fix order of registration in v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13749 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 886f17c34372ded14504ad684b71cd786faa8e42 Author: Oliver Buchtala Date: Sat Sep 8 00:48:43 2012 +0000 Implement namespace support for v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13748 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 90bbc6430bf5fb8f234c5ea46a09ef5f528ec72d Author: Oliver Buchtala Date: Sat Sep 8 00:48:24 2012 +0000 Update v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13747 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 6c90d1eb6d46bd1dd52aa3121d38511974423d8b Author: Oliver Buchtala Date: Sat Sep 8 00:48:11 2012 +0000 Minor improvements in v8 emitter implementation git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13746 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 83ac7193155a0d91fad992f197a448591f3e829c Author: Oliver Buchtala Date: Sat Sep 8 00:47:51 2012 +0000 Add manual generated v8 wrapper examples to v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13745 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit a0b71935f278ff342583e17cdf6e94d43ac77c58 Author: Oliver Buchtala Date: Sat Sep 8 00:47:38 2012 +0000 Update v8 code generator specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13744 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 3c30e2d382cbbacef66563bcc8d54289f9543339 Author: Oliver Buchtala Date: Sat Sep 8 00:47:19 2012 +0000 Add initial Javascript V8 emitter implementation. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13743 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 4bcfca05dd0eff51c4ecfa11ed182a6bcf147dbf Author: Oliver Buchtala Date: Sat Sep 8 00:46:31 2012 +0000 Add some implementation details to specification of v8 code generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13742 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit e888d7a892702aa0a3e42449737c8f1bfb747a2f Author: Oliver Buchtala Date: Sat Sep 8 00:46:18 2012 +0000 Add a document about mapping C++ language features to Javascript. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13741 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 5b5fdb171e720228b24c2f9fbb1667649693b3ab Author: Oliver Buchtala Date: Sat Sep 8 00:46:03 2012 +0000 Add a paragraph about control flow analysis to V8 specification. Control flow analysis for use cases: - static variables - simple class - class properties - class methods - static class variables and functions - inheritance. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13740 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 5c3fef6367ba41982032dea8a2b29f6a7f62de9f Author: Oliver Buchtala Date: Sat Sep 8 00:45:49 2012 +0000 Add initial version of a CMake configuration. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13739 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit ba40fffd91bc07fc5020fe7870a6104863a39f94 Author: Oliver Buchtala Date: Sat Sep 8 00:45:35 2012 +0000 Add initial specification of code generator templates for V8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13738 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit d71a5f483a6ad3307ff306ce2c72cfcd0e361556 Author: Oliver Buchtala Date: Sat Sep 8 00:44:54 2012 +0000 Add module for Javascript target. This module comes with a design that allows different code emitter implementations. For the the phase of development the module is split into multiple files which will be merged together when development converges. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13737 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit c86ce942c2d0498169d4371bdd6c9acd503fdffa Author: Oliver Buchtala Date: Fri May 11 19:20:07 2012 +0000 Correct place of copyright entry. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13070 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit d6060ceced397c2dd3baaba94c783d0045ddc38e Author: Oliver Buchtala Date: Fri May 11 13:55:16 2012 +0000 Add copyright entry for Oliver Buchtala. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13067 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .gitignore | 8 + .travis.yml | 10 +- COPYRIGHT | 4 +- Doc/Manual/Javascript.html | 770 ++++++ Doc/Manual/chapters | 1 + Doc/Manual/style.css | 6 +- Examples/Makefile.in | 80 + Examples/javascript/check.list | 13 + Examples/javascript/class/Makefile | 3 + Examples/javascript/class/binding.gyp | 8 + Examples/javascript/class/example.cxx | 28 + Examples/javascript/class/example.h | 34 + Examples/javascript/class/example.i | 10 + Examples/javascript/class/example.js | 1 + Examples/javascript/class/runme.js | 46 + Examples/javascript/constant/Makefile | 3 + Examples/javascript/constant/binding.gyp | 8 + Examples/javascript/constant/example.h | 8 + Examples/javascript/constant/example.i | 24 + Examples/javascript/constant/example.js | 1 + Examples/javascript/constant/runme.js | 14 + Examples/javascript/enum/Makefile | 3 + Examples/javascript/enum/binding.gyp | 8 + Examples/javascript/enum/example.cxx | 37 + Examples/javascript/enum/example.h | 13 + Examples/javascript/enum/example.i | 11 + Examples/javascript/enum/example.js | 1 + Examples/javascript/enum/runme.js | 34 + Examples/javascript/exception/Makefile | 3 + Examples/javascript/exception/binding.gyp | 8 + Examples/javascript/exception/example.cxx | 1 + Examples/javascript/exception/example.h | 53 + Examples/javascript/exception/example.i | 12 + Examples/javascript/exception/example.js | 1 + Examples/javascript/exception/runme.js | 64 + Examples/javascript/functor/Makefile | 3 + Examples/javascript/functor/binding.gyp | 8 + Examples/javascript/functor/example.cxx | 0 Examples/javascript/functor/example.i | 25 + Examples/javascript/functor/example.js | 1 + Examples/javascript/functor/runme.js | 15 + Examples/javascript/js_example.mk | 52 + Examples/javascript/namespace/Makefile | 3 + Examples/javascript/namespace/binding.gyp | 8 + Examples/javascript/namespace/example.cxx | 36 + Examples/javascript/namespace/example.h | 20 + Examples/javascript/namespace/example.i | 10 + Examples/javascript/namespace/example.js | 1 + Examples/javascript/namespace/runme.js | 10 + Examples/javascript/operator/Makefile | 3 + Examples/javascript/operator/binding.gyp | 8 + Examples/javascript/operator/example.h | 36 + Examples/javascript/operator/example.i | 34 + Examples/javascript/operator/example.js | 1 + Examples/javascript/operator/runme.js | 25 + Examples/javascript/overload/Makefile | 3 + Examples/javascript/overload/binding.gyp | 8 + Examples/javascript/overload/example.h | 28 + Examples/javascript/overload/example.i | 16 + Examples/javascript/overload/example.js | 1 + Examples/javascript/overload/runme.js | 9 + Examples/javascript/pointer/Makefile | 3 + Examples/javascript/pointer/binding.gyp | 8 + Examples/javascript/pointer/example.cxx | 16 + Examples/javascript/pointer/example.i | 30 + Examples/javascript/pointer/example.js | 1 + Examples/javascript/pointer/runme.js | 35 + Examples/javascript/pointer/typemaps.i | 0 Examples/javascript/reference/Makefile | 3 + Examples/javascript/reference/binding.gyp | 8 + Examples/javascript/reference/example.cxx | 46 + Examples/javascript/reference/example.h | 26 + Examples/javascript/reference/example.i | 42 + Examples/javascript/reference/example.js | 1 + Examples/javascript/reference/runme.js | 67 + Examples/javascript/reference/swig_gdb.log | 22 + Examples/javascript/simple/Makefile | 3 + Examples/javascript/simple/binding.gyp | 8 + Examples/javascript/simple/example.cxx | 18 + Examples/javascript/simple/example.i | 7 + Examples/javascript/simple/example.js | 1 + Examples/javascript/simple/runme.js | 26 + Examples/javascript/template/Makefile | 3 + Examples/javascript/template/binding.gyp | 8 + Examples/javascript/template/example.h | 32 + Examples/javascript/template/example.i | 17 + Examples/javascript/template/example.js | 1 + Examples/javascript/template/runme.js | 30 + Examples/javascript/variables/Makefile | 3 + Examples/javascript/variables/binding.gyp | 8 + Examples/javascript/variables/example.cxx | 96 + Examples/javascript/variables/example.h | 6 + Examples/javascript/variables/example.i | 49 + Examples/javascript/variables/example.js | 1 + Examples/javascript/variables/runme.js | 68 + Examples/javascript/variables/swig_gdb.log | 9 + Examples/test-suite/common.mk | 7 +- Examples/test-suite/constructor_copy.i | 2 +- Examples/test-suite/director_nspace.i | 2 +- Examples/test-suite/infinity.i | 48 + Examples/test-suite/javascript/Makefile.in | 181 ++ .../javascript/abstract_access_runme.js | 6 + .../javascript/abstract_inherit_runme.js | 40 + .../javascript/abstract_typedef2_runme.js | 6 + .../javascript/abstract_typedef_runme.js | 8 + .../javascript/abstract_virtual_runme.js | 11 + .../javascript/array_member_runme.js | 22 + .../javascript/arrays_global_runme.js | 18 + .../test-suite/javascript/callback_runme.js | 30 + .../javascript/char_binary_runme.js | 38 + .../javascript/char_strings_runme.js | 11 + .../javascript/class_ignore_runme.js | 6 + .../javascript/class_scope_weird_runme.js | 6 + .../javascript/complextest_runme.js | 22 + .../test-suite/javascript/constover_runme.js | 33 + .../javascript/constructor_copy_runme.js | 42 + .../test-suite/javascript/cpp_enum_runme.js | 28 + .../javascript/cpp_namespace_runme.js | 47 + .../test-suite/javascript/cpp_static_runme.js | 9 + .../javascript/director_alternating_runme.js | 5 + .../test-suite/javascript/disown_runme.js | 22 + .../javascript/dynamic_cast_runme.js | 12 + Examples/test-suite/javascript/empty_runme.js | 1 + .../javascript/enum_template_runme.js | 8 + .../test-suite/javascript/infinity_runme.js | 4 + .../javascript/javascript_unicode_runme.js | 9 + .../namespace_virtual_method_runme.js | 3 + .../javascript/node_template/binding.gyp.in | 30 + .../javascript/node_template/index.js.in | 1 + .../javascript/nspace_extend_runme.js | 27 + .../test-suite/javascript/nspace_runme.js | 77 + .../javascript/overload_copy_runme.js | 4 + .../javascript/preproc_include_runme.js | 23 + .../test-suite/javascript/preproc_runme.js | 14 + .../test-suite/javascript/rename1_runme.js | 68 + .../test-suite/javascript/rename2_runme.js | 68 + .../test-suite/javascript/rename3_runme.js | 68 + .../test-suite/javascript/rename4_runme.js | 68 + .../javascript/rename_scope_runme.js | 17 + .../javascript/rename_simple_runme.js | 50 + .../javascript/ret_by_value_runme.js | 8 + Examples/test-suite/javascript/setup_test.sh | 6 + .../javascript/struct_value_runme.js | 11 + .../javascript/template_static_runme.js | 3 + .../javascript/typedef_class_runme.js | 7 + .../javascript/typedef_inherit_runme.js | 23 + .../javascript/typedef_scope_runme.js | 12 + .../javascript/typemap_arrays_runme.js | 5 + .../javascript/typemap_delete_runme.js | 5 + .../javascript/typemap_namespace_runme.js | 7 + .../javascript/typemap_ns_using_runme.js | 4 + .../test-suite/javascript/using1_runme.js | 4 + .../test-suite/javascript/using2_runme.js | 4 + .../test-suite/javascript/varargs_runme.js | 44 + Examples/test-suite/javascript_unicode.i | 10 + Examples/test-suite/nspace.i | 2 +- Examples/test-suite/nspace_extend.i | 2 +- Lib/javascript/jsc/arrays_javascript.i | 123 + Lib/javascript/jsc/ccomplex.i | 26 + Lib/javascript/jsc/cdata.i | 1 + Lib/javascript/jsc/complex.i | 6 + Lib/javascript/jsc/exception.i | 1 + Lib/javascript/jsc/javascript.swg | 19 + Lib/javascript/jsc/javascriptcode.swg | 418 +++ Lib/javascript/jsc/javascriptcomplex.swg | 146 + Lib/javascript/jsc/javascriptfragments.swg | 23 + Lib/javascript/jsc/javascripthelpers.swg | 69 + Lib/javascript/jsc/javascriptinit.swg | 67 + Lib/javascript/jsc/javascriptkw.swg | 40 + Lib/javascript/jsc/javascriptprimtypes.swg | 182 ++ Lib/javascript/jsc/javascriptrun.swg | 298 ++ Lib/javascript/jsc/javascriptruntime.swg | 19 + Lib/javascript/jsc/javascriptstrings.swg | 184 ++ Lib/javascript/jsc/javascripttypemaps.swg | 54 + Lib/javascript/jsc/std_common.i | 5 + Lib/javascript/jsc/std_complex.i | 19 + Lib/javascript/jsc/std_deque.i | 1 + Lib/javascript/jsc/std_except.i | 1 + Lib/javascript/jsc/std_map.i | 74 + Lib/javascript/jsc/std_pair.i | 34 + Lib/javascript/jsc/std_string.i | 69 + Lib/javascript/jsc/std_vector.i | 85 + Lib/javascript/jsc/stl.i | 10 + Lib/javascript/jsc/typemaps.i | 148 + Lib/javascript/v8/arrays_javascript.i | 125 + Lib/javascript/v8/ccomplex.i | 26 + Lib/javascript/v8/cdata.i | 1 + Lib/javascript/v8/complex.i | 6 + Lib/javascript/v8/exception.i | 1 + Lib/javascript/v8/javascript.swg | 19 + Lib/javascript/v8/javascriptcode.swg | 468 ++++ Lib/javascript/v8/javascriptcomplex.swg | 123 + Lib/javascript/v8/javascriptfragments.swg | 23 + Lib/javascript/v8/javascripthelpers.swg | 87 + Lib/javascript/v8/javascriptinit.swg | 118 + Lib/javascript/v8/javascriptkw.swg | 40 + Lib/javascript/v8/javascriptprimtypes.swg | 198 ++ Lib/javascript/v8/javascriptrun.swg | 462 ++++ Lib/javascript/v8/javascriptruntime.swg | 39 + Lib/javascript/v8/javascriptstrings.swg | 59 + Lib/javascript/v8/javascripttypemaps.swg | 43 + Lib/javascript/v8/node.i | 12 + Lib/javascript/v8/std_common.i | 5 + Lib/javascript/v8/std_complex.i | 19 + Lib/javascript/v8/std_deque.i | 1 + Lib/javascript/v8/std_except.i | 1 + Lib/javascript/v8/std_map.i | 74 + Lib/javascript/v8/std_pair.i | 33 + Lib/javascript/v8/std_string.i | 79 + Lib/javascript/v8/std_vector.i | 85 + Lib/javascript/v8/stl.i | 10 + Lib/javascript/v8/typemaps.i | 148 + Lib/typemaps/strings.swg | 4 +- Makefile.in | 19 +- Source/Makefile.am | 1 + Source/Modules/javascript.cxx | 2428 +++++++++++++++++ Source/Modules/swigmain.cxx | 2 + Tools/javascript/Makefile.in | 58 + Tools/javascript/javascript.cxx | 66 + Tools/javascript/js_shell.cxx | 156 ++ Tools/javascript/js_shell.h | 53 + Tools/javascript/jsc_shell.cxx | 233 ++ Tools/javascript/v8_shell.cxx | 310 +++ Tools/swigconfig.h.cmake | 89 + Tools/swigprinters.gdb | 24 + Tools/swigprinters.py | 574 ++++ configure.ac | 232 ++ swig-v8/swig-v8.xcodeproj/project.pbxproj | 153 ++ 228 files changed, 12567 insertions(+), 16 deletions(-) create mode 100644 Doc/Manual/Javascript.html create mode 100644 Examples/javascript/check.list create mode 100755 Examples/javascript/class/Makefile create mode 100644 Examples/javascript/class/binding.gyp create mode 100755 Examples/javascript/class/example.cxx create mode 100755 Examples/javascript/class/example.h create mode 100755 Examples/javascript/class/example.i create mode 100644 Examples/javascript/class/example.js create mode 100755 Examples/javascript/class/runme.js create mode 100755 Examples/javascript/constant/Makefile create mode 100644 Examples/javascript/constant/binding.gyp create mode 100644 Examples/javascript/constant/example.h create mode 100755 Examples/javascript/constant/example.i create mode 100644 Examples/javascript/constant/example.js create mode 100755 Examples/javascript/constant/runme.js create mode 100755 Examples/javascript/enum/Makefile create mode 100644 Examples/javascript/enum/binding.gyp create mode 100755 Examples/javascript/enum/example.cxx create mode 100755 Examples/javascript/enum/example.h create mode 100755 Examples/javascript/enum/example.i create mode 100644 Examples/javascript/enum/example.js create mode 100755 Examples/javascript/enum/runme.js create mode 100755 Examples/javascript/exception/Makefile create mode 100644 Examples/javascript/exception/binding.gyp create mode 100644 Examples/javascript/exception/example.cxx create mode 100644 Examples/javascript/exception/example.h create mode 100644 Examples/javascript/exception/example.i create mode 100644 Examples/javascript/exception/example.js create mode 100644 Examples/javascript/exception/runme.js create mode 100755 Examples/javascript/functor/Makefile create mode 100644 Examples/javascript/functor/binding.gyp create mode 100644 Examples/javascript/functor/example.cxx create mode 100644 Examples/javascript/functor/example.i create mode 100644 Examples/javascript/functor/example.js create mode 100644 Examples/javascript/functor/runme.js create mode 100644 Examples/javascript/js_example.mk create mode 100755 Examples/javascript/namespace/Makefile create mode 100644 Examples/javascript/namespace/binding.gyp create mode 100644 Examples/javascript/namespace/example.cxx create mode 100644 Examples/javascript/namespace/example.h create mode 100644 Examples/javascript/namespace/example.i create mode 100644 Examples/javascript/namespace/example.js create mode 100644 Examples/javascript/namespace/runme.js create mode 100755 Examples/javascript/operator/Makefile create mode 100644 Examples/javascript/operator/binding.gyp create mode 100644 Examples/javascript/operator/example.h create mode 100644 Examples/javascript/operator/example.i create mode 100644 Examples/javascript/operator/example.js create mode 100644 Examples/javascript/operator/runme.js create mode 100755 Examples/javascript/overload/Makefile create mode 100644 Examples/javascript/overload/binding.gyp create mode 100644 Examples/javascript/overload/example.h create mode 100644 Examples/javascript/overload/example.i create mode 100644 Examples/javascript/overload/example.js create mode 100644 Examples/javascript/overload/runme.js create mode 100755 Examples/javascript/pointer/Makefile create mode 100644 Examples/javascript/pointer/binding.gyp create mode 100755 Examples/javascript/pointer/example.cxx create mode 100755 Examples/javascript/pointer/example.i create mode 100644 Examples/javascript/pointer/example.js create mode 100755 Examples/javascript/pointer/runme.js create mode 100644 Examples/javascript/pointer/typemaps.i create mode 100755 Examples/javascript/reference/Makefile create mode 100644 Examples/javascript/reference/binding.gyp create mode 100755 Examples/javascript/reference/example.cxx create mode 100755 Examples/javascript/reference/example.h create mode 100755 Examples/javascript/reference/example.i create mode 100644 Examples/javascript/reference/example.js create mode 100755 Examples/javascript/reference/runme.js create mode 100644 Examples/javascript/reference/swig_gdb.log create mode 100755 Examples/javascript/simple/Makefile create mode 100644 Examples/javascript/simple/binding.gyp create mode 100644 Examples/javascript/simple/example.cxx create mode 100644 Examples/javascript/simple/example.i create mode 100644 Examples/javascript/simple/example.js create mode 100755 Examples/javascript/simple/runme.js create mode 100755 Examples/javascript/template/Makefile create mode 100644 Examples/javascript/template/binding.gyp create mode 100644 Examples/javascript/template/example.h create mode 100644 Examples/javascript/template/example.i create mode 100644 Examples/javascript/template/example.js create mode 100644 Examples/javascript/template/runme.js create mode 100755 Examples/javascript/variables/Makefile create mode 100644 Examples/javascript/variables/binding.gyp create mode 100755 Examples/javascript/variables/example.cxx create mode 100755 Examples/javascript/variables/example.h create mode 100755 Examples/javascript/variables/example.i create mode 100644 Examples/javascript/variables/example.js create mode 100755 Examples/javascript/variables/runme.js create mode 100644 Examples/javascript/variables/swig_gdb.log create mode 100644 Examples/test-suite/infinity.i create mode 100755 Examples/test-suite/javascript/Makefile.in create mode 100644 Examples/test-suite/javascript/abstract_access_runme.js create mode 100644 Examples/test-suite/javascript/abstract_inherit_runme.js create mode 100644 Examples/test-suite/javascript/abstract_typedef2_runme.js create mode 100644 Examples/test-suite/javascript/abstract_typedef_runme.js create mode 100644 Examples/test-suite/javascript/abstract_virtual_runme.js create mode 100644 Examples/test-suite/javascript/array_member_runme.js create mode 100644 Examples/test-suite/javascript/arrays_global_runme.js create mode 100644 Examples/test-suite/javascript/callback_runme.js create mode 100644 Examples/test-suite/javascript/char_binary_runme.js create mode 100644 Examples/test-suite/javascript/char_strings_runme.js create mode 100644 Examples/test-suite/javascript/class_ignore_runme.js create mode 100644 Examples/test-suite/javascript/class_scope_weird_runme.js create mode 100644 Examples/test-suite/javascript/complextest_runme.js create mode 100644 Examples/test-suite/javascript/constover_runme.js create mode 100644 Examples/test-suite/javascript/constructor_copy_runme.js create mode 100644 Examples/test-suite/javascript/cpp_enum_runme.js create mode 100644 Examples/test-suite/javascript/cpp_namespace_runme.js create mode 100644 Examples/test-suite/javascript/cpp_static_runme.js create mode 100644 Examples/test-suite/javascript/director_alternating_runme.js create mode 100644 Examples/test-suite/javascript/disown_runme.js create mode 100644 Examples/test-suite/javascript/dynamic_cast_runme.js create mode 100644 Examples/test-suite/javascript/empty_runme.js create mode 100644 Examples/test-suite/javascript/enum_template_runme.js create mode 100644 Examples/test-suite/javascript/infinity_runme.js create mode 100644 Examples/test-suite/javascript/javascript_unicode_runme.js create mode 100644 Examples/test-suite/javascript/namespace_virtual_method_runme.js create mode 100644 Examples/test-suite/javascript/node_template/binding.gyp.in create mode 100644 Examples/test-suite/javascript/node_template/index.js.in create mode 100644 Examples/test-suite/javascript/nspace_extend_runme.js create mode 100644 Examples/test-suite/javascript/nspace_runme.js create mode 100644 Examples/test-suite/javascript/overload_copy_runme.js create mode 100644 Examples/test-suite/javascript/preproc_include_runme.js create mode 100644 Examples/test-suite/javascript/preproc_runme.js create mode 100644 Examples/test-suite/javascript/rename1_runme.js create mode 100644 Examples/test-suite/javascript/rename2_runme.js create mode 100644 Examples/test-suite/javascript/rename3_runme.js create mode 100644 Examples/test-suite/javascript/rename4_runme.js create mode 100644 Examples/test-suite/javascript/rename_scope_runme.js create mode 100644 Examples/test-suite/javascript/rename_simple_runme.js create mode 100644 Examples/test-suite/javascript/ret_by_value_runme.js create mode 100644 Examples/test-suite/javascript/setup_test.sh create mode 100644 Examples/test-suite/javascript/struct_value_runme.js create mode 100644 Examples/test-suite/javascript/template_static_runme.js create mode 100644 Examples/test-suite/javascript/typedef_class_runme.js create mode 100644 Examples/test-suite/javascript/typedef_inherit_runme.js create mode 100644 Examples/test-suite/javascript/typedef_scope_runme.js create mode 100644 Examples/test-suite/javascript/typemap_arrays_runme.js create mode 100644 Examples/test-suite/javascript/typemap_delete_runme.js create mode 100644 Examples/test-suite/javascript/typemap_namespace_runme.js create mode 100644 Examples/test-suite/javascript/typemap_ns_using_runme.js create mode 100644 Examples/test-suite/javascript/using1_runme.js create mode 100644 Examples/test-suite/javascript/using2_runme.js create mode 100644 Examples/test-suite/javascript/varargs_runme.js create mode 100644 Examples/test-suite/javascript_unicode.i create mode 100644 Lib/javascript/jsc/arrays_javascript.i create mode 100644 Lib/javascript/jsc/ccomplex.i create mode 100644 Lib/javascript/jsc/cdata.i create mode 100644 Lib/javascript/jsc/complex.i create mode 100644 Lib/javascript/jsc/exception.i create mode 100644 Lib/javascript/jsc/javascript.swg create mode 100644 Lib/javascript/jsc/javascriptcode.swg create mode 100644 Lib/javascript/jsc/javascriptcomplex.swg create mode 100644 Lib/javascript/jsc/javascriptfragments.swg create mode 100644 Lib/javascript/jsc/javascripthelpers.swg create mode 100644 Lib/javascript/jsc/javascriptinit.swg create mode 100644 Lib/javascript/jsc/javascriptkw.swg create mode 100644 Lib/javascript/jsc/javascriptprimtypes.swg create mode 100644 Lib/javascript/jsc/javascriptrun.swg create mode 100644 Lib/javascript/jsc/javascriptruntime.swg create mode 100644 Lib/javascript/jsc/javascriptstrings.swg create mode 100644 Lib/javascript/jsc/javascripttypemaps.swg create mode 100755 Lib/javascript/jsc/std_common.i create mode 100644 Lib/javascript/jsc/std_complex.i create mode 100644 Lib/javascript/jsc/std_deque.i create mode 100644 Lib/javascript/jsc/std_except.i create mode 100755 Lib/javascript/jsc/std_map.i create mode 100755 Lib/javascript/jsc/std_pair.i create mode 100755 Lib/javascript/jsc/std_string.i create mode 100755 Lib/javascript/jsc/std_vector.i create mode 100755 Lib/javascript/jsc/stl.i create mode 100644 Lib/javascript/jsc/typemaps.i create mode 100644 Lib/javascript/v8/arrays_javascript.i create mode 100644 Lib/javascript/v8/ccomplex.i create mode 100644 Lib/javascript/v8/cdata.i create mode 100644 Lib/javascript/v8/complex.i create mode 100644 Lib/javascript/v8/exception.i create mode 100644 Lib/javascript/v8/javascript.swg create mode 100644 Lib/javascript/v8/javascriptcode.swg create mode 100644 Lib/javascript/v8/javascriptcomplex.swg create mode 100644 Lib/javascript/v8/javascriptfragments.swg create mode 100644 Lib/javascript/v8/javascripthelpers.swg create mode 100644 Lib/javascript/v8/javascriptinit.swg create mode 100644 Lib/javascript/v8/javascriptkw.swg create mode 100644 Lib/javascript/v8/javascriptprimtypes.swg create mode 100644 Lib/javascript/v8/javascriptrun.swg create mode 100644 Lib/javascript/v8/javascriptruntime.swg create mode 100644 Lib/javascript/v8/javascriptstrings.swg create mode 100644 Lib/javascript/v8/javascripttypemaps.swg create mode 100644 Lib/javascript/v8/node.i create mode 100755 Lib/javascript/v8/std_common.i create mode 100644 Lib/javascript/v8/std_complex.i create mode 100644 Lib/javascript/v8/std_deque.i create mode 100644 Lib/javascript/v8/std_except.i create mode 100755 Lib/javascript/v8/std_map.i create mode 100755 Lib/javascript/v8/std_pair.i create mode 100755 Lib/javascript/v8/std_string.i create mode 100755 Lib/javascript/v8/std_vector.i create mode 100755 Lib/javascript/v8/stl.i create mode 100644 Lib/javascript/v8/typemaps.i create mode 100644 Source/Modules/javascript.cxx create mode 100644 Tools/javascript/Makefile.in create mode 100644 Tools/javascript/javascript.cxx create mode 100644 Tools/javascript/js_shell.cxx create mode 100644 Tools/javascript/js_shell.h create mode 100644 Tools/javascript/jsc_shell.cxx create mode 100755 Tools/javascript/v8_shell.cxx create mode 100644 Tools/swigconfig.h.cmake create mode 100644 Tools/swigprinters.gdb create mode 100755 Tools/swigprinters.py create mode 100644 swig-v8/swig-v8.xcodeproj/project.pbxproj diff --git a/.gitignore b/.gitignore index 48826d914..8d72cea5d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ # Editor files and various other junk .*.sw? *.bak +*.log +.DS_Store # Local PCRE pcre @@ -23,6 +25,7 @@ pcre *.so *.so.* *.dylib +*.bundle # C/C++ static libraries, based on: # https://github.com/github/gitignore/blob/master/C.gitignore @@ -71,6 +74,7 @@ Examples/xml/Makefile Source/Include/stamp-h1 Source/Include/swigconfig.h Source/Makefile +Tools/javascript/Makefile .deps config.log config.status @@ -85,6 +89,7 @@ Source/CParse/parser.c Source/CParse/parser.h Source/eswig swig +Tools/javascript/javascript # Generated documentation Doc/Manual/CCache.html @@ -102,6 +107,7 @@ Examples/test-suite/d/*/ Examples/test-suite/go/*/ Examples/test-suite/guile/*/ Examples/test-suite/java/*/ +Examples/test-suite/javascript/*/ Examples/test-suite/lua/*/ Examples/test-suite/mzscheme/*/ Examples/test-suite/ocaml/*/ @@ -114,6 +120,8 @@ Examples/test-suite/r/*/ Examples/test-suite/ruby/*/ Examples/test-suite/tcl/*/ Examples/test-suite/uffi/*/ +*_wrap.c +*_wrap.cxx # Python generated files, based on: # https://github.com/github/gitignore/blob/master/Python.gitignore diff --git a/.travis.yml b/.travis.yml index 5d47074e9..58b3e4ca6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ -language: cpp +language: c compiler: - - clang - gcc env: - SWIGLANG= @@ -14,6 +13,12 @@ matrix: env: SWIGLANG=guile - compiler: gcc env: SWIGLANG=java + - compiler: gcc + env: SWIGLANG=javascript ENGINE=node + - compiler: gcc + env: SWIGLANG=javascript ENGINE=jsc + - compiler: gcc + env: SWIGLANG=javascript ENGINE=v8 - compiler: gcc env: SWIGLANG=lua - compiler: gcc @@ -43,6 +48,7 @@ before_install: - if test -z "$SWIGLANG"; then sudo apt-get -qq install yodl; fi - if test "$SWIGLANG" = "csharp"; then sudo apt-get -qq install mono-devel; fi - if test "$SWIGLANG" = "go"; then go env | sed -e 's/^/export /' > goenvsetup && source goenvsetup && rm -f goenvsetup; fi # Until configure.ac is fixed + - if test "$SWIGLANG" = "javascript"; then sudo apt-get install -qq rlwrap python-software-properties && echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs libv8-dev libwebkitgtk-dev && sudo npm install -g node-gyp; fi - if test "$SWIGLANG" = "guile"; then sudo apt-get -qq install guile-2.0-dev; fi - if test "$SWIGLANG" = "lua"; then sudo apt-get -qq install lua5.1 liblua5.1-dev; fi - if test "$SWIGLANG" = "octave"; then sudo apt-get -qq install octave3.2 octave3.2-headers; fi diff --git a/COPYRIGHT b/COPYRIGHT index 3f4711a47..28b7f1f0d 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -15,7 +15,9 @@ Active SWIG Developers: Olly Betts (olly@survex.com) (PHP) Joseph Wang (joequant@gmail.com) (R) Xavier Delacour (xavier.delacour@gmail.com) (Octave) - David Nadlinger (code@klickverbot.at) (D) + David Nadlinger (code@klickverbot.at) + Oliver Buchtala (oliver.buchtala@gmail.com) (Javascript) + Neha Narang (narangneha03@gmail.com) (Javascript) Past SWIG developers and major contributors include: Dave Beazley (dave-swig@dabeaz.com) (SWIG core, Python, Tcl, Perl) diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html new file mode 100644 index 000000000..a53e2a7cd --- /dev/null +++ b/Doc/Manual/Javascript.html @@ -0,0 +1,770 @@ + + + + + + + SWIG AND JAVASCRIPT + + + + + +
+

Overview

+

This chapter describes SWIG support for Javascript. The module is designed to support JavascriptCore and V8 as target engine. Currently only JavascriptCore support is implemented. JavaScriptCore is the built-in JavaScript engine for WebKit, whereas V8 is the engine used by Chromium.

+

JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. C++, on the other hand, is statically typed, compiled, general purpose programming language. The approach I followed here is "Test driven" where I have written the examples/test-cases to be supported for Javascript one-by-one and implemented the required module files in parallel. The support for Javascript would be added similar to other supported target languages in swig. Swig comes with an "Examples" directory for Javascript like other supported language. The directory contains examples for every supported feature of the target language. There is also a test-suite directory for javascript which contains additional tests.

+

Preliminaries

+

In order to use this module, you will need to have installed javascriptcore and you can install it by installing package libwebkit-dev You can find out some necessary compiler/linker flag by

+
pkg-config javascriptcoregtk-1.0 --cflags --libs
+
+

Using the module

+

To generate an extension for JavascriptCore one would call swig as follows

+

swig -c++ -javascript -jsc example.i +
+

This generates a C++ source file containing the wrapper.

+

How does Javascript talk to C++?

+

JavascriptCore provides a C-API which allows to extend a Javascript interpreter with native methods and structures. Normally, this is used to implement the builtin features of the language. However, by extending the interpreter, it is also possible to add your own commands and variables. A reference manual of this API can be found here.

+

Typically, when you add a new command to the javascript interpreter you need to do two things: first you need to write a special "wrapper" function that serves as the glue between the interpreter and the underlying C function. Then you need to give the interpreter information about the wrapper by providing details about the name of the function, arguments, and so forth. The next few sections illustrate the process.

+

Wrapper functions

+

Suppose you have an ordinary C function like this :

+

int fact(int n) { + if (n <= 1) return 1; + else return n*fact(n-1); +} +
+

In order to access this function from a scripting language, it is necessary to write a special "wrapper" function that serves as the glue between the scripting language and the underlying C function. A wrapper function must do three things :

+
    +
  • Gather function arguments and make sure they are valid.
  • +
  • Call the C function.
  • +
  • Convert the return value into a form recognized by the javascript.
  • +
+

As an example, the javascript wrapper function for the fact() function above example might look like the following :

+

JSValueRef wrap_fact(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + int arg1 = (int)JSValueToNumber(context, argv[0], NULL); + int arg2 = (int)JSValueToNumber(context, argv[1], NULL); + int result = (int)fact(arg1,arg2); + JSValueRef jsresult = JSValueMakeNumber(context, result); + return jsresult; +} +
+

Once you have created a wrapper function, the final step is to tell the javascript about the new function. This is done by register function called by the javascript when the module is loaded. For example, adding the above function to the javascript interpreter requires code like the following :

+

bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_globalvarsclassname = JSStringCreateWithUTF8CString(globalvarsclassname); + JSObjectSetProperty(context,js_globalvarsclassname,JSObjectMakeFunctionWithCallback(context, + js_globalvarsclassname, callback), kJSPropertyAttributeNone,NULL); + JSStringRelease(jsstring); + return true; +} + +int example_init(JSContextRef context) { + JSObjectRef global; + ... + jsc_registerFunction(context, global, "fact", wrap_fact); + ... +} +
+

When executed, javascript will now have a new command called "fact" that you can use like any other Javascript command. Although the process of adding a new function to javascript has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code.

+

Variable Linking

+

Variable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language interpreter. For example, suppose you had the following variable:

+

double Foo = 3.5; +
+

To provide such access, variables are commonly manipulated using a pair of get/set functions. For example, whenever the value of a variable is read, a "get" function is invoked. Similarly, whenever the value of a variable is changed, a "set" function is called.

+

bool Foo_set(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef value, + JSValueRef* exception) +{ + JSValueRef jsresult; + double arg1 = (double)JSValueToNumber(context, value, NULL); + Foo = arg1; + jscresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef Foo_get(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + double result = (double)Foo; + jsresult = JSValueMakeNumber(context, result); + return jsresult; +} +
+

In many languages, calls to the get/set functions can be attached to evaluation and assignment operators. Therefore, evaluating a variable such as Foo might implicitly call the get function. Similarly, typing Foo = 4 would call the underlying set function to change the value.

+

A tour of basic C/C++ wrapping

+

By default, SWIG tries to build a very natural javascript interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping.

+

Modules

+

The SWIG %module directive specifies the name of the Javascript module. If you specify %module example, then everything is wrapped into a Javascript 'example' module. Underneath the covers, this module consists of a cpp source file example.cpp. When choosing a module name, make sure you don't use the same name as a built-in Javascript command or standard module name.

+

Global variables

+

C/C++ global variables are fully supported by SWIG. However, the underlying mechanism is somewhat different than you might expect due to the way that javascript works.

+

// SWIG interface file with global variables +%module example +... +%inline %{ +extern double Foo; +extern int gcd(int x, int y); +%} +... +
+

Now look at the javascript:

+

print("Global variable Foo=" + example.Foo); +example.Foo = 3.1415926; +print("Variable Foo changed to=" + example.Foo); +print("GCD of x and y is=" + example.gcd(x,y)); +
+

Constants and enums

+

C/C++ constants are installed as javascript objects containing the appropriate value. To create a constant, use #define, enum, or the %constant directive. For example:

+

#define ICONST 42 +#define FCONST 2.1828 +%constant int iconst = 37; +
+

In javascript they are treated as:

+

print("ICONST = " + example.ICONST + " (should be 42)\n"); +print("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +print("iconst = " + example.iconst + " (should be 37)\n"); +
+

For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just stick an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile. Enums are treated as constants.So if we have enums in c++ as:

+

void enum_test(color c, Foo::speed s); +
+

In javascript they are treated as:

+

example.enum_test(example.RED, example.Foo.IMPULSE); +example.enum_test(example.BLUE, example.Foo.WARP); +example.enum_test(example.GREEN, example.Foo.LUDICROUS); +
+

Inside the class

+

For class enums as below:

+

class Foo { +public: +Foo() { } +enum speed { IMPULSE, WARP, LUDICROUS }; +} +
+

In javascript they are treated as:

+

print(" Foo_IMPULSE =" + example.Foo.IMPULSE); +print(" Foo_WARP =" + example.Foo.WARP); +print(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); +
+

Pointers

+

C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface

+

/* File : example.i */ +%module example +%{ +extern void add(int *, int *, int *); +%} +
+

When wrapped, you will be able to use the functions in a natural way from javascript. For example:

+

// Call the add() function with some pointers +example.add(a, b, c); +
+

// In javascript the code look like as:

+

a = example.new_intp(); +example.intp_assign(a,37); +
+
    +
  • The first one creates an int-pointer instance.
  • +
  • The second one assigns it the value 37.
  • +
+

C++ classes

+

C++ classes are wrapped by javascript classes as well. For example, if you have this class,

+

class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; +}; +
+

you can use it in javascript like this:

+

print("Creating some objects:"); +c = new example.Circle(10); +print("area = " + c.area()); +
+

Class data members are accessed in the same manner as C structures.

+

Static class members and functions are mapped to javascript in a straight-forward manner:

+

class Spam { +public: + static void foo(); + static int bar; +}; +
+

In javascript, the static member can be access in this way:

+

// ----- Access a static member ----- +print("\nA access of static member is" + example.Spam.Foo); // access static member as properties of the class object. +
+

C++ inheritance

+

SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this

+

class A { +public: + void foo(); + virtual void bar(); +}; +class B: public A { +public: + virtual void bar(); +}; +
+

Those classes are wrapped into a hierarchy of javascript classes that reflect the same inheritance structure. All of the usual javascript utility functions work normally:

+

var a = new example.A(); +a.foo(); +a.bar(); +var b = new example.B(); +b.foo(); +b.bar(); +print("b.cPtr = " + b.getCPtr()); +
+

C++ overloaded functions

+

C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this:

+

void f(int val) { + std::cout << "Called f(int)." << std::endl; +} +void f(int val1, int val2) { + std::cout << "Called f(int, int)." << std::endl; +} +void f(const char* s) { + std::cout << "Called f(const char*)." << std::endl; +} +
+

You can use them in javascript in a straightforward manner:

+

example.f(1); +example.f(1, 2); +example.f("bla"); +
+

C++ operators

+

Certain C++ overloaded operators can be handled automatically by SWIG. Though, in javascript operator overloading is not possible. Instead one has to make use of the %rename feature.

+

For example, consider a class like this:

+

/* File : example.h */ +#include <math.h> +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; +
+

When wrapped, it works like you expect:

+

a = new example.Complex(2,3); +b = new example.Complex(-5,10); + +print ("a =" + a); +print ("b =" + b); + +c = a.plus(b); + +print("c =" + c); +print("a*b =" + a.times(b)); +print("a-c =" + a.minus(c)); + +e = example.Complex.copy(a.minus(c)); +print("e =" + e); + +// Big expression +f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); +print("f =" + f); +
+

One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this

+

class Complex { +... +friend Complex operator+(double, const Complex &c); +... +}; +
+

then SWIG ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example:

+

%rename(Complex_add_dc) operator+(double, const Complex &);

+

There are ways to make this operator appear as part of the class using the %extend directive.

+

C++ namespaces:

+

SWIG is aware of C++ namespaces, but namespace names do not appear in the module nor do namespaces result in a module that is broken up into submodules or packages. For example, if you have a file like this,

+

%module example +namespace nspace { +extern int gcd(int x, int y); +extern double Foo; +class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; + }; +} +
+

for namespaces, you use the %feature directive in interface file. %feature attaches a new attribute to any parse tree node that matches given prototype.

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%feature("nspace", 1); +%include "example.h" +
+

it works in javascript as follows:

+

print("Global variable Foo=" + example.nspace.Foo); +example.nspace.Foo = 5; +print("Variable Foo changed to " + example.nspace.Foo); +print("GCD of number 6,18 is " + example.nspace.gcd(6,18)); +print("Creating some objects:"); +c = new example.nspace.Circle(10); +print("area = " + c.area()); +
+

If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example:

+

%rename(Bar_spam) Bar::spam; +namespace Foo { + int spam(); +} +namespace Bar { + int spam(); +} +
+

If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence.

+

C++ templates

+

C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example:

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ +%template(maxint) max<int>; +%template(maxdouble) max<double>; +%template(vecint) vector<int>; +%template(vecdouble) vector<double>; +
+

In javascript:

+

//Call some templated functions +print(example.maxint(3,7)); +print(example.maxdouble(3.14,2.18)); + +// Create some class + +iv = new example.vecint(100); +dv = new example.vecdouble(1000); + +for(i=0;i<=100;i++) + iv.setitem(i,2*i); + +for(i=0;i<=1000;i++) + dv.setitem(i, 1.0/(i+1)); + +sum = 0; +for(i=0;i<=100;i++) + sum = sum + iv.getitem(i); + +print(sum); + +sum = 0.0; +for(i=0;i<=1000;i++) + sum = sum + dv.getitem(i); +print(sum); +
+

Exception handling

+

The SWIG %exception directive can be used to create a user-definable exception handler for converting exceptions in your C/C++ program into javascript exceptions. The chapter on customization features contains more details, but suppose you have a C++ class like the following:

+

Since several methods in this class can throw an exception for an out-of-bounds access, you might want to catch this in the javascript extension by writing the following in an interface file:

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" +
+

Actually in JS there is no support for typed exceptions.For now there is support for integer and string exception. Example for integer exception

+

JSValueRef jsc_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +*exception = JSValueMakeNumber(context, 13); +int result = (int)gcd(arg1,arg2); +JSValueRef jsresult = JSValueMakeNumber(context, result); +
+

and for string exception:

+

JSValueRef wrap_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +JSStringRef message = JSStringCreateWithUTF8CString("This is a test error."); +*exception = JSValueMakeString(context, message); +JSStringRelease(message); +int result = (int)gcd(arg1,arg2); +JSValueRef jscresult = JSValueMakeNumber(context, result); +return jsresult; +} +
+

How to use generated modules?

+

Basically there is no standard extension mechanism in Javascript. We provided a custom interpreter with extension abilities. If JSC is embedded into a custom application, one has to make use of a generated module initializer function that allows easy extension of interpreter. The basic approach is as follows:

+

Basic Mechanism

+
    +
  • Creating the context
  • +
  • Calling module initializer
  • +
  • Evaluate Javascript
  • +
+

Creating the context

+

JSGlobalContextRef context = JSGlobalContextCreate(NULL); +JSObjectRef globalObject = JSContextGetGlobalObject(context); +... +
+

Calling module initializer

+

extern int example_init(JSGlobalContextRef context); + ... + example_init(context); + ... +
+

Evaluate Javascript

+

// Evaluate the javascript +char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str()); +JSStringRef jsScript; +if(!scriptContent) { + printf("FAIL: runme script could not be loaded.\n"); + failed = 1; + } + else { + JSValueRef ex; + jsScript = JSStringCreateWithUTF8CString(scriptContent); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); + if (!jsResult && ex) { + jsc_printError(context, ex, scriptPath); + failed = 1; + } + } + if (scriptContent != NULL) { + free(scriptContent); + } + JSStringRelease(jsScript); + JSGlobalContextRelease(context); + globalObject = 0; + for(std::vector<HANDLE>::iterator it = loaded_modules.begin(); + it != loaded_modules.end(); ++it) { + HANDLE handle = *it; + dlclose(handle); + } + if (failed) { + printf("FAIL: Some tests failed.\n"); + return 1; + } +} +
+

Typemaps

+

A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from javascript to C, you might define a typemap like this:

+

%typemap(in) int { + $1 = ($1_ltype)JSValueToNumber(context, $input, NULL); %} + printf("Received an integer : %d\n",$1); +} +
+

Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int.

+

Javascript typemaps

+

The previous section illustrated an "in" typemap for converting javascript objects to C. A variety of different typemap methods are defined by the javascript module. For example, to convert a C integer back into a javascript object, you might define an "out" typemap like this:

+

%typemap(out) int { + $result = JSValueMakeNumber(context, $1); +} +
+

The Javascript module makes use of Swig's unified template library.

+

Typemap variables

+

Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables:

+

$1: A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Javascript.

+

$input: A javascript Object * holding a raw javascript object with an argument or variable value.

+

$result: A javascript Object * that holds the result to be returned to javascript.

+

$1_name: The parameter name that was matched.

+

$1_type: The actual C datatype matched by the typemap.

+

$1_ltype: An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of $1_type. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned.

+

$symname: The javascript name of the wrapper function being created.

+

Javascript: Specification of a Code Generator for JSC

+

The module implementation tries to accomplish a separation of logic and code generation by making use of code templates. In the following, the templates are explained.

+

Top Level structure

+

The generated code consists of the following blocks:

+

<RUNTIME> +<INCLUDES> +<HELPER_FUNCTIONS> +<FUNCTION_WRAPPERS> +<INITIALIZER> +
+
    +
  • RUNTIME: runtime code generated by swig
  • +
  • HELPER_FUNCTIONS: static, from swg-file
  • +
  • INCLUDES: static, module property
  • +
  • FUNCTION_WRAPPERS: dynamically growing, on method declarations
  • +
  • INITIALIZER: dynamically growing, aggregates everything
  • +
+

INCLUDES

+

#include <JavaScriptCore/JavaScript.h> +<USER_DEFINED_INCLUDES> +
+

USER_DEFINED_INCLUDES: a module property

+

HELPER_FUNCTIONS

+

A lot of boiler-plate code can be shifted into static helper functions:

+

bool JS_registerClass(JSGlobalContextRef& context, JSObjectRef& parentObject,const char* className, + JSClassDefinition* definition) { + JSStringRef js_className = JSStringCreateWithUTF8CString(className); + JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); + JSObjectSetProperty(context, parentObject,js_className, classObject,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_className); + return true; +} + +bool JS_registerNamespace(JSGlobalContextRef& context,JSObjectRef& namespaceObj,JSObjectRef& parentNamespace,const char* name) +{ + JSStringRef js_name = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(context, parentNamespace,js_name, namespaceObj,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_name); + return true; +} + +bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context,object,js_functionName,JSObjectMakeFunctionWithCallback(context, + js_functionName, callback), kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} +bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char buffer[256]; + char msg[512]; + int res; + JSStringGetUTF8CString(propertyName, buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } + return false; +} + +JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { + JSValueRef val; + JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); + val = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return val; +} +
+

FUNCTION_WRAPPERS

+

There are different types of function wrappers: - Member Functions - Getproperty / Setproperty - Global Functions (global/namespace/class) - Constructors / Destructors

+

Member Functions

+

JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • functionname: the name of generated wrapper for function
  • +
  • LOCALS: declarations for input arguments
  • +
  • CODE: contains input marshalling, the action, and output marshalling
  • +
+

Setproperty

+

bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • setname: the name of the generated wrapper for setproperty.
  • +
  • LOCALS: declarations for input arguments
  • +
  • CODE: contains input marshalling, and the action
  • +
+

Getproperty

+

JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • getname: the name of the generated wrapper for the getproperty
  • +
  • LOCALS: declarations for output arguments
  • +
  • CODE: contains the action, and output marshalling
  • +
+

Global Functions

+

JSStaticValue ${namespace}_values[] = { + ${jsglobalvariables} + { 0, 0, 0, 0 } +}; +JSStaticFunction ${namespace}_functions[] = { + ${jsglobalfunctions} + { 0, 0, 0 } +}; +JSClassDefinition ${namespace}_classDefinition; +
+

Variable declaration

+

{"${propertyname}",${getname}, ${setname}, kJSPropertyAttributeNone} +
+

This is used to fill variable definition tables. kJSPropertyAttributeNone is JSC specific and means that the variable has a getter and setter. Even for read-only variables a setter is used which throws an exception.

+

Constructor

+

~~

+

JSObjectRef wrap_createclassnamemangled{overloadext}(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { ${LOCALS} ${CODE} return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_${type_mangled}, SWIG_POINTER_OWN);

+
goto fail;
+fail:
+return NULL;
+
+

}

+
- `classname_mangled` is the mangled qualified class name,   e.g., `foo::A -> foo_A`
+- `LOCALS`: declarations for input arguments 
+- `CODE`: contains input marshalling, and the action 
+
+## Destructors
+
+

void wrap${classname_mangled}_finalize(JSObjectRef thisObject) { SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); if(t && t->swigCMemOwn) delete (${type}*)(t->swigCObject); if(t) delete t; }

+

- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + +## Initializer +
+

bool ${modulename}_initialize(JSGlobalContextRef context) { SWIG_InitializeModule(0);

+
JSObjectRef global_object = JSContextGetGlobalObject(context);
+
+/* Initialize the base swig type object */
+_SwigObject_objectDefinition.staticFunctions = _SwigObject_functions;
+_SwigObject_objectDefinition.staticValues = _SwigObject_values;
+_SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition);
+
+/* Create objects for namespaces */
+${create_namespaces}
+
+/* Create classes */
+${initializercode}
+
+/* Register namespaces */
+${register_namespaces}
+
+return true;
+
+

}

+

## Class template defintions + +A class is specified by a static part (`*_classDefinition`) and a dynamic part (`*_objectDefinition`). +
+

${classname_mangled}_classDefinition.staticFunctions = ${classname_mangled}_staticFunctions; ${classname_mangled}_classDefinition.staticValues = ${classname_mangled}_staticValues; ${classname_mangled}_classDefinition.callAsConstructor = _wrap_create_${classname_mangled}; ${classname_mangled}_objectDefinition.staticValues = ${classname_mangled}_values; ${classname_mangled}_objectDefinition.staticFunctions = ${classname_mangled}_functions; ${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef; JSClassRef ${classname_mangled}_classRef = JSClassCreate(&${classname_mangled}objectDefinition); SWIGTYPE${classtype_mangled}->clientdata = ${classname_mangled}_classRef;%}

+

Notes: +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + which is retrieved by `Swig_name_mangle(Getattr(n, "name"))` +- ClassDefinitions are built using the staticValues array and the staticFunction array. The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties to the class object. + +## Inheritance +
+

{${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef};

+

- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` +- Note: multiple inheritance is not possible; thus we will always take the first parent class + +## Namespaces + +Namespaces are objects without class templates. i.e., instances are created, referenced locally, used as contexts for other registrations, and stored in the according parent contexts. +
+

${namespace}_classDefinition.staticFunctions = ${namespace}_functions; ${namespace}_classDefinition.staticValues = ${namespace}_values; JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL);

+

## Registration + +The registration part consists of registering classes at contexts (i.e., global or namespace), methods and properties at classes or contexts, and namespaces as objects at parent contexts. + +* Global functions +
+

JS_registerFunction(${context}, ${context_object}, "${functionname}", ${functionwrapper}

+

* Classes +
+

JS_registerClass(context, ${namespace}_object, "${classname}", &${classname_mangled}_classDefinition)

+

Note: every class template has an associated constructor function wrapper, which is registered here + +* Namespaces +
+

${namespace}_classDefinition.staticFunctions = ${namespace}_functions; ${namespace}_classDefinition.staticValues = ${namespace}_values; JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL);

+

Namespaces are registered using: +
+

JS_registerNamespace(context, ${namespace}_object, ${parent_namespace}_object, "${namespace}");

+

~~

+
+ + diff --git a/Doc/Manual/chapters b/Doc/Manual/chapters index 45d35e793..c5f655254 100644 --- a/Doc/Manual/chapters +++ b/Doc/Manual/chapters @@ -23,6 +23,7 @@ D.html Go.html Guile.html Java.html +Javascript.html Lisp.html Lua.html Modula3.html diff --git a/Doc/Manual/style.css b/Doc/Manual/style.css index 02329e56f..7eabf91ae 100644 --- a/Doc/Manual/style.css +++ b/Doc/Manual/style.css @@ -25,7 +25,7 @@ div.indent { margin-right: 4em; } -div.code { +div.code, div:not(.code) pre { border-style: solid; border-width: 1px; padding: 2pt; @@ -82,3 +82,7 @@ div.indent p { margin-right: 0; } +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + text-decoration:none; + color: #000000; +} diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 218d8eca5..c06f09f9a 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -589,6 +589,86 @@ java_clean: rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *@JAVASO@ +################################################################## +##### JAVASCRIPT ###### +################################################################## + +# Note: These targets are also from within Makefiles in the Example directories. +# There is a common makefile, 'Examples/javascript/js_example.mk' to simplify +# create a configuration for a new example. + + +ROOT_DIR = @ROOT_DIR@ +JSCFLAGS = @JSCFLAGS@ +JSCXXFLAGS = @JSCXXFLAGS@ +JSINCLUDES = @JSCOREINC@ @JSV8INC@ +JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ +JSLIBRARYPREFIX = @JSLIBRARYPREFIX@ +JSSO =@JSSO@ +JSLDSHARED = @JSLDSHARED@ +JSCXXSHARED = @JSCXXSHARED@ + +SWIGJS = $(SWIG) -javascript + +# ---------------------------------------------------------------- +# Creating and building Javascript wrappers +# ---------------------------------------------------------------- + +javascript_wrapper: + $(SWIGJS) $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH) + +javascript_wrapper_cpp: $(SRCS) + $(SWIGJS) -c++ $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.cxx $(INTERFACEPATH) + +javascript_build: $(SRCS) + $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) + $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + +javascript_build_cpp:: $(SRCS) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) + $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + +# TODO: make node-gyp configurable and detected via ./configure +javascript_build_node: $(SRCS) + node-gyp --loglevel=silent configure build 1>>/dev/null + +# These targets are used by the test-suite: + +javascript: $(SRCS) javascript_custom_interpreter + $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) + $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) + $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + +javascript_cpp: $(SRCS) javascript_custom_interpreter + $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) + $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Running a javascript example +# ----------------------------------------------------------------- + +javascript_custom_interpreter: + (cd $(ROOT_DIR)/Tools/javascript && $(MAKE) JSENGINE='$(JSENGINE)') + +javascript_run: javascript_custom_interpreter + $(ROOT_DIR)/Tools/javascript/javascript -$(JSENGINE) -L $(TARGET) runme.js + +# TODO: make node configurable and detected via ./configure +javascript_run_node: + node runme.js + +# ----------------------------------------------------------------- +# Cleaning the javascript examples +# ----------------------------------------------------------------- + +javascript_clean: + rm -rf build + rm -f *_wrap* runme + rm -f core @EXTRA_CLEAN@ + rm -f *.@OBJEXT@ *@JSSO@ *.$(SO) + (cd $(ROOT_DIR)/Tools/javascript && $(MAKE) -s clean) + ################################################################## ##### ANDROID ###### ################################################################## diff --git a/Examples/javascript/check.list b/Examples/javascript/check.list new file mode 100644 index 000000000..040267812 --- /dev/null +++ b/Examples/javascript/check.list @@ -0,0 +1,13 @@ +class +constant +enum +#exception +functor +#namespace +operator +overload +pointer +#reference +simple +template +variables diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/class/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/class/binding.gyp b/Examples/javascript/class/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/class/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/class/example.cxx b/Examples/javascript/class/example.cxx new file mode 100755 index 000000000..e23fa6f73 --- /dev/null +++ b/Examples/javascript/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ +#include +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/javascript/class/example.h b/Examples/javascript/class/example.h new file mode 100755 index 000000000..64b7684fa --- /dev/null +++ b/Examples/javascript/class/example.h @@ -0,0 +1,34 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; diff --git a/Examples/javascript/class/example.i b/Examples/javascript/class/example.i new file mode 100755 index 000000000..75700b305 --- /dev/null +++ b/Examples/javascript/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/javascript/class/example.js b/Examples/javascript/class/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/class/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/class/runme.js b/Examples/javascript/class/runme.js new file mode 100755 index 000000000..e1d5d9797 --- /dev/null +++ b/Examples/javascript/class/runme.js @@ -0,0 +1,46 @@ +var example = require("./example"); + +// ----- Object creation ----- + +console.log("Creating some objects:"); +c = new example.Circle(10); +console.log("Created circle " + c); +s = new example.Square(10); +console.log("Created square " + s); + +// ----- Access a static member ----- +console.log("\nA total of " + example.Shape.nshapes + " shapes were created"); // access static member as properties of the class object + +// ----- Member data access ----- +// Set the location of the object. +// Note: methods in the base class Shape are used since +// x and y are defined there. + +c.x = 20; +c.y = 30; +s.x = -10; +s.y = 5; + +console.log("\nHere is their new position:"); +console.log("Circle = (" + c.x + "," + c.y + ")"); +console.log("Square = (" + s.x + "," + s.y + ")"); + +// ----- Call some methods ----- +console.log("\nHere are some properties of the shapes:"); +console.log("Circle:"); +console.log("area = " + c.area() + ""); +console.log("perimeter = " + c.perimeter() + ""); +console.log("\n"); +console.log("Square:"); +console.log("area = " + s.area() + ""); +console.log("perimeter = " + s.perimeter() + ""); + +// ----- Delete everything ----- +console.log("\nGuess I'll clean up now"); +// Note: this invokes the virtual destructor +delete c; +delete s; + +console.log(example.Shape.nshapes + " shapes remain"); + +console.log("Goodbye"); diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile new file mode 100755 index 000000000..a2570636e --- /dev/null +++ b/Examples/javascript/constant/Makefile @@ -0,0 +1,3 @@ +SRCS = + +include ../js_example.mk diff --git a/Examples/javascript/constant/binding.gyp b/Examples/javascript/constant/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/constant/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/constant/example.h b/Examples/javascript/constant/example.h new file mode 100644 index 000000000..2c88ebd1e --- /dev/null +++ b/Examples/javascript/constant/example.h @@ -0,0 +1,8 @@ +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" +#define EXTERN extern +#define FOO (ICONST + BAR) diff --git a/Examples/javascript/constant/example.i b/Examples/javascript/constant/example.i new file mode 100755 index 000000000..a6d28e7c9 --- /dev/null +++ b/Examples/javascript/constant/example.i @@ -0,0 +1,24 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following directives also produce constants */ +%constant int iconst = 37; +%constant double fconst = 3.14; diff --git a/Examples/javascript/constant/example.js b/Examples/javascript/constant/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/constant/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/constant/runme.js b/Examples/javascript/constant/runme.js new file mode 100755 index 000000000..2188bf099 --- /dev/null +++ b/Examples/javascript/constant/runme.js @@ -0,0 +1,14 @@ +var example = require("./example"); + +console.log("ICONST = " + example.ICONST + " (should be 42)\n"); +console.log("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +console.log("CCONST = " + example.CCONST + " (should be 'x')\n"); +console.log("CCONST2 = " + example.CCONST2 + " (this should be on a new line)\n"); +console.log("SCONST = " + example.SCONST + " (should be 'Hello World')\n"); +console.log("SCONST2 = " + example.SCONST2 + " (should be '\"Hello World\"')\n"); +console.log("EXPR = " + example.EXPR + " (should be 48.5484)\n"); +console.log("iconst = " + example.iconst + " (should be 37)\n"); +console.log("fconst = " + example.fconst + " (should be 3.14)\n"); + +console.log("EXTERN = " + example.EXTERN + " (should be undefined)\n"); +console.log("FOO = " + example.FOO + " (should be undefined)\n"); diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/enum/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/enum/binding.gyp b/Examples/javascript/enum/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/enum/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/enum/example.cxx b/Examples/javascript/enum/example.cxx new file mode 100755 index 000000000..6785e57ac --- /dev/null +++ b/Examples/javascript/enum/example.cxx @@ -0,0 +1,37 @@ +/* File : example.c */ + +#include "example.h" +#include + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/Examples/javascript/enum/example.h b/Examples/javascript/enum/example.h new file mode 100755 index 000000000..9119cd9fc --- /dev/null +++ b/Examples/javascript/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/Examples/javascript/enum/example.i b/Examples/javascript/enum/example.i new file mode 100755 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/javascript/enum/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/javascript/enum/example.js b/Examples/javascript/enum/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/enum/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/enum/runme.js b/Examples/javascript/enum/runme.js new file mode 100755 index 000000000..d4e89e8c8 --- /dev/null +++ b/Examples/javascript/enum/runme.js @@ -0,0 +1,34 @@ +var example = require("./example"); + +// ----- Object creation ----- + +// Print out the value of some enums +console.log("*** color ***"); +console.log(" RED =" + example.RED); +console.log(" BLUE =" + example.BLUE); +console.log(" GREEN =" + example.GREEN); + +console.log("\n*** Foo::speed ***"); +console.log(" Foo_IMPULSE =" + example.Foo.IMPULSE); +console.log(" Foo_WARP =" + example.Foo.WARP); +console.log(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); + +console.log("\nTesting use of enums with functions\n"); + +example.enum_test(example.RED, example.Foo.IMPULSE); +example.enum_test(example.BLUE, example.Foo.WARP); +example.enum_test(example.GREEN, example.Foo.LUDICROUS); +example.enum_test(1234,5678); + +console.log("\nTesting use of enum with class method"); +f = new example.Foo(); + +f.enum_test(example.Foo.IMPULSE); +f.enum_test(example.Foo.WARP); +f.enum_test(example.Foo.LUDICROUS); + +// enum value BLUE of enum color is accessed as property of cconst +console.log("example.BLUE= " + example.BLUE); + +// enum value LUDICROUS of enum Foo::speed is accessed as as property of cconst +console.log("example.speed.LUDICROUS= " + example.Foo.LUDICROUS); diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/exception/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/exception/binding.gyp b/Examples/javascript/exception/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/exception/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/exception/example.cxx b/Examples/javascript/exception/example.cxx new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Examples/javascript/exception/example.cxx @@ -0,0 +1 @@ + diff --git a/Examples/javascript/exception/example.h b/Examples/javascript/exception/example.h new file mode 100644 index 000000000..7cf917d01 --- /dev/null +++ b/Examples/javascript/exception/example.h @@ -0,0 +1,53 @@ +/* File : example.h */ + +#include +#ifndef SWIG +struct A { +}; +#endif + +class Exc { +public: + Exc(int c, const char *m) { + code = c; + strncpy(msg,m,256); + } + int code; + char msg[256]; +}; + +#if defined(_MSC_VER) + #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + +class Test { +public: + int simple() throw(int) { + throw(37); + return 1; + } + int message() throw(const char *) { + throw("I died."); + return 1; + } + int hosed() throw(Exc) { + throw(Exc(42,"Hosed")); + return 1; + } + int unknown() throw(A*) { + static A a; + throw &a; + return 1; + } + int multi(int x) throw(int, const char *, Exc) { + if (x == 1) throw(37); + if (x == 2) throw("Bleah!"); + if (x == 3) throw(Exc(42,"No-go-diggy-die")); + return 1; + } +}; + +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + diff --git a/Examples/javascript/exception/example.i b/Examples/javascript/exception/example.i new file mode 100644 index 000000000..08672c3a8 --- /dev/null +++ b/Examples/javascript/exception/example.i @@ -0,0 +1,12 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/javascript/exception/example.js b/Examples/javascript/exception/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/exception/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/exception/runme.js b/Examples/javascript/exception/runme.js new file mode 100644 index 000000000..977f51ebc --- /dev/null +++ b/Examples/javascript/exception/runme.js @@ -0,0 +1,64 @@ +var example = require("./example"); + +console.log("Trying to catch some exceptions."); +t = new example.Test(); +try{ + t.unknown(); + throw -1; +} catch(error) +{ + if(error == -1) { + console.log("t.unknown() didn't throw"); + } else { + console.log("successfully catched throw in Test::unknown()."); + } +} + +try{ + t.simple(); + throw -1; +} +catch(error){ + if(error == -1) { + console.log("t.simple() did not throw"); + } else { + console.log("successfully catched throw in Test::simple()."); + } +} + +try{ + t.message(); + throw -1; +} catch(error){ + if(error == -1) { + console.log("t.message() did not throw"); + } else { + console.log("successfully catched throw in Test::message()."); + } +} + +try{ + t.hosed(); + throw -1; +} +catch(error){ + if(error == -1) { + console.log("t.hosed() did not throw"); + } else { + console.log("successfully catched throw in Test::hosed()."); + } +} + +for (var i=1; i<4; i++) { + try{ + t.multi(i); + throw -1; + } + catch(error){ + if(error == -1) { + console.log("t.multi(" + i + ") did not throw"); + } else { + console.log("successfully catched throw in Test::multi()."); + } + } +} diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/functor/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/functor/binding.gyp b/Examples/javascript/functor/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/functor/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/functor/example.cxx b/Examples/javascript/functor/example.cxx new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/functor/example.i b/Examples/javascript/functor/example.i new file mode 100644 index 000000000..0450c2124 --- /dev/null +++ b/Examples/javascript/functor/example.i @@ -0,0 +1,25 @@ +/* File : example.i */ +%module example + + +%inline %{ +// From B. Strousjoup, "The C++ Programming Language, Third Edition", p. 514 +template class Sum { + T res; +public: + Sum(T i = 0) : res(i) { } + void operator() (T x) { res += x; } + T result() const { return res; } +}; + +%} + +%rename(call) *::operator(); // the fn call operator + +// Instantiate a few versions +%template(intSum) Sum; +%template(doubleSum) Sum; + + + + diff --git a/Examples/javascript/functor/example.js b/Examples/javascript/functor/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/functor/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/functor/runme.js b/Examples/javascript/functor/runme.js new file mode 100644 index 000000000..dc12470f4 --- /dev/null +++ b/Examples/javascript/functor/runme.js @@ -0,0 +1,15 @@ +var example = require("./example"); + +a = new example.intSum(0); +b = new example.doubleSum(100.0); + +// Use the objects. They should be callable just like a normal +// javascript function. + +for (i=1;i<=100;i++) + a.call(i); // Note: function call + b.call(Math.sqrt(i)); // Note: function call + +console.log(a.result()); +console.log(b.result()); + diff --git a/Examples/javascript/js_example.mk b/Examples/javascript/js_example.mk new file mode 100644 index 000000000..6cb6eb113 --- /dev/null +++ b/Examples/javascript/js_example.mk @@ -0,0 +1,52 @@ +# Note: as a convention an example must be in a child directory of this. +# These paths are relative to such an example directory +EXAMPLES_TOP=../.. +SWIG_TOP=../../.. + +SWIG = $(SWIG_TOP)/preinst-swig + +# TODO: we could only set these only if not yet set... +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +ifneq (, $(ENGINE)) + JSENGINE=$(ENGINE) +else + JSENGINE=node +endif + +SWIGOPT=-$(JSENGINE) + +ifeq (node,$(JSENGINE)) + +build: wrapper + $(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' JSENGINE='$(JSENGINE)' javascript_build_node + +else + +build: wrapper + $(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' JSENGINE='$(JSENGINE)' javascript_build_cpp + +endif + +wrapper: + $(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +ifeq (node,$(JSENGINE)) + +check: build + $(MAKE) -f $(EXAMPLES_TOP)/Makefile JSENGINE='$(JSENGINE)' javascript_run_node + +else + +check: build + $(MAKE) -f $(EXAMPLES_TOP)/Makefile JSENGINE='$(JSENGINE)' TARGET='$(TARGET)' javascript_run + +endif + +clean: + $(MAKE) -f $(EXAMPLES_TOP)/Makefile javascript_clean diff --git a/Examples/javascript/namespace/Makefile b/Examples/javascript/namespace/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/namespace/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/namespace/binding.gyp b/Examples/javascript/namespace/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/namespace/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/namespace/example.cxx b/Examples/javascript/namespace/example.cxx new file mode 100644 index 000000000..5beeb09fe --- /dev/null +++ b/Examples/javascript/namespace/example.cxx @@ -0,0 +1,36 @@ +/* File : example.c */ + +#include +#include "example.h" + +#define M_PI 3.14159 + + +/* A global variable */ +namespace nspace +{ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +Circle::Circle(): radius(1.0) {} + +Circle::Circle(double r): radius(r) { + std::cout << "created Circle with r=" << radius << std::endl; +} + +double Circle::area() { + std::cout << "Circle::area called, r=" << radius << std::endl; + return M_PI*radius*radius; +} +} diff --git a/Examples/javascript/namespace/example.h b/Examples/javascript/namespace/example.h new file mode 100644 index 000000000..7f76c2f07 --- /dev/null +++ b/Examples/javascript/namespace/example.h @@ -0,0 +1,20 @@ + +namespace nspace { + +extern int gcd(int x, int y); +extern double Foo; + +class Circle +{ +public: + Circle(); + + Circle(double r); + + double area(); + + double radius; + +}; + +} diff --git a/Examples/javascript/namespace/example.i b/Examples/javascript/namespace/example.i new file mode 100644 index 000000000..e14b10b44 --- /dev/null +++ b/Examples/javascript/namespace/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%feature("nspace", 1); + +%include "example.h" diff --git a/Examples/javascript/namespace/example.js b/Examples/javascript/namespace/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/namespace/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/namespace/runme.js b/Examples/javascript/namespace/runme.js new file mode 100644 index 000000000..08e0d3769 --- /dev/null +++ b/Examples/javascript/namespace/runme.js @@ -0,0 +1,10 @@ +var example = require("./example"); + +console.log("Global variable Foo=" + example.nspace.Foo); +example.nspace.Foo = 5; +console.log("Variable Foo changed to " + example.nspace.Foo); +console.log("GCD of number 6,18 is " + example.nspace.gcd(6,18)); + +console.log("Creating some objects:"); +c = new example.nspace.Circle(10); +console.log("area = " + c.area()); diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile new file mode 100755 index 000000000..a2570636e --- /dev/null +++ b/Examples/javascript/operator/Makefile @@ -0,0 +1,3 @@ +SRCS = + +include ../js_example.mk diff --git a/Examples/javascript/operator/binding.gyp b/Examples/javascript/operator/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/operator/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/operator/example.h b/Examples/javascript/operator/example.h new file mode 100644 index 000000000..4da6a2307 --- /dev/null +++ b/Examples/javascript/operator/example.h @@ -0,0 +1,36 @@ +/* File : example.h */ +#include + +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; + + + + + diff --git a/Examples/javascript/operator/example.i b/Examples/javascript/operator/example.i new file mode 100644 index 000000000..7a1bd45e1 --- /dev/null +++ b/Examples/javascript/operator/example.i @@ -0,0 +1,34 @@ +/* File : example.i */ +%module example +#pragma SWIG nowarn=SWIGWARN_IGNORE_OPERATOR_EQ +%{ +#include "example.h" +%} + +/* This header file is a little tough to handle because it has overloaded + operators and constructors. We're going to try and deal with that here */ + +/* This turns the copy constructor in a function ComplexCopy() that can + be called */ + +%rename(assign) Complex::operator=; +%rename(plus) Complex::operator+; +%rename(minus) Complex::operator-(const Complex &) const; +%rename(uminus) Complex::operator-() const; +%rename(times) Complex::operator*; + +/* Now grab the original header file */ +%include "example.h" + +/* An output method that turns a complex into a short string */ +%extend Complex { + char *toString() { + static char temp[512]; + sprintf(temp,"(%g,%g)", $self->re(), $self->im()); + return temp; + } + static Complex* copy(const Complex& c) { + return new Complex(c); + } +}; + diff --git a/Examples/javascript/operator/example.js b/Examples/javascript/operator/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/operator/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/operator/runme.js b/Examples/javascript/operator/runme.js new file mode 100644 index 000000000..a700918d6 --- /dev/null +++ b/Examples/javascript/operator/runme.js @@ -0,0 +1,25 @@ +var example = require("./example"); + +a = new example.Complex(2,3); +b = new example.Complex(-5,10); + +console.log ("a =" + a); +console.log ("b =" + b); + +c = a.plus(b); + +console.log("c =" + c); +console.log("a*b =" + a.times(b)); +console.log("a-c =" + a.minus(c)); + +e = example.Complex.copy(a.minus(c)); +console.log("e =" + e); + +// Big expression +f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); +console.log("f =" + f); + + + + + diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile new file mode 100755 index 000000000..a2570636e --- /dev/null +++ b/Examples/javascript/overload/Makefile @@ -0,0 +1,3 @@ +SRCS = + +include ../js_example.mk diff --git a/Examples/javascript/overload/binding.gyp b/Examples/javascript/overload/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/overload/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/overload/example.h b/Examples/javascript/overload/example.h new file mode 100644 index 000000000..2f112f1e1 --- /dev/null +++ b/Examples/javascript/overload/example.h @@ -0,0 +1,28 @@ +#include + +void f() { + std::cout << "Called f()." << std::endl; +} + +void f(int val) { + std::cout << "Called f(int)." << std::endl; +} +void f(int val1, int val2) { + std::cout << "Called f(int, int)." << std::endl; +} + +void f(const char* s) { + std::cout << "Called f(const char*)." << std::endl; +} + +void f(bool val) { + std::cout << "Called f(bool)." << std::endl; +} + +void f(long val) { + std::cout << "Called f(long)." << std::endl; +} + +void f(double val) { + std::cout << "Called f(double)." << std::endl; +} diff --git a/Examples/javascript/overload/example.i b/Examples/javascript/overload/example.i new file mode 100644 index 000000000..b86689f8a --- /dev/null +++ b/Examples/javascript/overload/example.i @@ -0,0 +1,16 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* + Note: overloading is implemented in a sloppy way currently + i.e., only the number of arguments is taken into conideration + for dispatching. + To solve the problem one has to rename such conflicting methods. +*/ +%rename(f_double) f(double val); + +%include "example.h" diff --git a/Examples/javascript/overload/example.js b/Examples/javascript/overload/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/overload/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/overload/runme.js b/Examples/javascript/overload/runme.js new file mode 100644 index 000000000..1e6c861a6 --- /dev/null +++ b/Examples/javascript/overload/runme.js @@ -0,0 +1,9 @@ +var example = require("./example"); + +example.f(); +example.f(1); +example.f(1, 2); +example.f("bla"); +example.f(false); +example.f(11111111111); +example.f_double(1.0); diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/pointer/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/pointer/binding.gyp b/Examples/javascript/pointer/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/pointer/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/pointer/example.cxx b/Examples/javascript/pointer/example.cxx new file mode 100755 index 000000000..8762329fe --- /dev/null +++ b/Examples/javascript/pointer/example.cxx @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(int *x, int *y, int *result) { + *result = *x + *y; +} + +void subtract(int *x, int *y, int *result) { + *result = *x - *y; +} + +int divide(int n, int d, int *r) { + int q; + q = n/d; + *r = n - q*d; + return q; +} diff --git a/Examples/javascript/pointer/example.i b/Examples/javascript/pointer/example.i new file mode 100755 index 000000000..38c67d7d2 --- /dev/null +++ b/Examples/javascript/pointer/example.i @@ -0,0 +1,30 @@ +/* File : example.i */ +%module example + +%{ +extern void add(int *, int *, int *); +extern void subtract(int *, int *, int *); +extern int divide(int, int, int *); +%} + +/* This example illustrates a couple of different techniques + for manipulating C pointers */ + +/* First we'll use the pointer library */ +extern void add(int *x, int *y, int *result); +%include cpointer.i +%pointer_functions(int, intp); + +/* Next we'll use some typemaps */ + +%include typemaps.i +extern void subtract(int *INPUT, int *INPUT, int *OUTPUT); + +/* Next we'll use typemaps and the %apply directive */ + +%apply int *OUTPUT { int *r }; +extern int divide(int n, int d, int *r); + + + + diff --git a/Examples/javascript/pointer/example.js b/Examples/javascript/pointer/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/pointer/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/pointer/runme.js b/Examples/javascript/pointer/runme.js new file mode 100755 index 000000000..7f1e51c9e --- /dev/null +++ b/Examples/javascript/pointer/runme.js @@ -0,0 +1,35 @@ +var example = require("./example"); + +// First create some objects using the pointer library. +console.log("Testing the pointer library\n"); +a = example.new_intp(); +b = example.new_intp(); +c = example.new_intp(); + +example.intp_assign(a,37); +example.intp_assign(b,42); + +console.log(" a = " + example.intp_value(a) + "\n"); +console.log(" b = " + example.intp_value(b) + "\n"); +console.log(" c = " + example.intp_value(c) + "\n"); + +//// Call the add() function with some pointers +example.add(a, b, c); + +// +//// Now get the result +r = example.intp_value(c); +console.log(" 37 + 42 = " + r + "\n"); + +// Clean up the pointers +example.delete_intp(a); +example.delete_intp(b); +example.delete_intp(c); + +//// Now try the typemap library +//// This should be much easier. Now how it is no longer +//// necessary to manufacture pointers. +//"OUTPUT" Mapping is not supported +//console.log("Trying the typemap library"); +//r = example.subtract(37,42); +//console.log("37 - 42 =" + r); diff --git a/Examples/javascript/pointer/typemaps.i b/Examples/javascript/pointer/typemaps.i new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/reference/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/reference/binding.gyp b/Examples/javascript/reference/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/reference/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/reference/example.cxx b/Examples/javascript/reference/example.cxx new file mode 100755 index 000000000..8a513bf49 --- /dev/null +++ b/Examples/javascript/reference/example.cxx @@ -0,0 +1,46 @@ +/* File : example.cxx */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include "example.h" +#include +#include + +Vector operator+(const Vector &a, const Vector &b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +char *Vector::print() { + static char temp[512]; + sprintf(temp,"Vector %p (%g,%g,%g)", this, x,y,z); + return temp; +} + +VectorArray::VectorArray(int size) { + items = new Vector[size]; + maxsize = size; +} + +VectorArray::~VectorArray() { + delete [] items; +} + +Vector &VectorArray::operator[](int index) { + if ((index < 0) || (index >= maxsize)) { + printf("Panic! Array index out of bounds.\n"); + exit(1); + } + return items[index]; +} + +int VectorArray::size() { + return maxsize; +} + diff --git a/Examples/javascript/reference/example.h b/Examples/javascript/reference/example.h new file mode 100755 index 000000000..4915adb1b --- /dev/null +++ b/Examples/javascript/reference/example.h @@ -0,0 +1,26 @@ +/* File : example.h */ + +class Vector { +private: + double x,y,z; +public: + Vector() : x(0), y(0), z(0) { }; + Vector(double x, double y, double z) : x(x), y(y), z(z) { }; + friend Vector operator+(const Vector &a, const Vector &b); + char *print(); +}; + +class VectorArray { +private: + Vector *items; + int maxsize; +public: + VectorArray(int maxsize); + ~VectorArray(); + Vector &operator[](int); + int size(); +}; + + + + diff --git a/Examples/javascript/reference/example.i b/Examples/javascript/reference/example.i new file mode 100755 index 000000000..1cf19c82c --- /dev/null +++ b/Examples/javascript/reference/example.i @@ -0,0 +1,42 @@ +/* File : example.i */ + +/* This file has a few "typical" uses of C++ references. */ + +%module example + +%{ +#include "example.h" +%} + +class Vector { +public: + Vector(double x, double y, double z); + ~Vector(); + char *print(); +}; + +/* This helper function calls an overloaded operator */ +%inline %{ +Vector addv(Vector &a, Vector &b) { + return a+b; +} +%} + +/* Wrapper around an array of vectors class */ + +class VectorArray { +public: + VectorArray(int maxsize); + ~VectorArray(); + int size(); + + /* This wrapper provides an alternative to the [] operator */ + %extend { + Vector &get(int index) { + return (*$self)[index]; + } + void set(int index, Vector &a) { + (*$self)[index] = a; + } + } +}; diff --git a/Examples/javascript/reference/example.js b/Examples/javascript/reference/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/reference/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/reference/runme.js b/Examples/javascript/reference/runme.js new file mode 100755 index 000000000..935d2b948 --- /dev/null +++ b/Examples/javascript/reference/runme.js @@ -0,0 +1,67 @@ +// This file illustrates the manipulation of C++ references in Javascript. +var example = require("./example"); + +// ----- Object creation ----- + +console.log("Creating some objects:\n"); +a = new example.Vector(3,4,5); +b = new example.Vector(10,11,12); + +console.log(" created" + a.print()); +console.log(" created" + b.print()); + +// ----- Call an overloaded operator ----- + +// This calls the wrapper we placed around operator+(const Vector &a, const Vector &) +// It returns a new allocated object. + +console.log("Adding a+b\n"); +c = example.addv(a, b); +console.log("a+b = " + c.print()); + + +// TODO: Note: Unless we free the result, a memory leak will occur +//delete_Vector(c); + +// ----- Create a vector array ----- + +// Note: Using the high-level interface here +console.log("Creating an array of vectors\n"); +va = new example.VectorArray(10); +console.log("va = " + va + "\n"); + +// ----- Set some values in the array ----- + +// These operators copy the value of a and b to the vector array +va.set(0,a); +va.set(1,b); + +// This will work, but it will cause a memory leak! +va.set(2,example.addv(a,b)); + +// The non-leaky way to do it +//c = addv(a,b); +//va.set(3,c); +//delete_Vector(c); + +// Get some values from the array + +console.log("Getting some array values\n"); +for (i = 0; i < 5; i++) { + temp = va.get(i); + console.log(i,temp.print()); +} + +// Watch under resource meter to check on this +console.log("Making sure we don't leak memory.\n"); +for (i = 0; i < 1000000; i++) { + c = va.get(i % 10); +} +//---------TODO--------- +//----- Clean up ----- +//console.log("Cleaning up\n"); + +//example.delete_VectorArray(va); +//example.delete_Vector(a); +//example.delete_Vector(b); + diff --git a/Examples/javascript/reference/swig_gdb.log b/Examples/javascript/reference/swig_gdb.log new file mode 100644 index 000000000..57bca0306 --- /dev/null +++ b/Examples/javascript/reference/swig_gdb.log @@ -0,0 +1,22 @@ +Loaded swig printers +SwigStringPrinter: Could not convert const char* to string +SwigListIterator: Construction failed. + Cannot access memory at address 0x7d894828ec834853. +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigListIterator: Construction failed. + Cannot access memory at address 0x7d894828ec834853. +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not dereference struct String* diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/simple/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/simple/binding.gyp b/Examples/javascript/simple/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/simple/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/simple/example.cxx b/Examples/javascript/simple/example.cxx new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/Examples/javascript/simple/example.cxx @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/javascript/simple/example.i b/Examples/javascript/simple/example.i new file mode 100644 index 000000000..24093b9bf --- /dev/null +++ b/Examples/javascript/simple/example.i @@ -0,0 +1,7 @@ +/* File : example.i */ +%module example + +%inline %{ +extern int gcd(int x, int y); +extern double Foo; +%} diff --git a/Examples/javascript/simple/example.js b/Examples/javascript/simple/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/simple/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/simple/runme.js b/Examples/javascript/simple/runme.js new file mode 100755 index 000000000..be2c18669 --- /dev/null +++ b/Examples/javascript/simple/runme.js @@ -0,0 +1,26 @@ +var example = require("./example"); + +/* Call our gcd() function */ + +x = 42; +y = 105; +g = example.gcd(x,y); +console.log("GCD of x and y is=" + g); + +/* Manipulate the Foo global variable */ + +/* Output its current value */ +console.log("Global variable Foo=" + example.Foo); + +/* Change its value */ +example.Foo = 3.1415926; + +/* See if the change took effect */ +console.log("Variable Foo changed to=" + example.Foo); + + + + + + + diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile new file mode 100755 index 000000000..a2570636e --- /dev/null +++ b/Examples/javascript/template/Makefile @@ -0,0 +1,3 @@ +SRCS = + +include ../js_example.mk diff --git a/Examples/javascript/template/binding.gyp b/Examples/javascript/template/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/template/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/template/example.h b/Examples/javascript/template/example.h new file mode 100644 index 000000000..7401df650 --- /dev/null +++ b/Examples/javascript/template/example.h @@ -0,0 +1,32 @@ +/* File : example.h */ + +// Some template definitions + +template T max(T a, T b) { return a>b ? a : b; } + +template class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } +#ifdef SWIG + %extend { + T getitem(int index) { + return $self->get(index); + } + void setitem(int index, T val) { + $self->set(index,val); + } + } +#endif +}; + diff --git a/Examples/javascript/template/example.i b/Examples/javascript/template/example.i new file mode 100644 index 000000000..8f94c4da1 --- /dev/null +++ b/Examples/javascript/template/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ + +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + diff --git a/Examples/javascript/template/example.js b/Examples/javascript/template/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/template/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/template/runme.js b/Examples/javascript/template/runme.js new file mode 100644 index 000000000..55894dfd5 --- /dev/null +++ b/Examples/javascript/template/runme.js @@ -0,0 +1,30 @@ +var example = require("./example"); + +//Call some templated functions +console.log(example.maxint(3,7)); +console.log(example.maxdouble(3.14,2.18)); + +// Create some class + +iv = new example.vecint(100); +dv = new example.vecdouble(1000); + +for(i=0;i<=100;i++) + iv.setitem(i,2*i); + +for(i=0;i<=1000;i++) + dv.setitem(i, 1.0/(i+1)); + +sum = 0; +for(i=0;i<=100;i++) + sum = sum + iv.getitem(i); + +console.log(sum); + +sum = 0.0; +for(i=0;i<=1000;i++) + sum = sum + dv.getitem(i); +console.log(sum); + +delete iv; +delete dv; diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/variables/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/variables/binding.gyp b/Examples/javascript/variables/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/variables/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/variables/example.cxx b/Examples/javascript/variables/example.cxx new file mode 100755 index 000000000..3ad4c2323 --- /dev/null +++ b/Examples/javascript/variables/example.cxx @@ -0,0 +1,96 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include +#include +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +#ifdef __cplusplus // Note: for v8 this must be linkable with g++, without extern cstrvar is mangled +extern const char cstrvar[] = "Goodbye"; +#else +const char cstrvar[] = "Goodbye"; +#endif +const +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %p\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d,%d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/javascript/variables/example.h b/Examples/javascript/variables/example.h new file mode 100755 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/javascript/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/javascript/variables/example.i b/Examples/javascript/variables/example.i new file mode 100755 index 000000000..591b871ed --- /dev/null +++ b/Examples/javascript/variables/example.i @@ -0,0 +1,49 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Some global variable declarations */ +%inline %{ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char cstrvar[]; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; +%} + + +/* Some read-only variables */ + +%immutable; + +%inline %{ +extern int status; +extern char path[256]; +%} + +%mutable; + +/* Some helper functions to make it easier to test */ +%inline %{ +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); +%} + diff --git a/Examples/javascript/variables/example.js b/Examples/javascript/variables/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/variables/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/variables/runme.js b/Examples/javascript/variables/runme.js new file mode 100755 index 000000000..d07861713 --- /dev/null +++ b/Examples/javascript/variables/runme.js @@ -0,0 +1,68 @@ +var example = require("./example"); + +// Try to set the values of some global variables +example.ivar = 42; +example.svar = -31000; +example.lvar = 65537; +example.uivar = 123456; +example.usvar = 61000; +example.ulvar = 654321; +example.scvar = -13; +example.ucvar = 251; +example.cvar = "S"; +example.fvar = 3.14159; +example.dvar = 2.1828; +example.strvar = "Hello World"; +example.iptrvar= example.new_int(37); +example.ptptr = example.new_Point(37,42); +example.name = "Bill"; + +// Now console.log out the values of the variables +console.log("Variables (values console.loged from Python)" + "\n"); +console.log("ivar = " + example.ivar + "\n"); +console.log("svar = " + example.svar + "\n"); +console.log("lvar = " + example.lvar + "\n"); +console.log("uivar = " + example.uivar + "\n"); +console.log("usvar = " + example.usvar + "\n"); +console.log("ulvar = " + example.ulvar + "\n"); +console.log("scvar = " + example.scvar + "\n"); +console.log("ucvar = " + example.ucvar + "\n"); +console.log("fvar = " + example.fvar + "\n"); +console.log("dvar = " + example.dvar + "\n"); +console.log("cvar = " + example.cvar + "\n"); +console.log("strvar = " + example.strvar+ "\n"); +console.log("cstrvar = " + example.cstrvar+ "\n"); +console.log("iptrvar = " + example.iptrvar+ "\n"); +console.log("name = " + example.name + "\n"); +console.log("ptptr = " + example.ptptr + ": " + example.Point_print(example.ptptr) + "\n"); +console.log("pt = " + example.pt + ": " + example.Point_print(example.pt) + "\n"); + + +console.log("\nVariables (values console.loged from C)"); + +example.print_vars(); + +console.log("\nNow I'm going to try and modify some read only variables"); + +console.log("Tring to set 'path'"); +try{ + example.path = "Whoa!"; + console.log("Hey, what's going on?!?! This shouldn't work"); +} +catch(e){ + console.log("Good."); +} + +console.log("Trying to set 'status'"); +try{ + example.status = 0; + console.log("Hey, what's going on?!?! This shouldn't work"); +} catch(e){ + console.log("Good."); +} + +console.log("\nI'm going to try and update a structure variable.\n"); +example.pt = example.ptptr; +console.log("The new value is: "); +example.pt_print(); +console.log("You should see the value: " + example.Point_print(example.ptptr)); diff --git a/Examples/javascript/variables/swig_gdb.log b/Examples/javascript/variables/swig_gdb.log new file mode 100644 index 000000000..2fe437110 --- /dev/null +++ b/Examples/javascript/variables/swig_gdb.log @@ -0,0 +1,9 @@ +Loaded swig printers +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index b9239315a..14f13bed8 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -98,6 +98,7 @@ C_TEST_BROKEN += \ tag_no_clash_with_variable # C++ test cases. (Can be run individually using: make testcase.cpptest) +ifndef SKIP_CPP_CASES CPP_TEST_CASES += \ abstract_access \ abstract_inherit \ @@ -489,6 +490,7 @@ CPP_TEST_CASES += \ voidtest \ wallkw \ wrapmacro +endif # C++11 test cases. CPP11_TEST_CASES = \ @@ -562,6 +564,7 @@ CPP_TEST_CASES += $(CPP11_TEST_CASES) endif # C test cases. (Can be run individually using: make testcase.ctest) +ifndef SKIP_C_CASES C_TEST_CASES += \ arrays \ bom_utf8 \ @@ -612,9 +615,10 @@ C_TEST_CASES += \ typemap_subst \ union_parameter \ unions - +endif # Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest) +ifndef SKIP_MULTI_CPP_CASES MULTI_CPP_TEST_CASES += \ clientdata_prop \ imports \ @@ -623,6 +627,7 @@ MULTI_CPP_TEST_CASES += \ mod \ template_typedef_import \ multi_import +endif # Custom tests - tests with additional commandline options wallkw.cpptest: SWIGOPT += -Wallkw diff --git a/Examples/test-suite/constructor_copy.i b/Examples/test-suite/constructor_copy.i index bfbd706f4..8e92e7840 100644 --- a/Examples/test-suite/constructor_copy.i +++ b/Examples/test-suite/constructor_copy.i @@ -73,7 +73,7 @@ public: %include "std_vector.i" -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) #define SWIG_GOOD_VECTOR %ignore std::vector::vector(size_type); %ignore std::vector::resize(size_type); diff --git a/Examples/test-suite/director_nspace.i b/Examples/test-suite/director_nspace.i index fdea75e2f..f24227c68 100644 --- a/Examples/test-suite/director_nspace.i +++ b/Examples/test-suite/director_nspace.i @@ -40,7 +40,7 @@ namespace TopLevel %include // nspace feature only supported by these languages -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) || defined(SWIGJAVASCRIPT) %nspace TopLevel::Bar::Foo; %nspace TopLevel::Bar::FooBar; #else diff --git a/Examples/test-suite/infinity.i b/Examples/test-suite/infinity.i new file mode 100644 index 000000000..41741eb94 --- /dev/null +++ b/Examples/test-suite/infinity.i @@ -0,0 +1,48 @@ +%module infinity + +#include + +/* C99 defines INFINITY + Because INFINITY may be defined by compiler built-ins, we can't use #define. + Instead, expose the variable MYINFINITY and then use %rename to make it INFINITY in the scripting language. +*/ +%rename(INFINITY) MYINFINITY; + + +%inline %{ +#include + +/* C99 math.h defines INFINITY. If not available, this is the fallback. */ +#ifndef INFINITY + #ifdef _MSC_VER + union MSVC_EVIL_FLOAT_HACK + { + unsigned __int8 Bytes[4]; + float Value; + }; + static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}}; + #define INFINITY (INFINITY_HACK.Value) + #endif + + #ifdef __GNUC__ + #define INFINITY (__builtin_inf()) + #elif defined(__clang__) + #if __has_builtin(__builtin_inf) + #define INFINITY (__builtin_inf()) + #endif + #endif + + #ifndef INFINITY + #define INFINITY (1e1000) + #endif +#endif + +/* This will allow us to bind the real INFINITY value through SWIG via MYINFINITY. Use %rename to fix the name. */ +const double MYINFINITY = INFINITY; + +/* Use of float is intentional because the original bug was in the float conversion due to overflow checking. */ +float use_infinity(float inf_val) +{ + return inf_val; +} +%} diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in new file mode 100755 index 000000000..49652f0bd --- /dev/null +++ b/Examples/test-suite/javascript/Makefile.in @@ -0,0 +1,181 @@ +####################################################################### +# Makefile for javascript test-suite +####################################################################### + +LANGUAGE = javascript +SCRIPTSUFFIX = _runme.js +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +SWIG = $(top_builddir)/preinst_swig + +ifneq (, $(ENGINE)) + JSENGINE=$(ENGINE) +else + JSENGINE=node +endif + +# Note: the javascript generator is not ready yet for the real game. +# To be able keep the behavior continously tested that is expected to work already +# we have a 'light' version of the test-suite +# This will be removed and replaced by a list of 'BROKEN_TEST_CASES' when +# the number gets smaller (currently we have about 65 broken tests for JSC, and 85 for V8) + +ifneq (,$(SMOKE)) + +C_TEST_CASES = \ + preproc \ + preproc_include + +CPP_TEST_CASES = \ + abstract_access \ + abstract_typedef \ + abstract_typedef2 \ + abstract_virtual \ + arrays_global \ + array_member \ + char_binary \ + class_ignore \ + class_scope_weird \ + complextest \ + constover \ + constructor_copy \ + cpp_enum \ + cpp_namespace \ + cpp_static \ + enum_template \ + namespace_virtual_method \ + nspace \ + nspace_extend \ + overload_copy \ + rename_simple \ + rename_scope \ + ret_by_value \ + struct_value \ + template_static \ + typedef_class \ + typedef_inherit \ + typedef_scope \ + typemap_arrays \ + typemap_delete \ + typemap_namespace \ + typemap_ns_using \ + using1 \ + using2 \ + javascript_unicode + +SKIP_CPP_CASES = @SKIP_CPP_CASES@ +SKIP_C_CASES = @SKIP_C_CASES@ +SKIP_CPP_STD_CASES = @SKIP_CPP_STD_CASES@ +SKIP_MULTI_CPP_CASES = @SKIP_MULTI_CPP_CASES@ + +endif + +include $(srcdir)/../common.mk + +_setup = \ + if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ + echo "$(ACTION)ing testcase $* (with run test) under javascript ($(JSENGINE))" ; \ + else \ + echo "$(ACTION)ing testcase $* under javascript ($(JSENGINE))" ; \ + fi; + +ifneq (jsc,$(ENGINE)) + + # This test can not be run with v8 as it uses v8 API incompatible output typemaps + typemap_variables.cpptest: + echo "skipping testcase typemap_variables under javascript ($(JSENGINE))." + + # with v8 we have to generate C++ wrappers only + # these tests did raise warnings which are ignored + nested.ctest: SWIGOPT += -w312,-325 + nested_structs.ctest: SWIGOPT += -w312,-325 + unions.ctest: SWIGOPT += -w312,-325 + +endif + +ifeq (node,$(JSENGINE)) + + SWIGOPT += -v8 -DBUILDING_NODE_EXTENSION=1 + + # shut up some warnings + # contract macro has an empty 'else' at the end... + aggregate.cpptest: GYP_CFLAGS = \"-Wno-empty-body\" + contract.cpptest: GYP_CFLAGS = \"-Wno-empty-body\" + + # dunno... ignoring generously + apply_signed_char.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\" + constant_pointers.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\" + enum_thorough.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\" + + __setup = \ + sh ./setup_test.sh $* $(GYP_CFLAGS); \ + $(SWIG) -c++ -javascript $(SWIGOPT) ../$*.i; + + nodejs_swig_and_compile = \ + node-gyp --loglevel=silent --directory $* configure build 1>>/dev/null + + run_testcase = \ + if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ + node $(srcdir)/$*$(SCRIPTSUFFIX); \ + fi + + %.cpptest: + $(_setup) + $(__setup) + $(nodejs_swig_and_compile) + $(run_testcase) + + %.ctest: + $(_setup) + $(__setup) + $(nodejs_swig_and_compile) + $(run_testcase) + + %.multicpptest: + $(_setup) + +else + + SWIGOPT += -$(JSENGINE) + + run_testcase = \ + if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ + $(top_srcdir)/Tools/javascript/javascript -$(JSENGINE) $(srcdir)/$*$(SCRIPTSUFFIX); \ + fi + + %.cpptest: + $(_setup) + +$(swig_and_compile_cpp) + $(run_testcase) + + %.multicpptest: + $(_setup) + +$(swig_and_compile_multi_cpp) + $(run_testcase) + +endif + +ifeq (v8,$(ENGINE)) + %.ctest: + $(_setup) + +$(swig_and_compile_cpp) + $(run_testcase) + +endif + +ifeq (jsc,$(ENGINE)) + %.ctest: + $(_setup) + +$(swig_and_compile_c) + $(run_testcase) +endif + +%.clean: + rm -rf $* + +clean: + rm -f *_wrap.cxx + rm -f *_wrap.c + rm -f *.so + rm -f *.o diff --git a/Examples/test-suite/javascript/abstract_access_runme.js b/Examples/test-suite/javascript/abstract_access_runme.js new file mode 100644 index 000000000..8f87d2105 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_access_runme.js @@ -0,0 +1,6 @@ +var abstract_access = require("./abstract_access"); + +var d = new abstract_access.D() +if (d.do_x() != 1) { + throw "Error"; +} diff --git a/Examples/test-suite/javascript/abstract_inherit_runme.js b/Examples/test-suite/javascript/abstract_inherit_runme.js new file mode 100644 index 000000000..3af2eae74 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_inherit_runme.js @@ -0,0 +1,40 @@ +var abstract_inherit = require("./abstract_inherit"); + +// Shouldn't be able to instantiate any of these classes +// since none of them implements the pure virtual function +// declared in the base class (Foo). +var Foo = abstract_inherit.Foo; +var Bar = abstract_inherit.Bar; +var Spam = abstract_inherit.Spam; + +var caughtException = false; +try { + new Foo(); +} catch (err) { + caughtException = true; +} +if (!caughtException) { + throw new Error("Foo should be instantiated as it is abstract"); +} + +caughtException = false; +try { + new Bar(); +} catch (err) { + caughtException = true; +} + +if (!caughtException) { + throw new Error("Bar should be instantiated as it is abstract"); +} + +caughtException = false; +try { + new Spam(); +} catch (err) { + caughtException = true; +} + +if (!caughtException) { + throw new Error("Spam should be instantiated as it is abstract"); +} diff --git a/Examples/test-suite/javascript/abstract_typedef2_runme.js b/Examples/test-suite/javascript/abstract_typedef2_runme.js new file mode 100644 index 000000000..c177e49c3 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_typedef2_runme.js @@ -0,0 +1,6 @@ +var abstract_typedef2 = require("./abstract_typedef2"); + +var a = new abstract_typedef2.A_UF(); + +if (a == undefined) + throw "Error"; diff --git a/Examples/test-suite/javascript/abstract_typedef_runme.js b/Examples/test-suite/javascript/abstract_typedef_runme.js new file mode 100644 index 000000000..abcfc581d --- /dev/null +++ b/Examples/test-suite/javascript/abstract_typedef_runme.js @@ -0,0 +1,8 @@ +var abstract_typedef = require("./abstract_typedef"); + +var e = new abstract_typedef.Engine(); +var a = new abstract_typedef.A() + +if (a.write(e) != 1) { + throw "Error"; +} diff --git a/Examples/test-suite/javascript/abstract_virtual_runme.js b/Examples/test-suite/javascript/abstract_virtual_runme.js new file mode 100644 index 000000000..9e2814e41 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_virtual_runme.js @@ -0,0 +1,11 @@ +var abstract_virtual = require("./abstract_virtual"); + +d = new abstract_virtual.D() + +if (d == undefined) + throw "Error"; + +e = new abstract_virtual.E() + +if (e == undefined) + throw "Error"; diff --git a/Examples/test-suite/javascript/array_member_runme.js b/Examples/test-suite/javascript/array_member_runme.js new file mode 100644 index 000000000..8c4ef1da5 --- /dev/null +++ b/Examples/test-suite/javascript/array_member_runme.js @@ -0,0 +1,22 @@ +var array_member = require("./array_member"); + +var f = new array_member.Foo(); +f.data = array_member.global_data; + +for (var i=0; i<8; i++) { + if (array_member.get_value(f.data,i) != array_member.get_value(array_member.global_data,i)) { + throw "Bad array assignment (1)"; + } +} + +for (var i=0; i<8; i++) { + array_member.set_value(f.data,i,-i); +} + +array_member.global_data = f.data; + +for (var i=0; i<8; i++){ + if (array_member.get_value(f.data,i) != array_member.get_value(array_member.global_data,i)) { + throw "Bad array assignment (2)"; + } +} diff --git a/Examples/test-suite/javascript/arrays_global_runme.js b/Examples/test-suite/javascript/arrays_global_runme.js new file mode 100644 index 000000000..fdb365f83 --- /dev/null +++ b/Examples/test-suite/javascript/arrays_global_runme.js @@ -0,0 +1,18 @@ +var arrays_global = require("./arrays_global"); + +arrays_global.array_i = arrays_global.array_const_i; + +arrays_global.BeginString_FIX44a; +arrays_global.BeginString_FIX44b; +arrays_global.BeginString_FIX44c; +arrays_global.BeginString_FIX44d; +arrays_global.BeginString_FIX44d; +arrays_global.BeginString_FIX44b = "12"+'\0'+"45"; +arrays_global.BeginString_FIX44b; +arrays_global.BeginString_FIX44d; +arrays_global.BeginString_FIX44e; +arrays_global.BeginString_FIX44f; + +arrays_global.test_a("hello","hi","chello","chi"); + +arrays_global.test_b("1234567","hi"); diff --git a/Examples/test-suite/javascript/callback_runme.js b/Examples/test-suite/javascript/callback_runme.js new file mode 100644 index 000000000..9b1ef01a3 --- /dev/null +++ b/Examples/test-suite/javascript/callback_runme.js @@ -0,0 +1,30 @@ +var callback = require("./callback"); + +if (callback.foo(2) !== 2) { + throw new Error("Failed."); +} +if (callback.A_bar(2) !== 4) { + throw new Error("Failed."); +} +if (callback.foobar(3, callback.foo) != callback.foo(3)) { + throw new Error("Failed."); +} +if (callback.foobar(3, foo) != callback.foo(3)) { + throw new Error("Failed."); +} +if (callback.foobar(3, callback.A_bar) != callback.A_bar(3)) { + throw new Error("Failed."); +} +if (callback.foobar(3, callback.foof) != callback.foof(3)) { + throw new Error("Failed."); +} +if (callback.foobar_i(3, callback.foo_i) != callback.foo_i(3)) { + throw new Error("Failed."); +} +if (callback.foobar_d(3.5, callback.foo_d) != callback.foo_d(3.5)) { + throw new Error("Failed."); +} +var a = new callback.A(); +if (callback.foobarm(3, a, callback.A.foom_cb_ptr) != a.foom(3)) { + throw new Error("Failed."); +} diff --git a/Examples/test-suite/javascript/char_binary_runme.js b/Examples/test-suite/javascript/char_binary_runme.js new file mode 100644 index 000000000..42abe6060 --- /dev/null +++ b/Examples/test-suite/javascript/char_binary_runme.js @@ -0,0 +1,38 @@ +var char_binary = require("./char_binary"); + +var t = new char_binary.Test(); +if (t.strlen('hile') != 4) { + print(t.strlen('hile')); + throw("bad multi-arg typemap 1"); +} + +if (t.strlen('hil\0') != 4) { + throw("bad multi-arg typemap 2"); +} + +/* + * creating a raw char* + */ +var pc = char_binary.new_pchar(5); +char_binary.pchar_setitem(pc, 0, 'h'); +char_binary.pchar_setitem(pc, 1, 'o'); +char_binary.pchar_setitem(pc, 2, 'l'); +char_binary.pchar_setitem(pc, 3, 'a'); +char_binary.pchar_setitem(pc, 4, 0); + + +if (t.strlen(pc) != 4) { + throw("bad multi-arg typemap (3)"); +} + +char_binary.var_pchar = pc; +if (char_binary.var_pchar != "hola") { + print(char_binary.var_pchar); + throw("bad pointer case (1)"); +} + +char_binary.var_namet = pc; +if (char_binary.var_namet != "hola") { + throw("bad pointer case (2)"); +} +char_binary.delete_pchar(pc); diff --git a/Examples/test-suite/javascript/char_strings_runme.js b/Examples/test-suite/javascript/char_strings_runme.js new file mode 100644 index 000000000..cca50d851 --- /dev/null +++ b/Examples/test-suite/javascript/char_strings_runme.js @@ -0,0 +1,11 @@ +var char_strings = require("./char_strings"); + +var assertIsEqual = function(expected, actual) { + if (expected !== actual) { + throw new Error("Expected "+expected+", was "+actual); + } +}; + +assertIsEqual("hi there", char_strings.CharPingPong("hi there")); +assertIsEqual("hi there", char_strings.CharArrayPingPong("hi there")); +assertIsEqual("hi there", char_strings.CharArrayDimsPingPong("hi there")); diff --git a/Examples/test-suite/javascript/class_ignore_runme.js b/Examples/test-suite/javascript/class_ignore_runme.js new file mode 100644 index 000000000..f0a32a1c4 --- /dev/null +++ b/Examples/test-suite/javascript/class_ignore_runme.js @@ -0,0 +1,6 @@ +var class_ignore = require("./class_ignore"); + +a = new class_ignore.Bar(); + +if (class_ignore.do_blah(a) != "Bar::blah") + throw "Error"; diff --git a/Examples/test-suite/javascript/class_scope_weird_runme.js b/Examples/test-suite/javascript/class_scope_weird_runme.js new file mode 100644 index 000000000..ac745d023 --- /dev/null +++ b/Examples/test-suite/javascript/class_scope_weird_runme.js @@ -0,0 +1,6 @@ +var class_scope_weird = require("./class_scope_weird"); + +f = new class_scope_weird.Foo(); +g = new class_scope_weird.Foo(3); +if (f.bar(3) != 3) + throw RuntimeError; diff --git a/Examples/test-suite/javascript/complextest_runme.js b/Examples/test-suite/javascript/complextest_runme.js new file mode 100644 index 000000000..1fcc97648 --- /dev/null +++ b/Examples/test-suite/javascript/complextest_runme.js @@ -0,0 +1,22 @@ +var complextest = require("./complextest"); + +a = [-1,2]; + +expected = [-1, -2]; + +a_c = complextest.Conj(a); +if (a_c.toString() != expected.toString()) + throw "Error in Conj(a)"; + +a_c_f = complextest.Conjf(a); +if (a_c_f.toString() != expected.toString()) + throw "Error in Conjf(a)"; + +v = new complextest.VectorStdCplx(); +v.add([1,2]); +v.add([2,3]); +v.add([4,3]); +v.add(1); + +// TODO: how to check validity? +complextest.Copy_h(v); diff --git a/Examples/test-suite/javascript/constover_runme.js b/Examples/test-suite/javascript/constover_runme.js new file mode 100644 index 000000000..764d8b328 --- /dev/null +++ b/Examples/test-suite/javascript/constover_runme.js @@ -0,0 +1,33 @@ +var constover = require("./constover"); + +p = constover.test("test"); +if (p != "test") { + throw "test failed!"; +} + +p = constover.test_pconst("test"); +if (p != "test_pconst") { + throw "test_pconst failed!"; +} + +f = new constover.Foo(); + +p = f.test("test"); +if (p != "test") { + throw "member-test failed!"; +} + +p = f.test_pconst("test"); +if (p != "test_pconst") { + throw "member-test_pconst failed!"; +} + +p = f.test_constm("test"); +if (p != "test_constmethod") { + throw "member-test_constm failed!"; +} + +p = f.test_pconstm("test"); +if (p != "test_pconstmethod") { + throw "member-test_pconstm failed!"; +} diff --git a/Examples/test-suite/javascript/constructor_copy_runme.js b/Examples/test-suite/javascript/constructor_copy_runme.js new file mode 100644 index 000000000..39dce52ce --- /dev/null +++ b/Examples/test-suite/javascript/constructor_copy_runme.js @@ -0,0 +1,42 @@ +var constructor_copy = require("./constructor_copy"); + +f1 = new constructor_copy.Foo1(3); +f11 = new constructor_copy.Foo1(f1); + +if (f1.x != f11.x) { + throw "error in ctor copy for Foo1"; +} + +var good = 0; + +f8 = new constructor_copy.Foo8() +try { + f81 = new constructor_copy.Foo8(f8); + good = 0; +} catch (err) { + good = 1; +} + +if (good == 0) { + throw "Error: should not allow calling copy ctor for Foo8"; +} + + +bi = new constructor_copy.Bari(5); +bc = new constructor_copy.Bari(bi); + +if (bi.x != bc.x) { + throw "Error in copy ctor of Bari"; +} + +bd = new constructor_copy.Bard(5); +try { + bc = new constructor_copy.Bard(bd); + good = 0; +} catch (err) { + good = 1; +} + +if (good == 0) { + throw "Error: should not allow calling copy ctor for Bard"; +} diff --git a/Examples/test-suite/javascript/cpp_enum_runme.js b/Examples/test-suite/javascript/cpp_enum_runme.js new file mode 100644 index 000000000..35f7c60ac --- /dev/null +++ b/Examples/test-suite/javascript/cpp_enum_runme.js @@ -0,0 +1,28 @@ +var cpp_enum = require("./cpp_enum"); + +var f = new cpp_enum.Foo() + +if(f.hola != cpp_enum.Hello){ + print(f.hola); + throw "Error"; +} + +f.hola = cpp_enum.Foo.Hi +if(f.hola != cpp_enum.Foo.Hi){ + print(f.hola); + throw "Error"; +} + +f.hola = cpp_enum.Hello + +if(f.hola != cpp_enum.Hello){ + print(f.hola); + throw "Error"; +} + +cpp_enum.Foo.hi = cpp_enum.Hello +if(cpp_enum.Foo.hi != cpp_enum.Hello){ + print(cpp_enum.Foo.hi); + throw "Error"; +} + diff --git a/Examples/test-suite/javascript/cpp_namespace_runme.js b/Examples/test-suite/javascript/cpp_namespace_runme.js new file mode 100644 index 000000000..3bdfef3e9 --- /dev/null +++ b/Examples/test-suite/javascript/cpp_namespace_runme.js @@ -0,0 +1,47 @@ +var cpp_namespace = require("./cpp_namespace"); + +var n = cpp_namespace.fact(4); +if (n != 24){ + throw ("Bad return value error!"); +} +if (cpp_namespace.Foo != 42){ + throw ("Bad variable value error!"); +} + +t = new cpp_namespace.Test(); +if (t.method() != "Test::method"){ + throw ("Bad method return value error!"); +} +if (cpp_namespace.do_method(t) != "Test::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method2(t) != "Test::method"){ + throw ("Bad return value error!"); +} +cpp_namespace.weird("hello", 4); +delete t; + +t2 = new cpp_namespace.Test2(); +t3 = new cpp_namespace.Test3(); +t4 = new cpp_namespace.Test4(); +t5 = new cpp_namespace.Test5(); +if (cpp_namespace.foo3(42) != 42){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t2,40) != "Test2::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t3,40) != "Test3::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t4,40) != "Test4::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t5,40) != "Test5::method"){ + throw ("Bad return value error!"); +} diff --git a/Examples/test-suite/javascript/cpp_static_runme.js b/Examples/test-suite/javascript/cpp_static_runme.js new file mode 100644 index 000000000..2579aeafe --- /dev/null +++ b/Examples/test-suite/javascript/cpp_static_runme.js @@ -0,0 +1,9 @@ +var cpp_static = require("./cpp_static"); + +cpp_static.StaticFunctionTest.static_func(); +cpp_static.StaticFunctionTest.static_func_2(1); +cpp_static.StaticFunctionTest.static_func_3(1,2); +cpp_static.StaticMemberTest.static_int = 10; +if (cpp_static.StaticMemberTest.static_int != 10) +throw "error"; + diff --git a/Examples/test-suite/javascript/director_alternating_runme.js b/Examples/test-suite/javascript/director_alternating_runme.js new file mode 100644 index 000000000..a0411eace --- /dev/null +++ b/Examples/test-suite/javascript/director_alternating_runme.js @@ -0,0 +1,5 @@ +var director_alternating = require("./director_alternating"); + +id = director_alternating.getBar().id(); +if (id != director_alternating.idFromGetBar()) + throw ("Error, Got wrong id: " + str(id)); diff --git a/Examples/test-suite/javascript/disown_runme.js b/Examples/test-suite/javascript/disown_runme.js new file mode 100644 index 000000000..a4a6fd880 --- /dev/null +++ b/Examples/test-suite/javascript/disown_runme.js @@ -0,0 +1,22 @@ +var disown = require("./disown"); + +var a = new disown.A(); +var tmp = a.thisown; +a.thisown = 0 +if (a.thisown) { + throw new Error("Failed."); +} +a.thisown = 1 +if (!a.thisown) { + throw new Error("Failed."); +} +a.thisown = tmp +if (a.thisown != tmp) { + throw new Error("Failed."); +} + +var b = new disown.B(); +b.acquire(a); +if (a.thisown) { + throw new Error("Failed."); +} diff --git a/Examples/test-suite/javascript/dynamic_cast_runme.js b/Examples/test-suite/javascript/dynamic_cast_runme.js new file mode 100644 index 000000000..0029cb0f8 --- /dev/null +++ b/Examples/test-suite/javascript/dynamic_cast_runme.js @@ -0,0 +1,12 @@ +var dynamic_cast = require("./dynamic_cast"); + +var f = new dynamic_cast.Foo(); +var b = new dynamic_cast.Bar(); + +var x = f.blah(); +var y = b.blah(); + +var a = dynamic_cast.do_test(y); +if (a != "Bar::test") { + throw new Error("Failed."); +} diff --git a/Examples/test-suite/javascript/empty_runme.js b/Examples/test-suite/javascript/empty_runme.js new file mode 100644 index 000000000..db06b3902 --- /dev/null +++ b/Examples/test-suite/javascript/empty_runme.js @@ -0,0 +1 @@ +var empty = require("./empty"); \ No newline at end of file diff --git a/Examples/test-suite/javascript/enum_template_runme.js b/Examples/test-suite/javascript/enum_template_runme.js new file mode 100644 index 000000000..20f8c3482 --- /dev/null +++ b/Examples/test-suite/javascript/enum_template_runme.js @@ -0,0 +1,8 @@ +var enum_template = require("./enum_template"); + +if (enum_template.MakeETest() != 1) + throw "RuntimeError"; + +if (enum_template.TakeETest(0) != null) + throw "RuntimeError"; + diff --git a/Examples/test-suite/javascript/infinity_runme.js b/Examples/test-suite/javascript/infinity_runme.js new file mode 100644 index 000000000..1dcf366c6 --- /dev/null +++ b/Examples/test-suite/javascript/infinity_runme.js @@ -0,0 +1,4 @@ +var infinity = require("./infinity"); + +var my_infinity = infinity.INFINTY; +var ret_val = infinity.use_infinity(my_infinity); diff --git a/Examples/test-suite/javascript/javascript_unicode_runme.js b/Examples/test-suite/javascript/javascript_unicode_runme.js new file mode 100644 index 000000000..f5f747aa7 --- /dev/null +++ b/Examples/test-suite/javascript/javascript_unicode_runme.js @@ -0,0 +1,9 @@ +var javascript_unicode = require("./javascript_unicode"); + +var str = "olé"; + +var copy = javascript_unicode.copy_string(str); + +if (str !== copy) { + print("Error: copy is not equal: original="+str+", copy="+copy); +} diff --git a/Examples/test-suite/javascript/namespace_virtual_method_runme.js b/Examples/test-suite/javascript/namespace_virtual_method_runme.js new file mode 100644 index 000000000..24d3bd487 --- /dev/null +++ b/Examples/test-suite/javascript/namespace_virtual_method_runme.js @@ -0,0 +1,3 @@ +var namespace_virtual_method = require("./namespace_virtual_method"); + +x = new namespace_virtual_method.Spam(); diff --git a/Examples/test-suite/javascript/node_template/binding.gyp.in b/Examples/test-suite/javascript/node_template/binding.gyp.in new file mode 100644 index 000000000..209774ae0 --- /dev/null +++ b/Examples/test-suite/javascript/node_template/binding.gyp.in @@ -0,0 +1,30 @@ +{ + "targets": [ + { + "target_name": "$testcase", + "sources":[ "../$testcase_wrap.cxx" ], + "include_dirs": ["../.."], + 'defines': [ + 'BUILDING_NODE_EXTENSION=1', + ], + 'conditions': [ + ['OS=="mac"', + { + 'xcode_settings': { + 'GCC_ENABLE_CPP_RTTI': 'YES', + 'GCC_ENABLE_CPP_EXCEPTIONS' : 'YES' + } + } + ], + ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', + { + 'cflags': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter", $cflags], + 'cflags_cc': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter", $cflags], + 'cflags!': [ '-fno-exceptions' ], + 'cflags_cc!': [ '-fno-exceptions', '-fno-rtti' ] + } + ] + ], + } + ], +} diff --git a/Examples/test-suite/javascript/node_template/index.js.in b/Examples/test-suite/javascript/node_template/index.js.in new file mode 100644 index 000000000..72330499d --- /dev/null +++ b/Examples/test-suite/javascript/node_template/index.js.in @@ -0,0 +1 @@ +module.exports = require('./build/Release/$testcase'); diff --git a/Examples/test-suite/javascript/nspace_extend_runme.js b/Examples/test-suite/javascript/nspace_extend_runme.js new file mode 100644 index 000000000..ab81c19d3 --- /dev/null +++ b/Examples/test-suite/javascript/nspace_extend_runme.js @@ -0,0 +1,27 @@ +var nspace_extend = require("./nspace_extend"); + +// constructors and destructors +var color1 = new nspace_extend.Outer.Inner1.Color(); +var color = new nspace_extend.Outer.Inner1.Color(color1); +delete color1; + +// class methods +color.colorInstanceMethod(20.0); +nspace_extend.Outer.Inner1.Color.colorStaticMethod(20.0); +var created = nspace_extend.Outer.Inner1.Color.create(); + + +// constructors and destructors +var color2 = new nspace_extend.Outer.Inner2.Color(); +color = new nspace_extend.Outer.Inner2.Color(color2); +delete color2; + +// class methods +color.colorInstanceMethod(20.0); +nspace_extend.Outer.Inner2.Color.colorStaticMethod(20.0); +created = nspace_extend.Outer.Inner2.Color.create(); + +// Same class different namespaces +var col1 = new nspace_extend.Outer.Inner1.Color(); +var col2 = nspace_extend.Outer.Inner2.Color.create(); +col2.colors(col1, col1, col2, col2, col2); diff --git a/Examples/test-suite/javascript/nspace_runme.js b/Examples/test-suite/javascript/nspace_runme.js new file mode 100644 index 000000000..929a6b21d --- /dev/null +++ b/Examples/test-suite/javascript/nspace_runme.js @@ -0,0 +1,77 @@ +var nspace = require("./nspace"); + +var color1 = new nspace.Outer.Inner1.Color(); +var color = new nspace.Outer.Inner1.Color(color1); +delete color1; + +// class methods +color.colorInstanceMethod(20.0); +nspace.Outer.Inner1.Color.colorStaticMethod(20.0); +var created = nspace.Outer.Inner1.Color.create(); + +// class enums +var someClass = new nspace.Outer.SomeClass(); +var channel = someClass.GetInner1ColorChannel(); +if (channel != nspace.Outer.Inner1.Color.Transmission) { + throw new Error("Failed."); +} + +// class anonymous enums +var val1 = nspace.Outer.Inner1.Color.ColorEnumVal1; +var val2 = nspace.Outer.Inner1.Color.ColorEnumVal2; +if (val1 !== 0 || val2 !== 0x22) { + throw new Error("Failed."); +} + +// instance member variables +color.instanceMemberVariable = 123; +if (color.instanceMemberVariable !== 123) { + throw new Error("Failed."); +} + +// static member variables +nspace.Outer.Inner1.Color.staticMemberVariable = 789; +if (nspace.Outer.Inner1.Color.staticMemberVariable !== 789) { + throw new Error("Failed."); +} + +if (nspace.Outer.Inner1.Color.staticConstMemberVariable !== 222) { + throw new Error("Failed."); +} + +if (nspace.Outer.Inner1.Color.staticConstEnumMemberVariable !== nspace.Outer.Inner1.Color.Transmission) { + throw new Error("Failed."); +} + +// Same class different namespaces +var col1 = new nspace.Outer.Inner1.Color(); +var col2 = nspace.Outer.Inner2.Color.create(); +col2.colors(col1, col1, col2, col2, col2); + +// TODO: why isn't it scoped in the namespace??? +nspace.namespaceFunction(color); +nspace.Outer.Inner1.namespaceVar = 111; +if (nspace.Outer.Inner1.namespaceVar !== 111) { + throw new Error("Failed."); +} + +// global enums +var outerChannel1 = someClass.GetInner1Channel(); +if (outerChannel1 != nspace.Outer.Inner1.Transmission1) { + throw new Error("Failed."); +} + +var outerChannel2 = someClass.GetInner2Channel(); +if (outerChannel2 !== nspace.Outer.Inner2.Transmission2) { + throw new Error("Failed."); +} + +// turn feature off / ignoring +var ns = new nspace.Outer.namespce(); +var nons = new nspace.NoNSpacePlease(); + +// Derived class +var blue3 = new nspace.Outer.Inner3.Blue(); +blue3.blueInstanceMethod(); +var blue4 = new nspace.Outer.Inner4.Blue(); +blue4.blueInstanceMethod(); diff --git a/Examples/test-suite/javascript/overload_copy_runme.js b/Examples/test-suite/javascript/overload_copy_runme.js new file mode 100644 index 000000000..1039ffda1 --- /dev/null +++ b/Examples/test-suite/javascript/overload_copy_runme.js @@ -0,0 +1,4 @@ +var overload_copy = require("./overload_copy"); + +f = new overload_copy.Foo(); +g = new overload_copy.Foo(f); diff --git a/Examples/test-suite/javascript/preproc_include_runme.js b/Examples/test-suite/javascript/preproc_include_runme.js new file mode 100644 index 000000000..4b827fbcc --- /dev/null +++ b/Examples/test-suite/javascript/preproc_include_runme.js @@ -0,0 +1,23 @@ +var preproc_include = require("./preproc_include"); + +if (preproc_include.multiply10(10) != 100) + throw "RuntimeError"; + +if (preproc_include.multiply20(10) != 200) + throw "RuntimeError"; + +if (preproc_include.multiply30(10) != 300) + throw "RuntimeError"; + +if (preproc_include.multiply40(10) != 400) + throw "RuntimeError"; + +if (preproc_include.multiply50(10) != 500) + throw "RuntimeError"; + +if (preproc_include.multiply60(10) != 600) + throw "RuntimeError"; + +if (preproc_include.multiply70(10) != 700) + throw "RuntimeError"; + diff --git a/Examples/test-suite/javascript/preproc_runme.js b/Examples/test-suite/javascript/preproc_runme.js new file mode 100644 index 000000000..669f9d1f0 --- /dev/null +++ b/Examples/test-suite/javascript/preproc_runme.js @@ -0,0 +1,14 @@ +var preproc = require("./preproc"); + +if (preproc.endif != 1) + throw "RuntimeError"; + +if (preproc.define != 1) + throw "RuntimeError"; + +if (preproc.defined != 1) + throw "RuntimeError"; + +if (2*preproc.one != preproc.two) + throw "RuntimeError"; + diff --git a/Examples/test-suite/javascript/rename1_runme.js b/Examples/test-suite/javascript/rename1_runme.js new file mode 100644 index 000000000..8374e6a89 --- /dev/null +++ b/Examples/test-suite/javascript/rename1_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename1"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename2_runme.js b/Examples/test-suite/javascript/rename2_runme.js new file mode 100644 index 000000000..bc6a95a59 --- /dev/null +++ b/Examples/test-suite/javascript/rename2_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename2"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename3_runme.js b/Examples/test-suite/javascript/rename3_runme.js new file mode 100644 index 000000000..9e57e80ea --- /dev/null +++ b/Examples/test-suite/javascript/rename3_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename3"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename4_runme.js b/Examples/test-suite/javascript/rename4_runme.js new file mode 100644 index 000000000..d651fc7a1 --- /dev/null +++ b/Examples/test-suite/javascript/rename4_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename4"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename_scope_runme.js b/Examples/test-suite/javascript/rename_scope_runme.js new file mode 100644 index 000000000..c0226df69 --- /dev/null +++ b/Examples/test-suite/javascript/rename_scope_runme.js @@ -0,0 +1,17 @@ +var rename_scope = require("./rename_scope"); + +var a = new rename_scope.Natural_UP(); +var b = new rename_scope.Natural_BP(); + +if (a.rtest() !== 1) { + throw new Error("a.rtest(): Expected 1, was " + a.rtest()); +} + +if (b.rtest() !== 1) { + throw new Error("b.rtest(): Expected 1, was " + b.rtest()); +} + +var f = rename_scope.equals; +if (f === undefined) { + throw new Error("Equality operator has not been renamed."); +} diff --git a/Examples/test-suite/javascript/rename_simple_runme.js b/Examples/test-suite/javascript/rename_simple_runme.js new file mode 100644 index 000000000..918dd68a5 --- /dev/null +++ b/Examples/test-suite/javascript/rename_simple_runme.js @@ -0,0 +1,50 @@ +var rename_simple = require("./rename_simple"); +var NewStruct = rename_simple.NewStruct; + +var s = new NewStruct(); + +// renamed instance variable +if (s.NewInstanceVariable !== 111) { + throw new Error("NewInstanceVariable: Expected 111, was " + s.NewInstanceVariable); +} + +// renamed instance method +if (s.NewInstanceMethod() !== 222) { + throw new Error("NewInstanceMethod(): Expected 222, was " + s.NewInstanceMethod()); +} + +// renamed static method +if (NewStruct.NewStaticMethod() !== 333) { + throw new Error("NewInstanceMethod(): Expected 333, was " + NewStruct.NewStaticMethod()); +} + +// renamed static variable +if (NewStruct.NewStaticVariable !== 444) { + throw new Error("NewInstanceMethod(): Expected 444, was " + NewStruct.NewStaticVariable); +} + +// renamed global function +if (rename_simple.NewFunction() !== 555) { + throw new Error("rename_simple.NewFunction(): Expected 555, was " + rename_simple.NewFunction()); +} + +// renamed global variable +if (rename_simple.NewGlobalVariable !== 666) { + throw new Error("rename_simple.NewGlobalVariable: Expected 666, was " + rename_simple.NewGlobalVariable); +} + +// setting renamed variables +s.NewInstanceVariable = 1111; +if (s.NewInstanceVariable !== 1111) { + throw new Error("NewInstanceVariable: Expected 1111, was " + s.NewInstanceVariable); +} + +NewStruct.NewStaticVariable = 4444; +if (NewStruct.NewStaticVariable !== 4444) { + throw new Error("NewInstanceMethod(): Expected 4444, was " + NewStruct.NewStaticVariable); +} + +rename_simple.NewGlobalVariable = 6666; +if (rename_simple.NewGlobalVariable !== 6666) { + throw new Error("rename_simple.NewGlobalVariable: Expected 6666, was " + rename_simple.NewGlobalVariable); +} diff --git a/Examples/test-suite/javascript/ret_by_value_runme.js b/Examples/test-suite/javascript/ret_by_value_runme.js new file mode 100644 index 000000000..d9a77a20b --- /dev/null +++ b/Examples/test-suite/javascript/ret_by_value_runme.js @@ -0,0 +1,8 @@ +var ret_by_value = require("./ret_by_value"); + +a = ret_by_value.get_test(); +if (a.myInt != 100) + throw "RuntimeError"; + +if (a.myShort != 200) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/setup_test.sh b/Examples/test-suite/javascript/setup_test.sh new file mode 100644 index 000000000..913a74c4b --- /dev/null +++ b/Examples/test-suite/javascript/setup_test.sh @@ -0,0 +1,6 @@ +#!/bin/sh +if [ ! -d $1 ]; then + mkdir $1; +fi +sed -e "s/\$testcase/$1/" -e "s/\$cflags/$2/" < node_template/binding.gyp.in > $1/binding.gyp +sed s/\$testcase/$1/ node_template/index.js.in > $1/index.js diff --git a/Examples/test-suite/javascript/struct_value_runme.js b/Examples/test-suite/javascript/struct_value_runme.js new file mode 100644 index 000000000..d6b26f726 --- /dev/null +++ b/Examples/test-suite/javascript/struct_value_runme.js @@ -0,0 +1,11 @@ +var struct_value = require("./struct_value"); + +b = new struct_value.Bar(); + +b.a.x = 3; +if (b.a.x != 3) +throw "RuntimeError"; + +b.b.x = 3; +if (b.b.x != 3) +throw "RuntimeError" diff --git a/Examples/test-suite/javascript/template_static_runme.js b/Examples/test-suite/javascript/template_static_runme.js new file mode 100644 index 000000000..477d97249 --- /dev/null +++ b/Examples/test-suite/javascript/template_static_runme.js @@ -0,0 +1,3 @@ +var template_static = require("./template_static"); + +template_static.Foo.bar_double(1); diff --git a/Examples/test-suite/javascript/typedef_class_runme.js b/Examples/test-suite/javascript/typedef_class_runme.js new file mode 100644 index 000000000..3e4dc9093 --- /dev/null +++ b/Examples/test-suite/javascript/typedef_class_runme.js @@ -0,0 +1,7 @@ +var typedef_class = require("./typedef_class"); + +a = new typedef_class.RealA(); +a.a = 3; + +b = new typedef_class.B(); +b.testA(a); diff --git a/Examples/test-suite/javascript/typedef_inherit_runme.js b/Examples/test-suite/javascript/typedef_inherit_runme.js new file mode 100644 index 000000000..4abcc2536 --- /dev/null +++ b/Examples/test-suite/javascript/typedef_inherit_runme.js @@ -0,0 +1,23 @@ +var typedef_inherit = require("./typedef_inherit"); + +a = new typedef_inherit.Foo(); +b = new typedef_inherit.Bar(); + +x = typedef_inherit.do_blah(a); +if (x != "Foo::blah") + print("Whoa! Bad return" + x); + +x = typedef_inherit.do_blah(b); +if (x != "Bar::blah") + print("Whoa! Bad return" + x); + +c = new typedef_inherit.Spam(); +d = new typedef_inherit.Grok(); + +x = typedef_inherit.do_blah2(c); +if (x != "Spam::blah") + print("Whoa! Bad return" + x); + +x = typedef_inherit.do_blah2(d); +if (x != "Grok::blah") + print ("Whoa! Bad return" + x); diff --git a/Examples/test-suite/javascript/typedef_scope_runme.js b/Examples/test-suite/javascript/typedef_scope_runme.js new file mode 100644 index 000000000..0ac56884c --- /dev/null +++ b/Examples/test-suite/javascript/typedef_scope_runme.js @@ -0,0 +1,12 @@ +var typedef_scope = require("./typedef_scope"); + +b = new typedef_scope.Bar(); +x = b.test1(42,"hello"); +if (x != 42) + print("Failed!!"); + +x = b.test2(42,"hello"); +if (x != "hello") + print("Failed!!"); + + diff --git a/Examples/test-suite/javascript/typemap_arrays_runme.js b/Examples/test-suite/javascript/typemap_arrays_runme.js new file mode 100644 index 000000000..cd6827ac9 --- /dev/null +++ b/Examples/test-suite/javascript/typemap_arrays_runme.js @@ -0,0 +1,5 @@ +var typemap_arrays = require("./typemap_arrays"); + +if (typemap_arrays.sumA(null) != 60) + throw "RuntimeError, Sum is wrong"; + diff --git a/Examples/test-suite/javascript/typemap_delete_runme.js b/Examples/test-suite/javascript/typemap_delete_runme.js new file mode 100644 index 000000000..4b3174956 --- /dev/null +++ b/Examples/test-suite/javascript/typemap_delete_runme.js @@ -0,0 +1,5 @@ +var typemap_delete = require("./typemap_delete"); + +r = new typemap_delete.Rect(123); +if (r.val != 123) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/typemap_namespace_runme.js b/Examples/test-suite/javascript/typemap_namespace_runme.js new file mode 100644 index 000000000..614e0ffeb --- /dev/null +++ b/Examples/test-suite/javascript/typemap_namespace_runme.js @@ -0,0 +1,7 @@ +var typemap_namespace = require("./typemap_namespace"); + +if (typemap_namespace.test1("hello") != "hello") + throw "RuntimeError"; + +if (typemap_namespace.test2("hello") != "hello") + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/typemap_ns_using_runme.js b/Examples/test-suite/javascript/typemap_ns_using_runme.js new file mode 100644 index 000000000..9115c16ae --- /dev/null +++ b/Examples/test-suite/javascript/typemap_ns_using_runme.js @@ -0,0 +1,4 @@ +var typemap_ns_using = require("./typemap_ns_using"); + +if (typemap_ns_using.spam(37) != 37) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/using1_runme.js b/Examples/test-suite/javascript/using1_runme.js new file mode 100644 index 000000000..a2e37fcb6 --- /dev/null +++ b/Examples/test-suite/javascript/using1_runme.js @@ -0,0 +1,4 @@ +var using1 = require("./using1"); + +if (using1.spam(37) != 37) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/using2_runme.js b/Examples/test-suite/javascript/using2_runme.js new file mode 100644 index 000000000..aa5e9b15f --- /dev/null +++ b/Examples/test-suite/javascript/using2_runme.js @@ -0,0 +1,4 @@ +var using2 = require("./using2"); + +if (using2.spam(37) != 37) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/varargs_runme.js b/Examples/test-suite/javascript/varargs_runme.js new file mode 100644 index 000000000..69d761e63 --- /dev/null +++ b/Examples/test-suite/javascript/varargs_runme.js @@ -0,0 +1,44 @@ +var varargs = require("./varargs"); + +if (varargs.test("Hello") != "Hello") { + throw new Error("Failed"); +} + +var f = new varargs.Foo("Greetings") +if (f.str != "Greetings") { + throw new Error("Failed"); +} + +if (f.test("Hello") != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_def("Hello",1) != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_def("Hello") != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_plenty("Hello") != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_plenty("Hello", 1) != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_plenty("Hello", 1, 2) != "Hello") { + throw new Error("Failed"); +} + +var thrown = false; +try { + varargs.test_plenty("Hello", 1, 2, 3); +} catch (err) { + thrown = true; +} +if (!thrown) { + throw new Error("Failed"); +} diff --git a/Examples/test-suite/javascript_unicode.i b/Examples/test-suite/javascript_unicode.i new file mode 100644 index 000000000..516eee5dd --- /dev/null +++ b/Examples/test-suite/javascript_unicode.i @@ -0,0 +1,10 @@ +%module javascript_unicode + +%newobject copy_string; + +%inline %{ +#include +const char* copy_string(const char* str) { + return strdup(str); +} +%} diff --git a/Examples/test-suite/nspace.i b/Examples/test-suite/nspace.i index 58c560412..3e4b3c214 100644 --- a/Examples/test-suite/nspace.i +++ b/Examples/test-suite/nspace.i @@ -2,7 +2,7 @@ %module nspace // nspace feature only supported by these languages -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) || defined(SWIGJAVASCRIPT) #if defined(SWIGJAVA) SWIG_JAVABODY_PROXY(public, public, SWIGTYPE) diff --git a/Examples/test-suite/nspace_extend.i b/Examples/test-suite/nspace_extend.i index e92ff8c1d..2f7c6fbe1 100644 --- a/Examples/test-suite/nspace_extend.i +++ b/Examples/test-suite/nspace_extend.i @@ -2,7 +2,7 @@ %module nspace_extend // nspace feature only supported by these languages -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) || defined(SWIGJAVASCRIPT) #if defined(SWIGJAVA) SWIG_JAVABODY_PROXY(public, public, SWIGTYPE) diff --git a/Lib/javascript/jsc/arrays_javascript.i b/Lib/javascript/jsc/arrays_javascript.i new file mode 100644 index 000000000..b9199d86b --- /dev/null +++ b/Lib/javascript/jsc/arrays_javascript.i @@ -0,0 +1,123 @@ +/* ----------------------------------------------------------------------------- + * arrays_javascript.i + * + * These typemaps give more natural support for arrays. The typemaps are not efficient + * as there is a lot of copying of the array values whenever the array is passed to C/C++ + * from JavaScript and vice versa. The JavaScript array is expected to be the same size as the C array. + * An exception is thrown if they are not. + * + * Example usage: + * Wrapping: + * + * %include + * %inline %{ + * extern int FiddleSticks[3]; + * %} + * + * Use from JavaScript like this: + * + * var fs = [10, 11, 12]; + * example.FiddleSticks = fs; + * fs = example.FiddleSticks; + * ----------------------------------------------------------------------------- */ + +%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {} +%fragment("SWIG_JSCGetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {} + +%typemap(in, fragment="SWIG_JSCGetIntProperty") int[], int[ANY] + (int length = 0, JSObjectRef array, JSValueRef jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if (JSValueIsObject(context, $input)) + { + // Convert into Array + array = JSValueToObject(context, $input, NULL); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL); + + // Get primitive value from JSObject + res = SWIG_AsVal(int)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) int[], int[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(int)) int[], int[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + JSValueRef values[length]; + + for (i = 0; i < length; i++) + { + values[i] = SWIG_From(int)($1[i]); + } + + $result = JSObjectMakeArray(context, length, values, NULL); +} + +%typemap(in, fragment="SWIG_JSCGetNumberProperty") double[], double[ANY] + (int length = 0, JSObjectRef array, JSValueRef jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if (JSValueIsObject(context, $input)) + { + // Convert into Array + array = JSValueToObject(context, $input, NULL); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL); + + // Get primitive value from JSObject + res = SWIG_AsVal(double)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) double[], double[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(double)) double[], double[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + JSValueRef values[length]; + + for (i = 0; i < length; i++) + { + values[i] = SWIG_From(double)($1[i]); + } + + $result = JSObjectMakeArray(context, length, values, NULL); +} diff --git a/Lib/javascript/jsc/ccomplex.i b/Lib/javascript/jsc/ccomplex.i new file mode 100644 index 000000000..50f0f95fe --- /dev/null +++ b/Lib/javascript/jsc/ccomplex.i @@ -0,0 +1,26 @@ +/* ----------------------------------------------------------------------------- + * ccomplex.i + * + * C complex typemaps + * ISO C99: 7.3 Complex arithmetic + * ----------------------------------------------------------------------------- */ + + +%include + +%{ +#include +%} + + +/* C complex constructor */ +#define CCplxConst(r, i) ((r) + I*(i)) + +%swig_cplxflt_convn(float complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(double complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(complex, CCplxConst, creal, cimag); + +/* declaring the typemaps */ +%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, complex); diff --git a/Lib/javascript/jsc/cdata.i b/Lib/javascript/jsc/cdata.i new file mode 100644 index 000000000..367965990 --- /dev/null +++ b/Lib/javascript/jsc/cdata.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/jsc/complex.i b/Lib/javascript/jsc/complex.i new file mode 100644 index 000000000..4c3b3c5e2 --- /dev/null +++ b/Lib/javascript/jsc/complex.i @@ -0,0 +1,6 @@ +#ifdef __cplusplus +%include +#else +%include +#endif + diff --git a/Lib/javascript/jsc/exception.i b/Lib/javascript/jsc/exception.i new file mode 100644 index 000000000..0246cfde8 --- /dev/null +++ b/Lib/javascript/jsc/exception.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/jsc/javascript.swg b/Lib/javascript/jsc/javascript.swg new file mode 100644 index 000000000..3a83b6495 --- /dev/null +++ b/Lib/javascript/jsc/javascript.swg @@ -0,0 +1,19 @@ +/* ----------------------------------------------------------------------------- + * javascript.swg + * + * Javascript typemaps + * ----------------------------------------------------------------------------- */ + +%include + +%include + +%include + +%include + +%include + +%include + +%include diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg new file mode 100644 index 000000000..60c52b2b3 --- /dev/null +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -0,0 +1,418 @@ +/* ----------------------------------------------------------------------------- + * js_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + + $jscode + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_veto_ctor: a vetoing ctor for abstract classes + * - $jswrapper: name of wrapper + * - $jsname: class name + * ----------------------------------------------------------------------------- */ +%fragment ("js_veto_ctor", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, + size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); + return 0; +} +%} + +/* ----------------------------------------------------------------------------- + * js_ctor_dispatcher: dispatcher for overloaded constructors + * - $jswrapper: name of wrapper + * - $jsname: class name + * - $jsdispatchcases: part containing code for dispatching + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor_dispatcher", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, + size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSObjectRef thisObject = NULL; + + // switch all cases by means of series of if-returns. + $jsdispatchcases + + // default: + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsname"); + + fail: + return thisObject; +} +%} + +/* ----------------------------------------------------------------------------- + * js_overloaded_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ +%fragment ("js_overloaded_ctor", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + $jscode + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_ctor_dispatch_case: template for a dispatch case for calling an overloaded ctor. + * - $jsargcount: number of arguments of called ctor + * - $jswrapper: wrapper of called ctor + * + * Note: a try-catch-like mechanism is used to switch cases + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor_dispatch_case", "templates") +%{ + if(argc == $jsargcount) { + thisObject = $jswrapper(context, NULL, argc, argv, exception); + if(thisObject != NULL) { *exception=0; return thisObject; } /* reset exception and return */ + } +%} + + +/* ----------------------------------------------------------------------------- + * js_dtor: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtor", "templates") +%{ +void $jswrapper(JSObjectRef thisObject) +{ + SwigPrivData* t = (SwigPrivData*) JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) free (($jstype)t->swigCObject); + if(t) free(t); +} +%} + +/* ----------------------------------------------------------------------------- + * js_dtor: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * - ${destructor_action}: The custom destructor action to invoke. + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtoroverride", "templates") +%{ +void $jswrapper(JSObjectRef thisObject) +{ + SwigPrivData* t = (SwigPrivData*) JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) { + $jstype arg1 = ($jstype)t->swigCObject; + ${destructor_action} + } + if(t) free(t); +} +%} + +/* ----------------------------------------------------------------------------- + * js_getter: template for getter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_getter", "templates") +%{ +JSValueRef $jswrapper(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + $jslocals + JSValueRef jsresult; + + $jscode + return jsresult; + + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_setter: template for setter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_setter", "templates") +%{ +bool $jswrapper(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + $jslocals + $jscode + + return true; + + goto fail; + fail: + return false; +} +%} + +/* ----------------------------------------------------------------------------- + * js_function: template for function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function", "templates") +%{ +JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + JSValueRef jsresult; + + if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + + $jscode + return jsresult; + + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_function_dispatcher: template for a function dispatcher for overloaded functions + * - $jswrapper: wrapper function name + * - $jsname: name of the wrapped function + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function_dispatcher", "templates") +%{ +JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + JSValueRef jsresult; + int res; + $jscode + + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); + return jsresult; + + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_overloaded_function: template for a overloaded function + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_overloaded_function", "templates") +%{ +int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception, JSValueRef* p_result) +{ + $jslocals + JSValueRef jsresult; + + if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + + $jscode + *p_result = jsresult; + return SWIG_OK; + + goto fail; + fail: + return SWIG_TypeError; +} +%} + +/* ----------------------------------------------------------------------------- + * js_function_dispatch_case: template for a case used in the function dispatcher + * - $jswrapper: wrapper function name + * - $jsargcount: number of arguments of overloaded function + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function_dispatch_case", "templates") +%{ + if(argc == $jsargcount) { + res = $jswrapper(context, function, thisObject, argc, argv, exception, &jsresult); + if(res == SWIG_OK) { *exception = 0; return jsresult; } + } +%} + +/* ----------------------------------------------------------------------------- + * jsc_variable_declaration: template for a variable table entry + * - $jsname: name of the variable + * - $jsgetter: wrapper of getter function + * - $jssetter: wrapper of setter function + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_variable_declaration", "templates") +%{ + {"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone}, +%} + + +/* ----------------------------------------------------------------------------- + * jsc_function_declaration: template for a function table entry + * - $jsname: name of the variable + * - $jswrapper: wrapper function + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_function_declaration", "templates") +%{ + {"$jsname", $jswrapper, kJSPropertyAttributeNone}, +%} + +/* ----------------------------------------------------------------------------- + * jsc_classtemplate_declaration: template for a namespace declaration + * - $jsmangledname: mangled class name + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_declaration", "templates") +%{ +JSClassDefinition $jsmangledname_classDefinition; + +JSClassDefinition $jsmangledname_objectDefinition; + +JSClassRef $jsmangledname_classRef; +%} + +/* ----------------------------------------------------------------------------- + * jsc_class_tables: template for a namespace declaration + * - $jsmangledname: mangled class name + * - $jsstaticclassvariables: list of static variable entries + * - $jsstaticclassfunctions: list of static function entries + * - $jsclassvariables: list of member variable entries + * - $jsclassfunctions: list of member function entries + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_tables", "templates") +%{ +JSStaticValue $jsmangledname_staticValues[] = { + $jsstaticclassvariables + { 0, 0, 0, 0 } +}; + +JSStaticFunction $jsmangledname_staticFunctions[] = { + $jsstaticclassfunctions + { 0, 0, 0 } +}; + +JSStaticValue $jsmangledname_values[] = { + $jsclassvariables + { 0, 0, 0, 0 } +}; + +JSStaticFunction $jsmangledname_functions[] = { + $jsclassfunctions + { 0, 0, 0 } +}; +%} + +/* ----------------------------------------------------------------------------- + * jsc_define_class_template: template for defining a class template + * - $jsmangledname: mangled class name + * - $jsmangledtype: mangled class type + * - $jsctor: wrapper of ctor + * - $jsbaseclass: mangled name of base class + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_definition", "templates") +%{ + $jsmangledname_classDefinition.staticFunctions = $jsmangledname_staticFunctions; + $jsmangledname_classDefinition.staticValues = $jsmangledname_staticValues; + $jsmangledname_classDefinition.callAsConstructor = $jsctor; + $jsmangledname_classDefinition.finalize = $jsdtor; + $jsmangledname_objectDefinition.staticValues = $jsmangledname_values; + $jsmangledname_objectDefinition.staticFunctions = $jsmangledname_functions; + $jsclass_inheritance + JSClassRef $jsmangledname_classRef = JSClassCreate(&$jsmangledname_objectDefinition); + SWIGTYPE_$jsmangledtype->clientdata = $jsmangledname_classRef; +%} + +%fragment ("jsc_class_inherit", templates) +%{ + if (SWIGTYPE_p$jsbaseclassmangled != NULL) { + $jsmangledname_objectDefinition.parentClass = (JSClassRef) SWIGTYPE_p$jsbaseclassmangled->clientdata; + } +%} + +%fragment ("jsc_class_noinherit", templates) +%{ + $jsmangledname_objectDefinition.parentClass = _SwigObject_classRef; +%} + + +/* ----------------------------------------------------------------------------- + * jsc_register_class: template for registration of a class + * - $jsname: class name + * - $jsmangledname: mangled class name + * - $jsnspace: mangled name of namespace + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_registration", "templates") +%{ + JS_registerClass(context, $jsnspace_object, "$jsname", &$jsmangledname_classDefinition); +%} + + +/* ----------------------------------------------------------------------------- + * jsc_nspace_declaration: template for a namespace declaration + * - $jsnspace: mangled name of the namespace + * - $jsglobalvariables: list of variable entries + * - $jsglobalfunctions: list if fuction entries + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_nspace_declaration", "templates") +%{ +JSStaticValue $jsnspace_values[] = { + $jsglobalvariables + { 0, 0, 0, 0 } +}; + +JSStaticFunction $jsnspace_functions[] = { + $jsglobalfunctions + { 0, 0, 0 } +}; + +JSClassDefinition $jsnspace_classDefinition; +%} + +/* ----------------------------------------------------------------------------- + * jsc_nspace_definition: template for definition of a namespace object + * - $jsmangledname: mangled name of namespace + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_nspace_definition", "templates") +%{ + $jsmangledname_classDefinition.staticFunctions = $jsmangledname_functions; + $jsmangledname_classDefinition.staticValues = $jsmangledname_values; + JSObjectRef $jsmangledname_object = JSObjectMake(context, JSClassCreate(&$jsmangledname_classDefinition), NULL); +%} + +/* ----------------------------------------------------------------------------- + * jsc_nspace_registration: template for registration of a namespace object + * - $jsname: name of namespace + * - $jsmangledname: mangled name of namespace + * - $jsparent: mangled name of parent namespace + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_nspace_registration", "templates") +%{ + JS_registerNamespace(context, $jsmangledname_object, $jsparent_object, "$jsname"); +%} diff --git a/Lib/javascript/jsc/javascriptcomplex.swg b/Lib/javascript/jsc/javascriptcomplex.swg new file mode 100644 index 000000000..7d165dce4 --- /dev/null +++ b/Lib/javascript/jsc/javascriptcomplex.swg @@ -0,0 +1,146 @@ +/* + Defines the As/From converters for double/float complex, you need to + provide complex Type, the Name you want to use in the converters, + the complex Constructor method, and the Real and Imag complex + accessor methods. + + See the std_complex.i and ccomplex.i for concret examples. +*/ + +/* the common from converter */ +%define %swig_fromcplx_conv(Type, Real, Imag) +%fragment(SWIG_From_frag(Type),"header", + fragment=SWIG_From_frag(double)) +{ +SWIGINTERNINLINE JSObjectRef +SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) +{ + JSValueRef vals[2]; + vals[0] = SWIG_From(double)(Real(c)); + vals[1] = SWIG_From(double)(Imag(c)); + return JSObjectMakeArray(context, 2, vals, NULL); +} +} +%enddef + +/* the double case */ +%define %swig_cplxdbl_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(double)) +{ +SWIGINTERN int +SWIG_AsVal_dec(Type) (JSValueRef o, Type* val) +{ + if (JSValueIsObject(context, o)) { + JSObjectRef array; + JSValueRef exception, js_re, js_im; + double re, im; + int res; + + exception = 0; + res = 0; + + array = JSValueToObject(context, o, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_re = JSObjectGetPropertyAtIndex(context, array, 0, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_im = JSObjectGetPropertyAtIndex(context, array, 1, &exception); + if(exception != 0) + return SWIG_TypeError; + + res = SWIG_AsVal(double)(js_re, &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(js_im, &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if (val) *val = Constructor(re, im); + return SWIG_OK; + } else { + double d; + int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(d, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +/* the float case */ +%define %swig_cplxflt_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(float)) { +SWIGINTERN int +SWIG_AsVal_dec(Type)(JSValueRef o, Type *val) +{ + if (JSValueIsObject(context, o)) { + JSObjectRef array; + JSValueRef exception, js_re, js_im; + double re, im; + int res; + + exception = 0; + res = 0; + + array = JSValueToObject(context, o, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_re = JSObjectGetPropertyAtIndex(context, array, 0, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_im = JSObjectGetPropertyAtIndex(context, array, 1, &exception); + if(exception != 0) + return SWIG_TypeError; + + res = SWIG_AsVal(double)(js_re, &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(js_im, &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if ((-FLT_MAX <= re && re <= FLT_MAX) && (-FLT_MAX <= im && im <= FLT_MAX)) { + if (val) *val = Constructor(%numeric_cast(re, float), + %numeric_cast(im, float)); + return SWIG_OK; + } else { + return SWIG_OverflowError; + } + } else { + float re; + int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(re, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} + +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \ +%swig_cplxflt_conv(Type, Constructor, Real, Imag) + + +#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \ +%swig_cplxdbl_conv(Type, Constructor, Real, Imag) diff --git a/Lib/javascript/jsc/javascriptfragments.swg b/Lib/javascript/jsc/javascriptfragments.swg new file mode 100644 index 000000000..4778bf033 --- /dev/null +++ b/Lib/javascript/jsc/javascriptfragments.swg @@ -0,0 +1,23 @@ +/* + + Create a file with this name, 'javascriptfragments.swg', in your working + directory and add all the %fragments you want to take precedence + over the default ones defined by swig. + + For example, if you add: + + %fragment(SWIG_AsVal_frag(int),"header") { + SWIGINTERNINLINE int + SWIG_AsVal(int)(PyObject *obj, int *val) + { + ; + } + } + + this will replace the code used to retrieve an integer value for all + the typemaps that need it, including: + + int, std::vector, std::list >, etc. + + +*/ diff --git a/Lib/javascript/jsc/javascripthelpers.swg b/Lib/javascript/jsc/javascripthelpers.swg new file mode 100644 index 000000000..820075ca6 --- /dev/null +++ b/Lib/javascript/jsc/javascripthelpers.swg @@ -0,0 +1,69 @@ +%insert(wrapper) %{ + +bool JS_registerClass(JSGlobalContextRef context, JSObjectRef parentObject, + const char* className, + JSClassDefinition* definition) { + + JSStringRef js_className = JSStringCreateWithUTF8CString(className); + JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); + JSObjectSetProperty(context, parentObject, + js_className, classObject, + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_className); + + return true; +} + +bool JS_registerNamespace(JSGlobalContextRef context, + JSObjectRef namespaceObj, JSObjectRef parentNamespace, + const char* name) +{ + JSStringRef js_name = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(context, parentNamespace, + js_name, namespaceObj, + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_name); + + return true; +} + + +bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context, object, js_functionName, + JSObjectMakeFunctionWithCallback(context, js_functionName, callback), + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} + +bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char buffer[256]; + char msg[512]; + int res; + + JSStringGetUTF8CString(propertyName, buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } + + return false; +} + +JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { + JSValueRef val; + + JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); + val = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + + return val; +} +%} diff --git a/Lib/javascript/jsc/javascriptinit.swg b/Lib/javascript/jsc/javascriptinit.swg new file mode 100644 index 000000000..a32ba336c --- /dev/null +++ b/Lib/javascript/jsc/javascriptinit.swg @@ -0,0 +1,67 @@ +%insert(init) %{ +SWIGRUNTIME void +SWIG_JSC_SetModule(swig_module_info *swig_module) {} + +SWIGRUNTIME swig_module_info * +SWIG_JSC_GetModule(void) { + return 0; +} + +#define SWIG_GetModule(clientdata) SWIG_JSC_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_JSC_SetModule(pointer) +%} + +%insert(init) "swiginit.swg" + +%fragment ("js_initializer_define", "templates") %{ +#define SWIGJSC_INIT $jsname_initialize +%} + +// Open the initializer function +%insert(init) +%{ + +#ifdef __cplusplus +extern "C" { +#endif + +bool SWIGJSC_INIT (JSGlobalContextRef context, JSObjectRef *exports) { + SWIG_InitializeModule(0); +%} + +/* ----------------------------------------------------------------------------- + * js_initializer: template for the module initializer function + * - $jsname: module name + * - $jscreatenamespaces: part with code for creating namespace objects + * - $jscreateclasses: part with code for creating classes + * - $jsregisternamespaces: part with code for registration of namespaces + * ----------------------------------------------------------------------------- */ +%fragment ("js_initializer", "templates") %{ + /* Initialize the base swig type object */ + _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; + _SwigObject_objectDefinition.staticValues = _SwigObject_values; + _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); + + /* Initialize the PackedData class */ + _SwigPackedData_objectDefinition.staticFunctions = _SwigPackedData_functions; + _SwigPackedData_objectDefinition.staticValues = _SwigPackedData_values; + _SwigPackedData_objectDefinition.finalize = _wrap_SwigPackedData_delete; + _SwigPackedData_classRef = JSClassCreate(&_SwigPackedData_objectDefinition); + + /* Create objects for namespaces */ + $jscreatenamespaces + + /* Register classes */ + $jsregisterclasses + + /* Register namespaces */ + $jsregisternamespaces + + *exports = exports_object; + + return true; +} +#ifdef __cplusplus +} +#endif +%} diff --git a/Lib/javascript/jsc/javascriptkw.swg b/Lib/javascript/jsc/javascriptkw.swg new file mode 100644 index 000000000..c3c118391 --- /dev/null +++ b/Lib/javascript/jsc/javascriptkw.swg @@ -0,0 +1,40 @@ +#ifndef JAVASCRIPT_JAVASCRIPTKW_SWG_ +#define JAVASCRIPT_JAVASCRIPTKW_SWG_ + +/* Warnings for Java keywords */ +#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",rename="_%s") `x` + +/* Taken from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Reserved_Words */ + +JAVASCRIPTKW(break); +JAVASCRIPTKW(case); +JAVASCRIPTKW(catch); +JAVASCRIPTKW(continue); +JAVASCRIPTKW(default); +JAVASCRIPTKW(delete); +JAVASCRIPTKW(do); +JAVASCRIPTKW(else); +JAVASCRIPTKW(finally); +JAVASCRIPTKW(for); +JAVASCRIPTKW(function); +JAVASCRIPTKW(if); +JAVASCRIPTKW(in); +JAVASCRIPTKW(instanceof); +JAVASCRIPTKW(new); +JAVASCRIPTKW(return); +JAVASCRIPTKW(switch); +JAVASCRIPTKW(this); +JAVASCRIPTKW(throw); +JAVASCRIPTKW(try); +JAVASCRIPTKW(typeof); +JAVASCRIPTKW(var); +JAVASCRIPTKW(void); +JAVASCRIPTKW(while); +JAVASCRIPTKW(with); + +/* others bad names if any*/ +// for example %namewarn("321:clone() is a javascript bad method name") *::clone(); + +#undef JAVASCRIPTKW + +#endif //JAVASCRIPT_JAVASCRIPTKW_SWG_ diff --git a/Lib/javascript/jsc/javascriptprimtypes.swg b/Lib/javascript/jsc/javascriptprimtypes.swg new file mode 100644 index 000000000..7e9898a24 --- /dev/null +++ b/Lib/javascript/jsc/javascriptprimtypes.swg @@ -0,0 +1,182 @@ +/* ------------------------------------------------------------ + * Primitive Types + * ------------------------------------------------------------ */ + +/* boolean */ + +%fragment(SWIG_From_frag(bool),"header") { +SWIGINTERNINLINE +JSValueRef SWIG_From_dec(bool)(bool value) +{ + return JSValueMakeBoolean(context, value); +} +} + +%fragment(SWIG_AsVal_frag(bool),"header", + fragment=SWIG_AsVal_frag(long)) { +SWIGINTERN +int SWIG_AsVal_dec(bool)(JSValueRef obj, bool *val) +{ + if(!JSValueIsBoolean(context, obj)) { + return SWIG_ERROR; + } + if (val) *val = JSValueToBoolean(context, obj); + return SWIG_OK; +} +} + +/* int */ + +%fragment(SWIG_From_frag(int),"header") { +SWIGINTERNINLINE JSValueRef + SWIG_From_dec(int)(int value) +{ + return JSValueMakeNumber(context, value); +} +} + +/* long */ + +%fragment(SWIG_From_frag(long),"header") { +SWIGINTERNINLINE JSValueRef +SWIG_From_dec(long)(long value) +{ + return JSValueMakeNumber(context, value); +} +} + +%fragment(SWIG_AsVal_frag(long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN int +SWIG_AsVal_dec(long)(JSValueRef obj, long* val) +{ + if (!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = (long) JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} +} + +/* unsigned long */ + +%fragment(SWIG_From_frag(unsigned long),"header", + fragment=SWIG_From_frag(long)) { +SWIGINTERNINLINE JSValueRef +SWIG_From_dec(unsigned long)(unsigned long value) +{ + return (value > LONG_MAX) ? + JSValueMakeNumber(context, value) : JSValueMakeNumber(context, %numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN int +SWIG_AsVal_dec(unsigned long)(JSValueRef obj, unsigned long *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + + long longVal = (long) JSValueToNumber(context, obj, NULL); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +/* long long */ +// Note: these are copied from 'long' and probably need fixing + +%fragment(SWIG_From_frag(long long),"header", + fragment=SWIG_From_frag(long), + fragment="") { +SWIGINTERNINLINE JSValueRef +SWIG_From_dec(long long)(long long value) +{ + return JSValueMakeNumber(context, value); +} +} + +%fragment(SWIG_AsVal_frag(long long),"header", + fragment=SWIG_AsVal_frag(long), + fragment="SWIG_CanCastAsInteger", + fragment="") { +SWIGINTERN int +SWIG_AsVal_dec(long long)(JSValueRef obj, long long* val) +{ + if (!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = (long long) JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} +} + +/* unsigned long long */ +// Note: these are copied from 'unsigned long' and probably need fixing + +%fragment(SWIG_From_frag(unsigned long long),"header", + fragment=SWIG_From_frag(long long), + fragment="") { +SWIGINTERN JSValueRef +SWIG_From_dec(unsigned long long)(unsigned long long value) +{ + return (value > LONG_MAX) ? + JSValueMakeNumber(context, value) : JSValueMakeNumber(context, %numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long long),"header", + fragment=SWIG_AsVal_frag(unsigned long), + fragment="SWIG_CanCastAsInteger", + fragment="") { +SWIGINTERN int +SWIG_AsVal_dec(unsigned long long)(JSValueRef obj, unsigned long long *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + + long long longVal = (unsigned long long) JSValueToNumber(context, obj, NULL); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +/* double */ + +%fragment(SWIG_From_frag(double),"header") { +SWIGINTERN JSValueRef +SWIG_From_dec(double) (double val) +{ + return JSValueMakeNumber(context, val); +} +} + +%fragment(SWIG_AsVal_frag(double),"header") { +SWIGINTERN int +SWIG_AsVal_dec(double)(JSValueRef obj, double *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} +} diff --git a/Lib/javascript/jsc/javascriptrun.swg b/Lib/javascript/jsc/javascriptrun.swg new file mode 100644 index 000000000..3463d2351 --- /dev/null +++ b/Lib/javascript/jsc/javascriptrun.swg @@ -0,0 +1,298 @@ +/* ---------------------------------------------------------------------------- + * Errors and exceptions + * + * ---------------------------------------------------------------------------*/ + +#define SWIG_Error(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_exception(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_fail goto fail + +void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* type) { + JSStringRef message = JSStringCreateWithUTF8CString(type); + *exception = JSValueMakeString(context, message); + JSStringRelease(message); +} + +void SWIG_JSC_exception(JSContextRef context, JSValueRef *exception, int code, const char* msg) { + SWIG_Javascript_Raise(context, exception, msg); +} + +/* ---------------------------------------------------------------------------- + * The parent class of all Proxies + * + * ---------------------------------------------------------------------------*/ + +typedef struct { + bool swigCMemOwn; + void *swigCObject; + swig_type_info *info; +} SwigPrivData; + +JSValueRef _wrap_SwigObject_disown(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SwigPrivData *cdata = (SwigPrivData *) JSObjectGetPrivate(obj); + + cdata->swigCMemOwn = false; + + jsresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef _wrap_SwigObject_getCPtr(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + long result; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SwigPrivData *cdata = (SwigPrivData*) JSObjectGetPrivate(obj); + + result = (long) cdata->swigCObject; + jsresult = JSValueMakeNumber(context, result); + + return jsresult; +} + +JSValueRef _wrap_SwigObject_equals(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + bool result; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SwigPrivData *cdata = (SwigPrivData*) JSObjectGetPrivate(obj); + + JSObjectRef obj2 = JSValueToObject(context, argv[0], NULL); + SwigPrivData *cdata2 = (SwigPrivData*) JSObjectGetPrivate(obj2); + + result = (cdata->swigCObject == cdata2->swigCObject); + jsresult = JSValueMakeBoolean(context, result); + + return jsresult; +} + +JSStaticValue _SwigObject_values[] = { + { + 0, 0, 0, 0 + } +}; + +JSStaticFunction _SwigObject_functions[] = { + { + "disown",_wrap_SwigObject_disown, kJSPropertyAttributeNone + }, + { + "equals",_wrap_SwigObject_equals, kJSPropertyAttributeNone + }, + { + "getCPtr",_wrap_SwigObject_getCPtr, kJSPropertyAttributeNone + }, + { + 0, 0, 0 + } +}; + +JSClassDefinition _SwigObject_objectDefinition; + +JSClassRef _SwigObject_classRef; + + +int SWIG_JSC_ConvertInstancePtr(JSContextRef context, JSObjectRef objRef, void** ptr, swig_type_info *info, int flags) { + SwigPrivData *cdata = (SwigPrivData *) JSObjectGetPrivate(objRef); + if(cdata == NULL) { + return SWIG_ERROR; + } + if(cdata->info != info) { + bool type_valid = false; + swig_cast_info *t = info->cast; + while(t != NULL) { + if(t->type == cdata->info) { + type_valid = true; + break; + } + t = t->next; + } + if(!type_valid) { + return SWIG_TypeError; + } + } + + *ptr = cdata->swigCObject; + + if(flags & SWIG_POINTER_DISOWN) { + cdata->swigCMemOwn = false; + } + + return SWIG_OK; +} + +int SWIG_JSC_ConvertPtr(JSContextRef context, JSValueRef valRef, void** ptr, swig_type_info *info, int flags) { + if(!JSValueIsObject(context, valRef)) { + return SWIG_TypeError; + } + + JSObjectRef objRef = JSValueToObject(context, valRef, NULL); + if(objRef == NULL) { + return SWIG_ERROR; + } + + return SWIG_JSC_ConvertInstancePtr(context, objRef, ptr, info, flags); +} + +JSObjectRef SWIG_JSC_NewPointerObj(JSContextRef context, void *ptr, swig_type_info *info, int flags) { + + JSClassRef classRef; + if(info->clientdata == NULL) { + classRef = _SwigObject_classRef; + } else { + classRef = (JSClassRef) info->clientdata; + } + + JSObjectRef result = JSObjectMake(context, classRef, NULL); + + SwigPrivData* cdata = (SwigPrivData*) malloc(sizeof(SwigPrivData)); + cdata->swigCObject = ptr; + cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; + cdata->info = info; + + JSObjectSetPrivate(result, cdata); + + return result; +} + +#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_JSC_ConvertPtr(context, obj, ptr, info, flags) +#define SWIG_NewPointerObj(ptr, info, flags) SWIG_JSC_NewPointerObj(context, ptr, info, flags) + +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_JSC_ConvertInstancePtr(context, obj, pptr, type, flags) +#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_JSC_NewPointerObj(context, thisvalue, type, flags) + +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_JSC_ConvertPtr(context, obj, pptr, type, 0) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_JSC_NewPointerObj(context, ptr, type, 0) + +/* ---------------------------------------------------------------------------- + * A class for packed data + * + * ---------------------------------------------------------------------------*/ + +typedef struct { + void *data; + size_t size; + swig_type_info *type; +} SwigPackedData; + +JSStaticValue _SwigPackedData_values[] = { + { + 0, 0, 0, 0 + } +}; +JSStaticFunction _SwigPackedData_functions[] = { + { + 0, 0, 0 + } +}; +JSClassDefinition _SwigPackedData_objectDefinition; +JSClassRef _SwigPackedData_classRef; + +SWIGRUNTIMEINLINE +int SwigJSCPacked_Check(JSContextRef context, JSValueRef valRef) { + return JSValueIsObjectOfClass(context, valRef, _SwigPackedData_classRef); +} + +SWIGRUNTIME +swig_type_info* SwigJSCPacked_UnpackData(JSContextRef context, JSValueRef valRef, void *ptr, size_t size) { + if (SwigJSCPacked_Check(context, valRef)) { + JSObjectRef objRef = JSValueToObject(context, valRef, NULL); + SwigPackedData *sobj = (SwigPackedData *) JSObjectGetPrivate(objRef); + if (sobj->size != size) return 0; + memcpy(ptr, sobj->data, size); + return sobj->type; + } else { + return 0; + } +} + +SWIGRUNTIME +int SWIG_JSC_ConvertPacked(JSContextRef context, JSValueRef valRef, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = SwigJSCPacked_UnpackData(context, valRef, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +SWIGRUNTIME +JSValueRef SWIG_JSC_NewPackedObj(JSContextRef context, void *data, size_t size, swig_type_info *type) { + + JSClassRef classRef = _SwigObject_classRef; + JSObjectRef result = JSObjectMake(context, classRef, NULL); + + SwigPackedData* cdata = (SwigPackedData*) malloc(sizeof(SwigPackedData)); + cdata->data = data; + cdata->size = size; + cdata->type = type; + + JSObjectSetPrivate(result, cdata); + + return result; +} + +/* SwigPackedData wrappers */ + +void _wrap_SwigPackedData_delete(JSObjectRef obj) +{ + SwigPackedData* cdata = (SwigPackedData*) JSObjectGetPrivate(obj); + if (cdata) { + free(cdata->data); + } +} + +/* for C++ member pointers, ie, member methods */ + +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_JSC_ConvertPacked(context, obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_JSC_NewPackedObj(context, ptr, sz, type) + + +/* --------------------------------------------------------------------------- + * Support for IN/OUTPUT typemaps (see Lib/typemaps/inoutlist.swg) + * + * ---------------------------------------------------------------------------*/ + +unsigned int SWIGJSC_ArrayLength(JSContextRef context, JSObjectRef arr) { + static JSStringRef LENGTH = 0; + JSValueRef exception = NULL; + JSValueRef js_length; + double length; + + if (LENGTH == 0) { + LENGTH = JSStringCreateWithUTF8CString("length"); + } + + js_length = JSObjectGetProperty(context, arr, LENGTH, &exception); + if (exception == 0 && JSValueIsNumber(context, js_length)) { + length = JSValueToNumber(context, js_length, 0); + return (unsigned int) length; + } else { + return 0; + } +} + +SWIGRUNTIME +JSValueRef SWIGJSC_AppendOutput(JSContextRef context, JSValueRef value, JSValueRef obj) { + JSObjectRef arr; + unsigned int length; + + if (JSValueIsUndefined(context, value)) { + arr = JSObjectMakeArray(context, 0, 0, 0); + } else { + arr = JSValueToObject(context, value, 0); + } + + length = SWIGJSC_ArrayLength(context, arr); + JSObjectSetPropertyAtIndex(context, arr, length, obj, 0); +} diff --git a/Lib/javascript/jsc/javascriptruntime.swg b/Lib/javascript/jsc/javascriptruntime.swg new file mode 100644 index 000000000..8f8390890 --- /dev/null +++ b/Lib/javascript/jsc/javascriptruntime.swg @@ -0,0 +1,19 @@ +/* ----------------------------------------------------------------------------- + * javascriptruntime.swg + * + * Javascript support code + * ----------------------------------------------------------------------------- */ + +%insert(runtime) %{ +#include +#include +#include +#include +#include +#include +%} + +%insert(runtime) "swigrun.swg"; /* SWIG API */ +%insert(runtime) "swigerrors.swg"; /* SWIG errors */ + +%insert(runtime) "javascriptrun.swg"; /* SWIG errors */ diff --git a/Lib/javascript/jsc/javascriptstrings.swg b/Lib/javascript/jsc/javascriptstrings.swg new file mode 100644 index 000000000..0581c1920 --- /dev/null +++ b/Lib/javascript/jsc/javascriptstrings.swg @@ -0,0 +1,184 @@ +/* ------------------------------------------------------------ + * utility methods for char strings + * ------------------------------------------------------------ */ +%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +SWIGINTERN int +SWIG_JSC_AsCharPtrAndSize(JSContextRef context, JSValueRef valRef, char** cptr, size_t* psize, int *alloc) +{ + if(JSValueIsString(context, valRef)) { + JSStringRef js_str = JSValueToStringCopy(context, valRef, NULL); + size_t len = JSStringGetMaximumUTF8CStringSize(js_str); + char* cstr = (char*) malloc(len * sizeof(char)); + /* JSStringGetUTF8CString returns the length including 0-terminator */ + len = JSStringGetUTF8CString(js_str, cstr, len); + + if(alloc) *alloc = SWIG_NEWOBJ; + if(psize) *psize = len; + if(cptr) *cptr = cstr; + + return SWIG_OK; + } else { + if(JSValueIsObject(context, valRef)) { + JSObjectRef obj = JSValueToObject(context, valRef, NULL); + // try if the object is a wrapped char[] + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + return SWIG_TypeError; + } else { + return SWIG_TypeError; + } + } +} +} + +%fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +SWIGINTERNINLINE JSValueRef +SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + // TODO: handle extra long strings + //swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + //return pchar_descriptor ? + // SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); + return JSValueMakeUndefined(context); + } else { + JSStringRef jsstring; + if(size < 2) { + char c[size+1]; + int i; + for(i=0;i + +/* Look for user fragments file. */ +%include + +/* Javascript fragments for fundamental types */ +%include + +/* Javascript fragments for char* strings */ +%include + +/* ------------------------------------------------------------ + * Unified typemap section + * ------------------------------------------------------------ */ + +#define SWIG_Object JSValueRef +#define VOID_Object JSValueMakeUndefined(context) + +/* append output */ +#define SWIG_AppendOutput(result, obj) SWIGJSC_AppendOutput(context, result, obj) + +/* set constant */ +#define SWIG_SetConstant(name, obj) + +/* raise */ +#define SWIG_Raise(obj, type, desc) SWIG_Javascript_Raise(context, exception, type) + +%insert("runtime") %{ +#define SWIG_JSC_FROM_DECL_ARGS(arg1) (JSContextRef context, arg1) +#define SWIG_JSC_FROM_CALL_ARGS(arg1) (context, arg1) +#define SWIG_JSC_AS_DECL_ARGS(arg1, arg2) (JSContextRef context, arg1, arg2) +#define SWIG_JSC_AS_CALL_ARGS(arg1, arg2) (context, arg1, arg2) +%} + +/* Include the unified typemap library */ +%include diff --git a/Lib/javascript/jsc/std_common.i b/Lib/javascript/jsc/std_common.i new file mode 100755 index 000000000..cee11e8ca --- /dev/null +++ b/Lib/javascript/jsc/std_common.i @@ -0,0 +1,5 @@ +%include + +%apply size_t { std::size_t }; +%apply const size_t& { const std::size_t& }; + diff --git a/Lib/javascript/jsc/std_complex.i b/Lib/javascript/jsc/std_complex.i new file mode 100644 index 000000000..088a4fe7b --- /dev/null +++ b/Lib/javascript/jsc/std_complex.i @@ -0,0 +1,19 @@ +/* + * STD C++ complex typemaps + */ + +%include + +%{ +#include +%} + +/* defining the complex as/from converters */ + +%swig_cplxdbl_convn(std::complex, std::complex, std::real, std::imag) +%swig_cplxflt_convn(std::complex, std::complex, std::real, std::imag) + +/* defining the typemaps */ + +%typemaps_primitive(%checkcode(CPLXDBL), std::complex); +%typemaps_primitive(%checkcode(CPLXFLT), std::complex); diff --git a/Lib/javascript/jsc/std_deque.i b/Lib/javascript/jsc/std_deque.i new file mode 100644 index 000000000..cb98f6c2f --- /dev/null +++ b/Lib/javascript/jsc/std_deque.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/jsc/std_except.i b/Lib/javascript/jsc/std_except.i new file mode 100644 index 000000000..af98428f6 --- /dev/null +++ b/Lib/javascript/jsc/std_except.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/jsc/std_map.i b/Lib/javascript/jsc/std_map.i new file mode 100755 index 000000000..e7812f38a --- /dev/null +++ b/Lib/javascript/jsc/std_map.i @@ -0,0 +1,74 @@ +/* ----------------------------------------------------------------------------- + * std_map.i + * + * SWIG typemaps for std::map + * ----------------------------------------------------------------------------- */ + +%include + +// ------------------------------------------------------------------------ +// std::map +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class map { + // add typemaps here + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef K key_type; + typedef T mapped_type; + map(); + map(const map &); + + unsigned int size() const; + bool empty() const; + void clear(); + %extend { + const T& get(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); + } + void set(const K& key, const T& x) { + (*self)[key] = x; + } + void del(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + throw std::out_of_range("key not found"); + } + bool has_key(const K& key) { + std::map::iterator i = self->find(key); + return i != self->end(); + } + } + }; + +// Legacy macros (deprecated) +%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) +#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary" +%enddef + +} diff --git a/Lib/javascript/jsc/std_pair.i b/Lib/javascript/jsc/std_pair.i new file mode 100755 index 000000000..fe45ee676 --- /dev/null +++ b/Lib/javascript/jsc/std_pair.i @@ -0,0 +1,34 @@ +/* ----------------------------------------------------------------------------- + * std_pair.i + * + * SWIG typemaps for std::pair + * ----------------------------------------------------------------------------- */ + +%include +%include + +// ------------------------------------------------------------------------ +// std::pair +// ------------------------------------------------------------------------ + +%{ +#include +%} + +namespace std { + + template struct pair { + + pair(); + pair(T first, U second); + pair(const pair& p); + + template pair(const pair &p); + + T first; + U second; + }; + + // add specializations here + +} diff --git a/Lib/javascript/jsc/std_string.i b/Lib/javascript/jsc/std_string.i new file mode 100755 index 000000000..fb1bd62b5 --- /dev/null +++ b/Lib/javascript/jsc/std_string.i @@ -0,0 +1,69 @@ +/* ----------------------------------------------------------------------------- + * std_string.i + * + * Typemaps for const std::string&. + * To use non-const std::string references use the following %apply: + * %apply const std::string & {std::string &}; + * + * ----------------------------------------------------------------------------- */ + +%{ +#include + +std::string SWIGJSC_valueToString(JSContextRef context, JSValueRef value) { + JSStringRef jsstring = JSValueToStringCopy(context, value, /* JSValueRef *exception */ 0); + unsigned int length = JSStringGetLength(jsstring); + char *cstr = new char[length + 1]; + JSStringGetUTF8CString(jsstring, cstr, length + 1); + + // create a copy + std::string result(cstr); + + JSStringRelease(jsstring); + delete[] cstr; + + return result; +} + +JSValueRef SWIGJSC_stringToValue(JSContextRef context, const std::string& s) +{ + JSValueRef result; + JSStringRef jsstring = JSStringCreateWithUTF8CString(s.c_str()); + result = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return result; +} +%} + +namespace std { + %naturalvar string; + + class string; + + + %typemap(in) string + %{ + $1 = SWIGJSC_valueToString(context, $input); + %} + + %typemap(in) const string & + %{ + $1 = new std::string(SWIGJSC_valueToString(context, $input)); + %} + + %typemap(freearg) const string & + %{ + delete $1; + %} + + %typemap(out) string + %{ + $result = SWIGJSC_stringToValue(context, $1); + %} + + %typemap(out) const string & + %{ + $result = SWIGJSC_stringToValue(context, *$1); + %} + +} diff --git a/Lib/javascript/jsc/std_vector.i b/Lib/javascript/jsc/std_vector.i new file mode 100755 index 000000000..3f29b19c7 --- /dev/null +++ b/Lib/javascript/jsc/std_vector.i @@ -0,0 +1,85 @@ +/* ----------------------------------------------------------------------------- + * std_vector.i + * ----------------------------------------------------------------------------- */ + +%include + +%{ +#include +#include +%} + +namespace std { + + template class vector { + public: + typedef size_t size_type; + typedef T value_type; + typedef const value_type& const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + public: + typedef size_t size_type; + typedef bool value_type; + typedef bool const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i +%include +%include +%include +%include + diff --git a/Lib/javascript/jsc/typemaps.i b/Lib/javascript/jsc/typemaps.i new file mode 100644 index 000000000..d3d8afb19 --- /dev/null +++ b/Lib/javascript/jsc/typemaps.i @@ -0,0 +1,148 @@ +/* ----------------------------------------------------------------------------- + * typemaps.i + * + * Pointer handling + * These mappings provide support for input/output arguments and common + * uses for C/C++ pointers. + * ----------------------------------------------------------------------------- */ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + +/* +The following methods can be applied to turn a pointer into a simple +"input" value. That is, instead of passing a pointer to an object, +you would use a real value instead. + + int *INPUT + short *INPUT + long *INPUT + long long *INPUT + unsigned int *INPUT + unsigned short *INPUT + unsigned long *INPUT + unsigned long long *INPUT + unsigned char *INPUT + bool *INPUT + float *INPUT + double *INPUT + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + %include + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +*/ + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + +/* +The following methods can be applied to turn a pointer into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. In the case of +multiple output values, they are returned in the form of a Python tuple. + + int *OUTPUT + short *OUTPUT + long *OUTPUT + long long *OUTPUT + unsigned int *OUTPUT + unsigned short *OUTPUT + unsigned long *OUTPUT + unsigned long long *OUTPUT + unsigned char *OUTPUT + bool *OUTPUT + float *OUTPUT + double *OUTPUT + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters).K: + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Python output of the function would be a tuple containing both +output values. + +*/ + +// INOUT +// Mappings for an argument that is both an input and output +// parameter + +/* +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned in the form of a Python tuple. + + int *INOUT + short *INOUT + long *INOUT + long long *INOUT + unsigned int *INOUT + unsigned short *INOUT + unsigned long *INOUT + unsigned long long *INOUT + unsigned char *INOUT + bool *INOUT + float *INOUT + double *INOUT + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include + void neg(double *INOUT); + +or you can use the %apply directive : + + %include + %apply double *INOUT { double *x }; + void neg(double *x); + +Unlike C, this mapping does not directly modify the input value (since +this makes no sense in Python). Rather, the modified input value shows +up as the return value of the function. Thus, to apply this function +to a Python variable you might do this : + + x = neg(x) + +Note : previous versions of SWIG used the symbol 'BOTH' to mark +input/output arguments. This is still supported, but will be slowly +phased out in future releases. + +*/ + +%include diff --git a/Lib/javascript/v8/arrays_javascript.i b/Lib/javascript/v8/arrays_javascript.i new file mode 100644 index 000000000..22b50be8f --- /dev/null +++ b/Lib/javascript/v8/arrays_javascript.i @@ -0,0 +1,125 @@ +/* ----------------------------------------------------------------------------- + * arrays_javascript.i + * + * These typemaps give more natural support for arrays. The typemaps are not efficient + * as there is a lot of copying of the array values whenever the array is passed to C/C++ + * from JavaScript and vice versa. The JavaScript array is expected to be the same size as the C array. + * An exception is thrown if they are not. + * + * Example usage: + * Wrapping: + * + * %include + * %inline %{ + * extern int FiddleSticks[3]; + * %} + * + * Use from JavaScript like this: + * + * var fs = [10, 11, 12]; + * example.FiddleSticks = fs; + * fs = example.FiddleSticks; + * ----------------------------------------------------------------------------- */ + +%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {} +%fragment("SWIG_JSCGetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {} + +%typemap(in, fragment="SWIG_JSCGetIntProperty") int[], int[ANY] + (int length = 0, v8::Local array, v8::Local jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if ($input->IsArray()) + { + // Convert into Array + array = v8::Local::Cast($input); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = array->Get(i); + + // Get primitive value from JSObject + res = SWIG_AsVal(int)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) int[], int[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(int)) int[], int[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + v8::Local array = v8::Array::New(length); + + for (i = 0; i < length; i++) + { + array->Set(i, SWIG_From(int)($1[i])); + } + + + $result = array; +} + +%typemap(in, fragment="SWIG_JSCGetNumberProperty") double[], double[ANY] + (int length = 0, v8::Local array, v8::Local jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if ($input->IsArray()) + { + // Convert into Array + array = v8::Local::Cast($input); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = array->Get(i); + + // Get primitive value from JSObject + res = SWIG_AsVal(double)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) double[], double[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(double)) double[], double[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + v8::Local array = v8::Array::New(length); + + for (i = 0; i < length; i++) + { + array->Set(i, SWIG_From(double)($1[i])); + } + + + $result = array; +} diff --git a/Lib/javascript/v8/ccomplex.i b/Lib/javascript/v8/ccomplex.i new file mode 100644 index 000000000..8eda920bb --- /dev/null +++ b/Lib/javascript/v8/ccomplex.i @@ -0,0 +1,26 @@ +/* ----------------------------------------------------------------------------- + * ccomplex.i + * + * C complex typemaps + * ISO C99: 7.3 Complex arithmetic + * ----------------------------------------------------------------------------- */ + + +%include + +%{ +#include +%} + + +/* C complex constructor */ +#define CCplxConst(r, i) ((r) + I*(i)) + +%swig_cplxflt_convn(float complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(double complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(complex, CCplxConst, creal, cimag); + +/* declaring the typemaps */ +%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, complex); diff --git a/Lib/javascript/v8/cdata.i b/Lib/javascript/v8/cdata.i new file mode 100644 index 000000000..367965990 --- /dev/null +++ b/Lib/javascript/v8/cdata.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/complex.i b/Lib/javascript/v8/complex.i new file mode 100644 index 000000000..4c3b3c5e2 --- /dev/null +++ b/Lib/javascript/v8/complex.i @@ -0,0 +1,6 @@ +#ifdef __cplusplus +%include +#else +%include +#endif + diff --git a/Lib/javascript/v8/exception.i b/Lib/javascript/v8/exception.i new file mode 100644 index 000000000..0246cfde8 --- /dev/null +++ b/Lib/javascript/v8/exception.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/javascript.swg b/Lib/javascript/v8/javascript.swg new file mode 100644 index 000000000..3a83b6495 --- /dev/null +++ b/Lib/javascript/v8/javascript.swg @@ -0,0 +1,19 @@ +/* ----------------------------------------------------------------------------- + * javascript.swg + * + * Javascript typemaps + * ----------------------------------------------------------------------------- */ + +%include + +%include + +%include + +%include + +%include + +%include + +%include diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg new file mode 100644 index 000000000..9bcb33176 --- /dev/null +++ b/Lib/javascript/v8/javascriptcode.swg @@ -0,0 +1,468 @@ +/* ----------------------------------------------------------------------------- + * js_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ + +%fragment("js_ctor", "templates") %{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + $jslocals + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + $jscode + + SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + SWIGV8_RETURN(self); + + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_veto_ctor: a vetoing ctor for abstract classes + * - $jswrapper: name of wrapper + * - $jsname: class name + * ----------------------------------------------------------------------------- */ +%fragment ("js_veto_ctor", "templates") +%{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { + v8::HandleScope scope; + SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_ctor_dispatcher: dispatcher for overloaded constructors + * - $jswrapper: name of wrapper + * - $jsname: class name + * - $jsdispatchcases: part containing code for dispatching + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor_dispatcher", "templates") +%{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { + v8::HandleScope scope; + OverloadErrorHandler errorHandler; + v8::Handle self; + + // switch all cases by means of series of if-returns. + $jsdispatchcases + + // default: + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); + +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_overloaded_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ +%fragment("js_overloaded_ctor", "templates") %{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args, V8ErrorHandler& SWIGV8_ErrorHandler) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + $jslocals + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + $jscode + + SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + SWIGV8_RETURN(self); + + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_ctor_dispatch_case: template for a dispatch case for calling an overloaded ctor. + * - $jsargcount: number of arguments of called ctor + * - $jswrapper: wrapper of called ctor + * + * Note: a try-catch-like mechanism is used to switch cases + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor_dispatch_case", "templates") +%{ + if(args.Length() == $jsargcount) { + errorHandler.err.Clear(); +#if SWIG_V8_VERSION < 0x031900 + self = $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return scope.Close(self); + } +#else + $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return; + } +#endif + } +%} + +/* ----------------------------------------------------------------------------- + * js_dtor: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtor", "templates") +%{ + +#if (SWIG_V8_VERSION < 0x031900) +void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) +{ + SWIGV8_Proxy *proxy = static_cast(parameter); +#else +void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) +{ +#endif + + if(proxy->swigCMemOwn && proxy->swigCObject) { +#ifdef SWIGRUNTIME_DEBUG + printf("Deleting wrapped instance: %s\n", proxy->info->name); +#endif + $jsfree proxy->swigCObject; + } + delete proxy; + + object.Clear(); +#if (SWIG_V8_VERSION < 0x031900) + object.Dispose(); +#elif (SWIG_V8_VERSION < 0x032100) + object->Dispose(isolate); +#else + object->Dispose(); +#endif +} +%} + +/* ----------------------------------------------------------------------------- + * js_dtoroverride: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * - ${destructor_action}: The custom destructor action to invoke. + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtoroverride", "templates") +%{ +#if (SWIG_V8_VERSION < 0x031900) +void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) +{ + SWIGV8_Proxy *proxy = static_cast(parameter); +#else +void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) +{ +#endif + if(proxy->swigCMemOwn && proxy->swigCObject) { + $jstype arg1 = ($jstype)proxy->swigCObject; + ${destructor_action} + } + delete proxy; + +#if (SWIG_V8_VERSION < 0x031900) + object.Dispose(); +#elif (SWIG_V8_VERSION < 0x032100) + object->Dispose(isolate); +#else + object->Dispose(); +#endif +} +%} + +/* ----------------------------------------------------------------------------- + * js_getter: template for getter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment("js_getter", "templates") +%{ +SwigV8ReturnValue $jswrapper(v8::Local property, const SwigV8PropertyCallbackInfo& info) { + v8::HandleScope scope; + v8::Handle jsresult; + $jslocals + $jscode + SWIGV8_RETURN_INFO(jsresult, info); + + goto fail; +fail: + SWIGV8_RETURN_INFO(v8::Undefined(), info); +} +%} + +/* ----------------------------------------------------------------------------- + * js_setter: template for setter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment("js_setter", "templates") +%{ +void $jswrapper(v8::Local property, v8::Local value, + const SwigV8PropertyCallbackInfoVoid& info) { + v8::HandleScope scope; + $jslocals + $jscode + goto fail; +fail: + return; +} +%} + +/* ----------------------------------------------------------------------------- + * js_function: template for function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment("js_function", "templates") +%{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { + v8::HandleScope scope; + v8::Handle jsresult; + $jslocals + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + + $jscode + SWIGV8_RETURN(jsresult); + + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_function_dispatcher: template for a function dispatcher for overloaded functions + * - $jswrapper: wrapper function name + * - $jsname: name of the wrapped function + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment("js_function_dispatcher", "templates") +%{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { + v8::HandleScope scope; + v8::Handle jsresult; + OverloadErrorHandler errorHandler; + $jscode + + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); + + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_overloaded_function: template for a overloaded function + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_overloaded_function", "templates") +%{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args, V8ErrorHandler& SWIGV8_ErrorHandler) +{ + v8::HandleScope scope; + v8::Handle jsresult; + $jslocals + $jscode + SWIGV8_RETURN(jsresult); + + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_function_dispatch_case: template for a case used in the function dispatcher + * - $jswrapper: wrapper function name + * - $jsargcount: number of arguments of overloaded function + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function_dispatch_case", "templates") +%{ + + if(args.Length() == $jsargcount) { + errorHandler.err.Clear(); +#if (SWIG_V8_VERSION < 0x031900) + jsresult = $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return scope.Close(jsresult); + } +#else + $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return; + } +#endif + } +%} + +/* ----------------------------------------------------------------------------- + * jsv8_declare_class_template: template for a class template declaration. + * - $jsmangledname: mangled class name + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_declare_class_template", "templates") +%{ + SWIGV8_ClientData $jsmangledname_clientData; +%} + +/* ----------------------------------------------------------------------------- + * jsv8_define_class_template: template for a class template definition. + * - $jsmangledname: mangled class name + * - $jsmangledtype: mangled class type + * - $jsdtor: the dtor wrapper + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_define_class_template", "templates") +%{ + v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); +#if (SWIG_V8_VERSION < 0x031900) + $jsmangledname_clientData.class_templ = v8::Persistent::New($jsmangledname_class); +#else + $jsmangledname_clientData.class_templ.Reset(v8::Isolate::GetCurrent(), $jsmangledname_class); +#endif + $jsmangledname_clientData.dtor = $jsdtor; + if (SWIGTYPE_$jsmangledtype->clientdata == 0) { + SWIGTYPE_$jsmangledtype->clientdata = &$jsmangledname_clientData; + } +%} + + +/* ----------------------------------------------------------------------------- + * jsv8_inherit: template for an class inherit statement. + * - $jsmangledname: mangled class name + * - $jsbaseclass: mangled name of the base class + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_inherit", "templates") +%{ + if (SWIGTYPE_p$jsbaseclass->clientdata && !(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ.IsEmpty())) + { +#if (SWIG_V8_VERSION < 0x031900) + $jsmangledname_class->Inherit(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ); +#else + $jsmangledname_class->Inherit( + v8::Handle::New( + v8::Isolate::GetCurrent(), + static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ) + ); +#endif + +#ifdef SWIGRUNTIME_DEBUG + printf("Inheritance successful $jsmangledname $jsbaseclass\n"); +#endif + } else { +#ifdef SWIGRUNTIME_DEBUG + printf("Unable to inherit baseclass, it didn't exist $jsmangledname $jsbaseclass\n"); +#endif + } +%} + +/* ----------------------------------------------------------------------------- + * jsv8_create_class_instance: template for creating an class object. + * - $jsname: class name + * - $jsmangledname: mangled class name + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_create_class_instance", "templates") +%{ + v8::Handle $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname"); + $jsmangledname_class_0->SetCallHandler($jsctor); + $jsmangledname_class_0->Inherit($jsmangledname_class); + $jsmangledname_class_0->SetHiddenPrototype(true); + v8::Handle $jsmangledname_obj = $jsmangledname_class_0->GetFunction(); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_class: template for a statement that registers a class in a parent namespace. + * - $jsname: class name + * - $jsmangledname: mangled class name + * - $jsparent: mangled name of parent namespace + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_class", "templates") +%{ + $jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_create_namespace: template for a statement that creates a namespace object. + * - $jsmangledname: mangled namespace name + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_create_namespace", "templates") +%{ + v8::Handle $jsmangledname_obj = v8::Object::New(); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_namespace: template for a statement that registers a namespace in a parent namespace. + * - $jsname: name of namespace + * - $jsmangledname: mangled name of namespace + * - $jsparent: mangled name of parent namespace + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_namespace", "templates") +%{ + $jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_member_function: template for a statement that registers a member function. + * - $jsmangledname: mangled class name + * - $jsname: name of the function + * - $jswrapper: wrapper of the member function + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_member_function", "templates") +%{ + SWIGV8_AddMemberFunction($jsmangledname_class, "$jsname", $jswrapper); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_member_variable: template for a statement that registers a member variable. + * - $jsmangledname: mangled class name + * - $jsname: name of the function + * - $jsgetter: wrapper of the getter function + * - $jssetter: wrapper of the setter function + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_member_variable", "templates") +%{ + SWIGV8_AddMemberVariable($jsmangledname_class, "$jsname", $jsgetter, $jssetter); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_static_function: template for a statement that registers a static class function. + * - $jsname: function name + * - $jswrapper: wrapper of the function + * - $jsparent: mangled name of parent namespace + * + * Note: this template is also used for global functions. + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_static_function", "templates") +%{ + SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_static_variable: template for a statement that registers a static variable. + * - $jsname: variable name + * - $jsparent: mangled name of parent namespace + * - $jsgetter: wrapper of the getter function + * - $jssetter: wrapper of the setter function + * + * Note: this template is also used for global variables. + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_static_variable", "templates") +%{ + SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter); +%} diff --git a/Lib/javascript/v8/javascriptcomplex.swg b/Lib/javascript/v8/javascriptcomplex.swg new file mode 100644 index 000000000..70c5baffb --- /dev/null +++ b/Lib/javascript/v8/javascriptcomplex.swg @@ -0,0 +1,123 @@ +/* + Defines the As/From converters for double/float complex, you need to + provide complex Type, the Name you want to use in the converters, + the complex Constructor method, and the Real and Imag complex + accessor methods. + + See the std_complex.i and ccomplex.i for concret examples. +*/ + +/* the common from converter */ +%define %swig_fromcplx_conv(Type, Real, Imag) +%fragment(SWIG_From_frag(Type),"header", + fragment=SWIG_From_frag(double)) +{ +SWIGINTERNINLINE v8::Handle +SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) +{ + v8::HandleScope scope; + v8::Local vals = v8::Array::New(2); + + vals->Set(0, SWIG_From(double)(Real(c))); + vals->Set(1, SWIG_From(double)(Imag(c))); + return scope.Close(vals); +} +} +%enddef + +/* the double case */ +%define %swig_cplxdbl_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(double)) +{ +SWIGINTERN int +SWIG_AsVal_dec(Type) (v8::Handle o, Type* val) +{ + v8::HandleScope scope; + + if (o->IsArray()) { + v8::Handle array = v8::Handle::Cast(o); + + if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); + double re, im; + int res; + + res = SWIG_AsVal(double)(array->Get(0), &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(array->Get(1), &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if (val) *val = Constructor(re, im); + return SWIG_OK; + } else if(o->IsNumber()){ + double d; + int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(d, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +/* the float case */ +%define %swig_cplxflt_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(float)) { +SWIGINTERN int +SWIG_AsVal_dec(Type) (v8::Handle o, Type* val) +{ + v8::HandleScope scope; + + if (o->IsArray()) { + v8::Handle array = v8::Handle::Cast(o); + + if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); + double re, im; + int res; + + res = SWIG_AsVal(double)(array->Get(0), &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(array->Get(1), &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if ((-FLT_MAX <= re && re <= FLT_MAX) && (-FLT_MAX <= im && im <= FLT_MAX)) { + if (val) *val = Constructor(%numeric_cast(re, float), + %numeric_cast(im, float)); + return SWIG_OK; + } else { + return SWIG_OverflowError; + } + } else if(o->IsNumber()){ + float re; + int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(re, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \ +%swig_cplxflt_conv(Type, Constructor, Real, Imag) + + +#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \ +%swig_cplxdbl_conv(Type, Constructor, Real, Imag) diff --git a/Lib/javascript/v8/javascriptfragments.swg b/Lib/javascript/v8/javascriptfragments.swg new file mode 100644 index 000000000..4778bf033 --- /dev/null +++ b/Lib/javascript/v8/javascriptfragments.swg @@ -0,0 +1,23 @@ +/* + + Create a file with this name, 'javascriptfragments.swg', in your working + directory and add all the %fragments you want to take precedence + over the default ones defined by swig. + + For example, if you add: + + %fragment(SWIG_AsVal_frag(int),"header") { + SWIGINTERNINLINE int + SWIG_AsVal(int)(PyObject *obj, int *val) + { + ; + } + } + + this will replace the code used to retrieve an integer value for all + the typemaps that need it, including: + + int, std::vector, std::list >, etc. + + +*/ diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg new file mode 100644 index 000000000..8da6627e2 --- /dev/null +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -0,0 +1,87 @@ +%insert(runtime) %{ + +// Note: since 3.19 there are new CallBack types, since 03.21.9 the old ones have been removed +#if SWIG_V8_VERSION < 0x031900 +typedef v8::InvocationCallback SwigV8FunctionCallback; +typedef v8::AccessorGetter SwigV8AccessorGetterCallback; +typedef v8::AccessorSetter SwigV8AccessorSetterCallback; +typedef v8::AccessorInfo SwigV8PropertyCallbackInfoVoid; +#else +typedef v8::FunctionCallback SwigV8FunctionCallback; +typedef v8::AccessorGetterCallback SwigV8AccessorGetterCallback; +typedef v8::AccessorSetterCallback SwigV8AccessorSetterCallback; +typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfoVoid; +#endif + +/** + * Creates a class template for a class with specified initialization function. + */ +v8::Handle SWIGV8_CreateClassTemplate(const char* symbol) { + v8::HandleScope scope; + v8::Local class_templ = v8::FunctionTemplate::New(); + class_templ->SetClassName(v8::String::NewSymbol(symbol)); + + v8::Handle inst_templ = class_templ->InstanceTemplate(); + inst_templ->SetInternalFieldCount(1); + + v8::Handle equals_templ = class_templ->PrototypeTemplate(); + equals_templ->Set(v8::String::NewSymbol("equals"), v8::FunctionTemplate::New(_SWIGV8_wrap_equals)); + + v8::Handle cptr_templ = class_templ->PrototypeTemplate(); + cptr_templ->Set(v8::String::NewSymbol("getCPtr"), v8::FunctionTemplate::New(_wrap_getCPtr)); + + return scope.Close(class_templ); +} + +/** + * Registers a class method with given name for a given class template. + */ +void SWIGV8_AddMemberFunction(v8::Handle class_templ, const char* symbol, + SwigV8FunctionCallback _func) { + v8::Handle proto_templ = class_templ->PrototypeTemplate(); + proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); +} + +/** + * Registers a class property with given name for a given class template. + */ +void SWIGV8_AddMemberVariable(v8::Handle class_templ, const char* symbol, + SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) { + v8::Handle proto_templ = class_templ->InstanceTemplate(); + proto_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); +} + +/** + * Registers a class method with given name for a given object. + */ +void SWIGV8_AddStaticFunction(v8::Handle obj, const char* symbol, + const SwigV8FunctionCallback& _func) { + obj->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); +} + +/** + * Registers a class method with given name for a given object. + */ +void SWIGV8_AddStaticVariable(v8::Handle obj, const char* symbol, + SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) { + obj->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); +} + +void JS_veto_set_variable(v8::Local property, v8::Local value, + const SwigV8PropertyCallbackInfoVoid& info) +{ + char buffer[256]; + char msg[512]; + int res; + + property->WriteUtf8(buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } +} + +%} // v8_helper_functions diff --git a/Lib/javascript/v8/javascriptinit.swg b/Lib/javascript/v8/javascriptinit.swg new file mode 100644 index 000000000..de1fe91f4 --- /dev/null +++ b/Lib/javascript/v8/javascriptinit.swg @@ -0,0 +1,118 @@ +%insert(init) %{ + +#include + +SWIGRUNTIME void +SWIG_V8_SetModule(void *, swig_module_info *swig_module) { + v8::Local global_obj = v8::Context::GetCurrent()->Global(); + v8::Local mod = v8::External::New(swig_module); + assert(!mod.IsEmpty()); + global_obj->SetHiddenValue(v8::String::New("swig_module_info_data"), mod); +} + +SWIGRUNTIME swig_module_info * +SWIG_V8_GetModule(void *) { + v8::Local global_obj = v8::Context::GetCurrent()->Global(); + v8::Local moduleinfo = global_obj->GetHiddenValue(v8::String::New("swig_module_info_data")); + + if (moduleinfo.IsEmpty()) + { + // It's not yet loaded + return 0; + } + + v8::Local moduleinfo_extern = v8::Local::Cast(moduleinfo); + + if (moduleinfo_extern.IsEmpty()) + { + // Something's not right + return 0; + } + + void *ptr = moduleinfo_extern->Value(); + assert(ptr); + swig_module_info *retptr = static_cast(ptr); + assert(retptr); + return retptr; +} + +#define SWIG_GetModule(clientdata) SWIG_V8_GetModule(clientdata) +#define SWIG_SetModule(clientdata, pointer) SWIG_V8_SetModule(clientdata, pointer) + +%} + +%insert(init) "swiginit.swg" + +// Open the initializer function definition here + +%fragment ("js_initializer_define", "templates") %{ +#define SWIGV8_INIT $jsname_initialize +%} + +%insert(init) %{ +// Note: 'extern "C"'' disables name mangling which makes it easier to load the symbol manually +// TODO: is it ok to do that? +extern "C" +#if (NODE_MODULE_VERSION < 0x000C) +void SWIGV8_INIT (v8::Handle exports) +#else +void SWIGV8_INIT (v8::Handle exports, v8::Handle /*module*/) +#endif +{ + SWIG_InitializeModule(static_cast(&exports)); + + v8::HandleScope scope; + v8::Handle exports_obj = exports; +%} + + +/* ----------------------------------------------------------------------------- + * js_initializer: template for the module initializer function + * - $jsname: module name + * - $jsv8nspaces: part with code creating namespace objects + * - $jsv8classtemplates: part with code creating class templates + * - $jsv8wrappers: part with code that registers wrapper functions + * - $jsv8inheritance: part with inherit statements + * - $jsv8classinstances: part with code creating class objects + * - $jsv8staticwrappers: part with code adding static functions to class objects + * - $jsv8registerclasses: part with code that registers class objects in namespaces + * - $jsv8registernspaces: part with code that registers namespaces in parent namespaces + * ----------------------------------------------------------------------------- */ +%fragment("js_initializer", "templates") +%{ + // a class template for creating proxies of undefined types +#if (SWIG_V8_VERSION < 0x031900) + SWIGV8_SWIGTYPE_Proxy_class_templ = v8::Persistent::New(SWIGV8_CreateClassTemplate("SwigProxy")); +#else + SWIGV8_SWIGTYPE_Proxy_class_templ.Reset(v8::Isolate::GetCurrent(), SWIGV8_CreateClassTemplate("SwigProxy")); +#endif + + /* create objects for namespaces */ + $jsv8nspaces + + /* create class templates */ + $jsv8classtemplates + + /* register wrapper functions */ + $jsv8wrappers + + /* setup inheritances */ + $jsv8inheritance + + /* class instances */ + $jsv8classinstances + + /* add static class functions and variables */ + $jsv8staticwrappers + + /* register classes */ + $jsv8registerclasses + + /* create and register namespace objects */ + $jsv8registernspaces +} + +#if defined(BUILDING_NODE_EXTENSION) +NODE_MODULE($jsname, $jsname_initialize); +#endif +%} diff --git a/Lib/javascript/v8/javascriptkw.swg b/Lib/javascript/v8/javascriptkw.swg new file mode 100644 index 000000000..c3c118391 --- /dev/null +++ b/Lib/javascript/v8/javascriptkw.swg @@ -0,0 +1,40 @@ +#ifndef JAVASCRIPT_JAVASCRIPTKW_SWG_ +#define JAVASCRIPT_JAVASCRIPTKW_SWG_ + +/* Warnings for Java keywords */ +#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",rename="_%s") `x` + +/* Taken from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Reserved_Words */ + +JAVASCRIPTKW(break); +JAVASCRIPTKW(case); +JAVASCRIPTKW(catch); +JAVASCRIPTKW(continue); +JAVASCRIPTKW(default); +JAVASCRIPTKW(delete); +JAVASCRIPTKW(do); +JAVASCRIPTKW(else); +JAVASCRIPTKW(finally); +JAVASCRIPTKW(for); +JAVASCRIPTKW(function); +JAVASCRIPTKW(if); +JAVASCRIPTKW(in); +JAVASCRIPTKW(instanceof); +JAVASCRIPTKW(new); +JAVASCRIPTKW(return); +JAVASCRIPTKW(switch); +JAVASCRIPTKW(this); +JAVASCRIPTKW(throw); +JAVASCRIPTKW(try); +JAVASCRIPTKW(typeof); +JAVASCRIPTKW(var); +JAVASCRIPTKW(void); +JAVASCRIPTKW(while); +JAVASCRIPTKW(with); + +/* others bad names if any*/ +// for example %namewarn("321:clone() is a javascript bad method name") *::clone(); + +#undef JAVASCRIPTKW + +#endif //JAVASCRIPT_JAVASCRIPTKW_SWG_ diff --git a/Lib/javascript/v8/javascriptprimtypes.swg b/Lib/javascript/v8/javascriptprimtypes.swg new file mode 100644 index 000000000..706a799b7 --- /dev/null +++ b/Lib/javascript/v8/javascriptprimtypes.swg @@ -0,0 +1,198 @@ +/* ------------------------------------------------------------ + * Primitive Types + * ------------------------------------------------------------ */ + +/* boolean */ + +%fragment(SWIG_From_frag(bool),"header") { +SWIGINTERNINLINE +v8::Handle +SWIG_From_dec(bool)(bool value) +{ + return v8::Boolean::New(value); +} +} + +%fragment(SWIG_AsVal_frag(bool),"header", + fragment=SWIG_AsVal_frag(long)) { +SWIGINTERN +int SWIG_AsVal_dec(bool)(v8::Handle obj, bool *val) +{ + if(!obj->IsBoolean()) { + return SWIG_ERROR; + } + + if (val) *val = obj->BooleanValue(); + return SWIG_OK; +} +} + +/* int */ + +%fragment(SWIG_From_frag(int),"header") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(int)(int value) +{ + return v8::Int32::New(value); +} +} + +%fragment(SWIG_AsVal_frag(int),"header") { +SWIGINTERN +int SWIG_AsVal_dec(int)(v8::Handle valRef, int* val) +{ + if (!valRef->IsNumber()) { + return SWIG_TypeError; + } + if(val) *val = valRef->IntegerValue(); + + return SWIG_OK; +} +} + +/* long */ + +%fragment(SWIG_From_frag(long),"header") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(long)(long value) +{ + return v8::Number::New(value); +} +} + +%fragment(SWIG_AsVal_frag(long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN +int SWIG_AsVal_dec(long)(v8::Handle obj, long* val) +{ + if (!obj->IsNumber()) { + return SWIG_TypeError; + } + if(val) *val = (long) obj->IntegerValue(); + + return SWIG_OK; +} +} + +/* unsigned long */ + +%fragment(SWIG_From_frag(unsigned long),"header", + fragment=SWIG_From_frag(long)) { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(unsigned long)(unsigned long value) +{ + return (value > LONG_MAX) ? + v8::Integer::NewFromUnsigned(value) : v8::Integer::New(%numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN +int SWIG_AsVal_dec(unsigned long)(v8::Handle obj, unsigned long *val) +{ + if(!obj->IsNumber()) { + return SWIG_TypeError; + } + + long longVal = (long) obj->NumberValue(); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +/* long long */ +// Note: these are copied from 'long' and probably need fixing + +%fragment(SWIG_From_frag(long long),"header", + fragment=SWIG_From_frag(long), + fragment="") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(long long)(long long value) +{ + return v8::Number::New(value); +} +} + +%fragment(SWIG_AsVal_frag(long long),"header", + fragment=SWIG_AsVal_frag(long), + fragment="SWIG_CanCastAsInteger", + fragment="") { +SWIGINTERN +int SWIG_AsVal_dec(long long)(v8::Handle obj, long long* val) +{ + if (!obj->IsNumber()) { + return SWIG_TypeError; + } + if(val) *val = (long long) obj->IntegerValue(); + + return SWIG_OK; +} +} + +/* unsigned long long */ +// Note: these are copied from 'unsigned long' and probably need fixing + +%fragment(SWIG_From_frag(unsigned long long),"header", + fragment=SWIG_From_frag(long long), + fragment="") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(unsigned long long)(unsigned long long value) +{ + return (value > LONG_MAX) ? + v8::Integer::NewFromUnsigned(value) : v8::Integer::New(%numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long long),"header", + fragment=SWIG_AsVal_frag(unsigned long), + fragment="SWIG_CanCastAsInteger", + fragment="") { +SWIGINTERN +int SWIG_AsVal_dec(unsigned long long)(v8::Handle obj, unsigned long long *val) +{ + if(!obj->IsNumber()) { + return SWIG_TypeError; + } + + long long longVal = (long long) obj->NumberValue(); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +/* double */ + +%fragment(SWIG_From_frag(double),"header") { +SWIGINTERN +v8::Handle SWIG_From_dec(double) (double val) +{ + return v8::Number::New(val); +} +} + +%fragment(SWIG_AsVal_frag(double),"header") { +SWIGINTERN +int SWIG_AsVal_dec(double)(v8::Handle obj, double *val) +{ + if(!obj->IsNumber()) { + return SWIG_TypeError; + } + if(val) *val = obj->NumberValue(); + + return SWIG_OK; +} +} + diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg new file mode 100644 index 000000000..2e0a46717 --- /dev/null +++ b/Lib/javascript/v8/javascriptrun.swg @@ -0,0 +1,462 @@ +/* --------------------------------------------------------------------------- + * Error handling + * + * ---------------------------------------------------------------------------*/ + +#define SWIG_Error(code, msg) SWIGV8_ErrorHandler.error(code, msg) +#define SWIG_exception(code, msg) SWIGV8_ErrorHandler.error(code, msg) +#define SWIG_fail goto fail +#define SWIGV8_OVERLOAD false + +void SWIG_V8_Raise(const char* msg) { + v8::ThrowException(v8::Exception::Error(v8::String::New(msg))); +} + +/* + Note: There are two contexts for handling errors. + A static V8ErrorHandler is used in not overloaded methods. + For overloaded methods the throwing type checking mechanism is used + during dispatching. As V8 exceptions can not be resetted properly + the trick is to use a dynamic ErrorHandler with same local name as the global + one. + + - See defintion of SWIG_Error above. + - See code templates 'JS_function_dispatcher', 'JS_functionwrapper_overload', + and 'JS_function_dispatch_case' in javascriptcode.swg + +*/ +class V8ErrorHandler { +public: + virtual ~V8ErrorHandler() {} + virtual void error(int code, const char* msg) { + SWIG_V8_Raise(msg); + } +}; +// this is used in usually +V8ErrorHandler SWIGV8_ErrorHandler; + +// instances of this are used in overloaded functions +class OverloadErrorHandler: public V8ErrorHandler { +public: + virtual void error(int code, const char* msg) { + err = v8::Exception::Error(v8::String::New(msg)); + if(code != SWIG_TypeError) { + v8::ThrowException(err); + } + } + v8::Handle err; +}; + +// Note: these typedefs and defines are used to deal with v8 API changes since version 3.19.00 + +#if (SWIG_V8_VERSION < 0x031900) +typedef v8::Handle SwigV8ReturnValue; +typedef v8::Arguments SwigV8Arguments; +typedef v8::AccessorInfo SwigV8PropertyCallbackInfo; +#define SWIGV8_RETURN(val) return scope.Close(val) +#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val) +#else +typedef void SwigV8ReturnValue; +typedef v8::FunctionCallbackInfo SwigV8Arguments; +typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; +#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return +#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return +#endif + + +/* --------------------------------------------------------------------------- + * Basic Proxy object + * + * ---------------------------------------------------------------------------*/ + +// Note: to trigger the v8 gc more often one can tell v8 about the memory consumption +// TODO: we could add a v8 specific parameter to control this value +#define SWIGV8_AVG_OBJ_SIZE 1000 + +class SWIGV8_Proxy { +public: + SWIGV8_Proxy(): swigCMemOwn(false), swigCObject(0), info(0) { + v8::V8::AdjustAmountOfExternalAllocatedMemory(SWIGV8_AVG_OBJ_SIZE); + }; + + ~SWIGV8_Proxy() { +#if (SWIG_V8_VERSION < 0x031900 || SWIG_V8_VERSION >= 0x032100) + handle.ClearWeak(); + handle.Dispose(); +#else + handle.ClearWeak(v8::Isolate::GetCurrent()); + handle.Dispose(v8::Isolate::GetCurrent()); +#endif + + handle.Clear(); + v8::V8::AdjustAmountOfExternalAllocatedMemory(-SWIGV8_AVG_OBJ_SIZE); + } + + bool swigCMemOwn; + void *swigCObject; + swig_type_info *info; + v8::Persistent handle; +}; + +class SWIGV8_ClientData { +public: + v8::Persistent class_templ; + +#if (SWIG_V8_VERSION < 0x031900) + void (*dtor) (v8::Persistent< v8::Value> object, void *parameter); +#else + void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); +#endif +}; + +v8::Persistent SWIGV8_SWIGTYPE_Proxy_class_templ; + +int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; + + if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; + +#if (SWIG_V8_VERSION < 0x031900) + v8::Handle cdataRef = objRef->GetInternalField(0); + SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); +#else + SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + + if(cdata == NULL) { + return SWIG_ERROR; + } + if(cdata->info != info) { + swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info); + if (!tc && cdata->info->name) { + tc = SWIG_TypeCheck(cdata->info->name, info); + } + bool type_valid = tc != 0; + if(!type_valid) { + return SWIG_TypeError; + } + } + *ptr = cdata->swigCObject; + if(flags & SWIG_POINTER_DISOWN) { + cdata->swigCMemOwn = false; + } + return SWIG_OK; +} + +#if (SWIG_V8_VERSION < 0x031900) +void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) +#else +void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) +#endif +{ +#if (SWIG_V8_VERSION < 0x031900) + SWIGV8_Proxy *proxy = static_cast(parameter); +#endif + + delete proxy; +} + +int SWIG_V8_GetInstancePtr(v8::Handle valRef, void** ptr) { + if(!valRef->IsObject()) { + return SWIG_TypeError; + } + v8::Handle objRef = valRef->ToObject(); + + if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; + +#if (SWIG_V8_VERSION < 0x031900) + v8::Handle cdataRef = objRef->GetInternalField(0); + SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); +#else + SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + + if(cdata == NULL) { + return SWIG_ERROR; + } + + *ptr = cdata->swigCObject; + + return SWIG_OK; +} + +void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info *info, int flags) { + SWIGV8_Proxy* cdata = new SWIGV8_Proxy(); + cdata->swigCObject = ptr; + cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; + cdata->info = info; + +#if (SWIG_V8_VERSION < 0x031900) + obj->SetPointerInInternalField(0, cdata); + cdata->handle = v8::Persistent::New(obj); +#else + obj->SetAlignedPointerInInternalField(0, cdata); + cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); +#endif + +#if (SWIG_V8_VERSION < 0x031900) + // clientdata must be set for owned data as we need to register the dtor + if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { + cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); + } else { + cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor); + } + cdata->handle.MarkIndependent(); +#else + if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); + } else { + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, SWIGV8_Proxy_DefaultDtor); + } + +#if (SWIG_V8_VERSION < 0x032100) + cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); +#else + cdata->handle.MarkIndependent(); +#endif + +#endif +} + +int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; + + if(!valRef->IsObject()) { + return SWIG_TypeError; + } + v8::Handle objRef = valRef->ToObject(); + return SWIG_V8_ConvertInstancePtr(objRef, ptr, info, flags); +} + +v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; + v8::Handle class_templ; + +#if (SWIG_V8_VERSION < 0x031900) + if(info->clientdata != 0) { + class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; + } else { + class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ; + } +#else + v8::Isolate *iso = v8::Isolate::GetCurrent(); + + if(info->clientdata != 0) { + class_templ = v8::Handle::New(iso, ((SWIGV8_ClientData*) info->clientdata)->class_templ); + } else { + class_templ = v8::Handle::New(iso, SWIGV8_SWIGTYPE_Proxy_class_templ); + } +#endif + + v8::Handle result = class_templ->InstanceTemplate()->NewInstance(); + SWIGV8_SetPrivateData(result, ptr, info, flags); + + return scope.Close(result); +} + +#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_V8_ConvertPtr(obj, ptr, info, flags) +#define SWIG_NewPointerObj(ptr, info, flags) SWIG_V8_NewPointerObj(ptr, info, flags) + +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_V8_ConvertInstancePtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_V8_NewPointerObj(thisvalue, type, flags) + +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_V8_ConvertPtr(obj, pptr, type, 0) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_V8_NewPointerObj(ptr, type, 0) + +#define SWIG_GetInstancePtr(obj, ptr) SWIG_V8_GetInstancePtr(obj, ptr) + +#if (SWIG_V8_VERSION < 0x031900) +v8::Handle _SWIGV8_wrap_equals(const v8::Arguments &args) { +#else +void _SWIGV8_wrap_equals(const v8::FunctionCallbackInfo& args) { +#endif + v8::HandleScope scope; + v8::Handle jsresult; + void *arg1 = (void *) 0 ; + void *arg2 = (void *) 0 ; + bool result; + int res1; + int res2; + + if(args.Length() != 1) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for equals."); + + res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ERROR, "Could not get pointer from 'this' object for equals."); + } + res2 = SWIG_GetInstancePtr(args[0], &arg2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "equals" "', argument " "1"" of type '" "void *""'"); + } + + result = (bool)(arg1 == arg2); + jsresult = v8::Boolean::New(result); + + SWIGV8_RETURN(jsresult); + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} + +#if (SWIG_V8_VERSION < 0x031900) +v8::Handle _wrap_getCPtr(const v8::Arguments &args) { +#else +void _wrap_getCPtr(const v8::FunctionCallbackInfo& args) { +#endif + v8::HandleScope scope; + v8::Handle jsresult; + void *arg1 = (void *) 0 ; + long result; + int res1; + + res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "getCPtr" "', argument " "1"" of type '" "void *""'"); + } + + result = (long)arg1; + jsresult = v8::Number::New(result); + + SWIGV8_RETURN(jsresult); + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} + +/* --------------------------------------------------------------------------- + * PackedData object + * + * ---------------------------------------------------------------------------*/ + +class SwigV8PackedData { +public: + SwigV8PackedData(void *data, size_t size, swig_type_info *type): data(data), size(size), type(type) {}; + + ~SwigV8PackedData() { + }; + + void* data; + size_t size; + swig_type_info *type; + + v8::Persistent handle; +}; + +SWIGRUNTIMEINLINE +int SwigV8Packed_Check(v8::Handle valRef) { + v8::HandleScope scope; + v8::Handle objRef = valRef->ToObject(); + if(objRef->InternalFieldCount() < 1) return false; + v8::Handle flag = objRef->GetHiddenValue(v8::String::New("__swig__packed_data__")); + return (flag->IsBoolean() && flag->BooleanValue()); +} + +SWIGRUNTIME +swig_type_info* SwigV8Packed_UnpackData(v8::Handle valRef, void *ptr, size_t size) { + if (SwigV8Packed_Check(valRef)) { + v8::HandleScope scope; + SwigV8PackedData *sobj; + + v8::Handle objRef = valRef->ToObject(); + +#if (SWIG_V8_VERSION < 0x031900) + v8::Handle cdataRef = objRef->GetInternalField(0); + sobj = static_cast(v8::External::Unwrap(cdataRef)); +#else + sobj = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + if (sobj == NULL || sobj->size != size) return 0; + memcpy(ptr, sobj->data, size); + return sobj->type; + } else { + return 0; + } +} + +SWIGRUNTIME +int SWIGV8_ConvertPacked(v8::Handle valRef, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = SwigV8Packed_UnpackData(valRef, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +#if (SWIG_V8_VERSION < 0x031900) +void _wrap_SwigV8PackedData_delete(v8::Persistent< v8::Value > object, void *parameter) +{ + SwigV8PackedData *cdata = static_cast(parameter); +#else +void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SwigV8PackedData *cdata) +{ +#endif + + delete cdata; + +#if (SWIG_V8_VERSION < 0x031900) + object.Clear(); + object.Dispose(); +#elif (SWIG_V8_VERSION < 0x032100) + object->Dispose(isolate); +#else + object->Dispose(); +#endif +} + +SWIGRUNTIME +v8::Handle SWIGV8_NewPackedObj(void *data, size_t size, swig_type_info *type) { + v8::HandleScope scope; + + SwigV8PackedData* cdata = new SwigV8PackedData(data, size, type); + v8::Handle obj = v8::Object::New(); + + obj->SetHiddenValue(v8::String::New("__swig__packed_data__"), v8::Boolean::New(true)); + +#if (SWIG_V8_VERSION < 0x031900) + obj->SetPointerInInternalField(0, cdata); + cdata->handle = v8::Persistent::New(obj); +#else + obj->SetAlignedPointerInInternalField(0, cdata); + cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); +#endif + +#if (SWIG_V8_VERSION < 0x031900) + cdata->handle.MakeWeak(cdata, _wrap_SwigV8PackedData_delete); + cdata->handle.MarkIndependent(); +#else + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, _wrap_SwigV8PackedData_delete); +# if (SWIG_V8_VERSION < 0x032100) + cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); +# else + cdata->handle.MarkIndependent(); +# endif +#endif + + return scope.Close(obj); +} + +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIGV8_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIGV8_NewPackedObj(ptr, sz, type) + + +/* --------------------------------------------------------------------------- + * Support for IN/OUTPUT typemaps (see Lib/typemaps/inoutlist.swg) + * + * ---------------------------------------------------------------------------*/ + +SWIGRUNTIME +v8::Handle SWIGV8_AppendOutput(v8::Handle result, v8::Handle obj) { + v8::HandleScope scope; + if (result->IsUndefined()) { + result = v8::Array::New(); + } + v8::Handle arr = v8::Handle::Cast(result); + arr->Set(arr->Length(), obj); + + return scope.Close(arr); +} diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg new file mode 100644 index 000000000..2e18d19bf --- /dev/null +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -0,0 +1,39 @@ +/* ----------------------------------------------------------------------------- + * javascriptruntime.swg + * + * ----------------------------------------------------------------------------- */ + +%define %swig_v8_define_version(version) +%insert("runtime") %{ +#ifndef SWIG_V8_VERSION +#define SWIG_V8_VERSION version +#endif +%} +%enddef + +#ifdef V8_VERSION +%swig_v8_define_version(V8_VERSION) +#else +// HACK: defining a default version +%swig_v8_define_version(0x031110) +#endif + +#ifdef BUILDING_NODE_EXTENSION +%insert("runtime") %{ +#include +%} +#endif + +%insert(runtime) %{ +#include + +#include +#include +#include +%} + +%insert(runtime) "swigrun.swg"; /* SWIG API */ +%insert(runtime) "swigerrors.swg"; /* SWIG errors */ + +%insert(runtime) "javascriptrun.swg" + diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg new file mode 100644 index 000000000..69b6836a8 --- /dev/null +++ b/Lib/javascript/v8/javascriptstrings.swg @@ -0,0 +1,59 @@ + +/* ------------------------------------------------------------ + * utility methods for char strings + * ------------------------------------------------------------ */ +%fragment("SWIG_AsCharPtrAndSize", "header", fragment="SWIG_pchar_descriptor") { +SWIGINTERN int +SWIG_AsCharPtrAndSize(v8::Handle valRef, char** cptr, size_t* psize, int *alloc) +{ + if(valRef->IsString()) { + v8::Handle js_str = valRef->ToString(); + + size_t len = js_str->Utf8Length() + 1; + char* cstr = new char[len]; + js_str->WriteUtf8(cstr, len); + + if(alloc) *alloc = SWIG_NEWOBJ; + if(psize) *psize = len; + if(cptr) *cptr = cstr; + + return SWIG_OK; + } else { + if(valRef->IsObject()) { + v8::Handle obj = valRef->ToObject(); + // try if the object is a wrapped char[] + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + return SWIG_TypeError; + } else { + return SWIG_TypeError; + } + } +} +} + +%fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +SWIGINTERNINLINE v8::Handle +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + // TODO: handle extra long strings + return v8::Undefined(); + } else { + v8::Handle js_str = v8::String::New(carray, size); + return js_str; + } + } else { + return v8::Undefined(); + } +} +} diff --git a/Lib/javascript/v8/javascripttypemaps.swg b/Lib/javascript/v8/javascripttypemaps.swg new file mode 100644 index 000000000..90317a1c7 --- /dev/null +++ b/Lib/javascript/v8/javascripttypemaps.swg @@ -0,0 +1,43 @@ +/* ------------------------------------------------------------ + * Typemap specializations for Javascript + * ------------------------------------------------------------ */ + +/* ------------------------------------------------------------ + * Fragment section + * ------------------------------------------------------------ */ + +/* Include fundamental fragemt definitions */ +%include + +/* Look for user fragments file. */ +%include + +/* Javascript fragments for fundamental types */ +%include + +/* Javascript fragments for char* strings */ +%include + + +/* ------------------------------------------------------------ + * Unified typemap section + * ------------------------------------------------------------ */ + +/* Javascript types */ + +#define SWIG_Object v8::Handle +#define VOID_Object v8::Undefined() + +/* Overload of the output/constant/exception/dirout handling */ + +/* append output */ +#define SWIG_AppendOutput(result, obj) SWIGV8_AppendOutput(result, obj) + +/* set constant */ +#define SWIG_SetConstant(name, obj) + +/* raise */ +#define SWIG_Raise(obj, type, desc) SWIG_V8_Raise(type) + +/* Include the unified typemap library */ +%include diff --git a/Lib/javascript/v8/node.i b/Lib/javascript/v8/node.i new file mode 100644 index 000000000..8bf9ef061 --- /dev/null +++ b/Lib/javascript/v8/node.i @@ -0,0 +1,12 @@ +%insert("begin") %{ +#ifndef BUILDING_NODE_EXTENSION +#define BUILDING_NODE_EXTENSION +#endif +%} + +%insert("runtime") %{ +// we are including relative to the src folder because of issues +// with other files which might be named "node.h" +#include +%} + diff --git a/Lib/javascript/v8/std_common.i b/Lib/javascript/v8/std_common.i new file mode 100755 index 000000000..cee11e8ca --- /dev/null +++ b/Lib/javascript/v8/std_common.i @@ -0,0 +1,5 @@ +%include + +%apply size_t { std::size_t }; +%apply const size_t& { const std::size_t& }; + diff --git a/Lib/javascript/v8/std_complex.i b/Lib/javascript/v8/std_complex.i new file mode 100644 index 000000000..088a4fe7b --- /dev/null +++ b/Lib/javascript/v8/std_complex.i @@ -0,0 +1,19 @@ +/* + * STD C++ complex typemaps + */ + +%include + +%{ +#include +%} + +/* defining the complex as/from converters */ + +%swig_cplxdbl_convn(std::complex, std::complex, std::real, std::imag) +%swig_cplxflt_convn(std::complex, std::complex, std::real, std::imag) + +/* defining the typemaps */ + +%typemaps_primitive(%checkcode(CPLXDBL), std::complex); +%typemaps_primitive(%checkcode(CPLXFLT), std::complex); diff --git a/Lib/javascript/v8/std_deque.i b/Lib/javascript/v8/std_deque.i new file mode 100644 index 000000000..cb98f6c2f --- /dev/null +++ b/Lib/javascript/v8/std_deque.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/std_except.i b/Lib/javascript/v8/std_except.i new file mode 100644 index 000000000..af98428f6 --- /dev/null +++ b/Lib/javascript/v8/std_except.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/std_map.i b/Lib/javascript/v8/std_map.i new file mode 100755 index 000000000..e7812f38a --- /dev/null +++ b/Lib/javascript/v8/std_map.i @@ -0,0 +1,74 @@ +/* ----------------------------------------------------------------------------- + * std_map.i + * + * SWIG typemaps for std::map + * ----------------------------------------------------------------------------- */ + +%include + +// ------------------------------------------------------------------------ +// std::map +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class map { + // add typemaps here + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef K key_type; + typedef T mapped_type; + map(); + map(const map &); + + unsigned int size() const; + bool empty() const; + void clear(); + %extend { + const T& get(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); + } + void set(const K& key, const T& x) { + (*self)[key] = x; + } + void del(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + throw std::out_of_range("key not found"); + } + bool has_key(const K& key) { + std::map::iterator i = self->find(key); + return i != self->end(); + } + } + }; + +// Legacy macros (deprecated) +%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) +#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary" +%enddef + +} diff --git a/Lib/javascript/v8/std_pair.i b/Lib/javascript/v8/std_pair.i new file mode 100755 index 000000000..8d6057223 --- /dev/null +++ b/Lib/javascript/v8/std_pair.i @@ -0,0 +1,33 @@ +/* ----------------------------------------------------------------------------- + * std_pair.i + * + * SWIG typemaps for std::pair + * ----------------------------------------------------------------------------- */ + +%include + +// ------------------------------------------------------------------------ +// std::pair +// ------------------------------------------------------------------------ + +%{ +#include +%} + +namespace std { + + template struct pair { + + pair(); + pair(T first, U second); + pair(const pair& p); + + template pair(const pair &p); + + T first; + U second; + }; + + // add specializations here + +} diff --git a/Lib/javascript/v8/std_string.i b/Lib/javascript/v8/std_string.i new file mode 100755 index 000000000..5ad1ead27 --- /dev/null +++ b/Lib/javascript/v8/std_string.i @@ -0,0 +1,79 @@ +/* ----------------------------------------------------------------------------- + * std_string.i + * + * Typemaps for std::string and const std::string&. + * + * To use non-const std::string references use the following %apply: + * %apply const std::string & {std::string &}; + * + * ----------------------------------------------------------------------------- */ + +%{ +#include +%} + +%fragment("SWIGV8_valueToString", "header", fragment="SWIG_AsCharPtrAndSize") { +std::string* SWIGV8_valueToStringPtr(v8::Handle val) { + + if (!val->IsString()) return 0; + + int alloc; + size_t size; + char* chars; + int res = SWIG_AsCharPtrAndSize(val, &chars, &size, &alloc); + + if(res != SWIG_OK) { + v8::ThrowException(v8::Exception::TypeError(v8::String::New("Could not convert to string."))); + return 0; + } + + // copies the data (again) + std::string *str = new std::string(chars); + + if (alloc) delete[] chars; + + return str; +} +} + +%fragment("SWIGV8_stringToValue", "header", fragment="SWIG_FromCharPtrAndSize") { +v8::Handle SWIGV8_stringToValue(const std::string &str) { + return SWIG_FromCharPtrAndSize(str.c_str(), str.length()); +} +} + +namespace std { + %naturalvar string; + + class string; + + %typemap(in, fragment="SWIGV8_valueToString") string (std::string* tmp) + %{ + tmp = SWIGV8_valueToStringPtr($input); + $1 = *tmp; + if (tmp == 0) { v8::ThrowException(v8::Exception::TypeError(v8::String::New("Null pointer."))); goto fail; } + if (tmp) delete tmp; + %} + + %typemap(in, fragment="SWIGV8_valueToString") const string & + %{ + $1 = SWIGV8_valueToStringPtr($input); + if ($1 == 0) { v8::ThrowException(v8::Exception::TypeError(v8::String::New("Null pointer."))); goto fail; } + %} + + %typemap(freearg) const string & + %{ + if ($1) delete $1; + %} + + %typemap(out, fragment="SWIGV8_stringToValue") string + %{ + $result = SWIGV8_stringToValue($1); + %} + + %typemap(out, fragment="SWIGV8_stringToValue") const string & + %{ + $result = SWIGV8_stringToValue(*$1); + %} + +} diff --git a/Lib/javascript/v8/std_vector.i b/Lib/javascript/v8/std_vector.i new file mode 100755 index 000000000..3f29b19c7 --- /dev/null +++ b/Lib/javascript/v8/std_vector.i @@ -0,0 +1,85 @@ +/* ----------------------------------------------------------------------------- + * std_vector.i + * ----------------------------------------------------------------------------- */ + +%include + +%{ +#include +#include +%} + +namespace std { + + template class vector { + public: + typedef size_t size_type; + typedef T value_type; + typedef const value_type& const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + public: + typedef size_t size_type; + typedef bool value_type; + typedef bool const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i +%include +%include +%include +%include + diff --git a/Lib/javascript/v8/typemaps.i b/Lib/javascript/v8/typemaps.i new file mode 100644 index 000000000..d3d8afb19 --- /dev/null +++ b/Lib/javascript/v8/typemaps.i @@ -0,0 +1,148 @@ +/* ----------------------------------------------------------------------------- + * typemaps.i + * + * Pointer handling + * These mappings provide support for input/output arguments and common + * uses for C/C++ pointers. + * ----------------------------------------------------------------------------- */ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + +/* +The following methods can be applied to turn a pointer into a simple +"input" value. That is, instead of passing a pointer to an object, +you would use a real value instead. + + int *INPUT + short *INPUT + long *INPUT + long long *INPUT + unsigned int *INPUT + unsigned short *INPUT + unsigned long *INPUT + unsigned long long *INPUT + unsigned char *INPUT + bool *INPUT + float *INPUT + double *INPUT + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + %include + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +*/ + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + +/* +The following methods can be applied to turn a pointer into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. In the case of +multiple output values, they are returned in the form of a Python tuple. + + int *OUTPUT + short *OUTPUT + long *OUTPUT + long long *OUTPUT + unsigned int *OUTPUT + unsigned short *OUTPUT + unsigned long *OUTPUT + unsigned long long *OUTPUT + unsigned char *OUTPUT + bool *OUTPUT + float *OUTPUT + double *OUTPUT + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters).K: + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Python output of the function would be a tuple containing both +output values. + +*/ + +// INOUT +// Mappings for an argument that is both an input and output +// parameter + +/* +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned in the form of a Python tuple. + + int *INOUT + short *INOUT + long *INOUT + long long *INOUT + unsigned int *INOUT + unsigned short *INOUT + unsigned long *INOUT + unsigned long long *INOUT + unsigned char *INOUT + bool *INOUT + float *INOUT + double *INOUT + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include + void neg(double *INOUT); + +or you can use the %apply directive : + + %include + %apply double *INOUT { double *x }; + void neg(double *x); + +Unlike C, this mapping does not directly modify the input value (since +this makes no sense in Python). Rather, the modified input value shows +up as the return value of the function. Thus, to apply this function +to a Python variable you might do this : + + x = neg(x) + +Note : previous versions of SWIG used the symbol 'BOTH' to mark +input/output arguments. This is still supported, but will be slowly +phased out in future releases. + +*/ + +%include diff --git a/Lib/typemaps/strings.swg b/Lib/typemaps/strings.swg index e31e5037f..6bac0b98a 100644 --- a/Lib/typemaps/strings.swg +++ b/Lib/typemaps/strings.swg @@ -499,7 +499,7 @@ * --- String fragment methods --- * ------------------------------------------------------------ */ - +#ifndef %_typemap2_string %define %_typemap2_string(StringCode, CharCode, Char, CharName, SWIG_AsCharPtrAndSize, @@ -602,7 +602,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val) SWIG_DeleteCharArray) %enddef - +#endif /* ------------------------------------------------------------ * String typemaps and fragments, with default allocators diff --git a/Makefile.in b/Makefile.in index 4407d1316..f4d0be077 100644 --- a/Makefile.in +++ b/Makefile.in @@ -84,6 +84,7 @@ skip-uffi = test -n "@SKIP_UFFI@" skip-r = test -n "@SKIP_R@" skip-go = test -n "@SKIP_GO@" skip-d = test -n "@SKIP_D@" +skip-javascript = test -n "@SKIP_JAVASCRIPT@" # Additional dependencies for some tests skip-gcj = test -n "@SKIP_GCJ@" @@ -129,6 +130,7 @@ check-aliveness: @$(skip-r) || ./$(TARGET) -r -help @$(skip-go) || ./$(TARGET) -go -help @$(skip-d) || ./$(TARGET) -d -help + @$(skip-javascript) || ./$(TARGET) -javascript -help check-ccache: test -z "$(ENABLE_CCACHE)" || (cd $(CCACHE) && $(MAKE) check) @@ -139,6 +141,7 @@ check-versions: \ check-perl5-version \ check-python-version \ check-java-version \ + check-javascript-version \ check-android-version \ check-guile-version \ check-mzscheme-version \ @@ -196,7 +199,8 @@ check-examples: \ check-cffi-examples \ check-r-examples \ check-go-examples \ - check-d-examples + check-d-examples \ + check-javascript-examples tcl_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/tcl/check.list) perl5_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/perl5/check.list) @@ -221,6 +225,7 @@ cffi_examples := r_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/r/check.list) go_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/go/check.list) d_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/d/check.list) +javascript_examples:=$(shell sed '/^\#/d' $(srcdir)/Examples/javascript/check.list) # all examples check-%-examples : @@ -274,7 +279,8 @@ check-test-suite: \ check-chicken-test-suite \ check-r-test-suite \ check-go-test-suite \ - check-d-test-suite + check-d-test-suite \ + check-javascript-test-suite check-%-test-suite: @if test -z "$(skip-$*)"; then \ @@ -326,7 +332,8 @@ all-test-suite: \ all-chicken-test-suite \ all-r-test-suite \ all-go-test-suite \ - all-d-test-suite + all-d-test-suite \ + all-javascript-test-suite all-%-test-suite: @$(MAKE) $(FLAGS) check-$*-test-suite ACTION=all @@ -354,7 +361,8 @@ broken-test-suite: \ broken-chicken-test-suite \ broken-r-test-suite \ broken-go-test-suite \ - broken-d-test-suite + broken-d-test-suite \ + broken-javascript-test-suite broken-%-test-suite: @$(MAKE) $(FLAGS) check-$*-test-suite ACTION=broken @@ -467,7 +475,8 @@ install-main: @$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@ lib-languages = gcj typemaps tcl perl5 python guile java mzscheme ruby php ocaml octave \ - pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d + pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d javascript javascript/jsc \ + javascript/v8 lib-modules = std diff --git a/Source/Makefile.am b/Source/Makefile.am index 49d571236..4dbede635 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -49,6 +49,7 @@ eswig_SOURCES = CParse/cscanner.c \ Modules/guile.cxx \ Modules/java.cxx \ Modules/lang.cxx \ + Modules/javascript.cxx \ Modules/lua.cxx \ Modules/main.cxx \ Modules/modula3.cxx \ diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx new file mode 100644 index 000000000..eae594727 --- /dev/null +++ b/Source/Modules/javascript.cxx @@ -0,0 +1,2428 @@ +#include "swigmod.h" + +/** + * Enables extra debugging information in typemaps. + */ +bool js_template_enable_debug = false; + +// keywords used for state variables +#define NAME "name" +#define NAME_MANGLED "name_mangled" +#define TYPE "type" +#define TYPE_MANGLED "type_mangled" +#define WRAPPER_NAME "wrapper" +#define IS_IMMUTABLE "is_immutable" +#define IS_STATIC "is_static" +#define IS_ABSTRACT "is_abstract" +#define GETTER "getter" +#define SETTER "setter" +#define PARENT "parent" +#define CTOR "ctor" +#define CTOR_WRAPPERS "ctor_wrappers" +#define CTOR_DISPATCHERS "ctor_dispatchers" +#define DTOR "dtor" +#define ARGCOUNT "wrap:argc" + +// keys for global state variables +#define CREATE_NAMESPACES "create_namespaces" +#define REGISTER_NAMESPACES "register_namespaces" +#define INITIALIZER "initializer" + +// keys for class scoped state variables +#define MEMBER_VARIABLES "member_variables" +#define MEMBER_FUNCTIONS "member_functions" +#define STATIC_FUNCTIONS "static_functions" +#define STATIC_VARIABLES "static_variables" +#define HAS_TEMPLATES "has_templates" + +#define RESET true + +/** + * A convenience class to manage state variables for emitters. + * The implementation delegates to swig Hash DOHs and provides + * named sub-hashes for class, variable, and function states. + */ +class JSEmitterState { + +public: + + JSEmitterState(); + + ~JSEmitterState(); + + DOH *global (); + + DOH *global (const char *key, DOH *initial = 0); + + DOH *clazz(bool reset = false); + + DOH *clazz(const char *key, DOH *initial = 0); + + DOH *function(bool reset = false); + + DOH *function(const char *key, DOH *initial = 0); + + DOH *variable(bool reset = false); + + DOH *variable(const char *key, DOH *initial = 0); + + static int IsSet(DOH *val); + +private: + + DOH *getState(const char *key, bool reset = false); + + Hash *_global; +}; + +/** + * A convenience class that wraps a code snippet used as template + * for code generation. + */ +class Template { + +public: + Template(const String *code); + + Template(const String *code, const String *templateName); + + Template(const Template & other); + + ~Template(); + + String *str(); + + Template & replace(const String *pattern, const String *repl); + + Template & print(DOH *doh); + + Template & pretty_print(DOH *doh); + + void operator=(const Template & t); + + Template & trim(); + +private: + + String *code; + String *templateName; + +}; + +/** + * JSEmitter represents an abstraction of javascript code generators + * for different javascript engines. + **/ +class JSEmitter { + +protected: + + typedef JSEmitterState State; + + enum MarshallingMode { + Setter, + Getter, + Ctor, + Function + }; + +public: + + enum JSEmitterType { + JavascriptCore, + V8 + }; + + JSEmitter(); + + virtual ~ JSEmitter(); + + /** + * Opens output files and temporary output DOHs. + */ + virtual int initialize(Node *n); + + /** + * Writes all collected code into the output file(s). + */ + virtual int dump(Node *n) = 0; + + /** + * Cleans up all open output DOHs. + */ + virtual int close() = 0; + + /** + * Switches the context for code generation. + * + * Classes, global variables and global functions may need to + * be registered in certain static tables. + * This method should be used to switch output DOHs correspondingly. + */ + virtual int switchNamespace(Node *); + + /** + * Invoked at the beginning of the classHandler. + */ + virtual int enterClass(Node *); + + /** + * Invoked at the end of the classHandler. + */ + virtual int exitClass(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the beginning of the variableHandler. + */ + virtual int enterVariable(Node *); + + /** + * Invoked at the end of the variableHandler. + */ + virtual int exitVariable(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the beginning of the functionHandler. + */ + virtual int enterFunction(Node *); + + /** + * Invoked at the end of the functionHandler. + */ + virtual int exitFunction(Node *) { + return SWIG_OK; + }; + + /** + * Invoked by functionWrapper callback after call to Language::functionWrapper. + */ + virtual int emitWrapperFunction(Node *n); + + /** + * Invoked from constantWrapper after call to Language::constantWrapper. + **/ + virtual int emitConstant(Node *n); + + /** + * Registers a given code snippet for a given key name. + * + * This method is called by the fragmentDirective handler + * of the JAVASCRIPT language module. + **/ + int registerTemplate(const String *name, const String *code); + + /** + * Retrieve the code template registered for a given name. + */ + Template getTemplate(const String *name); + + State & getState(); + +protected: + + /** + * Generates code for a constructor function. + */ + virtual int emitCtor(Node *n); + + /** + * Generates code for a destructor function. + */ + virtual int emitDtor(Node *n); + + /** + * Generates code for a function. + */ + virtual int emitFunction(Node *n, bool is_member, bool is_static); + + virtual int emitFunctionDispatcher(Node *n, bool /*is_member */ ); + + /** + * Generates code for a getter function. + */ + virtual int emitGetter(Node *n, bool is_member, bool is_static); + + /** + * Generates code for a setter function. + */ + virtual int emitSetter(Node *n, bool is_member, bool is_static); + + virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) = 0; + + virtual String *emitInputTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg); + + virtual void marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult = 0, bool emitReturnVariable = true); + + virtual void emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params); + + /** + * Helper function to retrieve the first parent class node. + */ + Node *getBaseClass(Node *n); + + Parm *skipIgnoredArgs(Parm *p); + + virtual int createNamespace(String *scope); + + virtual Hash *createNamespaceEntry(const char *name, const char *parent); + + virtual int emitNamespaces() = 0; + + +protected: + + Hash *templates; + + State state; + + // contains context specific data (DOHs) + // to allow generation of namespace related code + // which are switched on namespace change + Hash *namespaces; + Hash *current_namespace; + + String *defaultResultName; + + File *f_wrappers; +}; + +/* factory methods for concrete JSEmitters: */ + +JSEmitter *swig_javascript_create_JSCEmitter(); +JSEmitter *swig_javascript_create_V8Emitter(); + +/********************************************************************** + * JAVASCRIPT: swig module implementation + **********************************************************************/ + +class JAVASCRIPT:public Language { + +public: + + JAVASCRIPT():emitter(NULL) { + } ~JAVASCRIPT() { + delete emitter; + } + + virtual int functionHandler(Node *n); + virtual int globalfunctionHandler(Node *n); + virtual int variableHandler(Node *n); + virtual int globalvariableHandler(Node *n); + virtual int staticmemberfunctionHandler(Node *n); + virtual int classHandler(Node *n); + virtual int functionWrapper(Node *n); + virtual int constantWrapper(Node *n); + virtual void main(int argc, char *argv[]); + virtual int top(Node *n); + + /** + * Registers all %fragments assigned to section "templates". + **/ + virtual int fragmentDirective(Node *n); + +private: + + JSEmitter * emitter; +}; + +/* --------------------------------------------------------------------- + * functionWrapper() + * + * Low level code generator for functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::functionWrapper(Node *n) { + + // note: the default implementation only prints a message + // Language::functionWrapper(n); + emitter->emitWrapperFunction(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * functionHandler() + * + * Function handler for generating wrappers for functions + * --------------------------------------------------------------------- */ +int JAVASCRIPT::functionHandler(Node *n) { + + if (GetFlag(n, "isextension") == 1) { + SetFlag(n, "ismember"); + } + + emitter->enterFunction(n); + Language::functionHandler(n); + emitter->exitFunction(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * globalfunctionHandler() + * + * Function handler for generating wrappers for functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::globalfunctionHandler(Node *n) { + emitter->switchNamespace(n); + Language::globalfunctionHandler(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * staticmemberfunctionHandler() + * + * Function handler for generating wrappers for static member functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { + /* + * Note: storage=static is removed by Language::staticmemberfunctionHandler. + * So, don't rely on that after here. Instead use the state variable which is + * set by JSEmitter::enterFunction(). + */ + Language::staticmemberfunctionHandler(n); + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * variableHandler() + * + * Function handler for generating wrappers for variables + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::variableHandler(Node *n) { + + emitter->enterVariable(n); + Language::variableHandler(n); + emitter->exitVariable(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * globalvariableHandler() + * + * Function handler for generating wrappers for global variables + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::globalvariableHandler(Node *n) { + emitter->switchNamespace(n); + Language::globalvariableHandler(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * constantHandler() + * + * Function handler for generating wrappers for constants + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::constantWrapper(Node *n) { + emitter->switchNamespace(n); + + // Note: callbacks trigger this wrapper handler + // TODO: handle callback declarations + if (Equal(Getattr(n, "kind"), "function")) { + return SWIG_OK; + } + // TODO: the emitter for constants must be implemented in a cleaner way + // currently we treat it like a read-only variable + // however, there is a remaining bug with function pointer constants + // which could be fixed with a cleaner approach + emitter->emitConstant(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * classHandler() + * + * Function handler for generating wrappers for class + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::classHandler(Node *n) { + emitter->switchNamespace(n); + + emitter->enterClass(n); + Language::classHandler(n); + emitter->exitClass(n); + + return SWIG_OK; +} + +int JAVASCRIPT::fragmentDirective(Node *n) { + + // catch all fragment directives that have "templates" as location + // and register them at the emitter. + String *section = Getattr(n, "section"); + + if (Equal(section, "templates")) { + emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code")); + } else { + Swig_fragment_register(n); + } + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * top() + * + * Function handler for processing top node of the parse tree + * Wrapper code generation essentially starts from here + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::top(Node *n) { + emitter->initialize(n); + + Language::top(n); + + emitter->dump(n); + emitter->close(); + + return SWIG_OK; +} + +static const char *usage = (char *) "\ +Javascript Options (available with -javascript)\n\ + -jsc - creates a JavascriptCore extension \n\ + -v8 - creates a v8 extension \n\ + -node - creates a node.js extension \n\ + -debug-codetemplates - generates information about the origin of code templates.\n"; + + +/* --------------------------------------------------------------------- + * main() + * + * Entry point for the JAVASCRIPT module + * --------------------------------------------------------------------- */ + +void JAVASCRIPT::main(int argc, char *argv[]) { + // Set javascript subdirectory in SWIG library + SWIG_library_directory("javascript"); + + int mode = -1; + + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i], "-v8") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); + } else if (strcmp(argv[i], "-jsc") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::JavascriptCore; + SWIG_library_directory("javascript/jsc"); + } else if (strcmp(argv[i], "-node") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); + Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0); + } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { + Swig_mark_arg(i); + js_template_enable_debug = true; + } else if (strcmp(argv[i], "-help") == 0) { + fputs(usage, stdout); + return; + } + } + } + + switch (mode) { + case JSEmitter::V8: + { + emitter = swig_javascript_create_V8Emitter(); + Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0); + break; + } + case JSEmitter::JavascriptCore: + { + emitter = swig_javascript_create_JSCEmitter(); + Preprocessor_define("SWIG_JAVASCRIPT_JSC 1", 0); + break; + } + default: + { + Printf(stderr, "SWIG Javascript: Unknown emitter type.\n"); + SWIG_exit(-1); + break; + } + } + + // Add a symbol to the parser for conditional compilation + Preprocessor_define("SWIGJAVASCRIPT 1", 0); + + // Add typemap definitions + SWIG_typemap_lang("javascript"); + + // Set configuration file + SWIG_config_file("javascript.swg"); + + allow_overloading(); +} + +/* ----------------------------------------------------------------------------- + * swig_javascript() - Instantiate module + * ----------------------------------------------------------------------------- */ + +static Language *new_swig_javascript() { + return new JAVASCRIPT(); +} + +extern "C" Language *swig_javascript(void) { + return new_swig_javascript(); +} + +/********************************************************************** + * Emitter implementations + **********************************************************************/ + +/* ----------------------------------------------------------------------------- + * JSEmitter() + * ----------------------------------------------------------------------------- */ + +JSEmitter::JSEmitter() +: templates(NewHash()), namespaces(NULL), current_namespace(NULL), defaultResultName(NewString("result")), f_wrappers(NULL) { +} + +/* ----------------------------------------------------------------------------- + * ~JSEmitter() + * ----------------------------------------------------------------------------- */ + +JSEmitter::~JSEmitter() { + Delete(templates); +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::RegisterTemplate() : Registers a code template + * + * Note: this is used only by JAVASCRIPT::fragmentDirective(). + * ----------------------------------------------------------------------------- */ + +int JSEmitter::registerTemplate(const String *name, const String *code) { + if (!State::IsSet(state.global (HAS_TEMPLATES))) { + SetFlag(state.global (), HAS_TEMPLATES); + } + return Setattr(templates, name, code); +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::getTemplate() : Provides a registered code template + * ----------------------------------------------------------------------------- */ + +Template JSEmitter::getTemplate(const String *name) { + String *templ = Getattr(templates, name); + + if (!templ) { + Printf(stderr, "Could not find template %s\n.", name); + SWIG_exit(EXIT_FAILURE); + } + + Template t(templ, name); + return t; +} + +JSEmitterState & JSEmitter::getState() { + return state; +} + +int JSEmitter::initialize(Node * /*n */ ) { + + if (namespaces != NULL) { + Delete(namespaces); + } + namespaces = NewHash(); + Hash *global_namespace = createNamespaceEntry("exports", 0); + + Setattr(namespaces, "::", global_namespace); + current_namespace = global_namespace; + + f_wrappers = NewString(""); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * skipIgnoredArgs() + * --------------------------------------------------------------------- */ + +Parm *JSEmitter::skipIgnoredArgs(Parm *p) { + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + } + return p; +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::getBaseClass() : the node of the base class or NULL + * + * Note: the first base class is provided. Multiple inheritance is not + * supported. + * ----------------------------------------------------------------------------- */ + +Node *JSEmitter::getBaseClass(Node *n) { + // retrieve the first base class that is not %ignored + List *baselist = Getattr(n, "bases"); + if (baselist) { + Iterator base = First(baselist); + while (base.item && GetFlag(base.item, "feature:ignore")) { + base = Next(base); + } + return base.item; + } + return NULL; +} + + /* ----------------------------------------------------------------------------- + * JSEmitter::emitWrapperFunction() : dispatches emitter functions. + * + * This allows to have small sized, dedicated emitting functions. + * All state dependent branching is done here. + * ----------------------------------------------------------------------------- */ + +int JSEmitter::emitWrapperFunction(Node *n) { + int ret = SWIG_OK; + + String *kind = Getattr(n, "kind"); + + if (kind) { + + if (Equal(kind, "function") + // HACK: sneaky.ctest revealed that typedef'd (global) functions must be + // detected via the 'view' attribute. + || (Equal(kind, "variable") && Equal(Getattr(n, "view"), "globalfunctionHandler")) + ) { + bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); + bool is_static = GetFlag(state.function(), IS_STATIC); + ret = emitFunction(n, is_member, is_static); + } else if (Cmp(kind, "variable") == 0) { + bool is_static = GetFlag(state.variable(), IS_STATIC); + // HACK: smartpointeraccessed static variables are not treated as statics + if (GetFlag(n, "allocate:smartpointeraccess")) { + is_static = false; + } + + bool is_member = GetFlag(n, "ismember"); + bool is_setter = GetFlag(n, "memberset") || GetFlag(n, "varset"); + bool is_getter = GetFlag(n, "memberget") || GetFlag(n, "varget"); + if (is_setter) { + ret = emitSetter(n, is_member, is_static); + } else if (is_getter) { + ret = emitGetter(n, is_member, is_static); + } else { + Swig_print_node(n); + } + + } else { + Printf(stderr, "Warning: unsupported wrapper function type\n"); + Swig_print_node(n); + ret = SWIG_ERROR; + } + } else { + String *view = Getattr(n, "view"); + + if (Cmp(view, "constructorHandler") == 0) { + ret = emitCtor(n); + } else if (Cmp(view, "destructorHandler") == 0) { + ret = emitDtor(n); + } else { + Printf(stderr, "Warning: unsupported wrapper function type"); + Swig_print_node(n); + ret = SWIG_ERROR; + } + } + + return ret; +} + +int JSEmitter::enterClass(Node *n) { + state.clazz(RESET); + state.clazz(NAME, Getattr(n, "sym:name")); + state.clazz("nspace", current_namespace); + + // Creating a mangled name using the current namespace and the symbol name + String *mangled_name = NewString(""); + Printf(mangled_name, "%s_%s", Getattr(current_namespace, NAME_MANGLED), Getattr(n, "sym:name")); + state.clazz(NAME_MANGLED, SwigType_manglestr(mangled_name)); + Delete(mangled_name); + + state.clazz(TYPE, NewString(Getattr(n, "classtype"))); + + String *type = SwigType_manglestr(Getattr(n, "classtypeobj")); + String *classtype_mangled = NewString(""); + Printf(classtype_mangled, "p%s", type); + state.clazz(TYPE_MANGLED, classtype_mangled); + Delete(type); + + String *ctor_wrapper = NewString("_wrap_new_veto_"); + Append(ctor_wrapper, state.clazz(NAME)); + state.clazz(CTOR, ctor_wrapper); + state.clazz(CTOR_DISPATCHERS, NewString("")); + state.clazz(DTOR, NewString("0")); + + // HACK: assume that a class is abstract + // this is resolved by emitCtor (which is only called for non abstract classes) + SetFlag(state.clazz(), IS_ABSTRACT); + + return SWIG_OK; +} + +int JSEmitter::enterFunction(Node *n) { + state.function(RESET); + state.function(NAME, Getattr(n, "sym:name")); + if (Equal(Getattr(n, "storage"), "static")) { + SetFlag(state.function(), IS_STATIC); + } + return SWIG_OK; +} + +int JSEmitter::enterVariable(Node *n) { + // reset the state information for variables. + state.variable(RESET); + + // Retrieve a pure symbol name. Using 'sym:name' as a basis, as it considers %renamings. + if (Equal(Getattr(n, "view"), "memberconstantHandler")) { + // Note: this is kind of hacky/experimental + // For constants/enums 'sym:name' contains e.g., 'Foo_Hello' instead of 'Hello' + state.variable(NAME, Getattr(n, "memberconstantHandler:sym:name")); + } else { + state.variable(NAME, Swig_scopename_last(Getattr(n, "sym:name"))); + } + + if (Equal(Getattr(n, "storage"), "static")) { + SetFlag(state.variable(), IS_STATIC); + } + + if (!Language::instance()->is_assignable(n)) { + SetFlag(state.variable(), IS_IMMUTABLE); + } + // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[] + if (Equal(Getattr(n, "type"), "a().char")) { + SetFlag(state.variable(), IS_IMMUTABLE); + } + + return SWIG_OK; +} + +int JSEmitter::emitCtor(Node *n) { + + Wrapper *wrapper = NewWrapper(); + + bool is_overloaded = GetFlag(n, "sym:overloaded"); + + Template t_ctor(getTemplate("js_ctor")); + + //String *mangled_name = SwigType_manglestr(Getattr(n, "name")); + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + if (is_overloaded) { + t_ctor = getTemplate("js_overloaded_ctor"); + Append(wrap_name, Getattr(n, "sym:overname")); + } + Setattr(n, "wrap:name", wrap_name); + // note: removing the is_abstract flag, as this emitter + // is supposed to be called for non-abstract classes only. + Setattr(state.clazz(), IS_ABSTRACT, 0); + + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemap. + // Deleting wrapper->code here, to reset, and as it seemed to have no side effect elsewhere + Delete(wrapper->code); + wrapper->code = NewString(""); + + Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0)); + + marshalInputArgs(n, params, wrapper, Ctor, true, false); + String *action = emit_action(n); + Printv(wrapper->code, action, "\n", 0); + + emitCleanupCode(n, wrapper, params); + + t_ctor.replace("$jswrapper", wrap_name) + .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .replace("$jsargcount", Getattr(n, ARGCOUNT)) + .pretty_print(f_wrappers); + + Template t_ctor_case(getTemplate("js_ctor_dispatch_case")); + t_ctor_case.replace("$jswrapper", wrap_name) + .replace("$jsargcount", Getattr(n, ARGCOUNT)); + Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); + + DelWrapper(wrapper); + + // create a dispatching ctor + if (is_overloaded) { + if (!Getattr(n, "sym:nextSibling")) { + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Template t_mainctor(getTemplate("js_ctor_dispatcher")); + t_mainctor.replace("$jswrapper", wrap_name) + .replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsdispatchcases", state.clazz(CTOR_DISPATCHERS)) + .pretty_print(f_wrappers); + state.clazz(CTOR, wrap_name); + } + } else { + state.clazz(CTOR, wrap_name); + } + + return SWIG_OK; +} + +int JSEmitter::emitDtor(Node *n) { + + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + + SwigType *type = state.clazz(TYPE); + String *p_classtype = SwigType_add_pointer(state.clazz(TYPE)); + String *ctype = SwigType_lstr(p_classtype, ""); + String *free = NewString(""); + + // (Taken from JSCore implementation.) + /* The if (Extend) block was taken from the Ruby implementation. + * The problem is that in the case of an %extend to create a destructor for a struct to coordinate automatic memory cleanup with the Javascript collector, + * the swig function was not being generated. More specifically: + struct MyData { + %extend { + ~MyData() { + FreeData($self); + } + } + }; + %newobject CreateData; + struct MyData* CreateData(void); + %delobject FreeData; + void FreeData(struct MyData* the_data); + + where the use case is something like: + var my_data = example.CreateData(); + my_data = null; + + This function was not being generated: + SWIGINTERN void delete_MyData(struct MyData *self){ + FreeData(self); + } + + I don't understand fully why it wasn't being generated. It just seems to happen in the Lua generator. + There is a comment about staticmemberfunctionHandler having an inconsistency and I tracked down dome of the SWIGINTERN void delete_* + code to that function in the Language base class. + The Ruby implementation seems to have an explicit check for if(Extend) and explicitly generates the code, so that's what I'm doing here. + The Ruby implementation does other stuff which I omit. + */ + if (Extend) { + String *wrap = Getattr(n, "wrap:code"); + if (wrap) { + Printv(f_wrappers, wrap, NIL); + } + } + + // HACK: this is only for the v8 emitter. maybe set an attribute wrap:action of node + // TODO: generate dtors more similar to other wrappers + // EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used. + if (SwigType_isarray(type)) { + Printf(free, "delete [] (%s)", ctype); + } else { + Printf(free, "delete (%s)", ctype); + } + + String *destructor_action = Getattr(n, "wrap:action"); + // Adapted from the JSCore implementation. + /* The next challenge is to generate the correct finalize function for JavaScriptCore to call. + Originally, it would use this fragment from javascriptcode.swg + %fragment ("JS_destructordefn", "templates") + %{ + void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) + { + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject); + if(t) free(t); + } + %} + + But for the above example case of %extend to define a destructor on a struct, we need to override the system to not call + free ((${type}*)t->swigCObject); + and substitute it with what the user has provided. + To solve this, I created a variation fragment called JS_destructoroverridedefn: + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) { + ${type}* arg1 = (${type}*)t->swigCObject; + ${destructor_action} + } + if(t) free(t); + + Based on what I saw in the Lua and Ruby modules, I use Getattr(n, "wrap:action") + to decide if the user has a preferred destructor action. + Based on that, I decide which fragment to use. + And in the case of the custom action, I substitute that action in. + I noticed that destructor_action has the form + delete_MyData(arg1); + The explicit arg1 is a little funny, so I structured the fragment to create a temporary variable called arg1 to make the generation easier. + This might suggest this solution misunderstands a more complex case. + + Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above. + So this code doesn't actually quite work as I expect. The end result is that the code still works because + destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is wierd. + I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free. + + Maybe the fix for the destructor_action always true problem is that this is supposed to be embedded in the if(Extend) block above. + But I don't fully understand the conditions of any of these things, and since it works for the moment, I don't want to break more stuff. + */ + if (destructor_action) { + Template t_dtor = getTemplate("js_dtoroverride"); + state.clazz(DTOR, wrap_name); + t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) + .replace("$jswrapper", wrap_name) + .replace("$jsfree", free) + .replace("$jstype", ctype); + + t_dtor.replace("${destructor_action}", destructor_action); + Wrapper_pretty_print(t_dtor.str(), f_wrappers); + } else { + Template t_dtor = getTemplate("js_dtor"); + state.clazz(DTOR, wrap_name); + t_dtor.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jswrapper", wrap_name) + .replace("$jsfree", free) + .replace("$jstype", ctype) + .pretty_print(f_wrappers); + } + + Delete(p_classtype); + Delete(ctype); + Delete(free); + + return SWIG_OK; +} + +int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { + Wrapper *wrapper = NewWrapper(); + Template t_getter(getTemplate("js_getter")); + + // prepare wrapper name + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Setattr(n, "wrap:name", wrap_name); + state.variable(GETTER, wrap_name); + + // prepare local variables + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + + // prepare code part + String *action = emit_action(n); + marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); + marshalOutput(n, params, wrapper, action); + + emitCleanupCode(n, wrapper, params); + + t_getter.replace("$jswrapper", wrap_name) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .pretty_print(f_wrappers); + + DelWrapper(wrapper); + + return SWIG_OK; +} + +int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { + + // skip variables that are immutable + if (State::IsSet(state.variable(IS_IMMUTABLE))) { + return SWIG_OK; + } + + Wrapper *wrapper = NewWrapper(); + + Template t_setter(getTemplate("js_setter")); + + // prepare wrapper name + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Setattr(n, "wrap:name", wrap_name); + state.variable(SETTER, wrap_name); + + // prepare local variables + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + + // prepare code part + String *action = emit_action(n); + marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); + Append(wrapper->code, action); + + emitCleanupCode(n, wrapper, params); + + t_setter.replace("$jswrapper", wrap_name) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .pretty_print(f_wrappers); + + DelWrapper(wrapper); + + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::emitConstant() : triggers code generation for constants + * ----------------------------------------------------------------------------- */ + +int JSEmitter::emitConstant(Node *n) { + // HACK: somehow it happened under OSX that before everything started + // a lot of SWIG internal constants were emitted + // This didn't happen on other platforms yet... + // we ignore those premature definitions + if (!State::IsSet(state.global (HAS_TEMPLATES))) { + return SWIG_ERROR; + } + + Wrapper *wrapper = NewWrapper(); + SwigType *type = Getattr(n, "type"); + String *name = Getattr(n, "name"); + String *iname = Getattr(n, "sym:name"); + String *wname = Swig_name_wrapper(name); + String *rawval = Getattr(n, "rawval"); + String *value = rawval ? rawval : Getattr(n, "value"); + + Template t_getter(getTemplate("js_getter")); + + // call the variable methods as a constants are + // registred in same way + enterVariable(n); + state.variable(GETTER, wname); + // TODO: why do we need this? + Setattr(n, "wrap:name", wname); + + // special treatment of member pointers + if (SwigType_type(type) == T_MPOINTER) { + // TODO: this could go into a code-template + String *mpointer_wname = NewString(""); + Printf(mpointer_wname, "_wrapConstant_%s", iname); + Setattr(n, "memberpointer:constant:wrap:name", mpointer_wname); + String *str = SwigType_str(type, mpointer_wname); + Printf(f_wrappers, "static %s = %s;\n", str, value); + Delete(str); + value = mpointer_wname; + } + + marshalOutput(n, 0, wrapper, NewString(""), value, false); + + t_getter.replace("$jswrapper", wname) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .pretty_print(f_wrappers); + + exitVariable(n); + + DelWrapper(wrapper); + + return SWIG_OK; +} + +int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { + Wrapper *wrapper = NewWrapper(); + Template t_function(getTemplate("js_function")); + + bool is_overloaded = GetFlag(n, "sym:overloaded"); + + // prepare the function wrapper name + String *iname = Getattr(n, "sym:name"); + String *wrap_name = Swig_name_wrapper(iname); + if (is_overloaded) { + t_function = getTemplate("js_overloaded_function"); + Append(wrap_name, Getattr(n, "sym:overname")); + } + Setattr(n, "wrap:name", wrap_name); + state.function(WRAPPER_NAME, wrap_name); + + // prepare local variables + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + + // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generates an extra line of applied typemap. + // Deleting wrapper->code here fixes the problem, and seems to have no side effect elsewhere + Delete(wrapper->code); + wrapper->code = NewString(""); + + marshalInputArgs(n, params, wrapper, Function, is_member, is_static); + String *action = emit_action(n); + + marshalOutput(n, params, wrapper, action); + + emitCleanupCode(n, wrapper, params); + + Replaceall(wrapper->code, "$symname", iname); + + t_function.replace("$jswrapper", wrap_name) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .replace("$jsargcount", Getattr(n, ARGCOUNT)) + .pretty_print(f_wrappers); + + + DelWrapper(wrapper); + + return SWIG_OK; +} + +int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { + Wrapper *wrapper = NewWrapper(); + + // Generate call list, go to first node + Node *sibl = n; + + while (Getattr(sibl, "sym:previousSibling")) + sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up + + do { + String *siblname = Getattr(sibl, "wrap:name"); + + if (siblname) { + // handle function overloading + Template t_dispatch_case = getTemplate("js_function_dispatch_case"); + t_dispatch_case.replace("$jswrapper", siblname) + .replace("$jsargcount", Getattr(sibl, ARGCOUNT)); + + Append(wrapper->code, t_dispatch_case.str()); + } + + } while ((sibl = Getattr(sibl, "sym:nextSibling"))); + + Template t_function(getTemplate("js_function_dispatcher")); + + // Note: this dispatcher function gets called after the last overloaded function has been created. + // At this time, n.wrap:name contains the name of the last wrapper function. + // To get a valid function name for the dispatcher function we take the last wrapper name and + // substract the extension "sym:overname", + String *wrap_name = NewString(Getattr(n, "wrap:name")); + String *overname = Getattr(n, "sym:overname"); + int l1 = Len(wrap_name); + int l2 = Len(overname); + Delslice(wrap_name, l1 - l2, l1); + + Setattr(n, "wrap:name", wrap_name); + state.function(WRAPPER_NAME, wrap_name); + + t_function.replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code); + + // call this here, to replace all variables + t_function.replace("$jswrapper", wrap_name) + .replace("$jsname", state.function(NAME)) + .pretty_print(f_wrappers); + + // Delete the state variable + DelWrapper(wrapper); + + return SWIG_OK; +} + +String *JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg) { + // Get input typemap for current param + String *tm = Getattr(p, "tmap:in"); + SwigType *type = Getattr(p, "type"); + + if (tm != NULL) { + Replaceall(tm, "$input", arg); + Setattr(p, "emit:input", arg); + // do replacements for built-in variables + if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { + Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); + } else { + Replaceall(tm, "$disown", "0"); + } + Replaceall(tm, "$symname", Getattr(n, "sym:name")); + Printf(wrapper->code, "%s\n", tm); + } else { + Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(type, 0)); + } + + return tm; +} + +void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult, bool emitReturnVariable) { + SwigType *type = Getattr(n, "type"); + String *tm; + Parm *p; + + // adds a declaration for the result variable + if (emitReturnVariable) + emit_return_variable(n, type, wrapper); + // if not given, use default result identifier ('result') for output typemap + if (cresult == 0) + cresult = defaultResultName; + + tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode); + bool should_own = GetFlag(n, "feature:new"); + + if (tm) { + Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); + + if (should_own) { + Replaceall(tm, "$owner", "SWIG_POINTER_OWN"); + } else { + Replaceall(tm, "$owner", "0"); + } + Append(wrapper->code, tm); + + if (Len(tm) > 0) { + Printf(wrapper->code, "\n"); + } + } else { + Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name")); + } + + if (params) { + for (p = params; p;) { + if ((tm = Getattr(p, "tmap:argout"))) { + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(wrapper->code, tm, "\n", NIL); + p = Getattr(p, "tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + } + + Replaceall(wrapper->code, "$result", "jsresult"); +} + +void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) { + Parm *p; + String *tm; + + for (p = params; p;) { + if ((tm = Getattr(p, "tmap:freearg"))) { + //addThrows(n, "tmap:freearg", p); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(wrapper->code, tm, "\n", NIL); + p = Getattr(p, "tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + + if (GetFlag(n, "feature:new")) { + tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0); + if (tm != NIL) { + //addThrows(throws_hash, "newfree", n); + Printv(wrapper->code, tm, "\n", NIL); + } + } + +} + +int JSEmitter::switchNamespace(Node *n) { + // HACK: somehow this gets called when member functions are processed...ignoring + if (GetFlag(n, "ismember")) { + return SWIG_OK; + } + + String *nspace = Getattr(n, "sym:nspace"); + + // if nspace is deactivated, everything goes into the global scope + if (!GetFlag(n, "feature:nspace")) { + current_namespace = Getattr(namespaces, "::"); + return SWIG_OK; + } + + if (nspace == NULL) { + // enums and constants do not have 'sym:nspace' set + // so we try to get the namespace from the qualified name + if (Equal(Getattr(n, "nodeType"), "enumitem")) { + nspace = Swig_scopename_prefix(Getattr(n, "name")); + } + } + + if (nspace == NULL) { + current_namespace = Getattr(namespaces, "::"); + return SWIG_OK; + } + + String *scope = NewString(nspace); + // replace "." with "::" that we can use Swig_scopename_last + Replaceall(scope, ".", "::"); + + // if the scope is not yet registered + // create (parent) namespaces recursively + if (!Getattr(namespaces, scope)) { + createNamespace(scope); + } + current_namespace = Getattr(namespaces, scope); + + return SWIG_OK; +} + +int JSEmitter::createNamespace(String *scope) { + + String *parent_scope = Swig_scopename_prefix(scope); + Hash *parent_namespace; + if (parent_scope == 0) { + parent_namespace = Getattr(namespaces, "::"); + } else if (!Getattr(namespaces, parent_scope)) { + createNamespace(parent_scope); + parent_namespace = Getattr(namespaces, parent_scope); + } else { + parent_namespace = Getattr(namespaces, parent_scope); + } + assert(parent_namespace != 0); + + Hash *new_namespace = createNamespaceEntry(Char(scope), Char(Getattr(parent_namespace, "name"))); + Setattr(namespaces, scope, new_namespace); + + Delete(parent_scope); + return SWIG_OK; +} + +Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent) { + Hash *entry = NewHash(); + String *name = NewString(_name); + Setattr(entry, NAME, Swig_scopename_last(name)); + Setattr(entry, NAME_MANGLED, Swig_name_mangle(name)); + Setattr(entry, PARENT, NewString(parent)); + + Delete(name); + return entry; +} + +/********************************************************************** + * JavascriptCore: JSEmitter implementation for JavascriptCore engine + **********************************************************************/ + +class JSCEmitter:public JSEmitter { + +public: + + JSCEmitter(); + + virtual ~ JSCEmitter(); + + virtual int initialize(Node *n); + + virtual int dump(Node *n); + + virtual int close(); + + +protected: + + virtual int enterVariable(Node *n); + + virtual int exitVariable(Node *n); + + virtual int enterFunction(Node *n); + + virtual int exitFunction(Node *n); + + virtual int enterClass(Node *n); + + virtual int exitClass(Node *n); + + virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); + + virtual Hash *createNamespaceEntry(const char *name, const char *parent); + + virtual int emitNamespaces(); + +private: + + String *NULL_STR; + String *VETO_SET; + + // output file and major code parts + File *f_wrap_cpp; + File *f_runtime; + File *f_header; + File *f_init; + +}; + +JSCEmitter::JSCEmitter() +: JSEmitter(), NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), f_init(NULL) { +} + +JSCEmitter::~JSCEmitter() { + Delete(NULL_STR); + Delete(VETO_SET); +} + + +/* --------------------------------------------------------------------- + * marshalInputArgs() + * + * Process all of the arguments passed into the argv array + * and convert them into C/C++ function arguments using the + * supplied typemaps. + * --------------------------------------------------------------------- */ + +void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { + Parm *p; + String *tm; + + // determine an offset index, as members have an extra 'this' argument + // except: static members and ctors. + int startIdx = 0; + if (is_member && !is_static && mode != Ctor) { + startIdx = 1; + } + // store number of arguments for argument checks + int num_args = emit_num_arguments(parms) - startIdx; + String *argcount = NewString(""); + Printf(argcount, "%d", num_args); + Setattr(n, ARGCOUNT, argcount); + + // process arguments + int i = 0; + for (p = parms; p; i++) { + String *arg = NewString(""); + String *type = Getattr(p, "type"); + + // ignore varargs + if (SwigType_isvarargs(type)) + break; + + switch (mode) { + case Getter: + case Function: + if (is_member && !is_static && i == 0) { + Printv(arg, "thisObject", 0); + } else { + Printf(arg, "argv[%d]", i - startIdx); + } + break; + case Setter: + if (is_member && !is_static && i == 0) { + Printv(arg, "thisObject", 0); + } else { + Printv(arg, "value", 0); + } + break; + case Ctor: + Printf(arg, "argv[%d]", i); + break; + default: + throw "Illegal state."; + } + tm = emitInputTypemap(n, p, wrapper, arg); + Delete(arg); + if (tm) { + p = Getattr(p, "tmap:in:next"); + } else { + p = nextSibling(p); + } + } +} + +int JSCEmitter::initialize(Node *n) { + + JSEmitter::initialize(n); + + /* Get the output file name */ + String *outfile = Getattr(n, "outfile"); + + /* Initialize I/O */ + f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); + if (!f_wrap_cpp) { + FileErrorDisplay(outfile); + SWIG_exit(EXIT_FAILURE); + } + + /* Initialization of members */ + f_runtime = NewString(""); + f_init = NewString(""); + f_header = NewString(""); + + state.global (CREATE_NAMESPACES, NewString("")); + state.global (REGISTER_NAMESPACES, NewString("")); + state.global (INITIALIZER, NewString("")); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("begin", f_wrap_cpp); + Swig_register_filebyname("header", f_header); + Swig_register_filebyname("wrapper", f_wrappers); + Swig_register_filebyname("runtime", f_runtime); + Swig_register_filebyname("init", f_init); + + return SWIG_OK; +} + +int JSCEmitter::dump(Node *n) { + /* Get the module name */ + String *module = Getattr(n, "name"); + + // write the swig banner + Swig_banner(f_wrap_cpp); + + Template initializer_define(getTemplate("js_initializer_define")); + initializer_define.replace("$jsname", module).pretty_print(f_header); + + SwigType_emit_type_table(f_runtime, f_wrappers); + + Printv(f_wrap_cpp, f_runtime, "\n", 0); + Printv(f_wrap_cpp, f_header, "\n", 0); + Printv(f_wrap_cpp, f_wrappers, "\n", 0); + + emitNamespaces(); + + // compose the initializer function using a template + Template initializer(getTemplate("js_initializer")); + initializer.replace("$jsname", module) + .replace("$jsregisterclasses", state.global (INITIALIZER)) + .replace("$jscreatenamespaces", state.global (CREATE_NAMESPACES)) + .replace("$jsregisternamespaces", state.global (REGISTER_NAMESPACES)) + .pretty_print(f_init); + + Printv(f_wrap_cpp, f_init, 0); + + return SWIG_OK; +} + +int JSCEmitter::close() { + Delete(f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Delete(namespaces); + Delete(f_wrap_cpp); + return SWIG_OK; +} + +int JSCEmitter::enterFunction(Node *n) { + + JSEmitter::enterFunction(n); + + return SWIG_OK; +} + +int JSCEmitter::exitFunction(Node *n) { + Template t_function = getTemplate("jsc_function_declaration"); + + bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); + bool is_overloaded = GetFlag(n, "sym:overloaded"); + + // handle overloaded functions + if (is_overloaded) { + if (!Getattr(n, "sym:nextSibling")) { + //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); + // create dispatcher + emitFunctionDispatcher(n, is_member); + } else { + //don't register wrappers of overloaded functions in function tables + return SWIG_OK; + } + } + + t_function.replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)); + + if (is_member) { + if (GetFlag(state.function(), IS_STATIC)) { + Append(state.clazz(STATIC_FUNCTIONS), t_function.str()); + } else { + Append(state.clazz(MEMBER_FUNCTIONS), t_function.str()); + } + } else { + Append(Getattr(current_namespace, "functions"), t_function.str()); + } + + return SWIG_OK; +} + +int JSCEmitter::enterVariable(Node *n) { + JSEmitter::enterVariable(n); + state.variable(GETTER, NULL_STR); + state.variable(SETTER, VETO_SET); + return SWIG_OK; +} + + +int JSCEmitter::exitVariable(Node *n) { + Template t_variable(getTemplate("jsc_variable_declaration")); + t_variable.replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)); + + if (GetFlag(n, "ismember")) { + if (GetFlag(state.variable(), IS_STATIC) + || Equal(Getattr(n, "nodeType"), "enumitem")) { + Append(state.clazz(STATIC_VARIABLES), t_variable.str()); + } else { + Append(state.clazz(MEMBER_VARIABLES), t_variable.str()); + } + } else { + Append(Getattr(current_namespace, "values"), t_variable.str()); + } + + return SWIG_OK; +} + +int JSCEmitter::enterClass(Node *n) { + JSEmitter::enterClass(n); + state.clazz(MEMBER_VARIABLES, NewString("")); + state.clazz(MEMBER_FUNCTIONS, NewString("")); + state.clazz(STATIC_VARIABLES, NewString("")); + state.clazz(STATIC_FUNCTIONS, NewString("")); + + Template t_class_decl = getTemplate("jsc_class_declaration"); + t_class_decl.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .pretty_print(f_wrappers); + + return SWIG_OK; +} + +int JSCEmitter::exitClass(Node *n) { + Template t_class_tables(getTemplate("jsc_class_tables")); + t_class_tables.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsclassvariables", state.clazz(MEMBER_VARIABLES)) + .replace("$jsclassfunctions", state.clazz(MEMBER_FUNCTIONS)) + .replace("$jsstaticclassfunctions", state.clazz(STATIC_FUNCTIONS)) + .replace("$jsstaticclassvariables", state.clazz(STATIC_VARIABLES)) + .pretty_print(f_wrappers); + + /* adds the ctor wrappers at this position */ + // Note: this is necessary to avoid extra forward declarations. + //Append(f_wrappers, state.clazz(CTOR_WRAPPERS)); + + // for abstract classes add a vetoing ctor + if (GetFlag(state.clazz(), IS_ABSTRACT)) { + Template t_veto_ctor(getTemplate("js_veto_ctor")); + t_veto_ctor.replace("$jswrapper", state.clazz(CTOR)) + .replace("$jsname", state.clazz(NAME)) + .pretty_print(f_wrappers); + } + + /* adds a class template statement to initializer function */ + Template t_classtemplate(getTemplate("jsc_class_definition")); + + /* prepare registration of base class */ + String *jsclass_inheritance = NewString(""); + Node *base_class = getBaseClass(n); + if (base_class != NULL) { + Template t_inherit(getTemplate("jsc_class_inherit")); + t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsbaseclassmangled", SwigType_manglestr(Getattr(base_class, "name"))) + .pretty_print(jsclass_inheritance); + } else { + Template t_inherit(getTemplate("jsc_class_noinherit")); + t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .pretty_print(jsclass_inheritance); + } + + t_classtemplate.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) + .replace("$jsclass_inheritance", jsclass_inheritance) + .replace("$jsctor", state.clazz(CTOR)) + .replace("$jsdtor", state.clazz(DTOR)) + .pretty_print(state.global (INITIALIZER)); + Delete(jsclass_inheritance); + + /* Note: this makes sure that there is a swig_type added for this class */ + SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); + + /* adds a class registration statement to initializer function */ + Template t_registerclass(getTemplate("jsc_class_registration")); + t_registerclass.replace("$jsname", state.clazz(NAME)) + .replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsnspace", Getattr(state.clazz("nspace"), NAME_MANGLED)) + .pretty_print(state.global (INITIALIZER)); + + return SWIG_OK; +} + +Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent) { + Hash *entry = JSEmitter::createNamespaceEntry(name, parent); + Setattr(entry, "functions", NewString("")); + Setattr(entry, "values", NewString("")); + return entry; +} + +int JSCEmitter::emitNamespaces() { + Iterator it; + for (it = First(namespaces); it.item; it = Next(it)) { + Hash *entry = it.item; + String *name = Getattr(entry, NAME); + String *name_mangled = Getattr(entry, NAME_MANGLED); + String *parent = Getattr(entry, PARENT); + String *parent_mangled = Swig_name_mangle(parent); + String *functions = Getattr(entry, "functions"); + String *variables = Getattr(entry, "values"); + + // skip the global namespace which is given by the application + + Template namespace_definition(getTemplate("jsc_nspace_declaration")); + namespace_definition.replace("$jsglobalvariables", variables) + .replace("$jsglobalfunctions", functions) + .replace("$jsnspace", name_mangled) + .pretty_print(f_wrap_cpp); + + Template t_createNamespace(getTemplate("jsc_nspace_definition")); + t_createNamespace.replace("$jsmangledname", name_mangled); + Append(state.global (CREATE_NAMESPACES), t_createNamespace.str()); + + // Don't register 'exports' as namespace. It is return to the application. + if (!Equal("exports", name)) { + Template t_registerNamespace(getTemplate("jsc_nspace_registration")); + t_registerNamespace.replace("$jsmangledname", name_mangled) + .replace("$jsname", name) + .replace("$jsparent", parent_mangled); + Append(state.global (REGISTER_NAMESPACES), t_registerNamespace.str()); + } + + } + + return SWIG_OK; +} + +JSEmitter *swig_javascript_create_JSCEmitter() { + return new JSCEmitter(); +} + +/********************************************************************** + * V8: JSEmitter implementation for V8 engine + **********************************************************************/ + +class V8Emitter:public JSEmitter { + +public: + + V8Emitter(); + + virtual ~ V8Emitter(); + virtual int initialize(Node *n); + virtual int dump(Node *n); + virtual int close(); + virtual int enterClass(Node *n); + virtual int exitClass(Node *n); + virtual int enterVariable(Node *n); + virtual int exitVariable(Node *n); + virtual int exitFunction(Node *n); + +protected: + + virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); + virtual int emitNamespaces(); + +private: + + /* built-in parts */ + String *f_runtime; + String *f_header; + String *f_init; + String *f_post_init; + + /* part for class templates */ + String *f_class_templates; + + /* parts for initilizer */ + String *f_init_namespaces; + String *f_init_class_templates; + String *f_init_wrappers; + String *f_init_inheritance; + String *f_init_class_instances; + String *f_init_static_wrappers; + String *f_init_register_classes; + String *f_init_register_namespaces; + + // the output cpp file + File *f_wrap_cpp; + + String *NULL_STR; + String *VETO_SET; + String *moduleName; + +}; + +V8Emitter::V8Emitter() +: JSEmitter(), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")) { +} + +V8Emitter::~V8Emitter() { + Delete(NULL_STR); + Delete(VETO_SET); +} + +int V8Emitter::initialize(Node *n) { + JSEmitter::initialize(n); + + moduleName = Getattr(n, "name"); + + // Get the output file name + String *outfile = Getattr(n, "outfile"); + f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); + if (!f_wrap_cpp) { + FileErrorDisplay(outfile); + SWIG_exit(EXIT_FAILURE); + } + + f_runtime = NewString(""); + f_header = NewString(""); + f_class_templates = NewString(""); + f_init = NewString(""); + f_post_init = NewString(""); + + f_init_namespaces = NewString(""); + f_init_class_templates = NewString(""); + f_init_wrappers = NewString(""); + f_init_inheritance = NewString(""); + f_init_class_instances = NewString(""); + f_init_static_wrappers = NewString(""); + f_init_register_classes = NewString(""); + f_init_register_namespaces = NewString(""); + + // note: this is necessary for built-in generation of swig runtime code + Swig_register_filebyname("begin", f_wrap_cpp); + Swig_register_filebyname("runtime", f_runtime); + Swig_register_filebyname("header", f_header); + Swig_register_filebyname("wrapper", f_wrappers); + Swig_register_filebyname("init", f_init); + Swig_register_filebyname("post-init", f_post_init); + + return SWIG_OK; +} + +int V8Emitter::dump(Node *n) { + /* Get the module name */ + String *module = Getattr(n, "name"); + + // write the swig banner + Swig_banner(f_wrap_cpp); + + Template initializer_define(getTemplate("js_initializer_define")); + initializer_define.replace("$jsname", module).pretty_print(f_header); + + SwigType_emit_type_table(f_runtime, f_wrappers); + + Printv(f_wrap_cpp, f_runtime, "\n", 0); + Printv(f_wrap_cpp, f_header, "\n", 0); + Printv(f_wrap_cpp, f_class_templates, "\n", 0); + Printv(f_wrap_cpp, f_wrappers, "\n", 0); + + emitNamespaces(); + + // compose the initializer function using a template + // filled with sub-parts + Template initializer(getTemplate("js_initializer")); + initializer.replace("$jsname", moduleName) + .replace("$jsv8nspaces", f_init_namespaces) + .replace("$jsv8classtemplates", f_init_class_templates) + .replace("$jsv8wrappers", f_init_wrappers) + .replace("$jsv8inheritance", f_init_inheritance) + .replace("$jsv8classinstances", f_init_class_instances) + .replace("$jsv8staticwrappers", f_init_static_wrappers) + .replace("$jsv8registerclasses", f_init_register_classes) + .replace("$jsv8registernspaces", f_init_register_namespaces); + Printv(f_init, initializer.str(), 0); + + Printv(f_wrap_cpp, f_init, 0); + + Printv(f_wrap_cpp, f_post_init, 0); + + return SWIG_OK; +} + +int V8Emitter::close() { + Delete(f_runtime); + Delete(f_header); + Delete(f_class_templates); + Delete(f_init_namespaces); + Delete(f_init_class_templates); + Delete(f_init_wrappers); + Delete(f_init_inheritance); + Delete(f_init_class_instances); + Delete(f_init_static_wrappers); + Delete(f_init_register_classes); + Delete(f_init_register_namespaces); + Delete(f_init); + Delete(f_post_init); + Delete(f_wrap_cpp); + return SWIG_OK; +} + +int V8Emitter::enterClass(Node *n) { + JSEmitter::enterClass(n); + + // emit declaration of a v8 class template + Template t_decl_class(getTemplate("jsv8_declare_class_template")); + t_decl_class.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .trim() + .pretty_print(f_class_templates); + + return SWIG_OK; +} + +int V8Emitter::exitClass(Node *n) { + if (GetFlag(state.clazz(), IS_ABSTRACT)) { + Template t_veto_ctor(getTemplate("js_veto_ctor")); + t_veto_ctor.replace("$jswrapper", state.clazz(CTOR)) + .replace("$jsname", state.clazz(NAME)) + .pretty_print(f_wrappers); + } + + /* Note: this makes sure that there is a swig_type added for this class */ + String *clientData = NewString(""); + Printf(clientData, "&%s_clientData", state.clazz(NAME_MANGLED)); + + /* Note: this makes sure that there is a swig_type added for this class */ + SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); + + // emit definition of v8 class template + Template t_def_class = getTemplate("jsv8_define_class_template"); + t_def_class.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.clazz(NAME)) + .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) + .replace("$jsdtor", state.clazz(DTOR)) + .trim() + .pretty_print(f_init_class_templates); + + Template t_class_instance = getTemplate("jsv8_create_class_instance"); + t_class_instance.replace("$jsname", state.clazz(NAME)) + .replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsctor", state.clazz(CTOR)) + .trim() + .pretty_print(f_init_class_instances); + + // emit inheritance setup + Node *baseClass = getBaseClass(n); + if (baseClass) { + String *base_name = Getattr(baseClass, "name"); + + Template t_inherit = getTemplate("jsv8_inherit"); + + String *base_name_mangled = SwigType_manglestr(base_name); + t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsbaseclass", base_name_mangled) + .trim() + .pretty_print(f_init_inheritance); + Delete(base_name_mangled); + } + // emit registeration of class template + Template t_register = getTemplate("jsv8_register_class"); + t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.clazz(NAME)) + .replace("$jsparent", Getattr(state.clazz("nspace"), NAME_MANGLED)) + .trim() + .pretty_print(f_init_register_classes); + + return SWIG_OK; +} + +int V8Emitter::enterVariable(Node *n) { + JSEmitter::enterVariable(n); + + state.variable(GETTER, NULL_STR); + state.variable(SETTER, VETO_SET); + + return SWIG_OK; +} + +int V8Emitter::exitVariable(Node *n) { + if (GetFlag(n, "ismember")) { + if (GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem")) { + Template t_register = getTemplate("jsv8_register_static_variable"); + t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim().print(f_init_static_wrappers); + } else { + Template t_register = getTemplate("jsv8_register_member_variable"); + t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim() + .print(f_init_wrappers); + } + } else { + // Note: a global variable is treated like a static variable + // with the parent being a nspace object (instead of class object) + Template t_register = getTemplate("jsv8_register_static_variable"); + t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim() + .print(f_init_wrappers); + } + + return SWIG_OK; +} + +int V8Emitter::exitFunction(Node *n) { + bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); + + // create a dispatcher for overloaded functions + bool is_overloaded = GetFlag(n, "sym:overloaded"); + if (is_overloaded) { + if (!Getattr(n, "sym:nextSibling")) { + //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); + emitFunctionDispatcher(n, is_member); + } else { + //don't register wrappers of overloaded functions in function tables + return SWIG_OK; + } + } + // register the function at the specific context + if (is_member) { + if (GetFlag(state.function(), IS_STATIC)) { + Template t_register = getTemplate("jsv8_register_static_function"); + t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) + .trim() + .print(f_init_static_wrappers); + } else { + Template t_register = getTemplate("jsv8_register_member_function"); + t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) + .trim() + .print(f_init_wrappers); + } + } else { + // Note: a global function is treated like a static function + // with the parent being a nspace object instead of class object + Template t_register = getTemplate("jsv8_register_static_function"); + t_register.replace("$jsparent", Getattr(current_namespace, NAME)) + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) + .trim() + .pretty_print(f_init_static_wrappers); + } + + return SWIG_OK; +} + +void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { + Parm *p; + String *tm; + + int startIdx = 0; + if (is_member && !is_static && mode != Ctor) { + startIdx = 1; + } + // store number of arguments for argument checks + int num_args = emit_num_arguments(parms) - startIdx; + String *argcount = NewString(""); + Printf(argcount, "%d", num_args); + Setattr(n, ARGCOUNT, argcount); + + int i = 0; + for (p = parms; p; i++) { + String *arg = NewString(""); + String *type = Getattr(p, "type"); + + // ignore varargs + if (SwigType_isvarargs(type)) + break; + + switch (mode) { + case Getter: + if (is_member && !is_static && i == 0) { + Printv(arg, "info.Holder()", 0); + } else { + Printf(arg, "args[%d]", i - startIdx); + } + break; + case Function: + if (is_member && !is_static && i == 0) { + Printv(arg, "args.Holder()", 0); + } else { + Printf(arg, "args[%d]", i - startIdx); + } + break; + case Setter: + if (is_member && !is_static && i == 0) { + Printv(arg, "info.Holder()", 0); + } else { + Printv(arg, "value", 0); + } + break; + case Ctor: + Printf(arg, "args[%d]", i); + break; + default: + throw "Illegal state."; + } + + tm = emitInputTypemap(n, p, wrapper, arg); + Delete(arg); + + if (tm) { + p = Getattr(p, "tmap:in:next"); + } else { + p = nextSibling(p); + } + } +} + +int V8Emitter::emitNamespaces() { + Iterator it; + for (it = First(namespaces); it.item; it = Next(it)) { + Hash *entry = it.item; + String *name = Getattr(entry, NAME); + String *name_mangled = Getattr(entry, NAME_MANGLED); + String *parent = Getattr(entry, PARENT); + String *parent_mangled = Swig_name_mangle(parent); + + bool do_create = true; + bool do_register = true; + + if (Equal(parent, "")) { + do_register = false; + } + // Note: 'exports' is by convention the name of the object where + // globals are stored into + if (Equal(name, "exports")) { + do_create = false; + } + + if (do_create) { + // create namespace object and register it to the parent scope + Template t_create_ns = getTemplate("jsv8_create_namespace"); + t_create_ns.replace("$jsmangledname", name_mangled) + .trim() + .pretty_print(f_init_namespaces); + } + + if (do_register) { + Template t_register_ns = getTemplate("jsv8_register_namespace"); + t_register_ns.replace("$jsmangledname", name_mangled) + .replace("$jsname", name) + .replace("$jsparent", parent_mangled) + .trim(); + + // prepend in order to achieve reversed order of registration statements + Insert(f_init_register_namespaces, 0, t_register_ns.str()); + } + } + + return SWIG_OK; +} + +JSEmitter *swig_javascript_create_V8Emitter() { + return new V8Emitter(); +} + + +/********************************************************************** + * Helper implementations + **********************************************************************/ + +JSEmitterState::JSEmitterState() +: _global(NewHash()) { + // initialize sub-hashes + Setattr(_global, "class", NewHash()); + Setattr(_global, "function", NewHash()); + Setattr(_global, "variable", NewHash()); +} + +JSEmitterState::~JSEmitterState() { + Delete(_global); +} + +DOH *JSEmitterState::getState(const char *key, bool _new) { + if (_new) { + Hash *hash = NewHash(); + Setattr(_global, key, hash); + } + return Getattr(_global, key); +} + +DOH *JSEmitterState::global () { + return _global; +} + +DOH *JSEmitterState::global (const char *key, DOH *initial) { + if (initial != 0) { + Setattr(_global, key, initial); + } + return Getattr(_global, key); +} + +DOH *JSEmitterState::clazz(bool _new) { + return getState("class", _new); +} + +DOH *JSEmitterState::clazz(const char *key, DOH *initial) { + DOH *c = clazz(); + if (initial != 0) { + Setattr(c, key, initial); + } + return Getattr(c, key); +} + +DOH *JSEmitterState::function(bool _new) { + return getState("function", _new); +} + +DOH *JSEmitterState::function(const char *key, DOH *initial) { + DOH *f = function(); + if (initial != 0) { + Setattr(f, key, initial); + } + return Getattr(f, key); +} + +DOH *JSEmitterState::variable(bool _new) { + return getState("variable", _new); +} + +DOH *JSEmitterState::variable(const char *key, DOH *initial) { + DOH *v = variable(); + if (initial != 0) { + Setattr(v, key, initial); + } + return Getattr(v, key); +} + +/*static*/ +int JSEmitterState::IsSet(DOH *val) { + if (!val) { + return 0; + } else { + const char *cval = Char(val); + if (!cval) + return 0; + return (strcmp(cval, "0") != 0) ? 1 : 0; + } +} + +/* ----------------------------------------------------------------------------- + * Template::Template() : creates a Template class for given template code + * ----------------------------------------------------------------------------- */ + +Template::Template(const String *code_) { + + if (!code_) { + Printf(stdout, "Template code was null. Illegal input for template."); + SWIG_exit(EXIT_FAILURE); + } + code = NewString(code_); + templateName = NewString(""); +} + +Template::Template(const String *code_, const String *templateName_) { + + if (!code_) { + Printf(stdout, "Template code was null. Illegal input for template."); + SWIG_exit(EXIT_FAILURE); + } + + code = NewString(code_); + templateName = NewString(templateName_); +} + + +/* ----------------------------------------------------------------------------- + * Template::~Template() : cleans up of Template. + * ----------------------------------------------------------------------------- */ + +Template::~Template() { + Delete(code); + Delete(templateName); +} + +/* ----------------------------------------------------------------------------- + * String* Template::str() : retrieves the current content of the template. + * ----------------------------------------------------------------------------- */ + +String *Template::str() { + if (js_template_enable_debug) { + String *pre_code = NewString(""); + String *post_code = NewString(""); + String *debug_code = NewString(""); + Printf(pre_code, "/* begin fragment(\"%s\") */", templateName); + Printf(post_code, "/* end fragment(\"%s\") */", templateName); + Printf(debug_code, "%s\n%s\n%s\n", pre_code, code, post_code); + + Delete(code); + Delete(pre_code); + Delete(post_code); + + code = debug_code; + } + return code; +} + +Template & Template::trim() { + const char *str = Char(code); + if (str == 0) + return *this; + + int length = Len(code); + if (length == 0) + return *this; + + int idx; + for (idx = 0; idx < length; ++idx) { + if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n') + break; + } + int start_pos = idx; + + for (idx = length - 1; idx >= start_pos; --idx) { + if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n') + break; + } + int end_pos = idx; + + int new_length = end_pos - start_pos + 1; + char *newstr = new char[new_length + 1]; + memcpy(newstr, str + start_pos, new_length); + newstr[new_length] = 0; + + Delete(code); + code = NewString(newstr); + delete[]newstr; + + return *this; +} + +/* ----------------------------------------------------------------------------- + * Template& Template::replace(const String* pattern, const String* repl) : + * + * replaces all occurences of a given pattern with a given replacement. + * + * - pattern: the pattern to be replaced + * - repl: the replacement string + * - returns a reference to the Template to allow chaining of methods. + * ----------------------------------------------------------------------------- */ + +Template & Template::replace(const String *pattern, const String *repl) { + Replaceall(code, pattern, repl); + return *this; +} + +Template & Template::print(DOH *doh) { + Printv(doh, str(), 0); + return *this; +} + +Template & Template::pretty_print(DOH *doh) { + Wrapper_pretty_print(str(), doh); + return *this; +} + +Template::Template(const Template & t) { + code = NewString(t.code); + templateName = NewString(t.templateName); +} + +void Template::operator=(const Template & t) { + Delete(code); + Delete(templateName); + code = NewString(t.code); + templateName = NewString(t.templateName); +} diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx index 7c9cded70..97b21710a 100644 --- a/Source/Modules/swigmain.cxx +++ b/Source/Modules/swigmain.cxx @@ -51,6 +51,7 @@ extern "C" { Language *swig_r(void); Language *swig_go(void); Language *swig_d(void); + Language *swig_javascript(void); } struct swig_module { @@ -92,6 +93,7 @@ static swig_module modules[] = { {"-tcl8", swig_tcl, 0}, {"-uffi", swig_uffi, "Common Lisp / UFFI"}, {"-xml", swig_xml, "XML"}, + {"-javascript", swig_javascript, "Javascript"}, {NULL, NULL, NULL} }; diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in new file mode 100644 index 000000000..d58412b50 --- /dev/null +++ b/Tools/javascript/Makefile.in @@ -0,0 +1,58 @@ +# ---------------------------------------------------------------- +# Compile a custom javascript interpreter +# ---------------------------------------------------------------- +# +# Note: +# There is no common CLI Javascript interpreter. +# V8 comes with one 'd8' which however does not provide a means +# to load extensions. Therefore, by default we use nodejs as +# environment. +# For testing native v8 and jsc extensions we provide our own +# interpreter (see 'Tools/javascript'). +# +# ---------------------------------------------------------------- +CC = @CC@ +# HACK: under OSX a g++ compiled interpreter is seg-faulting when loading module libraries +# with 'c++' it works... probably some missing flags? +JSCXX = @JSINTERPRETERCXX@ +CFLAGS = @PLATCFLAGS@ +CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ +LINKFLAGS = @JSINTERPRETERLINKFLAGS@ + +ROOT_DIR = @ROOT_DIR@ +JSCFLAGS = @JSCFLAGS@ +JSCXXFLAGS = @JSCXXFLAGS@ +JSINCLUDES = @JSCOREINC@ @JSV8INC@ +JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ +JSLIBRARYPREFIX = @JSLIBRARYPREFIX@ +JSSO =@JSSO@ +JSLDSHARED = @JSLDSHARED@ +JSCXXSHARED = @JSCXXSHARED@ +JSV8ENABLED = @JSV8ENABLED@ +JSCENABLED = @JSCENABLED@ + +# These settings are provided by 'configure' (see '/configure.in') +ifeq (1, $(JSV8ENABLED)) + JS_INTERPRETER_SRC_V8 = v8_shell.cxx + JS_INTERPRETER_ENABLE_V8 = -DENABLE_V8 +endif + +ifeq (1, $(JSCENABLED)) + JS_INTERPRETER_SRC_JSC = jsc_shell.cxx + JS_INTERPRETER_ENABLE_JSC = -DENABLE_JSC +endif + +JS_INTERPRETER_DEFINES = $(JS_INTERPRETER_ENABLE_JSC) $(JS_INTERPRETER_ENABLE_V8) +JS_INTERPRETER_SRC = javascript.cxx js_shell.cxx $(JS_INTERPRETER_SRC_JSC) $(JS_INTERPRETER_SRC_V8) + +JS_INTERPRETER_OBJS = $(JS_INTERPRETER_SRC:.cxx=.o) + +%.o: %.cxx + $(JSCXX) $(JS_INTERPRETER_DEFINES) $(CXXFLAGS) $(JSINCLUDES) -o $@ -c $< + +javascript: $(JS_INTERPRETER_OBJS) + $(JSCXX) $^ $(CXXFLAGS) -o javascript $(JSDYNAMICLINKING) $(LINKFLAGS) + +clean: + rm -f *.o + rm -f javascript diff --git a/Tools/javascript/javascript.cxx b/Tools/javascript/javascript.cxx new file mode 100644 index 000000000..5e7cc0b20 --- /dev/null +++ b/Tools/javascript/javascript.cxx @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include + +#include "js_shell.h" + +void print_usage() { + std::cout << "javascript [-i] [-jsc|-v8] [-l module] " << std::endl; +} + +int main(int argc, char* argv[]) { + +#if defined(JAVASCRIPT_INTERPRETER_STOP) + std::cout << "Attach your Debugger and press any key to continue" << std::endl; + std::cin.get(); +#endif + + std::string scriptPath = ""; + + bool interactive = false; + JSShell* shell = 0; + + std::vector modulePath; + modulePath.push_back("."); + + for (int idx = 1; idx < argc; ++idx) { + if(strcmp(argv[idx], "-v8") == 0) { + shell = JSShell::Create(JSShell::V8); + } else if(strcmp(argv[idx], "-jsc") == 0) { + shell = JSShell::Create(JSShell::JSC); + } else if(strcmp(argv[idx], "-i") == 0) { + interactive = true; + } else if(strcmp(argv[idx], "-L") == 0) { + modulePath.push_back(argv[++idx]); + } else { + scriptPath = argv[idx]; + } + } + + if (shell == 0) { + shell = JSShell::Create(); + } + + shell->setModulePath(modulePath); + + bool failed = false; + + if(interactive) { + failed = !(shell->RunShell()); + } else { + failed = !(shell->RunScript(scriptPath)); + } + + if (failed) { + delete shell; + printf("FAIL: Error during execution of script.\n"); + return 1; + } + + delete shell; + + return 0; +} diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx new file mode 100644 index 000000000..539b83d65 --- /dev/null +++ b/Tools/javascript/js_shell.cxx @@ -0,0 +1,156 @@ +#include "js_shell.h" + +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#ifdef __APPLE__ +#define LIBRARY_EXT ".bundle" +#else +#define LIBRARY_EXT ".so" +#endif +#include +#define LOAD_LIBRARY(name) dlopen(name, RTLD_LAZY) +#define CLOSE_LIBRARY(handle) dlclose(handle) +#define LIBRARY_ERROR dlerror +#define LIBRARYFILE(name) std::string("lib").append(name).append(LIBRARY_EXT) +#else +#error "implement dll loading" +#endif + + +JSShell::~JSShell() { + + for(std::vector::iterator it = loaded_modules.begin(); + it != loaded_modules.end(); ++it) { + HANDLE handle = *it; + CLOSE_LIBRARY(handle); + } + +} + +// TODO: this could be done more intelligent... +// - can we achieve source file relative loading? +// - better path resolution +std::string JSShell::LoadModule(const std::string& name, HANDLE* library) { + + // works only for posix like OSs + size_t pathIdx = name.find_last_of("/"); + + std::string lib_name; + std::string module_name; + + if (pathIdx == std::string::npos) { + module_name = name; + lib_name = std::string(name).append(LIBRARY_EXT); + } else { + std::string path = name.substr(0, pathIdx+1); + module_name = name.substr(pathIdx+1); + lib_name = path.append(module_name).append(LIBRARY_EXT); + } + + std::string lib_path; + HANDLE handle = 0; + + for (int i = 0; i < module_path.size(); ++i) { + lib_path = module_path[i] + "/" + lib_name; + if (access( lib_path.c_str(), F_OK ) != -1) { + handle = LOAD_LIBRARY(lib_path.c_str()); + } + } + + if(handle == 0) { + std::cerr << "Could not find module " << lib_path << ":" + << std::endl << LIBRARY_ERROR() << std::endl; + return 0; + } + + loaded_modules.push_back(handle); + + *library = handle; + + return module_name; +} + +bool JSShell::RunScript(const std::string& scriptPath) { + std::string source = ReadFile(scriptPath); + if(!InitializeEngine()) return false; + + // Node.js compatibility: make `print` available as `console.log()` + ExecuteScript("var console = {}; console.log = print;", ""); + + if(!ExecuteScript(source, scriptPath)) { + return false; + } + + return DisposeEngine(); +} + +bool JSShell::RunShell() { + + if(!InitializeEngine()) return false; + + static const int kBufferSize = 1024; + while (true) { + char buffer[kBufferSize]; + printf("> "); + char* str = fgets(buffer, kBufferSize, stdin); + if (str == NULL) break; + std::string source(str); + ExecuteScript(source, "(shell)"); + } + printf("\n"); + return true; +} + +std::string JSShell::ReadFile(const std::string& fileName) +{ + std::string script; + + std::ifstream file(fileName.c_str()); + if (file.is_open()) { + while ( file.good() ) { + std::string line; + getline(file, line); + script.append(line); + script.append("\n"); + } + file.close(); + } else { + std::cout << "Unable to open file " << fileName << "." << std::endl; + } + + return script; +} + +#ifdef ENABLE_JSC +extern JSShell* JSCShell_Create(); +#endif +#ifdef ENABLE_V8 +extern JSShell* V8Shell_Create(); +#endif + +typedef JSShell*(*ShellFactory)(); + +static ShellFactory js_shell_factories[2] = { +#ifdef ENABLE_JSC +JSCShell_Create, +#else +0, +#endif +#ifdef ENABLE_V8 +V8Shell_Create, +#else +0, +#endif +}; + +JSShell *JSShell::Create(Engine engine) { + if(js_shell_factories[engine] == 0) { + throw "Engine not available."; + } + return js_shell_factories[engine](); +} diff --git a/Tools/javascript/js_shell.h b/Tools/javascript/js_shell.h new file mode 100644 index 000000000..1e2466b96 --- /dev/null +++ b/Tools/javascript/js_shell.h @@ -0,0 +1,53 @@ +#ifndef JS_SHELL_H +#define JS_SHELL_H + +#include +#include + +typedef void* HANDLE; +typedef void* MODULE; + +class JSShell { + +public: + enum Engine { + JSC = 0, + V8 + }; + +public: + + JSShell() {} + + virtual ~JSShell() = 0; + + static JSShell* Create(Engine engine = JSC); + + std::string LoadModule(const std::string& name, HANDLE* library); + + virtual bool RunScript(const std::string& scriptPath); + + virtual bool RunShell(); + + void setModulePath(const std::vector& modulePath) { + module_path = modulePath; + } + +protected: + + virtual bool InitializeEngine() = 0; + + virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath) = 0; + + virtual bool DisposeEngine() = 0; + + static std::string ReadFile(const std::string& fileName); + +protected: + + std::vector loaded_modules; + std::vector module_path; + +}; + +#endif // JS_SHELL_H diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx new file mode 100644 index 000000000..292c4042b --- /dev/null +++ b/Tools/javascript/jsc_shell.cxx @@ -0,0 +1,233 @@ +#include + +#include "js_shell.h" + +#include +#include + +#ifdef __GNUC__ +#include +#define LOAD_SYMBOL(handle, name) dlsym(handle, name) +#else +#error "implement dll loading" +#endif + +class JSCShell: public JSShell { + +typedef int (*JSCIntializer)(JSGlobalContextRef context, JSObjectRef *module); + +public: + + JSCShell() {}; + + virtual ~JSCShell(); + +protected: + + virtual bool InitializeEngine(); + + virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath); + + virtual bool DisposeEngine(); + +private: + + JSObjectRef Import(const std::string &moduleName); + + static JSValueRef Print(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); + + static JSValueRef Require(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); + + static bool RegisterFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback cbFunction); + + static void PrintError(JSContextRef, JSValueRef); + +private: + + JSGlobalContextRef context; +}; + +JSCShell::~JSCShell() { + if(context != 0) { + JSGlobalContextRelease(context); + context = 0; + } +} + +bool JSCShell::InitializeEngine() { + if(context != 0) { + JSGlobalContextRelease(context); + context = 0; + } + // TODO: check for initialization errors + context = JSGlobalContextCreate(NULL); + if(context == 0) return false; + JSObjectRef globalObject = JSContextGetGlobalObject(context); + + // store this for later use + JSClassDefinition __shell_classdef__ = JSClassDefinition(); + + JSClassRef __shell_class__ = JSClassCreate(&__shell_classdef__); + JSObjectRef __shell__ = JSObjectMake(context, __shell_class__, 0); + bool success = JSObjectSetPrivate(__shell__, (void*) (long) this); + if (!success) { + std::cerr << "Could not register the shell in the Javascript context" << std::endl; + return false; + } + JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__"); + JSObjectSetProperty(context, globalObject, shellKey, __shell__, kJSPropertyAttributeReadOnly, NULL); + JSStringRelease(shellKey); + + JSCShell::RegisterFunction(context, globalObject, "print", JSCShell::Print); + JSCShell::RegisterFunction(context, globalObject, "require", JSCShell::Require); + + return true; +} + +bool JSCShell::ExecuteScript(const std::string& source, const std::string& scriptPath) { + JSStringRef jsScript; + JSStringRef sourceURL; + JSValueRef ex; + jsScript = JSStringCreateWithUTF8CString(source.c_str()); + sourceURL = JSStringCreateWithUTF8CString(scriptPath.c_str()); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, sourceURL, 0, &ex); + JSStringRelease(jsScript); + if (jsResult == NULL && ex != NULL) { + JSCShell::PrintError(context, ex); + return false; + } + return true; +} + +bool JSCShell::DisposeEngine() { + JSGlobalContextRelease(context); + context = 0; + return true; +} + +JSValueRef JSCShell::Print(JSContextRef context, JSObjectRef object, + JSObjectRef globalobj, size_t argc, + const JSValueRef args[], JSValueRef* ex) { + if (argc > 0) + { + JSStringRef string = JSValueToStringCopy(context, args[0], NULL); + size_t numChars = JSStringGetMaximumUTF8CStringSize(string); + char *stringUTF8 = new char[numChars]; + JSStringGetUTF8CString(string, stringUTF8, numChars); + printf("%s\n", stringUTF8); + + delete[] stringUTF8; + } + + return JSValueMakeUndefined(context); +} + +// Attention: this feature should not create too high expectations. +// It is only capable of loading things relative to the execution directory +// and not relative to the parent script. +JSValueRef JSCShell::Require(JSContextRef context, JSObjectRef object, + JSObjectRef globalObj, size_t argc, + const JSValueRef args[], JSValueRef* ex) { + JSObjectRef module; + + JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__"); + JSValueRef shellAsVal = JSObjectGetProperty(context, globalObj, shellKey, NULL); + JSStringRelease(shellKey); + JSObjectRef shell = JSValueToObject(context, shellAsVal, 0); + JSCShell *_this = (JSCShell*) (long) JSObjectGetPrivate(shell); + + if (argc > 0) + { + JSStringRef string = JSValueToStringCopy(context, args[0], NULL); + size_t numChars = JSStringGetMaximumUTF8CStringSize(string); + char *stringUTF8 = new char[numChars]; + JSStringGetUTF8CString(string, stringUTF8, numChars); + + std::string modulePath(stringUTF8); + module = _this->Import(modulePath); + + delete[] stringUTF8; + } + + if (module) { + return module; + } else { + printf("Ooops.\n"); + return JSValueMakeUndefined(context); + } +} + +JSObjectRef JSCShell::Import(const std::string& module_path) { + + HANDLE library; + std::string module_name = LoadModule(module_path, &library); + + if (library == 0) { + printf("Could not load module."); + return 0; + } + + std::string symname = std::string(module_name).append("_initialize"); + + JSCIntializer init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); + if(init_function == 0) { + printf("Could not find module's initializer function."); + return 0; + } + + JSObjectRef module; + init_function(context, &module); + + return module; +} + +bool JSCShell::RegisterFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) { + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context, object, js_functionName, + JSObjectMakeFunctionWithCallback(context, js_functionName, callback), + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} + +void JSCShell::PrintError(JSContextRef ctx, JSValueRef err) { + char *buffer; + size_t length; + + JSStringRef string = JSValueToStringCopy(ctx, err, 0); + length = JSStringGetLength(string); + buffer = new char[length+1]; + JSStringGetUTF8CString(string, buffer, length+1); + std::string errMsg(buffer); + JSStringRelease(string); + delete[] buffer; + + JSObjectRef errObj = JSValueToObject(ctx, err, 0); + + if(errObj == 0) { + std::cerr << errMsg << std::endl; + return; + } + + JSStringRef sourceURLKey = JSStringCreateWithUTF8CString("sourceURL"); + JSStringRef sourceURLStr = JSValueToStringCopy(ctx, JSObjectGetProperty(ctx, errObj, sourceURLKey, 0), 0); + length = JSStringGetLength(sourceURLStr); + buffer = new char[length+1]; + JSStringGetUTF8CString(sourceURLStr, buffer, length+1); + std::string sourceURL(buffer); + delete[] buffer; + JSStringRelease(sourceURLStr); + JSStringRelease(sourceURLKey); + + JSStringRef lineKey = JSStringCreateWithUTF8CString("line"); + JSValueRef jsLine = JSObjectGetProperty(ctx, errObj, lineKey, 0); + int line = (int) JSValueToNumber(ctx, jsLine, 0); + JSStringRelease(lineKey); + + std::cerr << sourceURL << ":" << line << ":" << errMsg << std::endl; +} + +JSShell* JSCShell_Create() { + return new JSCShell(); +} diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx new file mode 100755 index 000000000..8a571e0f1 --- /dev/null +++ b/Tools/javascript/v8_shell.cxx @@ -0,0 +1,310 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include "js_shell.h" + +typedef int (*V8ExtensionInitializer) (v8::Handle module); + +class V8Shell: public JSShell { + +public: + V8Shell(); + + virtual ~V8Shell(); + + virtual bool RunScript(const std::string& scriptPath); + + virtual bool RunShell(); + + +protected: + + virtual bool InitializeEngine(); + + virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath); + + virtual bool DisposeEngine(); + +private: + + v8::Handle Import(const std::string& moduleName); + + v8::Persistent CreateShellContext(); + + void ReportException(v8::TryCatch* handler); + + static v8::Handle Print(const v8::Arguments& args); + + static v8::Handle Require(const v8::Arguments& args); + + static v8::Handle Quit(const v8::Arguments& args); + + static v8::Handle Version(const v8::Arguments& args); + + static const char* ToCString(const v8::String::Utf8Value& value); + +protected: + + v8::Persistent context; +}; + +#ifdef __GNUC__ +#include +#define LOAD_SYMBOL(handle, name) dlsym(handle, name) +#else +#error "implement dll loading" +#endif + +V8Shell::V8Shell() +{ +} + +V8Shell::~V8Shell() { + context.Dispose(); + v8::V8::Dispose(); +} + +bool V8Shell::RunScript(const std::string& scriptPath) { + + if (!context.IsEmpty()) { + context.Dispose(); + } + + std::string source = ReadFile(scriptPath); + + context = CreateShellContext(); + if (context.IsEmpty()) { + printf("Could not create context.\n"); + return false; + } + context->Enter(); + //v8::Context::Scope context_scope(context); + v8::HandleScope scope; + + // Store a pointer to this shell for later use + v8::Handle global = context->Global(); + v8::Local __shell__ = v8::External::New((void*) (long) this); + global->SetHiddenValue(v8::String::New("__shell__"), __shell__); + + // Node.js compatibility: make `print` available as `console.log()` + ExecuteScript("var console = {}; console.log = print;", ""); + + if(!ExecuteScript(source, scriptPath)) { + return false; + } + + context->Exit(); + context.Dispose(); + v8::V8::Dispose(); + + return true; +} + +bool V8Shell::RunShell() { + + if (!context.IsEmpty()) { + context.Dispose(); + } + + context = CreateShellContext(); + if (context.IsEmpty()) { + printf("Could not create context.\n"); + return false; + } + + context->Enter(); + + v8::Context::Scope context_scope(context); + + ExecuteScript("var console = {}; console.log = print;", ""); + + static const int kBufferSize = 1024; + while (true) { + char buffer[kBufferSize]; + printf("> "); + char* str = fgets(buffer, kBufferSize, stdin); + if (str == NULL) break; + std::string source(str); + ExecuteScript(source, "(shell)"); + } + printf("\n"); + + context->Exit(); + context.Dispose(); + v8::V8::Dispose(); + + return true; +} + + +bool V8Shell::InitializeEngine() { + return true; +} + +bool V8Shell::ExecuteScript(const std::string& source, const std::string& name) { + v8::HandleScope handle_scope; + v8::TryCatch try_catch; + v8::Handle script = v8::Script::Compile(v8::String::New(source.c_str()), v8::String::New(name.c_str())); + + // Stop if script is empty + if (script.IsEmpty()) { + // Print errors that happened during compilation. + ReportException(&try_catch); + return false; + } + + v8::Handle result = script->Run(); + + // Print errors that happened during execution. + if (try_catch.HasCaught()) { + ReportException(&try_catch); + return false; + } else { + return true; + } +} + +bool V8Shell::DisposeEngine() { + return true; +} + +v8::Persistent V8Shell::CreateShellContext() { + v8::HandleScope scope; + + // Create a template for the global object. + v8::Handle global = v8::ObjectTemplate::New(); + + // Bind global functions + global->Set(v8::String::New("print"), v8::FunctionTemplate::New(V8Shell::Print)); + global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(V8Shell::Quit)); + global->Set(v8::String::New("require"), v8::FunctionTemplate::New(V8Shell::Require)); + global->Set(v8::String::New("version"), v8::FunctionTemplate::New(V8Shell::Version)); + + v8::Persistent _context = v8::Context::New(NULL, global); + + return _context; +} + +v8::Handle V8Shell::Import(const std::string& module_path) +{ + v8::HandleScope scope; + + HANDLE library; + std::string module_name = LoadModule(module_path, &library); + + std::string symname = std::string(module_name).append("_initialize"); + + V8ExtensionInitializer init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); + + if(init_function == 0) { + printf("Could not find initializer function."); + return v8::Undefined(); + } + + v8::Local module = v8::Object::New(); + init_function(module); + return scope.Close(module); +} + +v8::Handle V8Shell::Print(const v8::Arguments& args) { + bool first = true; + for (int i = 0; i < args.Length(); i++) { + v8::HandleScope handle_scope; + if (first) { + first = false; + } else { + printf(" "); + } + v8::String::Utf8Value str(args[i]); + const char* cstr = V8Shell::ToCString(str); + printf("%s", cstr); + } + printf("\n"); + fflush(stdout); + return v8::Undefined(); +} + +v8::Handle V8Shell::Require(const v8::Arguments& args) { + v8::HandleScope scope; + + if (args.Length() != 1) { + printf("Illegal arguments for `require`"); + }; + + v8::String::Utf8Value str(args[0]); + const char* cstr = V8Shell::ToCString(str); + std::string moduleName(cstr); + + v8::Local global = v8::Context::GetCurrent()->Global(); + v8::Local hidden = global->GetHiddenValue(v8::String::New("__shell__")); + v8::Local __shell__ = v8::Local::Cast(hidden); + V8Shell* _this = (V8Shell*) (long) __shell__->Value(); + + v8::Handle module = _this->Import(moduleName); + + return scope.Close(module); +} + +v8::Handle V8Shell::Quit(const v8::Arguments& args) { + int exit_code = args[0]->Int32Value(); + fflush(stdout); + fflush(stderr); + exit(exit_code); + return v8::Undefined(); +} + +v8::Handle V8Shell::Version(const v8::Arguments& args) { + return v8::String::New(v8::V8::GetVersion()); +} + +void V8Shell::ReportException(v8::TryCatch* try_catch) { + v8::HandleScope handle_scope; + v8::String::Utf8Value exception(try_catch->Exception()); + const char* exception_string = V8Shell::ToCString(exception); + v8::Handle message = try_catch->Message(); + if (message.IsEmpty()) { + // V8 didn't provide any extra information about this error; just + // print the exception. + printf("%s\n", exception_string); + } else { + // Print (filename):(line number): (message). + v8::String::Utf8Value filename(message->GetScriptResourceName()); + const char* filename_string = V8Shell::ToCString(filename); + int linenum = message->GetLineNumber(); + printf("%s:%i: %s\n", filename_string, linenum, exception_string); + // Print line of source code. + v8::String::Utf8Value sourceline(message->GetSourceLine()); + const char* sourceline_string = V8Shell::ToCString(sourceline); + printf("%s\n", sourceline_string); + // Print wavy underline (GetUnderline is deprecated). + int start = message->GetStartColumn(); + for (int i = 0; i < start; i++) { + printf(" "); + } + int end = message->GetEndColumn(); + for (int i = start; i < end; i++) { + printf("^"); + } + printf("\n"); + v8::String::Utf8Value stack_trace(try_catch->StackTrace()); + if (stack_trace.length() > 0) { + const char* stack_trace_string = V8Shell::ToCString(stack_trace); + printf("%s\n", stack_trace_string); + } + } +} + +// Extracts a C string from a V8 Utf8Value. +const char* V8Shell::ToCString(const v8::String::Utf8Value& value) { + return *value ? *value : ""; +} + +JSShell* V8Shell_Create() { + return new V8Shell(); +} diff --git a/Tools/swigconfig.h.cmake b/Tools/swigconfig.h.cmake new file mode 100644 index 000000000..e4f0b42c4 --- /dev/null +++ b/Tools/swigconfig.h.cmake @@ -0,0 +1,89 @@ +/* Define to 1 if the system has the type `bool'. */ +#cmakedefine HAVE_BOOL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `dl' library (-ldl). */ +#cmakedefine HAVE_LIBDL 1 + +/* Define to 1 if you have the `dld' library (-ldld). */ +#cmakedefine HAVE_LIBDLD 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H 1 + +/* Define if popen is available */ +#cmakedefine HAVE_POPEN 1 + +/* Define if rxspencer is available */ +#cmakedefine HAVE_RXSPENCER 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#cmakedefine NO_MINUS_C_MINUS_O 1 + +/* Define to 1 if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS 1 + +/* Name of package */ +#define PACKAGE "swig" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "http://www.swig.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "swig" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "swig @SWIG_VERSION@" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "swig" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "@SWIG_VERSION@" + +/* Compiler that built SWIG */ +#define SWIG_CXX "@SWIG_CXX@" + +/* Directory for SWIG system-independent libraries */ +#define SWIG_LIB "/usr/local/share/swig/2.0.0" + +/* Directory for SWIG system-independent libraries (Unix install on native + Windows) */ +#define SWIG_LIB_WIN_UNIX "C:/cygwin/usr/local/share/swig/2.0.0" + +/* Platform that SWIG is built for */ +#define SWIG_PLATFORM "i686-pc-cygwin" + +/* Version number of package */ +#define VERSION "@SWIG_VERSION@" + +/* Default language */ +#define SWIG_LANG "-tcl" + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif diff --git a/Tools/swigprinters.gdb b/Tools/swigprinters.gdb new file mode 100644 index 000000000..661aa3ea1 --- /dev/null +++ b/Tools/swigprinters.gdb @@ -0,0 +1,24 @@ +python +import sys +import os + +try: + global SWIG_PRINTER_DIR + sys.path.insert(0, SWIG_PRINTER_DIR) +except NameError: + raise RuntimeError(""" +--------------------------------------------------------- +Change ~/.gdbinit to be able to use swig pretty printers: +> set python SWIG_PRINTER_DIR = /Tools +> source /Tools/swigprinters.gdb +--------------------------------------------------------- +""") + +from swigprinters import register_swig_printers, enableGdbPrintWorkaround, \ + setChildrenRecursionLevel + +#enableGdbPrintWorkaround() +#setChildrenRecursionLevel(2) +register_swig_printers (None) + +end diff --git a/Tools/swigprinters.py b/Tools/swigprinters.py new file mode 100755 index 000000000..741565997 --- /dev/null +++ b/Tools/swigprinters.py @@ -0,0 +1,574 @@ +import gdb +import gdb.types +import itertools +import re + +log_file = None +GDB_FLATTENED_CHILDREN_WORKAROUND = False +CHILDREN_MAX_RECURSION_LEVEL = 0 + +# workaround: don't cast the following DOHs to it's actual type +# to avoid infinite pretty-print loops +cast_black_list = { + 'Hash': set(['parentNode', 'symtab', 'csymtab', 'sym:symtab', 'inherit', 'nextSibling', 'previousSibling']) +} + +def print_(msg): + global log_file; + + if True: + if log_file == None: + log_file = open('swig_gdb.log', 'w') + log_file.write(msg) + + print(msg) + +class SwigStringPrinter: + """ + Pretty print Swig String* types. + """ + + def __init__ (self, typename, val): + self.typename = typename + self.val = val + + try: + self.t_swigstr_ptr = gdb.lookup_type("struct String").pointer() + self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() + except Exception as err: + print_("SwigStringPrinter: Could not retrieve gdb types.\n %s.\n"%(str(err))) + + def display_hint(self): + return 'string' + + def to_string(self): + ret = "" + + # Conversion taken from Swig Internals manual: + # http://peregrine.hpc.uwm.edu/Head-node-docs/swig/2.0.4/Devel/internals.html#7 + # (*(struct String *)(((DohBase *)s)->data)).str + + dohbase = None; + str_data = None; + char_ptr = None; + + try: + dohbase = self.val.reinterpret_cast(self.t_doh_base_ptr).dereference() + except Exception as err: + print_("SwigStringPrinter: Could not dereference DOHBase*\n"); + return ""; + + try: + str_data = dohbase['data'].reinterpret_cast(self.t_swigstr_ptr).dereference() + except Exception as err: + print_("SwigStringPrinter: Could not dereference struct String*\n"); + return ""; + + try: + char_ptr = str_data['str'] + except Exception as err: + print_("SwigStringPrinter: Could not access field (struct String).str\n"); + return ""; + + if char_ptr.is_lazy is True: + char_ptr.fetch_lazy () + + try: + ret = char_ptr.string() + except Exception as err: + print_("SwigStringPrinter: Could not convert const char* to string\n"); + return ""; + + return ret + +class SwigIterator: + + def __init__(self): + + self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() + self.t_string_ptr = gdb.lookup_type("String").pointer() + self.t_node_ptr = gdb.lookup_type("Node").pointer() + self.t_hash_ptr = gdb.lookup_type("Hash").pointer() + self.t_file_ptr = gdb.lookup_type("File").pointer() + self.t_void_ptr = gdb.lookup_type("void").pointer() + + def cast_doh(self, doh, name = None): + + if doh == 0: + return doh + + doh = doh.reinterpret_cast(self.t_doh_base_ptr); + + val_base = doh.dereference() + val_type = val_base['type'].dereference() + val_typestr = val_type['objname'].string() + + if not name == None and val_typestr in cast_black_list: + blacklist = cast_black_list[val_typestr] + if name in blacklist: + return doh + + if "String" == val_typestr: + doh = doh.reinterpret_cast(self.t_string_ptr) + elif "File" == val_typestr: + doh = doh.reinterpret_cast(self.t_file_ptr) + # BUG: GDB Pyhton can not handle cyclic references yet + # so these casts are deactivated + elif "Hash" == val_typestr: + doh = doh.reinterpret_cast(self.t_hash_ptr) + elif "Node" == val_typestr: + doh = doh.reinterpret_cast(self.t_node_ptr) + + return doh + +class SwigListIterator(SwigIterator): + + def __init__(self, val): + SwigIterator.__init__(self); + + try: + self.valid = False + + self.val = val.reinterpret_cast(self.t_doh_base_ptr) + val_base = self.val.dereference() + val_type = val_base['type'].dereference() + val_typestr = val_type['objname'].string() + #print_("SwigListIterator: constructing iterator for value of type %s"%val_typestr) + + self.t_struct_list_ptr = gdb.lookup_type("struct List").pointer() + + doh_base = self.val.dereference() + self.l = doh_base['data'].reinterpret_cast(self.t_struct_list_ptr).dereference() + + self.address = 0 + self._index = 0 + self.key = 0 + self.item = 0 + + self.address = self.val.dereference().address + + self.is_first = True + self.valid = True + + except Exception as err: + print_("SwigListIterator: Construction failed.\n %s.\n"%(str(err))) + + def __iter__(self): + return self + + def List_first(self): + + self.object = None; + self._index = 0 + self.key = 0 + self.nitems = int(self.l['nitems']) + self.items = self.l['items'] + + if self.nitems > 0: + self.item = self.items[0] + else: + self.stop() + + def List_next(self): + self._index = self._index + 1 + if self._index >= self.nitems: + self.stop() + else: + self.item = self.items[self._index] + + def next(self): + + if not self.valid: + self.stop() + + if self.is_first: + self.is_first = False + try: + self.List_first() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + else: + try: + self.List_next() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + + key_str = "[%d]"%self._index + item = 0 + + try: + item = self.cast_doh(self.item) + except Exception as err: + print_("SwigListIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) ) + self.stop() + + return (key_str, item) + + def stop(self): + self.is_first = True + self.item = 0 + self.key = 0 + raise StopIteration + +class SwigHashIterator(SwigIterator): + + def __init__(self, val): + SwigIterator.__init__(self); + + try: + self.valid = False + + self.val = val.reinterpret_cast(self.t_doh_base_ptr) + + self.t_struct_hash_ptr = gdb.lookup_type("struct Hash").pointer() + self.t_struct_hash_node_ptr = gdb.lookup_type("struct HashNode").pointer() + + doh_base = self.val.dereference() + hash_ = doh_base['data'].reinterpret_cast(self.t_struct_hash_ptr).dereference() + self.hashtable = hash_['hashtable'] + self.hashsize = int(hash_['hashsize']) + self.nitems = int(hash_['nitems']) + + self.next_ = 0 + self.address = 0 + self.pos = 0; + self._current = 0 + self.item = 0 + self.key = 0 + self._index = 0 + + self.address = self.val.dereference().address + + self.is_first = True + self.valid = True + + except Exception as err: + print_("SwigHashIterator: Construction failed.\n %s.\n"%(str(err))) + + def __iter__(self): + return self + + def Hash_firstiter(self): + self._current = 0; + self.item = 0; + self.key = 0; + self._index = 0; + + while (self._index < self.hashsize) and (self.hashtable[self._index] == 0): + self._index = self._index+1; + + if self._index >= self.hashsize: + self.stop(); + + self._current = self.hashtable[self._index] + self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr); + self.item = self._current['object']; + self.key = self._current['key']; + + self._current = self._current['next']; + + + def Hash_nextiter(self): + if self._current == 0: + self._index = self._index + 1 + while (self._index < self.hashsize) and (self.hashtable[self._index] == 0): + self._index = self._index + 1 + + if self._index >= self.hashsize: + self.item = 0; + self.key = 0; + self._current = 0; + self.stop() + + self._current = self.hashtable[self._index]; + + self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr); + self.key = self._current['key']; + self.item = self._current['object']; + + self._current = self._current['next']; + + + def next(self): + + if not self.valid: + self.stop() + + if self.is_first: + self.is_first = False + try: + self.Hash_firstiter() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + else: + try: + self.Hash_nextiter() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + + key_str = "" + item = 0 + try: + string_printer = SwigStringPrinter("String *", self.key) + key_str = string_printer.to_string() + except Exception as err: + print_("SwigHashIterator(%s): Exception during extracting key string:\n %s\n" % (str(self.address), str(err)) ) + self.stop() + + try: + item = self.cast_doh(self.item, key_str) + + except Exception as err: + print_("SwigHashIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) ) + self.stop() + + return (key_str, item) + + def stop(self): + self.is_first = True + raise StopIteration + +class AlternateKeyValueIterator(): + + def __init__(self, iterable): + self.it = iterable.__iter__() + self._next = None + self.count = -1 + + def __iter__(self): + return self + + def next(self): + if self._next == None: + key, value = self.it.next() + self._next = value + self.count = self.count + 1 + return ("[%d]"%self.count, key) + else: + value = self._next + self._next = None + return ("[%d]"%self.count, value) + +class NopIterator: + + def __init__(self): + pass + + def __iter__(self): + return self + + def next(self): + raise StopIteration + +class SwigListPrinter: + """ + Pretty print Swig List* types (also ParmList*). + """ + + def __init__ (self, typename, val): + + self.typename = typename + self.val = val + + it = SwigListIterator(val) + self.valid = it.valid + self.address = it.address + + + def display_hint(self): + return 'array' + + def to_string(self): + return "%s(%s)" % (str(self.typename), str(self.address)) + + def children(self): + + if not self.valid: + print_("SwigListPrinter: Invalid state.\n") + return NopIterator() + + try: + it = SwigListIterator(self.val) + return it + except Exception as err: + print_("SwigListPrinter: Error during creation of children iterator. \n %s \n" %(str(err))) + raise err + +class SwigHashPrinter: + """ + Pretty print Swig Hash* types (also Node*). + """ + + def __init__ (self, typename, val): + + self.typename = typename + self.val = val + it = SwigHashIterator(val) + self.valid = it.valid + self.address = it.address + self.level = 0; + + def display_hint(self): + return 'map' + + def to_string(self): + return "%s(%s)" % (str(self.typename), str(self.address)) + + def children(self): + global GDB_FLATTENED_CHILDREN_WORKAROUND + global CHILDREN_MAX_RECURSION_LEVEL + + if not self.valid: + print_("SwigHashPrinter: Invalid state.\n") + return NopIterator() + + if self.level > CHILDREN_MAX_RECURSION_LEVEL: + return NopIterator() + + try: + it = SwigHashIterator(self.val) + if GDB_FLATTENED_CHILDREN_WORKAROUND: + return AlternateKeyValueIterator(it) + return it + except Exception as err: + print_("SwigHashPrinter: Error during creation of children iterator. \n %s \n" %(str(err))) + raise err + +class SwigSimplePrinter: + def __init__ (self, typename, val): + self.typename = typename + self.val = val + + def display_hint(self): + return "string" + + def to_string(self): + return "%s(%s)"%(self.typename, str(self.val.address)) + +class SwigDelegatingPrinter: + + def __init__ (self, typename, val): + t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() + val_base = val.reinterpret_cast(t_doh_base_ptr).dereference() + val_type = val_base['type'].dereference() + val_typestr = val_type['objname'].string() + self.has_children = False + + if val_typestr == "Hash": + self.delegate = SwigHashPrinter(typename, val) + self.has_children = True + elif val_typestr == "List": + self.delegate = SwigListPrinter(typename, val) + self.has_children = True + elif val_typestr == "String": + self.delegate = SwigStringPrinter(typename, val) + else: + self.delegate = SwigSimplePrinter(typename, val) + + def display_hint(self): + return self.delegate.display_hint() + + def to_string(self): + return self.delegate.to_string() + + def children(self): + if not self.has_children: + return NopIterator() + + return self.delegate.children() + +class RxPrinter(object): + def __init__(self, name, function): + super(RxPrinter, self).__init__() + self.name = name + self.function = function + self.enabled = True + + def invoke(self, value): + if not self.enabled: + return None + return self.function(self.name, value) + +# A pretty-printer that conforms to the "PrettyPrinter" protocol from +# gdb.printing. It can also be used directly as an old-style printer. +class Printer(object): + def __init__(self, name): + super(Printer, self).__init__() + self.name = name + self.subprinters = [] + self.lookup = {} + self.enabled = True + self.compiled_rx = re.compile('^([a-zA-Z0-9_: *]+)$') + + def add(self, name, function): + if not self.compiled_rx.match(name): + raise ValueError, 'error: "%s" does not match' % name + + printer = RxPrinter(name, function) + self.subprinters.append(printer) + self.lookup[name] = printer + print('Added pretty printer for %s. ' % (name)) + + def __call__(self, val): + typename = str(val.type) + if typename in self.lookup: + ret = self.lookup[typename].invoke(val) + return ret + + # Cannot find a pretty printer. Return None. + return None + +swig_printer = None + +def register_swig_printers(obj): + global swig_printer + + if obj is None: + obj = gdb + + obj.pretty_printers.append(swig_printer) + +def build_swig_printer(): + global swig_printer + + swig_printer = Printer("swig") + swig_printer.add('String *', SwigStringPrinter) + swig_printer.add('const String *', SwigStringPrinter) + swig_printer.add('SwigType *', SwigStringPrinter) + swig_printer.add('Hash *', SwigHashPrinter) + swig_printer.add('const Hash *', SwigHashPrinter) + swig_printer.add('Node *', SwigHashPrinter) + swig_printer.add('const Node *', SwigHashPrinter) + swig_printer.add('Parm *', SwigHashPrinter) + swig_printer.add('const Parm *', SwigHashPrinter) + swig_printer.add('List *', SwigListPrinter) + swig_printer.add('const List *', SwigListPrinter) + swig_printer.add('ParmList *', SwigDelegatingPrinter) + swig_printer.add('const ParmList *', SwigDelegatingPrinter) + swig_printer.add('File *', SwigDelegatingPrinter) + #swig_printer.add('DOH *', SwigDelegatingPrinter) + #swig_printer.add('const DOH *', SwigDelegatingPrinter) + + print_("Loaded swig printers\n"); + +def enableGdbPrintWorkaround(): + global GDB_FLATTENED_CHILDREN_WORKAROUND + GDB_FLATTENED_CHILDREN_WORKAROUND = True + +def setChildrenRecursionLevel(level): + global CHILDREN_MAX_RECURSION_LEVEL + CHILDREN_MAX_RECURSION_LEVEL = level + +build_swig_printer() diff --git a/configure.ac b/configure.ac index f3414969e..1d5d9ace7 100644 --- a/configure.ac +++ b/configure.ac @@ -1087,6 +1087,231 @@ AC_SUBST(JAVALDSHARED) AC_SUBST(JAVACXXSHARED) AC_SUBST(JAVACFLAGS) +#---------------------------------------------------------------- +# Look for JAVASCRIPT +#---------------------------------------------------------------- +AC_ARG_WITH(javascript, AS_HELP_STRING([--without-javascript], [Disable JAVASCRIPT]), [with_javascript="$withval"], [with_javascript=yes]) + +# First, check for "--without-javascript" or "--with-javascript=no". +if test x"${with_javascript}" = xno -o x"${with_alllang}" = xno ; then + AC_MSG_NOTICE([Disabling Javascript]) + JAVASCRIPT= +else + JAVASCRIPT=1 + + #---------------------------------------------------------------- + # General Javascript settings shared by JSC and V8 + #---------------------------------------------------------------- + + case $host in + *-*-cygwin* | *-*-mingw*) + JSLIBRARYPREFIX="" + ;; + *) + JSLIBRARYPREFIX="lib" + ;; + esac + + case $host in + *-*-darwin*) + JSSO=".dylib" + JSLDSHARED='$(CC) -dynamiclib' + JSCXXSHARED='$(CXX) -dynamiclib' + # HACK: didn't manage to get dynamic module loading working with a g++ compiled interpreter + JSINTERPRETERCXX='c++' + JSINTERPRETERLINKFLAGS='-g -Wl,-search_paths_first -Wl,-headerpad_max_install_names' + ;; + *) + JSSO=$SO + JSLDSHARED='$(LDSHARED)' + JSCXXSHARED='$(CXXSHARED)' + JSINTERPRETERCXX='$(CXX)' + JSINTERPRETERLINKFLAGS='-ldl' + ;; + esac + + #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Look for Node.js which is the default javascript engine + # without it, the javascript test-suite will be skipped + #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AC_CHECK_PROGS(NODEJS, node) + + #---------------------------------------------------------------- + # Look for JavascriptCore (Webkit) settings (JSCOREINCDIR, JSCOREDYNAMICLINKING) + #---------------------------------------------------------------- + + # check for include files + AC_MSG_CHECKING(for include file JavaScriptCore/JavaScript.h) + AC_ARG_WITH(jscoreinc, [ --with-jscinc=path Set location of Javascript include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=]) + + if test -z "$JSCOREINCDIR"; then + JSCOREINCDIR="/usr/include/ /usr/local/include/" + + # Add in default directory for JavaScriptCore headers for Linux and MacOSX + case $host in + *-*-linux*) + JSCOREINCDIR="/usr/include/webkit-1.0/ /usr/include/webkitgtk-1.0/ /usr/local/include/webkit-1.0/JavaScriptCore/ $JSCOREINCDIR" + ;; + *-*-darwin*) + JSCOREINCDIR="/System/Library/Frameworks/JavaScriptCore.framework/Headers/ $JSCOREINCDIR" + ;; + *) + ;; + esac + fi + + for d in $JSCOREINCDIR ; do + if test -r "$d/JavaScriptCore/JavaScript.h" || test -r "$d/JavaScript.h" ; then + AC_MSG_RESULT($d) + JSCOREINCDIR=$d + JSCOREINC=-I\"$d\" + break + fi + done + + if test "$JSCOREINC" = "" ; then + AC_MSG_RESULT(not found) + fi + + # check for JavaScriptCore/Webkit libraries + AC_ARG_WITH(jscorelib,[ --with-jsclib =path Set location of the JavaScriptCore/Webkit library directory],[JSCORELIB="-L$withval"], [JSCORELIB=]) + AC_MSG_CHECKING(for JavaScriptCore/Webkit library) + + # look for the library when not provided + if test -z "$JSCORELIB"; then + case $host in + *-*-linux*) + dirs="/usr/lib/ /usr/local/lib/" + for i in $dirs ; do + if test -r $i/libjavascriptcoregtk-1.0.so; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -ljavascriptcoregtk-1.0" + break + fi + + if test -r $i/libwebkitgtk-1.0.so; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkitgtk-1.0" + break + fi + + if test -r $i/libwebkit-1.0.la; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkit-1.0" + break + fi + done + + if test -z "$JSCORELIB"; then + AC_MSG_RESULT(not found) + JSCENABLED=0 + else + JSCOREDYNAMICLINKING="$JSCORELIB" + JSCENABLED=1 + fi + ;; + *-*-darwin*) + JSCOREDYNAMICLINKING="-framework JavaScriptCore" + JSCENABLED=1 + ;; + *) + ;; + esac + fi + + #---------------------------------------------------------------- + # Look for V8 settings (JSV8INCDIR, JSV8DYNAMICLINKING) + #---------------------------------------------------------------- + + # check for include files + AC_MSG_CHECKING(for include file v8.h) + AC_ARG_WITH(jsv8inc, [ --with-v8inc=path Set location of Javascript include directory], [JSV8INCDIR="$withval"]) + + # if not include dir is specified we try to find + if test -z "$JSV8INCDIR"; then + # Add in default directory for JavaScriptCore headers for Linux and MacOSX + case $host in + *-*-linux*) + JSV8INCDIR="/usr/include /usr/local/include/ $JSV8INCDIR" + ;; + *-*-darwin*) + JSV8INCDIR="$JSV8INCDIR" + ;; + *) + ;; + esac + fi + + for d in $JSV8INCDIR ; do + if test -r "$d/v8.h" ; then + JSV8INCDIR=$d + JSV8INC=-I\"$d\" + break + fi + done + + if test "$JSV8INC" = "" ; then + AC_MSG_RESULT(not found) + else + AC_MSG_RESULT($JSV8INCDIR) + fi + + # check for V8 library + AC_MSG_CHECKING(for v8 library) + AC_ARG_WITH(jsv8lib,[ --with-v8lib=path Set location of V8 library directory],[JSV8LIBDIR="$withval"], [JSV8LIB=]) + + v8libdirs="$JSV8LIBDIR /usr/lib/ /usr/local/lib/" + for d in $v8libdirs ; do + if test -r $d/libv8.so; then + JSV8LIBDIR=$d + JSV8LIB="-L$d -lv8" + break + fi + done + + if test "$JSV8LIB" = "" ; then + AC_MSG_RESULT(not found) + JSV8ENABLED=0 + else + AC_MSG_RESULT($JSV8LIBDIR) + JSV8ENABLED=1 + fi + + + # linking options + case $host in + *-*-darwin*) + JSV8DYNAMICLINKING="" # TODO: add osx configuration + ;; + *-*-linux*) + JSV8DYNAMICLINKING="$JSV8LIB" + ;; + *) + JSV8DYNAMICLINKING="" + ;; + esac + +fi + +AC_SUBST(JSCFLAGS) +AC_SUBST(JSCXXFLAGS) +AC_SUBST(JSLIBRARYPREFIX) +AC_SUBST(JSSO) +AC_SUBST(JSLDSHARED) +AC_SUBST(JSCXXSHARED) + +AC_SUBST(JSINTERPRETERCXX) +AC_SUBST(JSINTERPRETERLINKFLAGS) + +AC_SUBST(JSCOREINC) +AC_SUBST(JSCOREDYNAMICLINKING) +AC_SUBST(JSV8INC) +AC_SUBST(JSV8DYNAMICLINKING) + +AC_SUBST(JSCENABLED) +AC_SUBST(JSV8ENABLED) + #---------------------------------------------------------------- # Look for gcj #---------------------------------------------------------------- @@ -2238,6 +2463,11 @@ if test -z "$JAVA" || test -z "$JAVAC" || test -z "$JAVAINC" ; then fi AC_SUBST(SKIP_JAVA) +SKIP_JAVASCRIPT= +if test -z "$JAVASCRIPT" || test -z "$NODEJS"; then + SKIP_JAVASCRIPT="1" +fi +AC_SUBST(SKIP_JAVASCRIPT) SKIP_GUILE= if test -z "$GUILE" || test -z "$GUILE_LIBS" ; then @@ -2421,6 +2651,8 @@ AC_CONFIG_FILES([ Examples/test-suite/d/Makefile Examples/test-suite/guile/Makefile Examples/test-suite/java/Makefile + Examples/test-suite/javascript/Makefile + Tools/javascript/Makefile Examples/test-suite/mzscheme/Makefile Examples/test-suite/ocaml/Makefile Examples/test-suite/octave/Makefile diff --git a/swig-v8/swig-v8.xcodeproj/project.pbxproj b/swig-v8/swig-v8.xcodeproj/project.pbxproj new file mode 100644 index 000000000..d6fcad63b --- /dev/null +++ b/swig-v8/swig-v8.xcodeproj/project.pbxproj @@ -0,0 +1,153 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXGroup section */ + A7E4F27918BDF64900ED77C7 = { + isa = PBXGroup; + children = ( + ); + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + A7E4F28018BDF64900ED77C7 /* swig-v8 */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = A7E4F28318BDF64900ED77C7 /* Build configuration list for PBXLegacyTarget "swig-v8" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + dependencies = ( + ); + name = "swig-v8"; + passBuildSettingsInEnvironment = 1; + productName = "swig-v8"; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + A7E4F27B18BDF64900ED77C7 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0450; + ORGANIZATIONNAME = "Oliver Buchtala"; + }; + buildConfigurationList = A7E4F27E18BDF64900ED77C7 /* Build configuration list for PBXProject "swig-v8" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = A7E4F27918BDF64900ED77C7; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A7E4F28018BDF64900ED77C7 /* swig-v8 */, + ); + }; +/* End PBXProject section */ + +/* Begin XCBuildConfiguration section */ + A7E4F28118BDF64900ED77C7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + A7E4F28218BDF64900ED77C7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + SDKROOT = macosx; + }; + name = Release; + }; + A7E4F28418BDF64900ED77C7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUGGING_SYMBOLS = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + A7E4F28518BDF64900ED77C7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A7E4F27E18BDF64900ED77C7 /* Build configuration list for PBXProject "swig-v8" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A7E4F28118BDF64900ED77C7 /* Debug */, + A7E4F28218BDF64900ED77C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A7E4F28318BDF64900ED77C7 /* Build configuration list for PBXLegacyTarget "swig-v8" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A7E4F28418BDF64900ED77C7 /* Debug */, + A7E4F28518BDF64900ED77C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = A7E4F27B18BDF64900ED77C7 /* Project object */; +}