changeset 411:2a0b8613498f

Js: add more stack tests
author David Demelier <markand@malikania.fr>
date Wed, 07 Oct 2015 08:30:19 +0200
parents a786ad1bdf75
children f16164e720ba
files C++/modules/Js/Js.cpp C++/modules/Js/Js.h C++/tests/Js/main.cpp
diffstat 3 files changed, 69 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/C++/modules/Js/Js.cpp	Tue Oct 06 16:25:51 2015 +0200
+++ b/C++/modules/Js/Js.cpp	Wed Oct 07 08:30:19 2015 +0200
@@ -63,4 +63,45 @@
 	}
 }
 
+void TypeInfo<Function>::push(Context &ctx, Function fn)
+{
+	/* 1. Push function wrapper */
+	duk_push_c_function(ctx, [] (duk_context *ctx) -> duk_ret_t {
+		Context context{ctx};
+
+		duk_push_current_function(ctx);
+		duk_get_prop_string(ctx, -1, "\xff""\xff""js-func");
+		Function *f = static_cast<Function *>(duk_to_pointer(ctx, -1));
+		duk_pop_2(ctx);
+
+		return static_cast<duk_ret_t>(f->function(context));
+	}, fn.nargs);
+
+	/* 2. Store the moved function */
+	duk_push_pointer(ctx, new Function(std::move(fn)));
+	duk_put_prop_string(ctx, -2, "\xff""\xff""js-func");
+
+	/* 3. Store deletion flags */
+	duk_push_boolean(ctx, false);
+	duk_put_prop_string(ctx, -2, "\xff""\xff""js-deleted");
+
+	/* 4. Push and set a finalizer */
+	duk_push_c_function(ctx, [] (duk_context *ctx) {
+		duk_get_prop_string(ctx, 0, "\xff""\xff""js-deleted");
+
+		if (duk_to_boolean(ctx, -1)) {
+			duk_push_boolean(ctx, true);
+			duk_put_prop_string(ctx, 0, "\xff""\xff""js-deleted");
+			duk_get_prop_string(ctx, 0, "\xff""\xff""js-func");
+			delete static_cast<Function *>(duk_to_pointer(ctx, -1));
+			duk_pop(ctx);
+		}
+
+		duk_pop(ctx);
+
+		return 0;
+	}, 1);
+	duk_set_finalizer(ctx, -2);
+}
+
 } // !js
--- a/C++/modules/Js/Js.h	Tue Oct 06 16:25:51 2015 +0200
+++ b/C++/modules/Js/Js.h	Wed Oct 07 08:30:19 2015 +0200
@@ -1082,46 +1082,7 @@
 template <>
 class TypeInfo<Function> {
 public:
-	static void push(Context &ctx, Function fn)
-	{
-		/* 1. Push function wrapper */
-		duk_push_c_function(ctx, [] (duk_context *ctx) -> duk_ret_t {
-			Context context{ctx};
-
-			duk_push_current_function(ctx);
-			duk_get_prop_string(ctx, -1, "\xff""\xff""js-func");
-			Function *f = static_cast<Function *>(duk_to_pointer(ctx, -1));
-			duk_pop_2(ctx);
-
-			return static_cast<duk_ret_t>(f->function(context));
-		}, fn.nargs);
-
-		/* 2. Store the moved function */
-		duk_push_pointer(ctx, new Function(std::move(fn)));
-		duk_put_prop_string(ctx, -2, "\xff""\xff""js-func");
-
-		/* 3. Store deletion flags */
-		duk_push_boolean(ctx, false);
-		duk_put_prop_string(ctx, -2, "\xff""\xff""js-deleted");
-
-		/* 4. Push and set a finalizer */
-		duk_push_c_function(ctx, [] (duk_context *ctx) {
-			duk_get_prop_string(ctx, 0, "\xff""\xff""js-deleted");
-
-			if (duk_to_boolean(ctx, -1)) {
-				duk_push_boolean(ctx, true);
-				duk_put_prop_string(ctx, 0, "\xff""\xff""js-deleted");
-				duk_get_prop_string(ctx, 0, "\xff""\xff""js-func");
-				delete static_cast<Function *>(duk_to_pointer(ctx, -1));
-				duk_pop(ctx);
-			}
-
-			duk_pop(ctx);
-
-			return 0;
-		}, 1);
-		duk_set_finalizer(ctx, -2);
-	}
+	static void push(Context &ctx, Function fn);
 };
 
 /**
--- a/C++/tests/Js/main.cpp	Tue Oct 06 16:25:51 2015 +0200
+++ b/C++/tests/Js/main.cpp	Wed Oct 07 08:30:19 2015 +0200
@@ -501,30 +501,35 @@
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.eval(Script{"x = 123;"});
 	ASSERT_EQ(123, context.getGlobal<int>("x"));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Eval, function)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.eval(Script{"function f() { x = 123; }; f();"});
 	ASSERT_EQ(123, context.getGlobal<int>("x"));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Eval, cfunction)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.putGlobal("f", Function{[] (Context &ctx) -> int {
 		ctx.putGlobal("x", 123);
 
 		return 0;
 	}});
 	context.eval(Script{"f()"});
-
 	ASSERT_EQ(123, context.getGlobal<int>("x"));
+	ASSERT_EQ(1, context.top());
 }
 
 /* ------------------------------------------------------------------
@@ -535,23 +540,27 @@
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	try {
 		context.peval(Script{"x = 1"});
 	} catch (const ErrorInfo &info) {
 		FAIL() << "error unexpected: " << info.what();
 	}
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Peval, failure)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	try {
 		context.peval(Script{"doesnotexists()"});
 
 		FAIL() << "expected exception";
 	} catch (const std::exception &) {
 	}
+	ASSERT_EQ(0, context.top());
 }
 
 /* ------------------------------------------------------------------
@@ -619,7 +628,7 @@
 		ctx.push(Object{});
 
 		/* "update" method */
-		ctx.putProperty(-1, "update", Function{[] (Context &ctx) -> int {
+		ctx.putProperty(-1, "update", Function{[&] (Context &ctx) -> int {
 			ctx.self<Player *>()->m_updated = true;
 
 			return 0;
@@ -659,11 +668,13 @@
 
 TEST(Pointer, simple)
 {
-	Context ctx;
+	Context context;
 	Player *p{new Player};
 
-	ctx.push(p);
-	Player *p2 = ctx.get<Player *>(-1);
+	ASSERT_EQ(0, context.top());
+	context.push(p);
+	Player *p2 = context.get<Player *>(-1);
+	ASSERT_EQ(1, context.top());
 
 	p2->m_updated = true;
 
@@ -696,16 +707,19 @@
 	auto f2 = [&] (Context &) -> int { f2called = true; return 0; };
 
 	FunctionMap map{
-		{ "f1", { f1, 0 }},
-		{ "f2", { f2, 0 }}
+		{ "f1", { f1, 0 } },
+		{ "f2", { f2, 0 } }
 	};
-	Context ctx;
+	Context context;
 
-	ctx.push(Global{});
-	ctx.push(map);
-	ctx.pop();
-	ctx.peval(Script{"f1();"});
-	ctx.peval(Script{"f2();"});
+	ASSERT_EQ(0, context.top());
+	context.push(Global{});
+	ASSERT_EQ(1, context.top());
+	context.push(map);
+	ASSERT_EQ(1, context.top());
+	context.pop();
+	context.peval(Script{"f1();"});
+	context.peval(Script{"f2();"});
 
 	ASSERT_TRUE(f1called);
 	ASSERT_TRUE(f2called);