Skip to content

Commit

Permalink
Added global property delete with some associated GC tests
Browse files Browse the repository at this point in the history
  • Loading branch information
craigminihan committed May 17, 2015
1 parent c8c74cc commit 8960f24
Show file tree
Hide file tree
Showing 9 changed files with 265 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ clean: force_true
mkdir build_OPT.OBJ && \
cd build_OPT.OBJ && \
export PATH=${PWD}/externals/installed/bin:${PATH} && \
../configure --prefix=${PWD}/externals/installed --disable-shared-js --disable-tests && \
../configure --prefix=${PWD}/externals/installed --disable-shared-js --disable-tests --enable-exact-rooting && \
make -j 2 && \
make install; \
fi
Expand Down
4 changes: 3 additions & 1 deletion src/libjsapi/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ class Context final {
JSContext* getContext() { return cx_; }
JS::HandleObject getGlobal() { return global_; }

operator JSContext*() { return cx_; }
operator JSContext*() { return cx_; }

void MaybeGC() { JS_MaybeGC(cx_); }

private:
friend bool Script::Compile();
Expand Down
8 changes: 8 additions & 0 deletions src/libjsapi/global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,12 @@ rs::jsapi::Global::GlobalFunctionState* rs::jsapi::Global::GetFunctionState(JSOb

void rs::jsapi::Global::SetFunctionState(JSObject* obj, GlobalFunctionState* state) {
JS_SetPrivate(obj, state);
}

bool rs::jsapi::Global::DeleteProperty(Context& cx, const char* name) {
return JS_DeleteProperty(cx, cx.getGlobal(), name);
}

bool rs::jsapi::Global::DeleteFunction(Context& cx, const char* name) {
return JS_DeleteProperty(cx, cx.getGlobal(), name);
}
3 changes: 3 additions & 0 deletions src/libjsapi/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class Global final {
static bool DefineProperty(Context& cx, const char* name, JSNative getter, JSNative setter, unsigned attrs = JSPROP_ENUMERATE);
static bool DefineFunction(Context& cx, const char* name, FunctionCallback callback, unsigned attrs = JSPROP_ENUMERATE);

static bool DeleteProperty(Context& cx, const char* name);
static bool DeleteFunction(Context& cx, const char* name);

private:
struct GlobalFunctionState {
GlobalFunctionState(FunctionCallback function) : function_(function) {}
Expand Down
18 changes: 18 additions & 0 deletions src/libjsapi/nbproject/Makefile-Debug.mk
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ TESTFILES= \
${TESTDIR}/TestFiles/f5 \
${TESTDIR}/TestFiles/f6 \
${TESTDIR}/TestFiles/f12 \
${TESTDIR}/TestFiles/f13 \
${TESTDIR}/TestFiles/f8 \
${TESTDIR}/TestFiles/f3 \
${TESTDIR}/TestFiles/f4 \
Expand Down Expand Up @@ -175,6 +176,16 @@ ${TESTDIR}/TestFiles/f12: ${TESTDIR}/tests/function_arguments_tests.o ${OBJECTFI
${MKDIR} -p ${TESTDIR}/TestFiles
${LINK.cc} --coverage -o ${TESTDIR}/TestFiles/f12 $^ ${LDLIBSOPTIONS} -lpthread -ldl `pkg-config --libs zlib`

${TESTDIR}/TestFiles/f13: ../../externals/installed/lib/libmozjs-31.a

${TESTDIR}/TestFiles/f13: ../../externals/installed/lib/libgtest.a

${TESTDIR}/TestFiles/f13: ../../externals/installed/lib/libgtest_main.a

${TESTDIR}/TestFiles/f13: ${TESTDIR}/tests/gc_tests.o ${OBJECTFILES:%.o=%_nomain.o}
${MKDIR} -p ${TESTDIR}/TestFiles
${LINK.cc} --coverage -o ${TESTDIR}/TestFiles/f13 $^ ${LDLIBSOPTIONS} -lpthread -ldl `pkg-config --libs zlib`

${TESTDIR}/TestFiles/f8: ../../externals/installed/lib/libmozjs-31.a

${TESTDIR}/TestFiles/f8: ../../externals/installed/lib/libgtest.a
Expand Down Expand Up @@ -284,6 +295,12 @@ ${TESTDIR}/tests/function_arguments_tests.o: tests/function_arguments_tests.cpp
$(COMPILE.cc) -g -I../../externals/installed/include/mozjs-31 -I../../externals/installed/include -I. -std=c++11 --coverage -MMD -MP -MF "$@.d" -o ${TESTDIR}/tests/function_arguments_tests.o tests/function_arguments_tests.cpp


${TESTDIR}/tests/gc_tests.o: tests/gc_tests.cpp
${MKDIR} -p ${TESTDIR}/tests
${RM} "$@.d"
$(COMPILE.cc) -g -I../../externals/installed/include/mozjs-31 -I../../externals/installed/include -I. -std=c++11 --coverage -MMD -MP -MF "$@.d" -o ${TESTDIR}/tests/gc_tests.o tests/gc_tests.cpp


${TESTDIR}/tests/global_property_tests.o: tests/global_property_tests.cpp
${MKDIR} -p ${TESTDIR}/tests
${RM} "$@.d"
Expand Down Expand Up @@ -475,6 +492,7 @@ ${OBJECTDIR}/value_nomain.o: ${OBJECTDIR}/value.o value.cpp
${TESTDIR}/TestFiles/f5 || true; \
${TESTDIR}/TestFiles/f6 || true; \
${TESTDIR}/TestFiles/f12 || true; \
${TESTDIR}/TestFiles/f13 || true; \
${TESTDIR}/TestFiles/f8 || true; \
${TESTDIR}/TestFiles/f3 || true; \
${TESTDIR}/TestFiles/f4 || true; \
Expand Down
18 changes: 18 additions & 0 deletions src/libjsapi/nbproject/Makefile-Release.mk
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ TESTFILES= \
${TESTDIR}/TestFiles/f5 \
${TESTDIR}/TestFiles/f6 \
${TESTDIR}/TestFiles/f12 \
${TESTDIR}/TestFiles/f13 \
${TESTDIR}/TestFiles/f8 \
${TESTDIR}/TestFiles/f3 \
${TESTDIR}/TestFiles/f4 \
Expand Down Expand Up @@ -175,6 +176,16 @@ ${TESTDIR}/TestFiles/f12: ${TESTDIR}/tests/function_arguments_tests.o ${OBJECTFI
${MKDIR} -p ${TESTDIR}/TestFiles
${LINK.cc} -o ${TESTDIR}/TestFiles/f12 $^ ${LDLIBSOPTIONS} -lpthread -ldl `pkg-config --libs zlib`

${TESTDIR}/TestFiles/f13: ../../externals/installed/lib/libmozjs-31.a

${TESTDIR}/TestFiles/f13: ../../externals/installed/lib/libgtest.a

${TESTDIR}/TestFiles/f13: ../../externals/installed/lib/libgtest_main.a

${TESTDIR}/TestFiles/f13: ${TESTDIR}/tests/gc_tests.o ${OBJECTFILES:%.o=%_nomain.o}
${MKDIR} -p ${TESTDIR}/TestFiles
${LINK.cc} -o ${TESTDIR}/TestFiles/f13 $^ ${LDLIBSOPTIONS} -lpthread -ldl `pkg-config --libs zlib`

${TESTDIR}/TestFiles/f8: ../../externals/installed/lib/libmozjs-31.a

${TESTDIR}/TestFiles/f8: ../../externals/installed/lib/libgtest.a
Expand Down Expand Up @@ -284,6 +295,12 @@ ${TESTDIR}/tests/function_arguments_tests.o: tests/function_arguments_tests.cpp
$(COMPILE.cc) -O2 -I../../externals/installed/include/mozjs-31 -I../../externals/installed/include -I. -std=c++11 -MMD -MP -MF "$@.d" -o ${TESTDIR}/tests/function_arguments_tests.o tests/function_arguments_tests.cpp


${TESTDIR}/tests/gc_tests.o: tests/gc_tests.cpp
${MKDIR} -p ${TESTDIR}/tests
${RM} "$@.d"
$(COMPILE.cc) -O2 -I../../externals/installed/include/mozjs-31 -I../../externals/installed/include -I. -std=c++11 -MMD -MP -MF "$@.d" -o ${TESTDIR}/tests/gc_tests.o tests/gc_tests.cpp


${TESTDIR}/tests/global_property_tests.o: tests/global_property_tests.cpp
${MKDIR} -p ${TESTDIR}/tests
${RM} "$@.d"
Expand Down Expand Up @@ -475,6 +492,7 @@ ${OBJECTDIR}/value_nomain.o: ${OBJECTDIR}/value.o value.cpp
${TESTDIR}/TestFiles/f5 || true; \
${TESTDIR}/TestFiles/f6 || true; \
${TESTDIR}/TestFiles/f12 || true; \
${TESTDIR}/TestFiles/f13 || true; \
${TESTDIR}/TestFiles/f8 || true; \
${TESTDIR}/TestFiles/f3 || true; \
${TESTDIR}/TestFiles/f4 || true; \
Expand Down
40 changes: 40 additions & 0 deletions src/libjsapi/nbproject/configurations.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
kind="TEST">
<itemPath>tests/function_arguments_tests.cpp</itemPath>
</logicalFolder>
<logicalFolder name="f13"
displayName="GC Tests"
projectFiles="true"
kind="TEST">
<itemPath>tests/gc_tests.cpp</itemPath>
</logicalFolder>
<logicalFolder name="f8"
displayName="Global Property Tests"
projectFiles="true"
Expand Down Expand Up @@ -229,6 +235,21 @@
<output>${TESTDIR}/TestFiles/f12</output>
</linkerTool>
</folder>
<folder path="TestFiles/f13">
<cTool>
<incDir>
<pElem>.</pElem>
</incDir>
</cTool>
<ccTool>
<incDir>
<pElem>.</pElem>
</incDir>
</ccTool>
<linkerTool>
<output>${TESTDIR}/TestFiles/f13</output>
</linkerTool>
</folder>
<folder path="TestFiles/f2">
<cTool>
<incDir>
Expand Down Expand Up @@ -382,6 +403,8 @@
</item>
<item path="tests/function_arguments_tests.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="tests/gc_tests.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="tests/global_property_tests.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="tests/multi_context_tests.cpp" ex="false" tool="1" flavor2="0">
Expand Down Expand Up @@ -527,6 +550,21 @@
<output>${TESTDIR}/TestFiles/f12</output>
</linkerTool>
</folder>
<folder path="TestFiles/f13">
<cTool>
<incDir>
<pElem>.</pElem>
</incDir>
</cTool>
<ccTool>
<incDir>
<pElem>.</pElem>
</incDir>
</ccTool>
<linkerTool>
<output>${TESTDIR}/TestFiles/f13</output>
</linkerTool>
</folder>
<folder path="TestFiles/f2">
<cTool>
<incDir>
Expand Down Expand Up @@ -680,6 +718,8 @@
</item>
<item path="tests/function_arguments_tests.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="tests/gc_tests.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="tests/global_property_tests.cpp" ex="false" tool="1" flavor2="0">
</item>
<item path="tests/multi_context_tests.cpp" ex="false" tool="1" flavor2="0">
Expand Down
4 changes: 4 additions & 0 deletions src/libjsapi/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class Runtime final {
return cx_;
}

void GCNow() { JS_GC(rt_); }

void MaybeGC() { JS_MaybeGC(cx_); }

private:

class Instance {
Expand Down
170 changes: 170 additions & 0 deletions src/libjsapi/tests/gc_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#include <gtest/gtest.h>

#include "../libjsapi.h"

rs::jsapi::Runtime rt_;

class GCTests : public ::testing::Test {
protected:
virtual void SetUp() {

}

virtual void TearDown() {

}
};

TEST_F(GCTests, test1) {
auto cx = rt_.NewContext();

rs::jsapi::Value value(*cx, 10);
rs::jsapi::Global::DefineProperty(*cx, "test", value);

cx->MaybeGC();

rs::jsapi::Value result(*cx);
cx->Evaluate("(function(){return test;})();", result);
ASSERT_TRUE(result.isInt32());
ASSERT_EQ(10, result.toInt32());

rt_.GCNow();
cx->Evaluate("(function(){return test;})();", result);
ASSERT_TRUE(result.isInt32());
ASSERT_EQ(10, result.toInt32());
}

TEST_F(GCTests, test2) {
auto cx = rt_.NewContext();

if (true) {
rs::jsapi::Value value(*cx, 10);
rs::jsapi::Global::DefineProperty(*cx, "test", value);
}

rt_.GCNow();

rs::jsapi::Value result(*cx);
cx->Evaluate("(function(){return test;})();", result);
ASSERT_TRUE(result.isInt32());
ASSERT_EQ(10, result.toInt32());
}

TEST_F(GCTests, test3) {
auto cx = rt_.NewContext();

bool deleted = false;

if (true) {
rs::jsapi::Value obj(*cx);
rs::jsapi::Object::Create(*cx, {}, nullptr, nullptr, {},
[&]() { deleted = true; }, obj);

ASSERT_TRUE(rs::jsapi::Global::DefineProperty(*cx, "test", obj));

rs::jsapi::Value result(*cx);
cx->Evaluate("(function(){return test;})();", result);
ASSERT_TRUE(result.isObject());
}

ASSERT_TRUE(rs::jsapi::Global::DeleteProperty(*cx, "test"));

rt_.GCNow();
ASSERT_TRUE(deleted);
}

TEST_F(GCTests, test4) {
auto cx = rt_.NewContext();

bool deleted = false;

ASSERT_TRUE(rs::jsapi::Global::DefineFunction(*cx, "testFn",
[](const std::vector<rs::jsapi::Value>&, rs::jsapi::Value&) {}));

if (true) {
rs::jsapi::Value func(*cx);
cx->Evaluate("(function(){return testFn;})();", func);
ASSERT_TRUE(func.isFunction());

// add a child object to the function so we can track the delete
rs::jsapi::Value obj(*cx);
rs::jsapi::Object::Create(*cx, {}, nullptr, nullptr, {},
[&]() { deleted = true; }, obj);

ASSERT_TRUE(JS_DefineProperty(*cx, func, "test", obj.getHandleObject(), 0));
}

ASSERT_TRUE(rs::jsapi::Global::DeleteFunction(*cx, "testFn"));

ASSERT_THROW({
rs::jsapi::Value result(*cx);
cx->Evaluate("(function(){return testFn;})();", result);
}, rs::jsapi::ScriptException);

// force a GC pass and then check the delete flag
rt_.GCNow();
ASSERT_TRUE(deleted);
}

#if 0
TEST_F(GCTests, test5) {
auto cx = rt_.NewContext();

bool deleted = false;

rs::jsapi::Value obj(*cx);
rs::jsapi::Object::Create(*cx, {}, nullptr, nullptr, {},
[&]() { deleted = true; }, obj);

// force a GC pass and then check the delete flag
rt_.GCNow();
ASSERT_FALSE(deleted);
}
#endif

#if 0
int deleted = 0;
static void Finalize(JSFreeOp* fop, JSObject* obj) {
++deleted;
}

JSClass klass = {
"rs_jsapi_test_object", 0, JS_PropertyStub, JS_DeletePropertyStub,
JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub,
JS_ConvertStub, &Finalize
};

void doIt(JSContext* cx) {
JS::RootedObject obj(cx, JS_NewObject(cx, &klass, JS::NullPtr(), JS::NullPtr()));
JS_NewObject(cx, &klass, JS::NullPtr(), JS::NullPtr());

// force a GC pass and then check the delete flag
rt_.GCNow();
ASSERT_EQ(1, deleted);
}

TEST_F(GCTests, test6) {
auto cx = rt_.NewContext();

JSAutoRequest ar(*cx);
if (true)
//if (deleted != 10)
{
//JSAutoRequest ar(*cx);

JS::RootedObject obj(*cx, JS_NewObject(*cx, &klass, JS::NullPtr(), JS::NullPtr()));
JS_NewObject(*cx, &klass, JS::NullPtr(), JS::NullPtr());

// force a GC pass and then check the delete flag
rt_.GCNow();
ASSERT_EQ(1, deleted);

//doIt(*cx);
}

// force a GC pass and then check the delete flag
rt_.GCNow();
rt_.GCNow();
ASSERT_EQ(2, deleted);
}
#endif

0 comments on commit 8960f24

Please sign in to comment.