spiderape-devel Mailing List for SpiderApe: Beefing up SpiderMonkey
Status: Beta
Brought to you by:
sgbeal
You can subscribe to this list here.
| 2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(2) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2006 |
Jan
(50) |
Feb
(6) |
Mar
(34) |
Apr
(7) |
May
(1) |
Jun
(1) |
Jul
(2) |
Aug
(18) |
Sep
|
Oct
(1) |
Nov
(5) |
Dec
|
| 2007 |
Jan
(4) |
Feb
(40) |
Mar
(2) |
Apr
|
May
|
Jun
(2) |
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
(1) |
| 2013 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
(1) |
Jul
(4) |
Aug
(4) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(1) |
| 2014 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <po...@sb...> - 2015-07-22 17:24:47
|
Be excited for my updated stock that will multiply 547%! This is the best timing for Blue Water Petroleum because the short trades now have to be covered! Todays update: Blue Water amplifies its newest technology. Strength Signal display B WP_C is oversold, this can stir a massive spike on Monday. Continue buying immediately!!! |
|
From: <7ef...@tm...> - 2015-07-22 16:23:43
|
Tanaris Power Inc (TPH_X) will empower 1.2 billion of phones! TPH_X could be the new Lenovo! They have announced the ultimate highest baterries!!! Big pr live: Tanaris Power, Inc acquires 9 lithium ownerships in Quebec, Canada!!! Get TPH_X Monday, Jul 20th, 2015 prior it developes into Lenovo. |
|
From: Stephan B. <st...@s1...> - 2007-12-04 08:15:08
|
On Dec 4, 2007 2:22 AM, Elton Lum <elt...@ya...> wrote: > Spiderape, and have begun adding it into my C++ app, however, I am being > asked to build a JS engine. I am a bit confused on this part. Isn't the JS > engine provided by the browser? If so, why do I need to build a JS > engine...like the one provided by SpiderMonkey? Hi, Elton! SpiderApe is just a wrapper around a *specific* JS Engine, namely SpiderMonkey. The engine built into MSIE is completely different (i'm not even sure if it has a public AP,I, as i don't use Windows). If you're programming for your browser then SpiderApe is not what you need because it cannot integrate with a specific browser's JS engine. Even for a browser which uses SpiderMonkey internally (e.g. Mozilla), SpiderApe cannot integrate directly with it. :( SpiderApe is intended for those rare other applications which embed JS but are *not* a browser. A more popular choice for such embedding nowadays is Python, but i have strong philosophical differences with Python's fundamentals and refuse to use it. :) -- ----- stephan beal http://wanderinghorse.net/home/stephan/ |
|
From: Stephan B. <st...@s1...> - 2007-09-26 06:07:11
|
Hiya! It's been a long time since i've read my list mails or posted to a list... Here's a status update: a) My cancer is theoretically gone, but i still make occasional visits to the clinic for a checkup and get twice-weekly infusions to help build up my (relatively weak) immune system. b) i released a new Ape last night. It's got only a few relatively minor changes from previous versions. Mostly it was released for the new ape::js_simple_object class, which simplifies some of my plugin code considerably. c) Last weekend i got a copy of the recent book "Programmer's Guide to nCurses", and that inspired me to revisit the ncurses plugin. So i've been hacking on the ncurses plugin considerably the past day or two, re-implementing the older OO layer on top of the newer (low-level) API. d) i don't have any drastic immediate plans for Ape. It does all that i want it to do, actually. i would like to go back through it and clean up the MonkeyWrapper internals and the Class<> code a bit, but those things are fairly low priority. MonkeyWrapper wasn't initially designed for subclassing, and that was added later, but subclassing still requires some intimate knowledge of the class internals. The Class<> code is amazing (thanks again, Jaap!), and works like a charm, but the code is a bit hard to follow and still lacks built-in support for subclassing custom classes, so i'd like to try to get that working eventually (i could really use it in some up-coming ncurses code). That's about it... :) -- ----- stephan beal http://wanderinghorse.net/home/stephan/ http://s11n.net/home/stephan/ |
|
From: Stephan B. <st...@s1...> - 2007-07-11 20:08:32
|
Hiya! The author of the awesome jQuery framework (http://jquery.com) has=20 written an emulated Document environment: http://ejohn.org/blog/bringing-the-browser-to-the-server/ i don't yet know if it'll work with SpiderMonkey, but it works with=20 Rhino (essentially the Java implementation of SpiderMonkey), so it=20 sounds hopeful. =2D-=20 =2D---- stephan beal http://s11n.net/home/stephan/ |
|
From: Stephan B. <st...@s1...> - 2007-06-28 23:47:59
|
=46YI: The source trees have been imported into Subversion, and future=20 development will take place there: Main tree: svn co https://spiderape.svn.sourceforge.net/svnroot/spiderape/trunk=20 Plugins: svn co https://spiderape.svn.sourceforge.net/svnroot/spiderape/plugins =2D-=20 =2D---- stephan beal http://s11n.net/home/stephan/ |
|
From: Stephan B. <st...@s1...> - 2007-06-20 14:59:37
|
Hi, all! After many months of not reading emails at all, i'm finally getting=20 re-involved in my online life. The SpiderApe code has gone untouched since late last year, and i don't=20 currently have any amazing ideas for changes. i will, at some point=20 soon, port the source tree to Subversion, but other than that it's=20 likely to stay static while i play catch-up on other projects. :) =2D-=20 =2D---- stephan beal http://s11n.net/home/stephan/ |
|
From: Jaap de W. <wo...@ne...> - 2007-03-05 08:48:42
|
> -----Original Message-----
> From: spi...@li...
> [mailto:spi...@li...] On
> Behalf Of stephan beal
> Sent: zondag 4 maart 2007 12:45
> To: spi...@li...
> Subject: Re: [Spiderape-devel] Multithreading and ape::bind functions.
>
>
> Hi, Jaap! Sorry for the delay. i was in Munich for a few days.
>
> On Wednesday 28 February 2007 16:36, Jaap de Wolff wrote:
> > This problem can be solved in two ways:
> > Make a lock mechanism in functions which use those classes
> (ThreadLock
> > will do the job, if you have an context pointer) (this is
> the way I am
> > solving it at this moment.)
>
> This would be my preference, i think.
>
Ok, if you want this, you have to do it yourself, in each member
function.
One of the disadvantages of this way, is that you need to use one
synchronisation object
for all the bind functions, which means there can never be two thread
using any bind function at the same time.
> > The other (more clean) way is to make a wrapper around the std:map,
> > which puts a lock around all access.
>
> That sounds like a lot more work. i can't think of a strong argument
> against this approach, though. Instead of a 1-to-1 wrapper, we could
> implement the locker as a policy class and use that policy class as a
> parameter for the map type:
>
> template <typename KeyT, typename ValT, typename LockerT>
> class locked_map
> {
> typedef std::map<KeyT,ValT> map_type;
> ... wrap map_type API and ...
> ... use LockerT to do the read/write locks ...
> };
>
> i think we could(?) use the same locker type for reads and writes.
Yes, we could, but the disadvantage is that this allows less access. I
think when we use a policy class, we can implement the locker class in
such a way that we make the prototype for both read and write, but at
first implement them the same way.
Then the generic Locker class would be something like:
class generic_locker
{
public:
typedef MySyncObject LockType;
generic_locker(LockType *lock, bool readonly):m_Lock(lock)
{
if (readonly)
{
ReadLock(m_Lock);
}
else
{
WriteLock(m_Lock);
}
}
~generic_locker()
{
Unlock(m_Lock);
}
static LockType *CreateSyncObject()
{
// implement
}
static RemoveSyncObject(LockType *lock)
{
// implement
}
private:
LockType *m_Lock;
.. Implement ReadLock(), WriteLock() and Unlock()
}
>
> Just coincidentally... about 10 days ago i wrote some mutex code for
> another project which i was planning on porting into Ape at
> some point.
> It simplifies the locking API and allows several different back-ends
> (currently pthreads, Win32 critical sections, or no locking). An
> example:
>
> struct foo {
> ...
>
> void lockedFunc() {
> mutex_sentry locker(this->mu);
> ... do something ...
> }
> mutex mu;
> };
>
> The lock is held through an instance of the mutex class, so
> we can have
> shared mutexes via functions:
>
> mutex & sharedMutex() {
> static mutex bob;
> return bob;
> }
>
> Using a shared mutex allows us to implement class-level locks, for
> example.
>
>
> --
> ----- stephan beal
> http://s11n.net/home/stephan/
> "Attention is narrowed perception." -- Alan W. Watts
>
|
|
From: stephan b. <st...@s1...> - 2007-03-04 11:49:22
|
Hi, Jaap! Sorry for the delay. i was in Munich for a few days.
On Wednesday 28 February 2007 16:36, Jaap de Wolff wrote:
> This problem can be solved in two ways:
> Make a lock mechanism in functions which use those classes
> (ThreadLock will do the job, if you have an context pointer)
> (this is the way I am solving it at this moment.)
This would be my preference, i think.
> The other (more clean) way is to make a wrapper around the std:map,
> which puts a lock around all access.
That sounds like a lot more work. i can't think of a strong argument=20
against this approach, though. Instead of a 1-to-1 wrapper, we could=20
implement the locker as a policy class and use that policy class as a=20
parameter for the map type:
template <typename KeyT, typename ValT, typename LockerT>
class locked_map
{
typedef std::map<KeyT,ValT> map_type;
... wrap map_type API and ...
... use LockerT to do the read/write locks ...
};
i think we could(?) use the same locker type for reads and writes.
Just coincidentally... about 10 days ago i wrote some mutex code for=20
another project which i was planning on porting into Ape at some point.=20
It simplifies the locking API and allows several different back-ends=20
(currently pthreads, Win32 critical sections, or no locking). An=20
example:
struct foo {
...
void lockedFunc() {
mutex_sentry locker(this->mu);
... do something ...
}
mutex mu;
};
The lock is held through an instance of the mutex class, so we can have=20
shared mutexes via functions:
mutex & sharedMutex() {
static mutex bob;
return bob;
}
Using a shared mutex allows us to implement class-level locks, for=20
example.
=2D-=20
=2D---- stephan beal
http://s11n.net/home/stephan/
"Attention is narrowed perception." -- Alan W. Watts
|
|
From: Jaap de W. <wo...@ne...> - 2007-02-28 15:40:26
|
Hello,
When using multithreading you have to be aware of the fact that the
std::map template is not designed for direct multithreading use.
This means that if in one thread a find() function is called, while in
another thread an erase() function is called, a deadlock situation CAN
occur.
As a result destroying an ape context, can result in a deadlock
situation if at the same time a function from the bind class is called
(eg get_object_by_string, unbind_object_from_string,
bind_object_to_string, get_jsval, get_native).
This means that someone who wants to use multithreading also must be
aware of this problem.
This problem can be solved in two ways:
Make a lock mechanism in functions which use those classes (ThreadLock
will do the job, if you have an context pointer)
(this is the way I am solving it at this moment.)
The other (more clean) way is to make a wrapper around the std:map,
which puts a lock around all access.
It should be like this:
ThreadMap<Key, Value>
{
typedef ThreadMap<Key, Value> _Myt;
typedef std::map<Key, Value> _Mybase;
typedef Key key_type;
typedef Value mapped_type;
typedef typename _Mybase::value_compare value_compare;
typedef typename _Mybase::allocator_type allocator_type;
typedef typename _Mybase::size_type size_type;
typedef typename _Mybase::difference_type difference_type;
typedef typename _Mybase::pointer pointer;
typedef typename _Mybase::const_pointer const_pointer;
typedef typename _Mybase::reference reference;
typedef typename _Mybase::const_reference const_reference;
typedef typename _Mybase::iterator iterator;
typedef typename _Mybase::const_iterator const_iterator;
typedef typename _Mybase::reverse_iterator reverse_iterator;
typedef typename _Mybase::const_reverse_iterator
const_reverse_iterator;
typedef typename _Mybase::value_type value_type;
SyncObject m_Sync;
std::map theMap;
void erase(iterator _Where)
{
WriteLock wl(m_Sync);
_Mybase::erase(_Where);
}
iterator find(key_type)
{
ReadLock rl(m_Sync);
return _Mybase::find(_Where); }
}
etc...
};
Jaap
|
|
From: stephan b. <st...@s1...> - 2007-02-25 19:11:26
|
On Sunday 25 February 2007 19:14, Jaap de Wolff wrote: > This opens a lot of possibilities for me! =46or me, too :). Now that i've got plugins for sqlite3 and XML, the only=20 significant features which are missing are networking and threading=20 (but threading is first necessary in order to make networking=20 possible). With those features in place, the power of javascript jumps=20 considerably. > Within a few months I have to do some SOAP interaction from within > SpiderApe, and as SOAP is just XML over IP, I will be able to > implement it almost only at script site! :) > Is there no code change required at the ape site for using 1.6? i didn't have to make any changes to Ape at all. i DID have to patch one=20 of the JS sources by adding the word 'throw()', but that just avoided a=20 compiler WARNING (not an error). Since i always compile with -Wall=20 and -Werror, that was killing my builds. > That would be very nice! The code in CVS right now seems to work fine with JS 1.6. i think you're=20 working from an older codebase, but if so i think it will still work=20 with JS 1.6. i think JS 1.6 is mostly internal changes, like the=20 support for inlined XML elements. The API seems to be mostly the same. PS: the only halfway comprehensive API docs i've found for E4X are=20 available in PDF here: http://www.ecma-international.org/publications/standards/Ecma-357.htm but achtung: the page numbers in that document's index are incorrect,=20 which makes it harder to find what you're looking for. =2D-=20 =2D---- stephan beal http://s11n.net/home/stephan/ "Attention is narrowed perception." -- Alan W. Watts |
|
From: stephan b. <st...@s1...> - 2007-02-25 19:00:20
|
On Sunday 25 February 2007 19:08, you wrote: > Yes it could, but when it takes approx. 300 times to get the fault > once, it will take about 90.000 times to get them two at a row. > But in fact sometimes we have to investigate why this error is > happening at all. Weird. i can't say much about that right now. > At this very moment I did see, that my script has started > 4000 > times, (with my own multithreading system) > and still not using much more handles and memory as at startup > Friday.=20 =3DD > That was a issue for me a year ago. Tommorow I will check if=20 > I can start 100 contextes at the same time, and then remove one while > running another. 100 contexts!!! Man, i can't imagine using more than 5. > (Of course when there are now new burning problems=20 > which preevnt me from doing this work) :( > When I have done that, I will commit those changes. :) > But about the global 'SpiderApe' object, I think you better > investigate yourself what exactly is going wrong. i'm considering removing that object. It's an undocumented=20 object/feature which stores all of the Ape-provided builtin functions=20 as members of the SpiderApe object. i've never actually used that=20 object in any code. My parents are visiting for the next 8 or 9 days or so, and we will=20 travel to Munich Tuesday-Saturday, so i'll be completely offline and=20 not hacking during that time. After they leave i'll be back to coding. Thanks for your continued help on the threading stuff! =2D-=20 =2D---- stephan beal http://s11n.net/home/stephan/ "Attention is narrowed perception." -- Alan W. Watts |
|
From: Jaap de W. <wo...@ne...> - 2007-02-25 18:18:42
|
This opens a lot of possibilities for me! Within a few months I have to do some SOAP interaction from within SpiderApe, and as SOAP is just XML over IP, I will be able to implement it almost only at script site! Is there no code change required at the ape site for using 1.6? That would be very nice! Jaap |
|
From: Jaap de W. <wo...@ne...> - 2007-02-25 18:13:01
|
> -----Original Message----- > From: spi...@li... > [mailto:spi...@li...] On > Behalf Of stephan beal > Sent: vrijdag 23 februari 2007 17:27 > To: spi...@li... > Subject: Re: [Spiderape-devel] Threading problems almost solved > > > On Friday 23 February 2007 16:20, Jaap de Wolff wrote: > > First thread_lock.hpp was different on what it needed to be: It was > > #if ! defined(JS_THREADSAFE) > > #define APE_CTX_LOCK(a) ape::ThreadLock tl(a) > > #define APE_CTX_UNLOCK(a) ape::ThreadUnlock tl(a) > > Ooops. That was certainly my fault. > > > That means that if the macro was used for thread locking, > it does not > > work at all! > > /me smacks his head. Yes, you certainly should ;) > > But FYI: the macro is no longer necessary because ThreadLock is now > available for single-threaded code (but does nothing). You are right, but all tests I told you to do where depending on the macro, so maybe thats the most important thing things are not going well. > But that catch might throw again. Why do you want/need to try > multiple > times here? Yes it could, but when it takes approx. 300 times to get the fault once, it will take about 90.000 times to get them two at a row. But in fact sometimes we have to investigate why this error is happening at all. > > > (btw I am not going to check in those modifications right > now, because > > I changed a lot more, which didn't influence the behaviour. > Right now > > I am going to check wether my main app can work which the modified > > MonkeyWrapper destructor, when starting threads during the whole > > weekend) > > Please commit the changes once you're happy with them! :) > At this very moment I did see, that my script has started > 4000 times, (with my own multithreading system) and still not using much more handles and memory as at startup Friday. That was a issue for me a year ago. Tommorow I will check if I can start 100 contextes at the same time, and then remove one while running another. (Of course when there are now new burning problems which preevnt me from doing this work) When I have done that, I will commit those changes. But about the global 'SpiderApe' object, I think you better investigate yourself what exactly is going wrong. Jaap |
|
From: stephan b. <st...@s1...> - 2007-02-23 19:32:34
|
i didn't realize that E4X integrates XML directly into the language,=20
including a new syntax for defining XML objects.
As a simple demonstration of how to use E4X, here's a function for the=20
SQLite3 plugin which queries a DB and returns the results as XML:
/************************************************************************
sqlite3_select_xml(dbh,sql)
Executes SQL code and collects the results as an XML object tree.
Requires that dbh is an sqlite3 db handle and that sql is an SQL
query.
If sqlite3_prepare(dbh,sql) fails then null is returned, otherwise
this function returns an XML tree with the following structure:
<root>
<sql>SQL CODE</sql>
<columns>
<col>COL_1</col>
<col>COL_N</col>
</columns>
<rows>
<row>
<field>VALUE_1</field>
<field>VALUE_N</field>
</row>
</rows>
</root>
The row.field elements will be in the same order as the columns.col
elements, for purposes of looping over them.
************************************************************************/
function sqlite3_select_xml( dbh, sql ) {
var sth =3D sqlite3_prepare( dbh, sql );
if( ! sth ) {
return null;
}
var colcount =3D sqlite3_column_count( sth );
var cols =3D [];
var xml =3D <root></root>;
var csql =3D <sql>{sql}</sql>;
xml.appendChild( csql );
var colsXML =3D <columns></columns>;
xml.appendChild( colsXML );
for( var i =3D 0; i < colcount; ++i )
{
var cn =3D sqlite3_column_name( sth, i );
cols[i] =3D cn;
colsXML.appendChild( <col>{cn}</col> );
//colsXML.appendChild( <{cn}>{cn}</{cn}> );
=09
}
var results =3D <rows></rows>;
xml.appendChild( results );
var rowcount =3D 0;
while( SQLITE_ROW =3D=3D sqlite3_step( sth ) )
{
++rowcount;
var row =3D <row></row>;
results.appendChild( row );
for( var c =3D 0; c < colcount; ++c ) {
row.appendChild( <field>{sqlite3_column_text( sth, c )}</field> );
}
}
xml.appendChild( <rowcount>{rowcount}</rowcount> );
sqlite3_finalize(sth);
return xml;
} // end of sqlite3_select_xml()
//-------------------------------------------------------
App =3D {};
App.dbn =3D ":memory:";
App.dbh =3D sqlite3_open( App.dbn );
assert( App.dbh );
sqlite3_exec( App.dbh, "create table if not exists t(a,b)" );
sqlite3_exec( App.dbh, "create table if not exists xx(a,b)" );
sqlite3_exec( App.dbh, "create table if not exists yy(a,b)" );
var xml =3D sqlite3_select_xml( App.dbh,
//"select rowid || name as KEY from sqlite_master"
"select rowid,* from sqlite_master where rootpage>=3D0"
);
sqlite3_close( App.dbh );
App.dbh =3D null;
// print('xml =3D=3D\n'+xml.toString());
var res =3D xml.rows;
var rows =3D res.elements('row');
var cols =3D xml.columns.elements();
var spacer=20
=3D '=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D';
print(spacer);
{ // print column headers
var buf =3D '';
for( var cn in cols ) {
buf +=3D cols[cn]+'\t';
}
print(buf);
}
print(spacer);
for( var i =3D 0; i < rows.length(); ++i )
{ // print values
var CH =3D rows[i];
var buf =3D '';
var f =3D CH.elements('field');
for( var cn in cols ) {
buf +=3D f[cn]+'\t';
}
print(buf);
}
print(spacer);
print(rows.length(),'row(s) returned.');
//-------------------------------------------------------
stephan@owl:~/cvs/ApePlugins/SQLite3> SpiderApe xml.js
Using sqlite3 version 3.3.13
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
rowid type name tbl_name rootpage sql
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
1 table t t 2 CREATE TABLE t(a,b)
2 table xx xx 3 CREATE TABLE xx(a,b)
3 table yy yy 4 CREATE TABLE yy(a,b)
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
3 row(s) returned.
The only place i found the API documented as in the ECMA E4X standard:
http://www.ecma-international.org/publications/standards/Ecma-357.htm
=2D-=20
=2D---- stephan beal
http://s11n.net/home/stephan/
"Attention is narrowed perception." -- Alan W. Watts
|
|
From: stephan b. <st...@s1...> - 2007-02-23 17:12:50
|
With JS 1.6 we get E4x. This is a useless example, but an example=20
nonetheless:
//--------------------------
var data =3D "<root><item><name>Bill for=20
short</name></item><item><name>Number Two</name></item></root>";
var xm =3D new XML(data);
assert(xm);
xm.appendChild( new XML("<another>another item</another>") );
for( var ch in xm.elements() ) {
var CH =3D xm.elements()[ch];
print( typeof ch, typeof CH, 'text() =3D=3D',CH.text() );
}
print("xm =3D=3D",xm);
print("Done!");
//--------------------------
stephan@owl:~/> SpiderApe ~/tmp/xml.js; echo $?
string xml text() =3D=3D
string xml text() =3D=3D
string xml text() =3D=3D another item
xm =3D=3D <root>
<item>
<name>Bill for short</name>
</item>
<item>
<name>Number Two</name>
</item>
<another>another item</another>
</root>
Done!
0
=2D-=20
=2D---- stephan beal
http://s11n.net/home/stephan/
"Attention is narrowed perception." -- Alan W. Watts
|
|
From: stephan b. <st...@s1...> - 2007-02-23 16:52:18
|
Hiya, i'm working on integrating the JS 1.6 code, but when compiling Ape=20 against it i get an evil warning: g++ -pipe -Wall -Werror -Wall -Werror -g -DDEBUG -D_DEBUG -fPIC -I../../i= nclude -I. -I../../src/js -I../../src/js/Linux_All_OPT.OBJ -I/home/stephan= /include -I/home/stephan/nspr/include/nspr -c -o=20 ape.o ape.cpp cc1plus: warnings being treated as errors =2E./../src/js/jscntxt.h: In static member function =E2=80=98static void*=20 JSAutoTempValueRooter::operator new(size_t)=E2=80=99: =2E./../src/js/jscntxt.h:617: warning: =E2=80=98operator new=E2=80=99 must = not return NULL=20 unless it is declared =E2=80=98throw()=E2=80=99 (or -fcheck-new is in effec= t) i don't really like the idea of adding -fcheck-new to the linker flags.=20 i hacked jscntxt.h to add 'throw()', and now the warning is gone. i will commit JS 1.6 in a little while. =2D-=20 =2D---- stephan beal http://s11n.net/home/stephan/ "Attention is narrowed perception." -- Alan W. Watts |
|
From: stephan b. <st...@s1...> - 2007-02-23 16:30:15
|
On Friday 23 February 2007 16:20, Jaap de Wolff wrote:
> First thread_lock.hpp was different on what it needed to be:
> It was
> #if ! defined(JS_THREADSAFE)
> #define APE_CTX_LOCK(a) ape::ThreadLock tl(a)
> #define APE_CTX_UNLOCK(a) ape::ThreadUnlock tl(a)
Ooops. That was certainly my fault.
> That means that if the macro was used for thread locking, it does not
> work at all!
/me smacks his head.
But FYI: the macro is no longer necessary because ThreadLock is now=20
available for single-threaded code (but does nothing).
> Second I also got your 'bind_object_to_string' problem when starting
> a new context,
> but that was because the class was defined twice:
> After removing
>
> ::ape::standard_class_initializers().push_back(
> :: JSThread::init_context
Ah, right!!! Doh!
> There was only one problem: I got a problem after 54 loops of
> creating 5 threads, etc. It did call (internally) the GC.
> At that moment it tried to destruct a previous created JSThread
> object (which is correct), but during the destruction of the
> "SpiderApe" object it did crash! Because the SpiderApe object is
> supposed to be a global object, it should not be removed.
Weird.
> When I removed SpiderApe::init_js_class() from
> standard_js_functions_initializer this problem was also fixed.
> Now there is still a locking problem which has to be in nspr.
>
> I rewrote the test script, in such a way threads are not using the
> vars of another thread
> (not sure I need to, but this way I am sure that doesn't influence my
> test):
Ah, thanks :).
<big snip>
> Everything works fine, except that I get about once in 300 started
> threads the famous error:
> bind_object_to_string(----): key is already bound to an object!
300 threads is wayyyyyy more than i plan on using at one time! i=20
currently have use for no more than 2 or 3 threads.
> When I also place in the JSThread constructor
> try
> {
> this->m_th =3D new JSThreadImpl( cx, obj,
> static_cast<thread::Mode>(m) );
> }
> catch(...)
> {
> this->m_th =3D new JSThreadImpl( cx, obj,
> static_cast<thread::Mode>(m) );
> }
> Threads stay going forever
But that catch might throw again. Why do you want/need to try multiple=20
times here?
> (btw I am not going to check in those modifications right now,
> because I changed a lot more, which didn't influence the behaviour.
> Right now I am going to check wether my main app can work which the
> modified MonkeyWrapper destructor, when starting threads during the
> whole weekend)
Please commit the changes once you're happy with them! :)
=2D-=20
=2D---- stephan beal
http://s11n.net/home/stephan/
"Attention is narrowed perception." -- Alan W. Watts
|
|
From: Jaap de W. <wo...@ne...> - 2007-02-23 15:24:15
|
I also tried to use your thread.cpp.
I did make a test project, where I included it, and most things are
working fine:
There where some problems at first, which maybe explain a lot of your
problems.
First thread_lock.hpp was different on what it needed to be:
It was
#if ! defined(JS_THREADSAFE)
#define APE_CTX_LOCK(a) ape::ThreadLock tl(a)
#define APE_CTX_UNLOCK(a) ape::ThreadUnlock tl(a)
#else
#define APE_CTX_LOCK(a)
#define APE_CTX_UNLOCK(a)
#endif
And it should be
#if defined(JS_THREADSAFE)
#define APE_CTX_LOCK(a) ape::ThreadLock tl(a)
#define APE_CTX_UNLOCK(a) ape::ThreadUnlock tl(a)
#else
#define APE_CTX_LOCK(a)
#define APE_CTX_UNLOCK(a)
#endif
That means that if the macro was used for thread locking, it does not
work at all!
Second I also got your 'bind_object_to_string' problem when starting a
new context,
but that was because the class was defined twice:
After removing
::ape::standard_class_initializers().push_back( JSThread::init_context
);,
And only calling
::ape::JSThread::init_js_class();
once.
With defining init_js_class(); most things are already done, as Define
already fills standard_class_initializers !
I did derive the class JSThreadImpl on both class Thread and
class ape::MonkeyWrapper.
And when I did that all, most of things where working well.
There was only one problem: I got a problem after 54 loops of creating 5
threads, etc. It did call (internally) the GC.
At that moment it tried to destruct a previous created JSThread object
(which is correct), but during the destruction of the "SpiderApe" object
it did crash! Because the SpiderApe object is supposed to be a global
object, it should not be removed.
When I removed SpiderApe::init_js_class() from
standard_js_functions_initializer this problem was also fixed.
Now there is still a locking problem which has to be in nspr.
I rewrote the test script, in such a way threads are not using the vars
of another thread
(not sure I need to, but this way I am sure that doesn't influence my
test):
for (var l = 0; l > -1; l++)
{
var mainthread = new JSThread();
mainthread.func = function() {
var threads = new Array();
var pos = 0;
for( var i = 0; i < 5; ++i ) {
var th = new JSThread();
th.val = i;
th.func = function(){
this.sleep(100 * this.val);
print((new Date()).toString(),"threaded #"+this.val);
};
th.start( th.func );
threads.push( th );
}
this.sleep(100);
threads[4].wait();
threads[3].wait();
threads[2].wait();
threads[1].wait();
threads[0].wait();
print("mainthread.start() is exiting!");
};
print("About to start main thread ", l);
mainthread.start(mainthread.func);
mainthread.wait();
}
After I had done all this, The system continues to run a long time,
until a deadlock situation comes:
At the moment of the deadlock, one thread is in the destructor of the
Monkey wrapper at line 542:
#if defined (JS_THREADSAFE)
// protect m_count and m_rt
PR_Lock(m_RuntimeLock);
#endif
One thread is in JS_Resume request, after locking the rt, and one thread
is in thread_impl::wait();
When I rewrite the MonkeyWrapper dtor the following way:
MonkeyWrapper::~MonkeyWrapper()
{
exit_classes(m_cx, m_g);
if( this->m_cx )
{
this->unmap_wrapper_instance();
JS_DestroyContext( this->m_cx );
}
}
Everything works fine, except that I get about once in 300 started
threads the famous error:
bind_object_to_string(----): key is already bound to an object!
When I also place in the JSThread constructor
try
{
this->m_th = new JSThreadImpl( cx, obj,
static_cast<thread::Mode>(m) );
}
catch(...)
{
this->m_th = new JSThreadImpl( cx, obj,
static_cast<thread::Mode>(m) );
}
Threads stay going forever
Jaap.
(btw I am not going to check in those modifications right now, because I
changed a lot more, which didn't influence the behaviour. Right now I am
going to check wether my main app can work which the modified
MonkeyWrapper destructor, when starting threads during the whole
weekend)
|
|
From: Jaap de W. <wo...@ne...> - 2007-02-23 15:21:53
|
Ok, I saw it already. > -----Original Message----- > From: spi...@li... > [mailto:spi...@li...] On > Behalf Of stephan beal > Sent: vrijdag 23 februari 2007 15:38 > To: spi...@li... > Subject: Re: [Spiderape-devel] Thread.cpp > > > On Friday 23 February 2007 08:05, Jaap de Wolff wrote: > > I did look to your files, and did see that you are not giving the > > right template arguments in init_js_class(), at the Member<> place > > (for instance sleep should return an void, and get an int) > > No, the Member sleep is for: > > JSBool JSThread::sleep(JSContext * cx, JSObject *, uint32 argc, jsval > *argv, jsval *rval ) > > so this is correct: > ci.Member<JSThread::strings::sleep>( &JSThread::sleep ); > > Instead of using fwd_to_member<> to do the func forwarding, i > do custom > arguments handling in JSNative-like members (like sleep()). > > The code heirarchy is a bit strange because it was derived > from code in > another project, written by someone else. He created a basic thread > interface class, called 'thread', and then implemented several > thread_impl.PLATFORM.cpp files, for different thread implementations. > Then i wrote thread_impl.nspr.cpp as a backend using nspr, so > JSThread doesn't know it's using nspr threads - it could also use > pthreads or win32 threads. > > :) > -- > ----- stephan beal > http://s11n.net/home/stephan/ > "Attention is narrowed perception." -- Alan W. Watts > |
|
From: stephan b. <st...@s1...> - 2007-02-23 14:41:46
|
On Friday 23 February 2007 08:05, Jaap de Wolff wrote: > I did look to your files, and did see that you are not giving the > right template arguments in init_js_class(), > at the Member<> place > (for instance sleep should return an void, and get an int) No, the Member sleep is for: JSBool JSThread::sleep(JSContext * cx, JSObject *, uint32 argc, jsval=20 *argv, jsval *rval ) so this is correct: ci.Member<JSThread::strings::sleep>( &JSThread::sleep ); Instead of using fwd_to_member<> to do the func forwarding, i do custom=20 arguments handling in JSNative-like members (like sleep()). The code heirarchy is a bit strange because it was derived from code in=20 another project, written by someone else. He created a basic thread=20 interface class, called 'thread', and then implemented several=20 thread_impl.PLATFORM.cpp files, for different thread implementations.=20 Then i wrote thread_impl.nspr.cpp as a backend using nspr, so JSThread doesn't know it's using nspr threads - it could also use=20 pthreads or win32 threads. :) =2D-=20 =2D---- stephan beal http://s11n.net/home/stephan/ "Attention is narrowed perception." -- Alan W. Watts |
|
From: Jaap de W. <wo...@ne...> - 2007-02-23 07:09:15
|
I did look to your files, and did see that you are not giving the right template arguments in init_js_class(), at the Member<> place (for instance sleep should return an void, and get an int) Jaap |
|
From: stephan b. <st...@s1...> - 2007-02-22 15:09:12
|
On Thursday 22 February 2007 08:47, Jaap de Wolff wrote:
> Two questions to get some more feeling about the problem:
> Is there a difference between your dual processor laptop and single
> processor computer at this point?
>
> When you use a huge contextChunkSize and maxRuntimeMem, instead of
> the defaults, does that influence the # iterations before you get
> this problem?
Good questions. i don't know. i'll have to try.
> std::set<ape::MonkeyWrapper *>::iterator iter;
> for (iter =3D m_ContextCollection.begin(); iter !=3D
> m_ContextCollection.end(); iter++)
> {
> APE_CTX_LOCK(iter->context());
> JS_GC(iter->context());
> }
In my opinion, JS_GC() should lock the context if it needs it locked=20
(but it doesn't - i just checked the code). The SpiderMonkey=20
locking/threading is very poorly designed, in my opinion, if client=20
code has to put all the locks in the right places.
:(
=2D-=20
=2D---- stephan beal
http://s11n.net/home/stephan/
"Attention is narrowed perception." -- Alan W. Watts
|
|
From: Jaap de W. <wo...@ne...> - 2007-02-22 07:33:01
|
.... > > When i do that, i get the following error during context init: > > Calling mainthread.start()... > Main thread wait()ing, then going bye-bye... > terminate called after throwing an instance of 'ape::exception' > what(): bind_object_to_string(82d02e0,CFile,82d8338): key > is already > bound to object @ 82d8138! > Aborted > > But i'm not sure why that's throwing because we should have two > different contexts at this point. ??? > > bind_object_to_string() is doing the right thing, IMO, > because we need > to bind MemberFunc objects on a per-context basis. i'm just not yet > sure why the bindings are happening a second time in the same context. > Ok, in the past, without really investigating my idea about this problem was: Sometimes a bind_object_to_string() was not followed by a unbind_object_from_string() at destruction. Now when I remove an old context, and immediate create a new one there is a significant change the new context pointer Will be the same as the old was (because the memory used is just freed). In this case the object which was not unbound should disallow creation of the new context. And everytime when I created a new context a second time in such a case, it worked. But maybe there is an other explanation... Jaap |
|
From: stephan b. <st...@s1...> - 2007-02-21 14:42:53
|
On Tuesday 20 February 2007 08:51, Jaap de Wolff wrote: > > function: TypeError: object is not a function > > Segmentation fault > > err=3D0 count=3D189 > > Ok, now look at the following points: > What is memory usage at this point? Unfortunately, i can't get any tests to run more than 6 or 8 iterations=20 without crashing, so i can't get any useful numbers. > Is GC (or MayBeGC) called on a regular base? i tried to call gc from some earlier tests but it caused a lockup or=20 deadlock. To go back to the previous mail: > Hey, that's an error I also get sometimes.=20 > I never investigated it, my solution was: Just create a new context. When i do that, i get the following error during context init: Calling mainthread.start()... Main thread wait()ing, then going bye-bye... terminate called after throwing an instance of 'ape::exception' what(): bind_object_to_string(82d02e0,CFile,82d8338): key is already=20 bound to object @ 82d8138! Aborted But i'm not sure why that's throwing because we should have two=20 different contexts at this point. ??? bind_object_to_string() is doing the right thing, IMO, because we need=20 to bind MemberFunc objects on a per-context basis. i'm just not yet=20 sure why the bindings are happening a second time in the same context. =2D-=20 =2D---- stephan beal http://s11n.net/home/stephan/ "Attention is narrowed perception." -- Alan W. Watts |