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 ();