77namespace pesapi {
88namespace qjsimpl {
99
10- struct TestStruct {
10+ struct TestStructBase {
11+ TestStructBase (int b) {
12+ this ->b = b;
13+ }
14+
15+ int b;
16+ int Foo (int a)
17+ {
18+ return a + b;
19+ }
20+ };
21+
22+ struct TestStruct : public TestStructBase {
1123 static int ctor_count;
1224 static int dtor_count;
1325 static TestStruct* lastCtorObject;
1426 static TestStruct* lastDtorObject;
15- TestStruct (int a) {
27+ TestStruct (int a) : TestStructBase(a - 1 ) {
1628 this ->a = a;
1729 ctor_count++;
1830 lastCtorObject = this ;
@@ -37,6 +49,8 @@ struct TestStruct {
3749 }
3850};
3951
52+ const void * baseTypeId = " TestStructBase" ;
53+
4054const void * typeId = " TestStruct" ;
4155
4256int TestStruct::ctor_count = 0 ;
@@ -57,6 +71,33 @@ static void TestStructFinalize(struct pesapi_ffi* apis, void* ptr, void* class_d
5771 delete (TestStruct*)ptr;
5872}
5973
74+ static void BGetterWrap (struct pesapi_ffi * apis, pesapi_callback_info info)
75+ {
76+ auto env = apis->get_env (info);
77+ auto self = apis->get_this (info);
78+ auto obj = (TestStructBase*)apis->get_native_object_ptr (env, self);
79+ apis->add_return (info, apis->create_int32 (env, obj->b ));
80+ }
81+
82+ static void BSetterWrap (struct pesapi_ffi * apis, pesapi_callback_info info)
83+ {
84+ auto env = apis->get_env (info);
85+ auto self = apis->get_this (info);
86+ auto obj = (TestStructBase*)apis->get_native_object_ptr (env, self);
87+ auto p0 = apis->get_arg (info, 0 );
88+ obj->b = apis->get_value_int32 (env, p0);
89+ }
90+
91+ static void BaseFooWrap (struct pesapi_ffi * apis, pesapi_callback_info info)
92+ {
93+ auto env = apis->get_env (info);
94+ auto self = apis->get_this (info);
95+ auto obj = (TestStructBase*)apis->get_native_object_ptr (env, self);
96+ auto p0 = apis->get_arg (info, 0 );
97+ int a = apis->get_value_int32 (env, p0);
98+ apis->add_return (info, apis->create_int32 (env, obj->Foo (a)));
99+ }
100+
60101static void AddWrap (struct pesapi_ffi * apis, pesapi_callback_info info)
61102{
62103 auto env = apis->get_env (info);
@@ -131,7 +172,25 @@ static void IncWrap(struct pesapi_ffi* apis, pesapi_callback_info info)
131172
132173class PApiBaseTest : public ::testing::Test {
133174public:
134- static void SetUpTestCase () {
175+ static void SetUpTestCase () {
176+ // 封装TestStructBase
177+ const int base_properties_count = 2 ;
178+ pesapi_property_descriptor base_properties = pesapi_alloc_property_descriptors (base_properties_count);
179+ pesapi_set_property_info (base_properties, 0 , " b" , false , BGetterWrap, BSetterWrap, NULL , NULL , NULL );
180+ pesapi_set_method_info (base_properties, 1 , " Foo" , false , BaseFooWrap, NULL , NULL );
181+ pesapi_define_class (baseTypeId, NULL , " TestStructBase" ,
182+ [](struct pesapi_ffi * apis, pesapi_callback_info info) -> void * { // Ctor
183+ auto env = apis->get_env (info);
184+ auto p0 = apis->get_arg (info, 0 );
185+ int b = apis->get_value_int32 (env, p0);
186+ return new TestStructBase (b);
187+ },
188+ [](struct pesapi_ffi * apis, void * ptr, void * class_data, void * env_private) { // Finalize
189+ delete static_cast <TestStructBase*>(ptr);
190+ },
191+ base_properties_count, base_properties, NULL );
192+
193+ // 封装TestStruct
135194 const int properties_count = 6 ;
136195 pesapi_property_descriptor properties = pesapi_alloc_property_descriptors (properties_count);
137196 pesapi_set_method_info (properties, 0 , " Add" , true , AddWrap, NULL , NULL );
@@ -140,7 +199,7 @@ class PApiBaseTest : public ::testing::Test {
140199 pesapi_set_property_info (properties, 3 , " ctor_count" , true , CtorCountGetterWrap, CtorCountSetterWrap, NULL , NULL , NULL );
141200 pesapi_set_method_info (properties, 4 , " GetSelf" , false , GetSelfWrap, NULL , NULL );
142201 pesapi_set_method_info (properties, 5 , " Inc" , false , IncWrap, NULL , NULL );
143- pesapi_define_class (typeId, NULL , " TestStruct" , TestStructCtor, TestStructFinalize, properties_count, properties, NULL );
202+ pesapi_define_class (typeId, baseTypeId , " TestStruct" , TestStructCtor, TestStructFinalize, properties_count, properties, NULL );
144203 }
145204
146205 static void TearDownTestCase () {
@@ -473,6 +532,26 @@ TEST_F(PApiBaseTest, ReturnAObject) {
473532 ASSERT_TRUE (apis->get_value_bool (env, ret));
474533}
475534
535+ TEST_F (PApiBaseTest, MutiObject) {
536+ auto env = apis->get_env_from_ref (env_ref);
537+
538+ auto code = R"(
539+ (function() {
540+ const TestStruct = loadClass('TestStruct');
541+ for (let i = 0; i < 1000; ++i) {
542+ const obj = new TestStruct(123);
543+ const self = obj.GetSelf();
544+ }
545+ })();
546+ )" ;
547+ auto ret = apis->eval (env, (const uint8_t *)(code), strlen (code), " test.js" );
548+ if (apis->has_caught (scope))
549+ {
550+ printf (" %s\n " , apis->get_exception_as_string (scope, true ));
551+ }
552+ ASSERT_FALSE (apis->has_caught (scope));
553+ }
554+
476555TEST_F (PApiBaseTest, RefArgument) {
477556 auto env = apis->get_env_from_ref (env_ref);
478557
@@ -495,6 +574,53 @@ TEST_F(PApiBaseTest, RefArgument) {
495574 EXPECT_EQ (5 , apis->get_value_int32 (env, ret));
496575}
497576
577+ TEST_F (PApiBaseTest, CallFunction) {
578+ auto env = apis->get_env_from_ref (env_ref);
579+
580+ auto code = R"(
581+ function sub(x, y) {
582+ return x - y;
583+ }
584+ sub;
585+ )" ;
586+ auto ret = apis->eval (env, (const uint8_t *)(code), strlen (code), " test.js" );
587+ if (apis->has_caught (scope))
588+ {
589+ printf (" %s\n " , apis->get_exception_as_string (scope, true ));
590+ }
591+ ASSERT_FALSE (apis->has_caught (scope));
592+ ASSERT_TRUE (apis->is_function (env, ret));
593+ pesapi_value argv[2 ] {apis->create_int32 (env, 5 ), apis->create_int32 (env, 3 )};
594+ auto func_call_ret = apis->call_function (env, ret, nullptr , 2 , argv);
595+ ASSERT_TRUE (apis->is_int32 (env, func_call_ret));
596+ EXPECT_EQ (2 , apis->get_value_int32 (env, func_call_ret));
597+ }
598+
599+ TEST_F (PApiBaseTest, SuperAccess) {
600+ auto env = apis->get_env_from_ref (env_ref);
601+
602+ auto code = R"(
603+ (function() {
604+ const TestStruct = loadClass('TestStruct');
605+ const obj = new TestStruct(123);
606+ let ret = "" + obj.b + ":"; // 122
607+ obj.b = 5
608+ ret += obj.Foo(6); // 11
609+ return ret;
610+ })();
611+ )" ;
612+ auto ret = apis->eval (env, (const uint8_t *)(code), strlen (code), " test.js" );
613+ if (apis->has_caught (scope))
614+ {
615+ printf (" %s\n " , apis->get_exception_as_string (scope, true ));
616+ }
617+ ASSERT_FALSE (apis->has_caught (scope));
618+ ASSERT_TRUE (apis->is_string (env, ret));
619+ char buff[1024 ];
620+ size_t len = sizeof (buff);
621+ const char * str = apis->get_value_string_utf8 (env, ret, buff, &len);
622+ EXPECT_STREQ (" 122:11" , str);
623+ }
498624
499625} // namespace qjsimpl
500626} // namespace pesapi
0 commit comments