You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
487 lines
14 KiB
487 lines
14 KiB
From 9c0fbdce2ee643c23b3be8fa391b779fc6afbab3 Mon Sep 17 00:00:00 2001
|
|
From: Ian Stakenvicius <axs@gentoo.org>
|
|
Date: Fri, 12 Oct 2012 08:09:57 +1300
|
|
Subject: Support spidermonkey 1.8.5 and newer
|
|
|
|
Fix support for x86_64
|
|
|
|
Bug: https://bugs.gentoo.org/404129
|
|
---
|
|
Makefile.PL | 44 ++++++++++++-----
|
|
SpiderMonkey.pm | 5 +-
|
|
SpiderMonkey.xs | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
t/error.t | 2 +-
|
|
4 files changed, 180 insertions(+), 21 deletions(-)
|
|
|
|
diff --git a/Makefile.PL b/Makefile.PL
|
|
index 901b773..6095dcd 100644
|
|
--- a/Makefile.PL
|
|
+++ b/Makefile.PL
|
|
@@ -12,6 +12,7 @@
|
|
######################################################################
|
|
|
|
use ExtUtils::MakeMaker;
|
|
+use ExtUtils::PkgConfig;
|
|
use Getopt::Long;
|
|
|
|
# Get the right lib and include dirs for different platforms
|
|
@@ -39,7 +40,7 @@ my %possible_install_paths = (
|
|
"/opt/local/lib" => "/opt/local/include", # MacPorts
|
|
);
|
|
|
|
-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
|
|
##############################
|
|
@@ -59,6 +60,19 @@ GetOptions(
|
|
"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;
|
|
}
|
|
@@ -80,13 +94,15 @@ foreach my $install_path(keys %possible_install_paths) {
|
|
}
|
|
}
|
|
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 = ();
|
|
@@ -96,15 +112,22 @@ foreach my $install_path(keys %possible_install_paths) {
|
|
}
|
|
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;
|
|
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
@@ -113,17 +136,13 @@ README file on how to download, compile and link it.
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
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';
|
|
@@ -162,10 +181,11 @@ WriteMakefile(
|
|
($] >= 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 --git a/SpiderMonkey.pm b/SpiderMonkey.pm
|
|
index 223204a..de210c3 100644
|
|
--- a/SpiderMonkey.pm
|
|
+++ b/SpiderMonkey.pm
|
|
@@ -162,9 +162,8 @@ sub init {
|
|
$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 --git a/SpiderMonkey.xs b/SpiderMonkey.xs
|
|
index 4d97117..1cfc9a5 100644
|
|
--- a/SpiderMonkey.xs
|
|
+++ b/SpiderMonkey.xs
|
|
@@ -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 @@ JSBool getsetter_dispatcher(
|
|
* 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 getsetter_dispatcher(
|
|
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 getter_dispatcher(
|
|
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 @@ int debug_enabled(
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
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 @@ FunctionDispatcher(JSContext *cx, JSObject *obj, uintN argc,
|
|
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 @@ FunctionDispatcher(JSContext *cx, JSObject *obj, uintN argc,
|
|
|
|
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 @@ FunctionDispatcher(JSContext *cx, JSObject *obj, uintN argc,
|
|
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 @@ FunctionDispatcher(JSContext *cx, JSObject *obj, uintN argc,
|
|
|
|
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 @@ ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) {
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
+#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 @@ JS_NewObject(cx, class, proto, parent)
|
|
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 @@ JS_InitClass(cx, iobj, parent_proto, clasp, constructor, nargs, ps, fs, static_p
|
|
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 @@ JS_InitClass(cx, iobj, parent_proto, clasp, constructor, nargs, ps, fs, static_p
|
|
XSRETURN_UNDEF;
|
|
}
|
|
RETVAL = obj;
|
|
+#ifdef JS_THREADSAFE
|
|
+ JS_EndRequest(cx);
|
|
+#endif
|
|
}
|
|
OUTPUT:
|
|
RETVAL
|
|
@@ -469,11 +583,17 @@ JS_InitStandardClasses(cx, gobj)
|
|
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 @@ JS_GetProperty(cx, obj, name)
|
|
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 @@ JS_GetElement(cx, obj, idx)
|
|
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 @@ JS_SetMaxBranchOperations(cx, max_branch_operations)
|
|
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 --git a/t/error.t b/t/error.t
|
|
index 732226c..de977a1 100644
|
|
--- a/t/error.t
|
|
+++ b/t/error.t
|
|
@@ -9,7 +9,7 @@ my $js1 = JavaScript::SpiderMonkey->new ();
|
|
$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 ();
|
|
--
|
|
2.14.3
|
|
|