mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge
This commit is contained in:
commit
de2d9819dd
@ -71,6 +71,7 @@ CPPSRCS = \
|
||||
testScriptObject.cpp \
|
||||
testSetPropertyWithNativeGetterStubSetter.cpp \
|
||||
testBug604087.cpp \
|
||||
testThreads.cpp \
|
||||
testTrap.cpp \
|
||||
testUTF8.cpp \
|
||||
testXDR.cpp \
|
||||
|
@ -29,58 +29,6 @@ BEGIN_TEST(testContexts_IsRunning)
|
||||
}
|
||||
END_TEST(testContexts_IsRunning)
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
#include "prthread.h"
|
||||
|
||||
struct ThreadData {
|
||||
JSRuntime *rt;
|
||||
JSObject *obj;
|
||||
const char *code;
|
||||
bool ok;
|
||||
};
|
||||
|
||||
BEGIN_TEST(testContexts_bug561444)
|
||||
{
|
||||
const char *code = "<a><b/></a>.b.@c = '';";
|
||||
EXEC(code);
|
||||
|
||||
jsrefcount rc = JS_SuspendRequest(cx);
|
||||
{
|
||||
ThreadData data = {rt, global, code, false};
|
||||
PRThread *thread =
|
||||
PR_CreateThread(PR_USER_THREAD, threadMain, &data,
|
||||
PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
|
||||
CHECK(thread);
|
||||
PR_JoinThread(thread);
|
||||
CHECK(data.ok);
|
||||
}
|
||||
JS_ResumeRequest(cx, rc);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void threadMain(void *arg) {
|
||||
ThreadData *d = (ThreadData *) arg;
|
||||
|
||||
JSContext *cx = JS_NewContext(d->rt, 8192);
|
||||
if (!cx)
|
||||
return;
|
||||
JS_BeginRequest(cx);
|
||||
{
|
||||
jsvalRoot v(cx);
|
||||
|
||||
JSAutoEnterCompartment ac;
|
||||
ac.enterAndIgnoreErrors(cx, d->obj);
|
||||
|
||||
if (!JS_EvaluateScript(cx, d->obj, d->code, strlen(d->code), __FILE__, __LINE__, v.addr()))
|
||||
return;
|
||||
}
|
||||
JS_DestroyContext(cx);
|
||||
d->ok = true;
|
||||
}
|
||||
END_TEST(testContexts_bug561444)
|
||||
#endif
|
||||
|
||||
BEGIN_TEST(testContexts_bug563735)
|
||||
{
|
||||
JSContext *cx2 = JS_NewContext(rt, 8192);
|
||||
|
155
js/src/jsapi-tests/testThreads.cpp
Normal file
155
js/src/jsapi-tests/testThreads.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
*/
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
||||
#include "tests.h"
|
||||
#include "prthread.h"
|
||||
|
||||
struct ThreadData {
|
||||
JSRuntime *rt;
|
||||
JSObject *obj;
|
||||
const char *code;
|
||||
bool ok;
|
||||
};
|
||||
|
||||
BEGIN_TEST(testThreads_bug561444)
|
||||
{
|
||||
const char *code = "<a><b/></a>.b.@c = '';";
|
||||
EXEC(code);
|
||||
|
||||
jsrefcount rc = JS_SuspendRequest(cx);
|
||||
{
|
||||
ThreadData data = {rt, global, code, false};
|
||||
PRThread *thread =
|
||||
PR_CreateThread(PR_USER_THREAD, threadMain, &data,
|
||||
PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
|
||||
CHECK(thread);
|
||||
PR_JoinThread(thread);
|
||||
CHECK(data.ok);
|
||||
}
|
||||
JS_ResumeRequest(cx, rc);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void threadMain(void *arg) {
|
||||
ThreadData *d = (ThreadData *) arg;
|
||||
|
||||
JSContext *cx = JS_NewContext(d->rt, 8192);
|
||||
if (!cx)
|
||||
return;
|
||||
JS_BeginRequest(cx);
|
||||
{
|
||||
JSAutoEnterCompartment ac;
|
||||
jsval v;
|
||||
d->ok = ac.enter(cx, d->obj) &&
|
||||
JS_EvaluateScript(cx, d->obj, d->code, strlen(d->code), __FILE__, __LINE__,
|
||||
&v);
|
||||
}
|
||||
JS_DestroyContext(cx);
|
||||
}
|
||||
END_TEST(testThreads_bug561444)
|
||||
|
||||
template <class T>
|
||||
class Repeat {
|
||||
size_t n;
|
||||
const T &t;
|
||||
|
||||
public:
|
||||
Repeat(size_t n, const T &t) : n(n), t(t) {}
|
||||
|
||||
bool operator()() const {
|
||||
for (size_t i = 0; i < n; i++)
|
||||
if (!t())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> Repeat<T> repeat(size_t n, const T &t) { return Repeat<T>(n, t); }
|
||||
|
||||
/* Class of callable that does something in n parallel threads. */
|
||||
template <class T>
|
||||
class Parallel {
|
||||
size_t n;
|
||||
const T &t;
|
||||
|
||||
struct pair { const Parallel *self; bool ok; };
|
||||
|
||||
static void threadMain(void *arg) {
|
||||
pair *p = (pair *) arg;
|
||||
if (!p->self->t())
|
||||
p->ok = false;
|
||||
}
|
||||
|
||||
public:
|
||||
Parallel(size_t n, const T &t) : n(n), t(t) {}
|
||||
|
||||
bool operator()() const {
|
||||
pair p = {this, true};
|
||||
|
||||
PRThread **thread = new PRThread *[n];
|
||||
if (!thread)
|
||||
return false;
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
thread[i] = PR_CreateThread(PR_USER_THREAD, threadMain, &p, PR_PRIORITY_NORMAL,
|
||||
PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
|
||||
if (thread[i] == NULL) {
|
||||
p.ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (i--)
|
||||
PR_JoinThread(thread[i]);
|
||||
|
||||
delete[] thread;
|
||||
return p.ok;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> Parallel<T> parallel(size_t n, const T &t) { return Parallel<T>(n, t); }
|
||||
|
||||
/* Class of callable that creates a compartment and runs some code in it. */
|
||||
class eval {
|
||||
JSRuntime *rt;
|
||||
const char *code;
|
||||
|
||||
public:
|
||||
eval(JSRuntime *rt, const char *code) : rt(rt), code(code) {}
|
||||
|
||||
bool operator()() const {
|
||||
JSContext *cx = JS_NewContext(rt, 8192);
|
||||
if (!cx)
|
||||
return false;
|
||||
|
||||
bool ok = false;
|
||||
{
|
||||
JSAutoRequest ar(cx);
|
||||
JSObject *global =
|
||||
JS_NewCompartmentAndGlobalObject(cx, JSAPITest::basicGlobalClass(), NULL);
|
||||
if (global) {
|
||||
JS_SetGlobalObject(cx, global);
|
||||
jsval rval;
|
||||
ok = JS_InitStandardClasses(cx, global) &&
|
||||
JS_EvaluateScript(cx, global, code, strlen(code), "", 0, &rval);
|
||||
}
|
||||
}
|
||||
JS_DestroyContextMaybeGC(cx);
|
||||
return ok;
|
||||
}
|
||||
};
|
||||
|
||||
BEGIN_TEST(testThreads_bug604782)
|
||||
{
|
||||
jsrefcount rc = JS_SuspendRequest(cx);
|
||||
bool ok = repeat(20, parallel(3, eval(rt, "for(i=0;i<1000;i++);")))();
|
||||
JS_ResumeRequest(cx, rc);
|
||||
CHECK(ok);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testThreads_bug604782)
|
||||
|
||||
#endif
|
@ -48,7 +48,7 @@
|
||||
|
||||
class jsvalRoot
|
||||
{
|
||||
public:
|
||||
public:
|
||||
explicit jsvalRoot(JSContext *context, jsval value = JSVAL_NULL)
|
||||
: cx(context), v(value)
|
||||
{
|
||||
@ -70,7 +70,7 @@ public:
|
||||
jsval * addr() { return &v; }
|
||||
jsval value() const { return v; }
|
||||
|
||||
private:
|
||||
private:
|
||||
JSContext *cx;
|
||||
jsval v;
|
||||
};
|
||||
@ -78,7 +78,7 @@ private:
|
||||
/* Note: Aborts on OOM. */
|
||||
class JSAPITestString {
|
||||
js::Vector<char, 0, js::SystemAllocPolicy> chars;
|
||||
public:
|
||||
public:
|
||||
JSAPITestString() {}
|
||||
JSAPITestString(const char *s) { *this += s; }
|
||||
JSAPITestString(const JSAPITestString &s) { *this += s; }
|
||||
@ -105,7 +105,7 @@ inline JSAPITestString operator+(JSAPITestString a, const JSAPITestString &b) {
|
||||
|
||||
class JSAPITest
|
||||
{
|
||||
public:
|
||||
public:
|
||||
static JSAPITest *list;
|
||||
JSAPITest *next;
|
||||
|
||||
@ -217,7 +217,17 @@ public:
|
||||
|
||||
JSAPITestString messages() const { return msgs; }
|
||||
|
||||
protected:
|
||||
static JSClass * basicGlobalClass() {
|
||||
static JSClass c = {
|
||||
"global", JSCLASS_GLOBAL_FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
return &c;
|
||||
}
|
||||
|
||||
protected:
|
||||
static JSBool
|
||||
print(JSContext *cx, uintN argc, jsval *vp)
|
||||
{
|
||||
@ -271,13 +281,7 @@ protected:
|
||||
}
|
||||
|
||||
virtual JSClass * getGlobalClass() {
|
||||
static JSClass basicGlobalClass = {
|
||||
"global", JSCLASS_GLOBAL_FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
return &basicGlobalClass;
|
||||
return basicGlobalClass();
|
||||
}
|
||||
|
||||
virtual JSObject * createGlobal() {
|
||||
@ -300,7 +304,7 @@ protected:
|
||||
|
||||
#define BEGIN_TEST(testname) \
|
||||
class cls_##testname : public JSAPITest { \
|
||||
public: \
|
||||
public: \
|
||||
virtual const char * name() { return #testname; } \
|
||||
virtual bool run()
|
||||
|
||||
@ -318,7 +322,7 @@ protected:
|
||||
|
||||
#define BEGIN_FIXTURE_TEST(fixture, testname) \
|
||||
class cls_##testname : public fixture { \
|
||||
public: \
|
||||
public: \
|
||||
virtual const char * name() { return #testname; } \
|
||||
virtual bool run()
|
||||
|
||||
|
@ -625,6 +625,13 @@ js_CurrentThread(JSRuntime *rt)
|
||||
JSThread::Map::AddPtr p = rt->threads.lookupForAdd(id);
|
||||
if (p) {
|
||||
thread = p->value;
|
||||
|
||||
/*
|
||||
* If thread has no contexts, it might be left over from a previous
|
||||
* thread with the same id but a different stack address.
|
||||
*/
|
||||
if (JS_CLIST_IS_EMPTY(&thread->contextList))
|
||||
thread->data.nativeStackBase = GetNativeStackBase();
|
||||
} else {
|
||||
JS_UNLOCK_GC(rt);
|
||||
thread = NewThread(id);
|
||||
@ -642,6 +649,7 @@ js_CurrentThread(JSRuntime *rt)
|
||||
JS_ASSERT(p->value == thread);
|
||||
}
|
||||
JS_ASSERT(thread->id == id);
|
||||
JS_ASSERT(thread->data.nativeStackBase == GetNativeStackBase());
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user