changeset 410:a786ad1bdf75

Js: - TypeInfo<Map>::push does not create an object, - Shared and Pointer helpers does not set the prototype on construct. - Add some assertions on stack.
author David Demelier <markand@malikania.fr>
date Tue, 06 Oct 2015 16:25:51 +0200
parents 0d004aba3ff6
children 2a0b8613498f
files C++/modules/Js/Js.h C++/tests/Js/main.cpp
diffstat 2 files changed, 89 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/C++/modules/Js/Js.h	Tue Oct 06 14:58:02 2015 +0200
+++ b/C++/modules/Js/Js.h	Tue Oct 06 16:25:51 2015 +0200
@@ -1249,8 +1249,6 @@
 public:
 	static void push(Context &ctx, const Map<T> &map)
 	{
-		duk_push_object(ctx);
-
 		for (const auto &pair : map) {
 			TypeInfo<T>::push(ctx, pair.second);
 			duk_put_prop_string(ctx, -2, pair.first.c_str());
@@ -1323,9 +1321,6 @@
 	duk_put_prop_string(ctx, -2, "\xff""\xff""js-deleted");
 	duk_push_pointer(ctx, new std::shared_ptr<T>(value));
 	duk_put_prop_string(ctx, -2, "\xff""\xff""js-shared-ptr");
-
-	TypeInfo<std::shared_ptr<T>>::prototype(ctx);
-	duk_set_prototype(ctx, -2);
 	duk_push_c_function(ctx, [] (duk_context *ctx) -> duk_ret_t {
 		duk_get_prop_string(ctx, 0, "\xff""\xff""js-deleted");
 
@@ -1357,6 +1352,8 @@
 {
 	duk_push_object(ctx);
 	apply(ctx, std::move(value));
+	TypeInfo<std::shared_ptr<T>>::prototype(ctx);
+	duk_set_prototype(ctx, -2);
 }
 
 template <typename T>
@@ -1397,8 +1394,6 @@
 	duk_put_prop_string(ctx, -2, "\xff""\xff""js-deleted");
 	duk_push_pointer(ctx, value);
 	duk_put_prop_string(ctx, -2, "\xff""\xff""js-ptr");
-	TypeInfo<T *>::prototype(ctx);
-	duk_set_prototype(ctx, -2);
 	duk_push_c_function(ctx, [] (duk_context *ctx) -> duk_ret_t {
 		duk_get_prop_string(ctx, 0, "\xff""\xff""js-deleted");
 
@@ -1430,6 +1425,8 @@
 {
 	duk_push_object(ctx);
 	apply(ctx, value);
+	TypeInfo<T *>::prototype(ctx);
+	duk_set_prototype(ctx, -2);
 }
 
 template <typename T>
--- a/C++/tests/Js/main.cpp	Tue Oct 06 14:58:02 2015 +0200
+++ b/C++/tests/Js/main.cpp	Tue Oct 06 16:25:51 2015 +0200
@@ -38,54 +38,69 @@
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(true);
 	ASSERT_TRUE(context.get<bool>(-1));
+	ASSERT_EQ(1, context.top());
 	context.push(false);
 	ASSERT_FALSE(context.get<bool>(-1));
+	ASSERT_EQ(2, context.top());
 }
 
 TEST(PushAndGet, integer)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(123);
 	ASSERT_EQ(123, context.get<int>(-1));
+	ASSERT_EQ(1, context.top());
 	context.push(456);
 	ASSERT_EQ(456, context.get<int>(-1));
+	ASSERT_EQ(2, context.top());
 }
 
 TEST(PushAndGet, number)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(10.5);
 	ASSERT_EQ(10.5, context.get<double>(-1));
+	ASSERT_EQ(1, context.top());
 	context.push(50.1);
 	ASSERT_EQ(50.1, context.get<double>(-1));
+	ASSERT_EQ(2, context.top());
 }
 
 TEST(PushAndGet, string)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push("hello world!");
 	ASSERT_EQ("hello world!", context.get<std::string>(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(PushAndGet, undefined)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(Undefined{});
 	ASSERT_EQ(DUK_TYPE_UNDEFINED, context.type(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(PushAndGet, null)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(Null{});
 	ASSERT_EQ(DUK_TYPE_NULL, context.type(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(PushAndGet, map)
@@ -96,20 +111,24 @@
 		{ "two",	2 }
 	};
 
+	ASSERT_EQ(0, context.top());
+	context.push(js::Object{});
 	context.push(map);
 
 	ASSERT_EQ(DUK_TYPE_OBJECT, context.type(-1));
 	ASSERT_EQ(1, context.getProperty<int>(-1, "one"));
 	ASSERT_EQ(2, context.getProperty<int>(-1, "two"));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(PushAndGet, vector)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(std::vector<int>{1, 2, 3});
-
 	ASSERT_EQ(DUK_TYPE_OBJECT, context.type(-1));
+	ASSERT_EQ(1, context.top());
 
 	auto array = context.get<std::vector<int>>(-1);
 	ASSERT_EQ(3U, array.size());
@@ -126,6 +145,8 @@
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
+
 	try {
 		context.push(Function{[] (Context &ctx) -> int {
 			ctx.require<bool>(0);
@@ -137,12 +158,16 @@
 		FAIL() << "exception expected";
 	} catch (...) {
 	}
+
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Require, integer)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
+
 	try {
 		context.push(Function{[] (Context &ctx) -> int {
 			ctx.require<int>(0);
@@ -154,12 +179,16 @@
 		FAIL() << "exception expected";
 	} catch (...) {
 	}
+
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Require, number)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
+
 	try {
 		context.push(Function{[] (Context &ctx) -> int {
 			ctx.require<double>(0);
@@ -171,12 +200,16 @@
 		FAIL() << "exception expected";
 	} catch (...) {
 	}
+
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Require, string)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
+
 	try {
 		context.push(Function{[] (Context &ctx) -> int {
 			ctx.require<std::string>(0);
@@ -188,12 +221,16 @@
 		FAIL() << "exception expected";
 	} catch (...) {
 	}
+
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Require, cstring)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
+
 	try {
 		context.push(Function{[] (Context &ctx) -> int {
 			ctx.require<const char *>(0);
@@ -205,6 +242,8 @@
 		FAIL() << "exception expected";
 	} catch (...) {
 	}
+
+	ASSERT_EQ(0, context.top());
 }
 
 /* --------------------------------------------------------
@@ -215,72 +254,90 @@
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(true);
 	ASSERT_TRUE(context.is<bool>(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Is, integer)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(123);
 	ASSERT_TRUE(context.is<int>(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Is, number)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(50.5);
 	ASSERT_TRUE(context.is<double>(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Is, string)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(std::string{"hello"});
 	ASSERT_TRUE(context.is<std::string>(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Is, cstring)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push("hello");
 	ASSERT_TRUE(context.is<const char *>(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Is, undefined)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(Undefined{});
 	ASSERT_TRUE(context.is<Undefined>(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Is, null)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(Null{});
 	ASSERT_TRUE(context.is<Null>(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Is, object)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(Object{});
 	ASSERT_TRUE(context.is<Object>(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Is, array)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(Array{});
 	ASSERT_TRUE(context.is<Array>(-1));
+	ASSERT_EQ(1, context.top());
 }
 
 /* --------------------------------------------------------
@@ -291,40 +348,50 @@
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	ASSERT_TRUE(context.optional<bool>(0, true));
 	ASSERT_FALSE(context.optional<bool>(0, false));
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Optional, integer)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	ASSERT_EQ(123, context.optional<int>(0, 123));
 	ASSERT_EQ(456, context.optional<int>(0, 456));
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Optional, number)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	ASSERT_EQ(10.0, context.optional<double>(0, 10.0));
 	ASSERT_EQ(20.0, context.optional<double>(0, 20.0));
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Optional, string)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	ASSERT_EQ("no", context.optional<std::string>(0, "no"));
 	ASSERT_EQ("yes", context.optional<std::string>(0, "yes"));
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Optional, cstring)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	ASSERT_STREQ("no", context.optional<const char *>(0, "no"));
 	ASSERT_STREQ("yes", context.optional<const char *>(0, "yes"));
+	ASSERT_EQ(0, context.top());
 }
 
 /* --------------------------------------------------------
@@ -336,60 +403,68 @@
 	Context context;
 
 	// boolean
+	ASSERT_EQ(0, context.top());
 	context.putGlobal("valueBoolean", true);
 	ASSERT_TRUE(context.getGlobal<bool>("valueBoolean"));
+	ASSERT_EQ(0, context.top());
 
 	// integer
+	ASSERT_EQ(0, context.top());
 	context.putGlobal("valueInteger", 123);
 	ASSERT_EQ(123, context.getGlobal<int>("valueInteger"));
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Basics, top)
 {
 	Context context;
 
-	int current = context.top();
+	ASSERT_EQ(0, context.top());
 	context.push(true);
-	ASSERT_EQ(current + 1, context.top());
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Basics, pop1)
 {
 	Context context;
 
-	int current = context.top();
+	ASSERT_EQ(0, context.top());
 	context.push(true);
 	context.pop();
-	ASSERT_EQ(current, context.top());
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Basics, pop2)
 {
 	Context context;
 
-	int current = context.top();
+	ASSERT_EQ(0, context.top());
 	context.push(true);
 	context.push(true);
 	context.pop(2);
-	ASSERT_EQ(current, context.top());
+	ASSERT_EQ(0, context.top());
 }
 
 TEST(Basics, putProperty)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(Object{});
 	context.putProperty(-1, "x", 123);
 	ASSERT_EQ(123, context.getProperty<int>(-1, "x"));
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Basics, enumerate)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(Object{});
 	context.putProperty(-1, "x", 123);
 	context.putProperty(-1, "y", 456);
+	ASSERT_EQ(1, context.top());
 	context.enumerate(-1, 0, true, [] (Context &ctx) {
 		ASSERT_EQ(DUK_TYPE_STRING, ctx.type(-2));
 		ASSERT_EQ(DUK_TYPE_NUMBER, ctx.type(-1));
@@ -399,18 +474,21 @@
 		if (ctx.get<std::string>(-2) == "y")
 			ASSERT_EQ(456, ctx.get<int>(-1));
 	});
+	ASSERT_EQ(1, context.top());
 }
 
 TEST(Basics, call)
 {
 	Context context;
 
+	ASSERT_EQ(0, context.top());
 	context.push(Function{[] (Context &ctx) -> int {
 		ctx.putGlobal("x", 123);
 
 		return 0;
 	}});
 	context.call();
+	ASSERT_EQ(1, context.top());
 
 	ASSERT_EQ(123, context.getGlobal<int>("x"));
 }