| diff -ur a/Makefile.PL b/Makefile.PL |
| --- a/Makefile.PL 2010-05-29 02:43:06.000000000 -0400 |
| +++ b/Makefile.PL 2012-10-11 14:56:18.000000000 -0400 |
| @@ -12,6 +12,7 @@ |
| ###################################################################### |
| |
| use ExtUtils::MakeMaker; |
| +use ExtUtils::PkgConfig; |
| use Getopt::Long; |
| |
| # Get the right lib and include dirs for different platforms |
| @@ -37,7 +38,7 @@ |
| "/usr/lib/firefox" => "/usr/include/firefox", |
| ); |
| |
| -my ($JS_LIB_DIR, @JS_INCL_DIRS, $JS_LIB_NAME); |
| +my ($JS_LIB_DIR, @JS_INCL_DIRS, $JS_LIB_NAME, $JS_LIBS, $JS_INCLUDES); |
| |
| #### Determine compile options |
| ############################## |
| @@ -57,6 +58,19 @@ |
| "JS_LIB_DIR=s" => \$JS_LIB_DIR, |
| "JS_LIB_NAME=s" => \$JS_LIB_NAME, |
| ); |
| + |
| +# try to find spidermonkey via pkg-config first |
| + |
| +$JS_LIBS = ExtUtils::PkgConfig->libs ('mozjs187'); |
| +if ("".$JS_LIBS ne "") { |
| + $JS_INCLUDES = ExtUtils::PkgConfig->cflags ('mozjs187'); |
| +} else { |
| + $JS_LIBS = ExtUtils::PkgConfig->libs ('mozjs185'); |
| + if ("".$JS_LIBS ne "") { |
| + $JS_INCLUDES = ExtUtils::PkgConfig->cflags ('mozjs185'); |
| + } else { |
| + |
| +# pkg-config did not work, use the old (direct) way to find older libs |
| if ($JS_LIB_DIR) { |
| push @JS_INCL_DIRS, $JS_LIB_DIR; |
| } |
| @@ -78,13 +92,15 @@ |
| } |
| } |
| if (scalar(@JS_INCL_DIRS) == scalar(@c_header_files)) { |
| - $JS_LIB_DIR = $libfile; |
| + $JS_LIB_DIR = "-L".$libfile; |
| $JS_LIB_DIR =~ s/$possible_lib$//; |
| |
| $JS_LIB_NAME = $possible_lib; |
| $JS_LIB_NAME =~ s/\.(a|so|dll)$//; |
| $JS_LIB_NAME =~ s/^lib//; |
| |
| + $JS_LIBS = "-l".$JS_LIB_NAME; |
| + |
| last; |
| } else { |
| @JS_INCL_DIRS = (); |
| @@ -94,15 +110,22 @@ |
| } |
| last if $JS_LIB_DIR; |
| } |
| +foreach my $include_dir(@JS_INCL_DIRS) { |
| + $JS_INCLUDES.=" -I".$include_dir; |
| +} |
| |
| if ($JS_INCL_DIRS[0] eq $JS_INCL_DIRS[1]) { |
| shift @JS_INCL_DIRS; |
| } |
| |
| +} # end of pkgcfg mozjs185 |
| +} # end of pkgcfg mozjs187 |
| + |
| + |
| ## If no SpiderMonkey library found report that and exit. |
| ## Otherwise print lib and include paths. |
| |
| -if (!$JS_LIB_DIR) { |
| +if (!$JS_LIBS) { |
| print <<EOT; |
| |
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| @@ -111,17 +134,13 @@ |
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| |
| EOT |
| - exit 0; |
| + exit 1; |
| } else { |
| - print "JS_LIB_DIR: $JS_LIB_DIR\n"; |
| - foreach my $include_dir(@JS_INCL_DIRS) { |
| - print "JS_INCL_DIR: $include_dir\n"; |
| - } |
| - print "JS_LIB_NAME: $JS_LIB_NAME\n"; |
| + print "JS_LIBS: $JS_LIBS\n"; |
| + print "JS_INCLUDES: $include_dir\n"; |
| } |
| |
| |
| - |
| ## Determine library name and system-related defines |
| if ($^O ne 'MSWin32') { |
| $JS_DEFINE = '-DXP_UNIX'; |
| @@ -160,10 +179,11 @@ |
| ($] >= 5.005 ? ## Add these new keywords supported since 5.005 |
| (ABSTRACT_FROM => 'SpiderMonkey.pm', # retrieve abstract from module |
| AUTHOR => 'Mike Schilli <m@perlmeister.com>') : ()), |
| - 'LIBS' => ["-L$JS_LIB_DIR -l$JS_LIB_NAME"], |
| + 'LIBS' => ["$JS_LIB_DIR $JS_LIBS"], |
| 'DEFINE' => $JS_DEFINE, # e.g., '-DHAVE_SOMETHING' |
| # Insert -I. if you add *.h files later: |
| - 'INC' => "-I".join " -I", @JS_INCL_DIRS, |
| +# 'INC' => "-I".join " -I", @JS_INCL_DIRS, |
| + 'INC' => $JS_INCLUDES, |
| # Un-comment this if you add C files to link with later: |
| # 'OBJECT' => '$(O_FILES)', # link all the C files too |
| ); |
| diff -ur a/SpiderMonkey.pm b/SpiderMonkey.pm |
| --- a/SpiderMonkey.pm 2010-05-29 02:49:31.000000000 -0400 |
| +++ b/SpiderMonkey.pm 2012-10-11 14:56:18.000000000 -0400 |
| @@ -161,9 +161,8 @@ |
| $self->{global_class} = |
| JavaScript::SpiderMonkey::JS_GlobalClass(); |
| $self->{global_object} = |
| - JavaScript::SpiderMonkey::JS_NewObject( |
| - $self->{context}, $self->{global_class}, |
| - $self->{global_class}, $self->{global_class}); |
| + JavaScript::SpiderMonkey::JS_NewCompartmentAndGlobalObject( |
| + $self->{context}, $self->{global_class}); |
| |
| JavaScript::SpiderMonkey::JS_InitStandardClasses($self->{context}, |
| $self->{global_object}); |
| diff -ur a/SpiderMonkey.xs b/SpiderMonkey.xs |
| --- a/SpiderMonkey.xs 2010-05-29 02:49:31.000000000 -0400 |
| +++ b/SpiderMonkey.xs 2012-10-11 14:56:18.000000000 -0400 |
| @@ -20,10 +20,13 @@ |
| #define snprintf _snprintf |
| #endif |
| |
| +#ifndef JSCLASS_GLOBAL_FLAGS |
| +#define JSCLASS_GLOBAL_FLAGS 0 |
| +#endif |
| /* JSRuntime needs this global class */ |
| static |
| JSClass global_class = { |
| - "Global", 0, |
| + "Global", JSCLASS_GLOBAL_FLAGS, |
| JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, |
| JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub |
| }; |
| @@ -67,10 +70,18 @@ |
| * I hope all reasonable machines can hold an address in |
| * an int. |
| */ |
| - XPUSHs(sv_2mortal(newSViv((int)obj))); |
| + XPUSHs(sv_2mortal(newSViv(PTR2IV(obj)))); |
| +#if JS_VERSION < 185 |
| XPUSHs(sv_2mortal(newSVpv(JS_GetStringBytes(JSVAL_TO_STRING(id)), 0))); |
| +#else |
| + XPUSHs(sv_2mortal(newSVpv(JS_EncodeString(cx, JSVAL_TO_STRING(id)), 0))); |
| +#endif |
| XPUSHs(sv_2mortal(newSVpv(what, 0))); |
| +#if JS_VERSION < 185 |
| XPUSHs(sv_2mortal(newSVpv(JS_GetStringBytes(JSVAL_TO_STRING(*vp)), 0))); |
| +#else |
| + XPUSHs(sv_2mortal(newSVpv(JS_EncodeString(cx, JSVAL_TO_STRING(*vp)), 0))); |
| +#endif |
| PUTBACK; |
| call_pv("JavaScript::SpiderMonkey::getsetter_dispatcher", G_DISCARD); |
| FREETMPS; |
| @@ -83,10 +94,21 @@ |
| JSBool getter_dispatcher( |
| JSContext *cx, |
| JSObject *obj, |
| +#if JS_VERSION < 185 |
| jsval id, |
| +#else |
| + jsid iid, |
| +#endif |
| jsval *vp |
| /* --------------------------------------------------------------------- */ |
| ) { |
| +#if JS_VERSION >= 185 |
| + jsval id; |
| + if (!JS_IdToValue(cx,iid,&id)) { |
| + fprintf(stderr, "getter_dispatcher: JS_IdToValue failed.\n"); |
| + return JS_FALSE; |
| + } |
| +#endif |
| return getsetter_dispatcher(cx, obj, id, vp, "getter"); |
| } |
| |
| @@ -94,10 +116,22 @@ |
| JSBool setter_dispatcher( |
| JSContext *cx, |
| JSObject *obj, |
| +#if JS_VERSION < 185 |
| jsval id, |
| +#else |
| + jsid iid, |
| + JSBool strict, |
| +#endif |
| jsval *vp |
| /* --------------------------------------------------------------------- */ |
| ) { |
| +#if JS_VERSION >= 185 |
| + jsval id; |
| + if (!JS_IdToValue(cx,iid,&id)) { |
| + fprintf(stderr, "setter_dispatcher: JS_IdToValue failed.\n"); |
| + return JS_FALSE; |
| + } |
| +#endif |
| return getsetter_dispatcher(cx, obj, id, vp, "setter"); |
| } |
| |
| @@ -128,10 +162,19 @@ |
| |
| /* --------------------------------------------------------------------- */ |
| static JSBool |
| +#if JS_VERSION < 185 |
| FunctionDispatcher(JSContext *cx, JSObject *obj, uintN argc, |
| jsval *argv, jsval *rval) { |
| +#else |
| +FunctionDispatcher(JSContext *cx, uintN argc, jsval *vp) { |
| +#endif |
| /* --------------------------------------------------------------------- */ |
| dSP; |
| +#if JS_VERSION >= 185 |
| + JSObject *obj = JS_THIS_OBJECT(cx,vp); |
| + jsval *argv = JS_ARGV(cx,vp); |
| + jsval rval; |
| +#endif |
| SV *sv; |
| char *n_jstr; |
| int n_jnum; |
| @@ -149,12 +192,20 @@ |
| ENTER ; |
| SAVETMPS ; |
| PUSHMARK(SP); |
| - XPUSHs(sv_2mortal(newSViv((int)obj))); |
| + XPUSHs(sv_2mortal(newSViv(PTR2IV(obj)))); |
| XPUSHs(sv_2mortal(newSVpv( |
| - JS_GetFunctionName(fun), 0))); |
| +#if JS_VERSION < 185 |
| + JS_GetStringBytes(JS_GetFunctionId(fun)), 0))); |
| +#else |
| + JS_EncodeString(cx, JS_GetFunctionId(fun)), 0))); |
| +#endif |
| for(i=0; i<argc; i++) { |
| XPUSHs(sv_2mortal(newSVpv( |
| +#if JS_VERSION < 185 |
| JS_GetStringBytes(JS_ValueToString(cx, argv[i])), 0))); |
| +#else |
| + JS_EncodeString(cx, JS_ValueToString(cx, argv[i])), 0))); |
| +#endif |
| } |
| PUTBACK; |
| count = call_pv("JavaScript::SpiderMonkey::function_dispatcher", G_SCALAR); |
| @@ -174,7 +225,11 @@ |
| |
| if(Debug) |
| fprintf(stderr, "DEBUG: %lx is a ref!\n", (long) sv); |
| - *rval = OBJECT_TO_JSVAL(SvIV(SvRV(sv))); |
| +#if JS_VERSION < 185 |
| + *rval = OBJECT_TO_JSVAL(INT2PTR(JSObject *,SvIV(SvRV(sv)))); |
| +#else |
| + JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(INT2PTR(JSObject *,SvIV(SvRV(sv))))); |
| +#endif |
| } |
| else if(SvIOK(sv)) { |
| /* It appears that we have been sent an int return |
| @@ -183,7 +238,11 @@ |
| n_jnum=SvIV(sv); |
| if(Debug) |
| fprintf(stderr, "DEBUG: %lx is an int (%d)\n", (long) sv,n_jnum); |
| +#if JS_VERSION < 185 |
| *rval = INT_TO_JSVAL(n_jnum); |
| +#else |
| + JS_SET_RVAL(cx,vp,INT_TO_JSVAL(n_jnum)); |
| +#endif |
| } else if(SvNOK(sv)) { |
| /* It appears that we have been sent an double return |
| * value. Thats fine we can give javascript an double |
| @@ -192,11 +251,20 @@ |
| |
| if(Debug) |
| fprintf(stderr, "DEBUG: %lx is a double(%f)\n", (long) sv,n_jdbl); |
| +#if JS_VERSION < 185 |
| *rval = DOUBLE_TO_JSVAL(JS_NewDouble(cx, n_jdbl)); |
| +#else |
| + JS_NewNumberValue(cx, n_jdbl, &rval); |
| + JS_SET_RVAL(cx,vp,rval); |
| +#endif |
| } else if(SvPOK(sv)) { |
| n_jstr = SvPV(sv, PL_na); |
| //warn("DEBUG: %s (%d)\n", n_jstr); |
| +#if JS_VERSION < 185 |
| *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, n_jstr)); |
| +#else |
| + JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(JS_NewStringCopyZ(cx, n_jstr))); |
| +#endif |
| } |
| } |
| |
| @@ -240,8 +308,13 @@ |
| } |
| |
| /* --------------------------------------------------------------------- */ |
| +#if JS_VERSION < 181 |
| static JSBool |
| BranchHandler(JSContext *cx, JSScript *script) { |
| +#else |
| +static JSBool |
| +BranchHandler(JSContext *cx) { |
| +#endif |
| /* --------------------------------------------------------------------- */ |
| PJS_Context* pcx = (PJS_Context*) JS_GetContextPrivate(cx); |
| |
| @@ -374,11 +447,46 @@ |
| JSObject *obj; |
| CODE: |
| { |
| +#ifdef JS_THREADSAFE |
| + JS_BeginRequest(cx); |
| +#endif |
| obj = JS_NewObject(cx, class, NULL, NULL); |
| if(!obj) { |
| XSRETURN_UNDEF; |
| } |
| RETVAL = obj; |
| +#ifdef JS_THREADSAFE |
| + JS_EndRequest(cx); |
| +#endif |
| + } |
| + OUTPUT: |
| + RETVAL |
| + |
| +###################################################################### |
| +JSObject * |
| +JS_NewCompartmentAndGlobalObject(cx, class) |
| + JSContext * cx |
| + JSClass * class |
| +###################################################################### |
| + PREINIT: |
| + JSObject *obj; |
| + CODE: |
| + { |
| +#ifdef JS_THREADSAFE |
| + JS_BeginRequest(cx); |
| +#endif |
| +#if JS_VERSION < 185 |
| + obj = JS_NewObject(cx, class, NULL, NULL); |
| +#else |
| + obj = JS_NewCompartmentAndGlobalObject(cx, class, NULL); |
| +#endif |
| + if(!obj) { |
| + XSRETURN_UNDEF; |
| + } |
| + RETVAL = obj; |
| +#ifdef JS_THREADSAFE |
| + JS_EndRequest(cx); |
| +#endif |
| } |
| OUTPUT: |
| RETVAL |
| @@ -404,6 +512,9 @@ |
| na = (uintN) nargs; |
| CODE: |
| { |
| +#ifdef JS_THREADSAFE |
| + JS_BeginRequest(cx); |
| +#endif |
| obj = JS_InitClass(cx, iobj, parent_proto, clasp, |
| constructor, nargs, ps, fs, static_ps, |
| static_fs); |
| @@ -411,6 +522,9 @@ |
| XSRETURN_UNDEF; |
| } |
| RETVAL = obj; |
| +#ifdef JS_THREADSAFE |
| + JS_EndRequest(cx); |
| +#endif |
| } |
| OUTPUT: |
| RETVAL |
| @@ -469,11 +583,17 @@ |
| JSBool rc; |
| CODE: |
| { |
| +#ifdef JS_THREADSAFE |
| + JS_BeginRequest(cx); |
| +#endif |
| rc = JS_InitStandardClasses(cx, gobj); |
| if(!rc) { |
| XSRETURN_UNDEF; |
| } |
| RETVAL = (int) rc; |
| +#ifdef JS_THREADSAFE |
| + JS_BeginRequest(cx); |
| +#endif |
| } |
| OUTPUT: |
| RETVAL |
| @@ -582,10 +702,18 @@ |
| rc = JS_GetProperty(cx, obj, name, &vp); |
| if(rc) { |
| str = JS_ValueToString(cx, vp); |
| +#if JS_VERSION < 185 |
| if(strcmp(JS_GetStringBytes(str), "undefined") == 0) { |
| +#else |
| + if(strcmp(JS_EncodeString(cx, str), "undefined") == 0) { |
| +#endif |
| sv = &PL_sv_undef; |
| } else { |
| +#if JS_VERSION < 185 |
| sv_setpv(sv, JS_GetStringBytes(str)); |
| +#else |
| + sv_setpv(sv, JS_EncodeString(cx, str)); |
| +#endif |
| } |
| } else { |
| sv = &PL_sv_undef; |
| @@ -675,10 +803,18 @@ |
| rc = JS_GetElement(cx, obj, idx, &vp); |
| if(rc) { |
| str = JS_ValueToString(cx, vp); |
| +#if JS_VERSION < 185 |
| if(strcmp(JS_GetStringBytes(str), "undefined") == 0) { |
| +#else |
| + if(strcmp(JS_EncodeString(cx, str), "undefined") == 0) { |
| +#endif |
| sv = &PL_sv_undef; |
| } else { |
| +#if JS_VERSION < 185 |
| sv_setpv(sv, JS_GetStringBytes(str)); |
| +#else |
| + sv_setpv(sv, JS_EncodeString(cx, str)); |
| +#endif |
| } |
| } else { |
| sv = &PL_sv_undef; |
| @@ -718,7 +854,11 @@ |
| PJS_Context* pcx = (PJS_Context *) JS_GetContextPrivate(cx); |
| pcx->branch_count = 0; |
| pcx->branch_max = max_branch_operations; |
| +#if JS_VERSION < 181 |
| JS_SetBranchCallback(cx, BranchHandler); |
| +#else |
| + JS_SetOperationCallback(cx, BranchHandler); |
| +#endif |
| } |
| OUTPUT: |
| |
| diff -ur a/t/error.t b/t/error.t |
| --- a/t/error.t 2010-05-28 13:02:43.000000000 -0400 |
| +++ b/t/error.t 2012-10-11 14:56:18.000000000 -0400 |
| @@ -9,7 +9,7 @@ |
| $js1->init (); |
| ok (!$js1->eval ($jscode1)); |
| ok ($@ !~ "\n"); |
| -ok ($@ =~ "SyntaxError"); |
| +ok ($@ =~ "SyntaxError" || $@ =~ "ReferenceError: invalid assignment left-hand side"); |
| #print "$@\n"; |
| my $jscode2 =<<EOF; |
| var fruit = non_existant_function (); |