diff --git a/coverage/amber.png b/coverage/amber.png new file mode 100644 index 0000000..2cab170 Binary files /dev/null and b/coverage/amber.png differ diff --git a/coverage/emerald.png b/coverage/emerald.png new file mode 100644 index 0000000..38ad4f4 Binary files /dev/null and b/coverage/emerald.png differ diff --git a/coverage/gcov.css b/coverage/gcov.css new file mode 100644 index 0000000..bfd0a83 --- /dev/null +++ b/coverage/gcov.css @@ -0,0 +1,519 @@ +/* All views: initial background and text color */ +body +{ + color: #000000; + background-color: #FFFFFF; +} + +/* All views: standard link format*/ +a:link +{ + color: #284FA8; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #00CB40; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #FF0040; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding-bottom: 10px; + font-family: sans-serif; + font-size: 20pt; + font-style: italic; + font-weight: bold; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: top; + white-space: nowrap; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + color: #284FA8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; +} + +/* All views: header item coverage table heading */ +td.headerCovTableHead +{ + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; +} + +/* All views: header item coverage table entry */ +td.headerCovTableEntry +{ + text-align: right; + color: #284FA8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #DAE7FE; +} + +/* All views: header item coverage table entry for high coverage rate */ +td.headerCovTableEntryHi +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #A7FC9D; +} + +/* All views: header item coverage table entry for medium coverage rate */ +td.headerCovTableEntryMed +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #FFEA20; +} + +/* All views: header item coverage table entry for ow coverage rate */ +td.headerCovTableEntryLo +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #FF0000; +} + +/* All views: header legend value for legend entry */ +td.headerValueLeg +{ + text-align: left; + color: #000000; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; + padding-top: 4px; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #6688D4; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: + table headline format */ +td.tableHead +{ + text-align: center; + color: #FFFFFF; + background-color: #6688D4; + font-family: sans-serif; + font-size: 120%; + font-weight: bold; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; +} + +span.tableHeadSort +{ + padding-right: 4px; +} + +/* Directory view/File view (all): filename entry format */ +td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284FA8; + background-color: #DAE7FE; + font-family: monospace; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #000000; +} + +/* Directory view/File view (all): percentage entry for files with + high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #A7FC9D; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #A7FC9D; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FFEA20; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FFEA20; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + white-space: nowrap; + font-family: sans-serif; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #FFFFFF; + font-size:80%; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: right; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #DAE7FE; +} + +/* Source code view: function entry */ +td.coverFn +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284FA8; + background-color: #DAE7FE; + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; + margin-top: 2px; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #EFE383; +} + +/* Source code view: format for lines which were executed */ +td.lineCov, +span.lineCov +{ + background-color: #CAD7FE; +} + +/* Source code view: format for Cov legend */ +span.coverLegendCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #CAD7FE; +} + +/* Source code view: format for lines which were not executed */ +td.lineNoCov, +span.lineNoCov +{ + background-color: #FF6230; +} + +/* Source code view: format for NoCov legend */ +span.coverLegendNoCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #FF6230; +} + +/* Source code view (function table): standard link - visited format */ +td.lineNoCov > a:visited, +td.lineCov > a:visited +{ + color: black; + text-decoration: underline; +} + +/* Source code view: format for lines which were executed only in a + previous version */ +span.lineDiffCov +{ + background-color: #B5F7AF; +} + +/* Source code view: format for branches which were executed + * and taken */ +span.branchCov +{ + background-color: #CAD7FE; +} + +/* Source code view: format for branches which were executed + * but not taken */ +span.branchNoCov +{ + background-color: #FF6230; +} + +/* Source code view: format for branches which were not executed */ +span.branchNoExec +{ + background-color: #FF6230; +} + +/* Source code view: format for the source code heading line */ +pre.sourceHeading +{ + white-space: pre; + font-family: monospace; + font-weight: bold; + margin: 0px; +} + +/* All views: header legend value for low rate */ +td.headerValueLegL +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 4px; + padding-right: 2px; + background-color: #FF0000; + font-size: 80%; +} + +/* All views: header legend value for med rate */ +td.headerValueLegM +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 2px; + background-color: #FFEA20; + font-size: 80%; +} + +/* All views: header legend value for hi rate */ +td.headerValueLegH +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 4px; + background-color: #A7FC9D; + font-size: 80%; +} + +/* All views except source code view: legend format for low coverage */ +span.coverLegendCovLo +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #FF0000; +} + +/* All views except source code view: legend format for med coverage */ +span.coverLegendCovMed +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #FFEA20; +} + +/* All views except source code view: legend format for hi coverage */ +span.coverLegendCovHi +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #A7FC9D; +} diff --git a/coverage/glass.png b/coverage/glass.png new file mode 100644 index 0000000..e1abc00 Binary files /dev/null and b/coverage/glass.png differ diff --git a/coverage/index-sort-f.html b/coverage/index-sort-f.html new file mode 100644 index 0000000..7ac4021 --- /dev/null +++ b/coverage/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcov.infoLines:65273688.6 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
88.6%88.6%
+
88.6 %652 / 736-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/index-sort-l.html b/coverage/index-sort-l.html new file mode 100644 index 0000000..830fe7a --- /dev/null +++ b/coverage/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcov.infoLines:65273688.6 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
88.6%88.6%
+
88.6 %652 / 736-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 0000000..d6f3c3d --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcov.infoLines:65273688.6 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
88.6%88.6%
+
88.6 %652 / 736-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/lcov.info b/coverage/lcov.info new file mode 100644 index 0000000..59b9391 --- /dev/null +++ b/coverage/lcov.info @@ -0,0 +1,756 @@ +SF:lib/src/object.dart +DA:14,3 +DA:15,3 +DA:17,3 +DA:18,3 +DA:25,3 +DA:27,3 +DA:31,15 +DA:33,8 +DA:34,3 +DA:35,3 +DA:39,0 +DA:41,0 +DA:44,0 +DA:53,3 +DA:54,3 +DA:55,3 +DA:56,6 +DA:57,15 +DA:60,3 +DA:61,18 +DA:65,0 +DA:67,0 +DA:68,0 +DA:71,3 +DA:73,3 +DA:74,3 +DA:75,3 +DA:76,3 +DA:78,15 +DA:79,6 +DA:87,2 +DA:88,2 +DA:89,0 +DA:90,0 +DA:92,4 +DA:93,5 +DA:97,0 +DA:99,0 +DA:102,3 +DA:103,3 +DA:104,6 +DA:108,2 +DA:110,2 +DA:111,2 +DA:112,2 +DA:124,3 +DA:125,3 +DA:126,6 +DA:127,9 +DA:128,9 +DA:131,3 +DA:133,3 +DA:134,3 +DA:135,3 +DA:136,3 +DA:138,6 +DA:139,9 +DA:140,3 +DA:143,1 +DA:145,2 +DA:146,3 +DA:152,6 +DA:154,3 +DA:156,3 +DA:157,3 +DA:158,9 +DA:160,0 +DA:161,0 +DA:163,3 +DA:164,3 +DA:168,3 +DA:169,3 +DA:170,3 +DA:172,0 +DA:174,3 +DA:175,6 +DA:177,3 +DA:178,3 +DA:179,3 +DA:180,3 +DA:181,6 +DA:182,3 +DA:187,2 +DA:189,4 +DA:198,3 +DA:200,3 +DA:201,6 +DA:203,3 +DA:206,6 +DA:208,3 +DA:210,3 +DA:211,6 +DA:212,3 +DA:214,6 +DA:215,12 +DA:217,0 +DA:218,12 +DA:219,3 +DA:221,0 +DA:223,0 +DA:229,3 +DA:232,3 +DA:233,3 +DA:234,1 +DA:235,3 +DA:236,6 +DA:237,3 +DA:239,3 +DA:241,6 +DA:242,5 +DA:243,0 +DA:244,3 +DA:247,2 +DA:248,4 +DA:249,4 +DA:250,2 +DA:253,3 +DA:255,3 +DA:256,6 +DA:258,3 +DA:259,6 +DA:260,8 +DA:262,3 +DA:263,0 +DA:266,6 +DA:267,6 +DA:268,6 +DA:272,3 +DA:273,3 +DA:274,3 +DA:275,6 +DA:281,3 +DA:282,3 +DA:283,3 +DA:284,3 +DA:285,3 +DA:290,3 +DA:292,3 +DA:293,6 +DA:294,6 +DA:300,3 +DA:302,3 +DA:305,3 +DA:307,3 +DA:310,0 +DA:312,0 +LF:146 +LH:126 +end_of_record +SF:lib/src/isolate.dart +DA:11,9 +DA:20,3 +DA:21,3 +DA:22,5 +DA:23,6 +DA:24,3 +DA:25,3 +DA:26,3 +DA:27,9 +DA:28,9 +DA:32,3 +DA:33,2 +DA:34,2 +DA:35,4 +DA:36,6 +DA:37,4 +DA:41,3 +DA:42,2 +DA:43,4 +DA:44,6 +DA:45,2 +DA:46,4 +DA:48,2 +DA:49,6 +DA:50,2 +DA:51,6 +DA:54,2 +DA:55,2 +DA:61,3 +DA:62,3 +DA:63,5 +DA:64,3 +DA:65,3 +DA:66,3 +DA:67,9 +DA:68,9 +DA:72,3 +DA:73,6 +DA:74,3 +DA:77,2 +DA:78,2 +DA:79,2 +DA:80,4 +DA:81,2 +DA:82,6 +DA:83,6 +DA:84,2 +DA:85,4 +DA:86,6 +DA:88,4 +DA:91,2 +DA:93,2 +DA:94,2 +DA:95,4 +DA:96,6 +DA:97,4 +DA:104,2 +DA:105,2 +DA:106,2 +DA:107,4 +DA:108,2 +DA:109,2 +DA:110,1 +DA:111,2 +DA:113,1 +DA:116,0 +DA:118,0 +DA:119,0 +DA:122,0 +DA:124,0 +DA:125,0 +DA:126,0 +DA:127,0 +DA:128,0 +DA:129,0 +DA:133,4 +DA:135,2 +DA:137,2 +DA:138,2 +DA:139,4 +DA:140,2 +DA:141,2 +DA:142,2 +DA:145,2 +DA:147,4 +DA:148,2 +DA:149,2 +DA:153,4 +DA:156,0 +DA:157,0 +DA:161,4 +DA:182,1 +DA:188,1 +DA:189,1 +DA:190,1 +DA:191,1 +DA:193,1 +DA:194,1 +DA:195,1 +DA:199,1 +DA:200,2 +DA:201,2 +DA:202,1 +DA:205,1 +DA:206,1 +DA:208,2 +DA:209,1 +DA:210,2 +DA:212,0 +DA:215,0 +DA:218,0 +DA:219,0 +DA:221,0 +DA:223,0 +DA:227,0 +DA:228,0 +DA:229,0 +DA:230,0 +DA:232,2 +DA:236,1 +DA:237,1 +DA:238,1 +DA:240,2 +DA:241,1 +DA:242,2 +DA:244,1 +DA:246,2 +DA:247,1 +DA:248,1 +DA:249,0 +DA:250,1 +DA:256,1 +DA:261,1 +DA:262,1 +DA:263,2 +DA:264,2 +DA:269,1 +DA:271,2 +DA:272,1 +DA:273,2 +DA:274,0 +DA:275,1 +LF:142 +LH:118 +end_of_record +SF:lib/src/wrapper.dart +DA:10,2 +DA:11,2 +DA:14,2 +DA:18,1 +DA:22,2 +DA:29,2 +DA:30,4 +DA:31,4 +DA:35,2 +DA:38,4 +DA:39,2 +DA:42,3 +DA:48,3 +DA:49,6 +DA:50,6 +DA:51,6 +DA:52,3 +DA:56,3 +DA:58,6 +DA:59,3 +DA:60,3 +DA:61,3 +DA:62,4 +DA:63,2 +DA:64,4 +DA:65,4 +DA:68,12 +DA:69,3 +DA:70,9 +DA:72,12 +DA:73,6 +DA:74,3 +DA:75,3 +DA:76,3 +DA:77,3 +DA:78,3 +DA:79,3 +DA:80,3 +DA:81,3 +DA:82,3 +DA:83,6 +DA:84,6 +DA:85,2 +DA:86,4 +DA:87,6 +DA:88,3 +DA:89,3 +DA:93,3 +DA:94,7 +DA:95,7 +DA:96,7 +DA:97,6 +DA:98,3 +DA:99,0 +DA:100,0 +DA:101,0 +DA:102,0 +DA:103,0 +DA:106,3 +DA:107,6 +DA:109,3 +DA:110,4 +DA:111,2 +DA:112,6 +DA:113,4 +DA:117,3 +DA:118,4 +DA:119,2 +DA:120,4 +DA:121,6 +DA:126,3 +DA:128,15 +DA:129,3 +DA:130,6 +DA:133,6 +DA:135,3 +DA:136,6 +DA:137,3 +DA:143,3 +DA:145,3 +DA:146,6 +DA:147,9 +DA:148,4 +DA:151,3 +DA:152,6 +DA:153,3 +DA:154,4 +DA:155,3 +DA:156,3 +DA:157,3 +DA:158,6 +DA:159,9 +DA:161,3 +DA:162,6 +DA:163,3 +DA:166,6 +DA:167,3 +DA:168,3 +DA:169,6 +DA:170,0 +DA:172,6 +DA:173,3 +DA:174,2 +DA:176,9 +DA:177,3 +DA:178,9 +DA:179,2 +DA:180,2 +DA:182,8 +DA:183,2 +DA:184,2 +DA:185,9 +DA:186,3 +DA:188,3 +DA:189,3 +DA:190,3 +DA:191,8 +DA:192,3 +DA:193,6 +DA:194,3 +DA:195,3 +DA:196,6 +DA:198,2 +DA:199,2 +DA:200,4 +DA:203,3 +DA:204,3 +DA:205,9 +DA:206,3 +DA:207,0 +DA:208,3 +DA:209,6 +DA:210,2 +DA:211,4 +DA:212,2 +DA:213,2 +DA:214,4 +DA:215,2 +DA:216,4 +DA:217,2 +DA:223,8 +DA:224,0 +DA:225,0 +DA:228,2 +DA:229,2 +DA:230,2 +DA:231,2 +DA:232,4 +DA:233,6 +DA:234,4 +DA:235,4 +DA:236,4 +DA:237,2 +DA:238,2 +DA:239,2 +DA:240,4 +DA:242,6 +DA:243,2 +LF:158 +LH:149 +end_of_record +SF:lib/src/engine.dart +DA:33,3 +DA:39,3 +DA:40,3 +DA:41,6 +DA:44,3 +DA:45,3 +DA:46,9 +DA:47,3 +DA:48,6 +DA:49,6 +DA:51,3 +DA:52,15 +DA:56,3 +DA:58,3 +DA:60,3 +DA:62,3 +DA:64,6 +DA:66,3 +DA:67,1 +DA:68,2 +DA:69,2 +DA:70,1 +DA:71,2 +DA:72,1 +DA:74,1 +DA:75,3 +DA:76,2 +DA:77,2 +DA:78,4 +DA:80,0 +DA:82,2 +DA:83,3 +DA:84,3 +DA:85,9 +DA:86,3 +DA:88,0 +DA:90,0 +DA:91,0 +DA:92,0 +DA:94,0 +DA:95,0 +DA:96,0 +DA:98,0 +DA:99,0 +DA:100,0 +DA:101,0 +DA:102,0 +DA:103,0 +DA:107,3 +DA:108,3 +DA:109,3 +DA:110,3 +DA:111,6 +DA:115,3 +DA:116,3 +DA:117,3 +DA:118,3 +DA:119,3 +DA:120,6 +DA:122,3 +DA:124,3 +DA:125,1 +DA:126,1 +DA:130,3 +DA:131,3 +DA:132,3 +DA:135,6 +DA:136,3 +DA:137,3 +DA:144,3 +DA:145,9 +DA:146,3 +DA:151,3 +DA:156,3 +DA:157,3 +DA:158,3 +DA:164,9 +DA:165,1 +DA:166,1 +DA:168,3 +DA:169,3 +LF:81 +LH:67 +end_of_record +SF:lib/src/ffi.dart +DA:14,3 +DA:16,3 +DA:17,3 +DA:25,3 +DA:26,6 +DA:29,3 +DA:30,6 +DA:31,9 +DA:36,3 +DA:37,7 +DA:40,3 +DA:41,7 +DA:44,3 +DA:51,3 +DA:52,3 +DA:53,3 +DA:54,12 +DA:56,3 +DA:57,2 +DA:58,10 +DA:60,3 +DA:61,2 +DA:116,15 +DA:117,3 +DA:118,3 +DA:119,0 +DA:120,0 +DA:121,0 +DA:122,0 +DA:123,0 +DA:124,0 +DA:125,0 +DA:126,0 +DA:132,0 +DA:142,0 +DA:147,9 +DA:148,3 +DA:159,9 +DA:160,3 +DA:172,3 +DA:174,6 +DA:176,9 +DA:178,9 +DA:180,3 +DA:181,6 +DA:185,9 +DA:187,3 +DA:192,3 +DA:193,3 +DA:194,6 +DA:195,12 +DA:198,3 +DA:202,6 +DA:203,9 +DA:211,0 +DA:223,9 +DA:224,3 +DA:231,3 +DA:234,3 +DA:235,6 +DA:238,12 +DA:240,3 +DA:241,12 +DA:243,6 +DA:244,2 +DA:245,2 +DA:246,4 +DA:247,1 +DA:248,6 +DA:249,1 +DA:252,6 +DA:253,6 +DA:254,1 +DA:255,1 +DA:263,9 +DA:264,3 +DA:275,9 +DA:276,3 +DA:283,3 +DA:284,6 +DA:285,6 +DA:286,0 +DA:287,6 +DA:294,9 +DA:295,3 +DA:305,9 +DA:306,3 +DA:320,9 +DA:321,3 +DA:332,3 +DA:338,3 +DA:339,3 +DA:340,6 +DA:343,3 +DA:347,3 +DA:348,3 +DA:349,21 +DA:356,9 +DA:357,3 +DA:367,9 +DA:368,3 +DA:378,9 +DA:379,3 +DA:390,6 +DA:391,2 +DA:403,6 +DA:404,2 +DA:416,6 +DA:417,2 +DA:429,9 +DA:430,3 +DA:438,3 +DA:442,3 +DA:443,6 +DA:444,3 +DA:453,0 +DA:466,6 +DA:467,2 +DA:477,6 +DA:478,2 +DA:490,9 +DA:491,3 +DA:500,3 +DA:505,6 +DA:513,0 +DA:523,0 +DA:528,0 +DA:535,9 +DA:536,3 +DA:548,0 +DA:561,6 +DA:562,2 +DA:574,6 +DA:575,2 +DA:587,6 +DA:588,2 +DA:600,9 +DA:601,3 +DA:613,9 +DA:614,3 +DA:622,3 +DA:626,6 +DA:627,6 +DA:628,3 +DA:629,6 +DA:637,9 +DA:638,3 +DA:646,3 +DA:650,3 +DA:651,6 +DA:655,3 +DA:664,9 +DA:665,3 +DA:678,9 +DA:679,3 +DA:692,9 +DA:693,3 +DA:706,9 +DA:707,3 +DA:719,9 +DA:720,3 +DA:732,6 +DA:733,2 +DA:745,9 +DA:746,3 +DA:757,6 +DA:758,2 +DA:771,9 +DA:772,3 +DA:789,6 +DA:790,2 +DA:805,9 +DA:806,3 +DA:818,9 +DA:819,3 +DA:831,6 +DA:832,2 +DA:848,6 +DA:849,2 +DA:864,6 +DA:865,2 +DA:874,9 +DA:875,3 +DA:878,12 +DA:885,9 +DA:886,3 +DA:903,9 +DA:904,3 +DA:915,3 +DA:922,15 +DA:923,3 +DA:924,9 +DA:925,3 +DA:926,6 +DA:928,6 +DA:930,9 +DA:931,3 +DA:932,3 +DA:933,21 +DA:940,9 +DA:941,3 +DA:951,3 +DA:952,1 +DA:962,9 +DA:963,3 +DA:974,9 +DA:975,3 +DA:987,6 +DA:988,2 +LF:209 +LH:192 +end_of_record diff --git a/coverage/ruby.png b/coverage/ruby.png new file mode 100644 index 0000000..991b6d4 Binary files /dev/null and b/coverage/ruby.png differ diff --git a/coverage/snow.png b/coverage/snow.png new file mode 100644 index 0000000..2cdae10 Binary files /dev/null and b/coverage/snow.png differ diff --git a/coverage/src/engine.dart.func-sort-c.html b/coverage/src/engine.dart.func-sort-c.html new file mode 100644 index 0000000..d4767f6 --- /dev/null +++ b/coverage/src/engine.dart.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - lcov.info - src/engine.dart - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - engine.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:678182.7 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/engine.dart.func.html b/coverage/src/engine.dart.func.html new file mode 100644 index 0000000..ed67dd1 --- /dev/null +++ b/coverage/src/engine.dart.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - lcov.info - src/engine.dart - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - engine.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:678182.7 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/engine.dart.gcov.html b/coverage/src/engine.dart.gcov.html new file mode 100644 index 0000000..4b087c1 --- /dev/null +++ b/coverage/src/engine.dart.gcov.html @@ -0,0 +1,248 @@ + + + + + + + LCOV - lcov.info - src/engine.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - engine.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:678182.7 %
Date:2021-03-31 22:28:15Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /*
+       2             :  * @Description: quickjs engine
+       3             :  * @Author: ekibun
+       4             :  * @Date: 2020-08-08 08:29:09
+       5             :  * @LastEditors: ekibun
+       6             :  * @LastEditTime: 2020-10-06 23:47:13
+       7             :  */
+       8             : part of '../flutter_qjs.dart';
+       9             : 
+      10             : /// Handler function to manage js module.
+      11             : typedef _JsModuleHandler = String Function(String name);
+      12             : 
+      13             : /// Handler to manage unhandled promise rejection.
+      14             : typedef _JsHostPromiseRejectionHandler = void Function(dynamic reason);
+      15             : 
+      16             : /// Quickjs engine for flutter.
+      17             : class FlutterQjs {
+      18             :   Pointer<JSRuntime>? _rt;
+      19             :   Pointer<JSContext>? _ctx;
+      20             : 
+      21             :   /// Max stack size for quickjs.
+      22             :   final int? stackSize;
+      23             : 
+      24             :   /// Message Port for event loop. Close it to stop dispatching event loop.
+      25             :   ReceivePort port = ReceivePort();
+      26             : 
+      27             :   /// Handler function to manage js module.
+      28             :   final _JsModuleHandler? moduleHandler;
+      29             : 
+      30             :   /// Handler function to manage js module.
+      31             :   final _JsHostPromiseRejectionHandler? hostPromiseRejectionHandler;
+      32             : 
+      33           3 :   FlutterQjs({
+      34             :     this.moduleHandler,
+      35             :     this.stackSize,
+      36             :     this.hostPromiseRejectionHandler,
+      37             :   });
+      38             : 
+      39           3 :   _ensureEngine() {
+      40           3 :     if (_rt != null) return;
+      41           6 :     final rt = jsNewRuntime((ctx, type, ptr) {
+      42             :       try {
+      43             :         switch (type) {
+      44           3 :           case JSChannelType.METHON:
+      45           3 :             final pdata = ptr.cast<Pointer<JSValue>>();
+      46           9 :             final argc = pdata.elementAt(1).value.cast<Int32>().value;
+      47           3 :             final pargs = [];
+      48           6 :             for (var i = 0; i < argc; ++i) {
+      49           6 :               pargs.add(_jsToDart(
+      50             :                 ctx,
+      51           3 :                 Pointer.fromAddress(
+      52          15 :                   pdata.elementAt(2).value.address + sizeOfJSValue * i,
+      53             :                 ),
+      54             :               ));
+      55             :             }
+      56           3 :             final JSInvokable func = _jsToDart(
+      57             :               ctx,
+      58           3 :               pdata.elementAt(3).value,
+      59             :             );
+      60           3 :             return _dartToJs(
+      61             :                 ctx,
+      62           3 :                 func.invoke(
+      63             :                   pargs,
+      64           6 :                   _jsToDart(ctx, pdata.elementAt(0).value),
+      65             :                 ));
+      66           3 :           case JSChannelType.MODULE:
+      67           1 :             if (moduleHandler == null) throw JSError('No ModuleHandler');
+      68           2 :             final ret = moduleHandler!(
+      69           2 :               ptr.cast<Utf8>().toDartString(),
+      70           1 :             ).toNativeUtf8();
+      71           2 :             Future.microtask(() {
+      72           1 :               malloc.free(ret);
+      73             :             });
+      74           1 :             return ret.cast();
+      75           3 :           case JSChannelType.PROMISE_TRACK:
+      76           2 :             final err = _parseJSException(ctx, ptr);
+      77           2 :             if (hostPromiseRejectionHandler != null) {
+      78           4 :               hostPromiseRejectionHandler!(err);
+      79             :             } else {
+      80           0 :               print('unhandled promise rejection: $err');
+      81             :             }
+      82           2 :             return nullptr;
+      83           3 :           case JSChannelType.FREE_OBJECT:
+      84           3 :             final rt = ctx.cast<JSRuntime>();
+      85           9 :             _DartObject.fromAddress(rt, ptr.address)?.free();
+      86           3 :             return nullptr;
+      87             :         }
+      88           0 :         throw JSError('call channel with wrong type');
+      89             :       } catch (e) {
+      90           0 :         if (type == JSChannelType.FREE_OBJECT) {
+      91           0 :           print('DartObject release error: $e');
+      92           0 :           return nullptr;
+      93             :         }
+      94           0 :         if (type == JSChannelType.MODULE) {
+      95           0 :           print('host Promise Rejection Handler error: $e');
+      96           0 :           return nullptr;
+      97             :         }
+      98           0 :         final throwObj = _dartToJs(ctx, e);
+      99           0 :         final err = jsThrow(ctx, throwObj);
+     100           0 :         jsFreeValue(ctx, throwObj);
+     101           0 :         if (type == JSChannelType.MODULE) {
+     102           0 :           jsFreeValue(ctx, err);
+     103           0 :           return nullptr;
+     104             :         }
+     105             :         return err;
+     106             :       }
+     107           3 :     }, port);
+     108           3 :     final stackSize = this.stackSize ?? 0;
+     109           3 :     if (stackSize > 0) jsSetMaxStackSize(rt, stackSize);
+     110           3 :     _rt = rt;
+     111           6 :     _ctx = jsNewContext(rt);
+     112             :   }
+     113             : 
+     114             :   /// Free Runtime and Context which can be recreate when evaluate again.
+     115           3 :   close() {
+     116           3 :     final rt = _rt;
+     117           3 :     final ctx = _ctx;
+     118           3 :     _rt = null;
+     119           3 :     _ctx = null;
+     120           6 :     if (ctx != null) jsFreeContext(ctx);
+     121             :     if (rt == null) return;
+     122           3 :     _executePendingJob();
+     123             :     try {
+     124           3 :       jsFreeRuntime(rt);
+     125           1 :     } on String catch (e) {
+     126           1 :       throw JSError(e);
+     127             :     }
+     128             :   }
+     129             : 
+     130           3 :   void _executePendingJob() {
+     131           3 :     final rt = _rt;
+     132           3 :     final ctx = _ctx;
+     133             :     if (rt == null || ctx == null) return;
+     134             :     while (true) {
+     135           6 :       int err = jsExecutePendingJob(rt);
+     136           3 :       if (err <= 0) {
+     137           3 :         if (err < 0) print(_parseJSException(ctx));
+     138             :         break;
+     139             :       }
+     140             :     }
+     141             :   }
+     142             : 
+     143             :   /// Dispatch JavaScript Event loop.
+     144           3 :   Future<void> dispatch() async {
+     145           9 :     await for (final _ in port) {
+     146           3 :       _executePendingJob();
+     147             :     }
+     148             :   }
+     149             : 
+     150             :   /// Evaluate js script.
+     151           3 :   dynamic evaluate(
+     152             :     String command, {
+     153             :     String? name,
+     154             :     int? evalFlags,
+     155             :   }) {
+     156           3 :     _ensureEngine();
+     157           3 :     final ctx = _ctx!;
+     158           3 :     final jsval = jsEval(
+     159             :       ctx,
+     160             :       command,
+     161             :       name ?? '<eval>',
+     162             :       evalFlags ?? JSEvalFlag.GLOBAL,
+     163             :     );
+     164           9 :     if (jsIsException(jsval) != 0) {
+     165           1 :       jsFreeValue(ctx, jsval);
+     166           1 :       throw _parseJSException(ctx);
+     167             :     }
+     168           3 :     final result = _jsToDart(ctx, jsval);
+     169           3 :     jsFreeValue(ctx, jsval);
+     170             :     return result;
+     171             :   }
+     172             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/ffi.dart.func-sort-c.html b/coverage/src/ffi.dart.func-sort-c.html new file mode 100644 index 0000000..95a60ff --- /dev/null +++ b/coverage/src/ffi.dart.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - lcov.info - src/ffi.dart - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - ffi.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:19220991.9 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/ffi.dart.func.html b/coverage/src/ffi.dart.func.html new file mode 100644 index 0000000..7443850 --- /dev/null +++ b/coverage/src/ffi.dart.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - lcov.info - src/ffi.dart - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - ffi.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:19220991.9 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/ffi.dart.gcov.html b/coverage/src/ffi.dart.gcov.html new file mode 100644 index 0000000..9d397a8 --- /dev/null +++ b/coverage/src/ffi.dart.gcov.html @@ -0,0 +1,1070 @@ + + + + + + + LCOV - lcov.info - src/ffi.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - ffi.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:19220991.9 %
Date:2021-03-31 22:28:15Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /*
+       2             :  * @Description: ffi
+       3             :  * @Author: ekibun
+       4             :  * @Date: 2020-09-19 10:29:04
+       5             :  * @LastEditors: ekibun
+       6             :  * @LastEditTime: 2020-12-02 11:14:35
+       7             :  */
+       8             : import 'dart:ffi';
+       9             : import 'dart:io';
+      10             : import 'dart:isolate';
+      11             : import 'package:ffi/ffi.dart';
+      12             : 
+      13             : extension ListFirstWhere<T> on Iterable<T> {
+      14           3 :   T? firstWhereOrNull(bool Function(T) test) {
+      15             :     try {
+      16           3 :       return firstWhere(test);
+      17           3 :     } on StateError {
+      18             :       return null;
+      19             :     }
+      20             :   }
+      21             : }
+      22             : 
+      23             : abstract class JSRef {
+      24             :   int _refCount = 0;
+      25           3 :   void dup() {
+      26           6 :     _refCount++;
+      27             :   }
+      28             : 
+      29           3 :   void free() {
+      30           6 :     _refCount--;
+      31           9 :     if (_refCount < 0) destroy();
+      32             :   }
+      33             : 
+      34             :   void destroy();
+      35             : 
+      36           3 :   static void freeRecursive(dynamic obj) {
+      37           7 :     _callRecursive(obj, (ref) => ref.free());
+      38             :   }
+      39             : 
+      40           3 :   static void dupRecursive(dynamic obj) {
+      41           7 :     _callRecursive(obj, (ref) => ref.dup());
+      42             :   }
+      43             : 
+      44           3 :   static void _callRecursive(
+      45             :     dynamic obj,
+      46             :     void Function(JSRef) cb, [
+      47             :     Set? cache,
+      48             :   ]) {
+      49             :     if (obj == null) return;
+      50             :     if (cache == null) cache = Set();
+      51           3 :     if (cache.contains(obj)) return;
+      52           3 :     if (obj is List) {
+      53           3 :       cache.add(obj);
+      54          12 :       List.from(obj).forEach((e) => _callRecursive(e, cb, cache));
+      55             :     }
+      56           3 :     if (obj is Map) {
+      57           2 :       cache.add(obj);
+      58          10 :       obj.values.toList().forEach((e) => _callRecursive(e, cb, cache));
+      59             :     }
+      60           3 :     if (obj is JSRef) {
+      61           2 :       cb(obj);
+      62             :     }
+      63             :   }
+      64             : }
+      65             : 
+      66             : abstract class JSRefLeakable {}
+      67             : 
+      68             : class JSEvalFlag {
+      69             :   static const GLOBAL = 0 << 0;
+      70             :   static const MODULE = 1 << 0;
+      71             : }
+      72             : 
+      73             : class JSChannelType {
+      74             :   static const METHON = 0;
+      75             :   static const MODULE = 1;
+      76             :   static const PROMISE_TRACK = 2;
+      77             :   static const FREE_OBJECT = 3;
+      78             : }
+      79             : 
+      80             : class JSProp {
+      81             :   static const CONFIGURABLE = (1 << 0);
+      82             :   static const WRITABLE = (1 << 1);
+      83             :   static const ENUMERABLE = (1 << 2);
+      84             :   static const C_W_E = (CONFIGURABLE | WRITABLE | ENUMERABLE);
+      85             : }
+      86             : 
+      87             : class JSTag {
+      88             :   static const FIRST = -11; /* first negative tag */
+      89             :   static const BIG_DECIMAL = -11;
+      90             :   static const BIG_INT = -10;
+      91             :   static const BIG_FLOAT = -9;
+      92             :   static const SYMBOL = -8;
+      93             :   static const STRING = -7;
+      94             :   static const MODULE = -3; /* used internally */
+      95             :   static const FUNCTION_BYTECODE = -2; /* used internally */
+      96             :   static const OBJECT = -1;
+      97             : 
+      98             :   static const INT = 0;
+      99             :   static const BOOL = 1;
+     100             :   static const NULL = 2;
+     101             :   static const UNDEFINED = 3;
+     102             :   static const UNINITIALIZED = 4;
+     103             :   static const CATCH_OFFSET = 5;
+     104             :   static const EXCEPTION = 6;
+     105             :   static const FLOAT64 = 7;
+     106             : }
+     107             : 
+     108             : abstract class JSValue extends Opaque {}
+     109             : 
+     110             : abstract class JSContext extends Opaque {}
+     111             : 
+     112             : abstract class JSRuntime extends Opaque {}
+     113             : 
+     114             : abstract class JSPropertyEnum extends Opaque {}
+     115             : 
+     116          15 : final DynamicLibrary _qjsLib = Platform.environment['FLUTTER_TEST'] == 'true'
+     117           3 :     ? (Platform.isWindows
+     118           3 :         ? DynamicLibrary.open('test/build/Debug/ffiquickjs.dll')
+     119           0 :         : Platform.isMacOS
+     120           0 :             ? DynamicLibrary.open('test/build/libffiquickjs.dylib')
+     121           0 :             : DynamicLibrary.open('test/build/libffiquickjs.so'))
+     122           0 :     : (Platform.isWindows
+     123           0 :         ? DynamicLibrary.open('flutter_qjs_plugin.dll')
+     124           0 :         : Platform.isAndroid
+     125           0 :             ? DynamicLibrary.open('libqjs.so')
+     126           0 :             : DynamicLibrary.process());
+     127             : 
+     128             : /// DLLEXPORT JSValue *jsThrow(JSContext *ctx, JSValue *obj)
+     129             : final Pointer<JSValue> Function(
+     130             :   Pointer<JSContext> ctx,
+     131             :   Pointer<JSValue> obj,
+     132           0 : ) jsThrow = _qjsLib
+     133             :     .lookup<
+     134             :         NativeFunction<
+     135             :             Pointer<JSValue> Function(
+     136             :       Pointer<JSContext>,
+     137             :       Pointer<JSValue>,
+     138             :     )>>('jsThrow')
+     139             :     .asFunction();
+     140             : 
+     141             : /// JSValue *jsEXCEPTION()
+     142           0 : final Pointer<JSValue> Function() jsEXCEPTION = _qjsLib
+     143             :     .lookup<NativeFunction<Pointer<JSValue> Function()>>('jsEXCEPTION')
+     144             :     .asFunction();
+     145             : 
+     146             : /// JSValue *jsUNDEFINED()
+     147           9 : final Pointer<JSValue> Function() jsUNDEFINED = _qjsLib
+     148           3 :     .lookup<NativeFunction<Pointer<JSValue> Function()>>('jsUNDEFINED')
+     149             :     .asFunction();
+     150             : 
+     151             : typedef _JSChannel = Pointer<JSValue> Function(
+     152             :     Pointer<JSContext> ctx, int method, Pointer<JSValue> argv);
+     153             : typedef _JSChannelNative = Pointer<JSValue> Function(
+     154             :     Pointer<JSContext> ctx, IntPtr method, Pointer<JSValue> argv);
+     155             : 
+     156             : /// JSRuntime *jsNewRuntime(JSChannel channel)
+     157             : final Pointer<JSRuntime> Function(
+     158             :   Pointer<NativeFunction<_JSChannelNative>>,
+     159           9 : ) _jsNewRuntime = _qjsLib
+     160           3 :     .lookup<
+     161             :         NativeFunction<
+     162             :             Pointer<JSRuntime> Function(
+     163             :       Pointer<NativeFunction<_JSChannelNative>>,
+     164             :     )>>('jsNewRuntime')
+     165             :     .asFunction();
+     166             : 
+     167             : class _RuntimeOpaque {
+     168             :   final _JSChannel _channel;
+     169             :   List<JSRef> _ref = [];
+     170             :   final ReceivePort _port;
+     171             :   int? _dartObjectClassId;
+     172           3 :   _RuntimeOpaque(this._channel, this._port);
+     173             : 
+     174           6 :   int? get dartObjectClassId => _dartObjectClassId;
+     175             : 
+     176           9 :   void addRef(JSRef ref) => _ref.add(ref);
+     177             : 
+     178           9 :   bool removeRef(JSRef ref) => _ref.remove(ref);
+     179             : 
+     180           3 :   JSRef? getRef(bool Function(JSRef ref) test) {
+     181           6 :     return _ref.firstWhereOrNull(test);
+     182             :   }
+     183             : }
+     184             : 
+     185           9 : final Map<Pointer<JSRuntime>, _RuntimeOpaque> runtimeOpaques = Map();
+     186             : 
+     187           3 : Pointer<JSValue>? channelDispacher(
+     188             :   Pointer<JSContext> ctx,
+     189             :   int type,
+     190             :   Pointer<JSValue> argv,
+     191             : ) {
+     192           3 :   final rt = type == JSChannelType.FREE_OBJECT
+     193           3 :       ? ctx.cast<JSRuntime>()
+     194           6 :       : jsGetRuntime(ctx);
+     195          12 :   return runtimeOpaques[rt]?._channel(ctx, type, argv);
+     196             : }
+     197             : 
+     198           3 : Pointer<JSRuntime> jsNewRuntime(
+     199             :   _JSChannel callback,
+     200             :   ReceivePort port,
+     201             : ) {
+     202           6 :   final rt = _jsNewRuntime(Pointer.fromFunction(channelDispacher));
+     203           9 :   runtimeOpaques[rt] = _RuntimeOpaque(callback, port);
+     204             :   return rt;
+     205             : }
+     206             : 
+     207             : /// DLLEXPORT void jsSetMaxStackSize(JSRuntime *rt, size_t stack_size)
+     208             : final void Function(
+     209             :   Pointer<JSRuntime>,
+     210             :   int,
+     211           0 : ) jsSetMaxStackSize = _qjsLib
+     212             :     .lookup<
+     213             :         NativeFunction<
+     214             :             Void Function(
+     215             :       Pointer<JSRuntime>,
+     216             :       IntPtr,
+     217             :     )>>('jsSetMaxStackSize')
+     218             :     .asFunction();
+     219             : 
+     220             : /// void jsFreeRuntime(JSRuntime *rt)
+     221             : final void Function(
+     222             :   Pointer<JSRuntime>,
+     223           9 : ) _jsFreeRuntime = _qjsLib
+     224           3 :     .lookup<
+     225             :         NativeFunction<
+     226             :             Void Function(
+     227             :       Pointer<JSRuntime>,
+     228             :     )>>('jsFreeRuntime')
+     229             :     .asFunction();
+     230             : 
+     231           3 : void jsFreeRuntime(
+     232             :   Pointer<JSRuntime> rt,
+     233             : ) {
+     234           3 :   final referenceleak = <String>[];
+     235           6 :   final opaque = runtimeOpaques[rt];
+     236             :   if (opaque != null) {
+     237             :     while (true) {
+     238          12 :       final ref = opaque._ref.firstWhereOrNull((ref) => ref is JSRefLeakable);
+     239             :       if (ref == null) break;
+     240           3 :       ref.destroy();
+     241          12 :       runtimeOpaques[rt]?._ref.remove(ref);
+     242             :     }
+     243           6 :     while (opaque._ref.isNotEmpty) {
+     244           2 :       final ref = opaque._ref.first;
+     245           2 :       final objStrs = ref.toString().split('\n');
+     246           4 :       final objStr = objStrs.length > 0 ? objStrs[0] + " ..." : objStrs[0];
+     247           1 :       referenceleak.add(
+     248           6 :           "  ${identityHashCode(ref)}\t${ref._refCount + 1}\t${ref.runtimeType.toString()}\t$objStr");
+     249           1 :       ref.destroy();
+     250             :     }
+     251             :   }
+     252           6 :   _jsFreeRuntime(rt);
+     253           6 :   if (referenceleak.length > 0) {
+     254           1 :     throw ('reference leak:\n    ADDR\tREF\tTYPE\tPROP\n' +
+     255           1 :         referenceleak.join('\n'));
+     256             :   }
+     257             : }
+     258             : 
+     259             : /// JSValue *jsNewCFunction(JSContext *ctx, JSValue *funcData)
+     260             : final Pointer<JSValue> Function(
+     261             :   Pointer<JSContext> ctx,
+     262             :   Pointer<JSValue> funcData,
+     263           9 : ) jsNewCFunction = _qjsLib
+     264           3 :     .lookup<
+     265             :         NativeFunction<
+     266             :             Pointer<JSValue> Function(
+     267             :       Pointer<JSContext>,
+     268             :       Pointer<JSValue>,
+     269             :     )>>('jsNewCFunction')
+     270             :     .asFunction();
+     271             : 
+     272             : /// JSContext *jsNewContext(JSRuntime *rt)
+     273             : final Pointer<JSContext> Function(
+     274             :   Pointer<JSRuntime> rt,
+     275           9 : ) _jsNewContext = _qjsLib
+     276           3 :     .lookup<
+     277             :         NativeFunction<
+     278             :             Pointer<JSContext> Function(
+     279             :       Pointer<JSRuntime>,
+     280             :     )>>('jsNewContext')
+     281             :     .asFunction();
+     282             : 
+     283           3 : Pointer<JSContext> jsNewContext(Pointer<JSRuntime> rt) {
+     284           6 :   final ctx = _jsNewContext(rt);
+     285           6 :   final runtimeOpaque = runtimeOpaques[rt];
+     286           0 :   if (runtimeOpaque == null) throw Exception('Runtime has been released!');
+     287           6 :   runtimeOpaque._dartObjectClassId = jsNewClass(ctx, 'DartObject');
+     288             :   return ctx;
+     289             : }
+     290             : 
+     291             : /// void jsFreeContext(JSContext *ctx)
+     292             : final void Function(
+     293             :   Pointer<JSContext>,
+     294           9 : ) jsFreeContext = _qjsLib
+     295           3 :     .lookup<
+     296             :         NativeFunction<
+     297             :             Void Function(
+     298             :       Pointer<JSContext>,
+     299             :     )>>('jsFreeContext')
+     300             :     .asFunction();
+     301             : 
+     302             : /// JSRuntime *jsGetRuntime(JSContext *ctx)
+     303             : final Pointer<JSRuntime> Function(
+     304             :   Pointer<JSContext>,
+     305           9 : ) jsGetRuntime = _qjsLib
+     306           3 :     .lookup<
+     307             :         NativeFunction<
+     308             :             Pointer<JSRuntime> Function(
+     309             :       Pointer<JSContext>,
+     310             :     )>>('jsGetRuntime')
+     311             :     .asFunction();
+     312             : 
+     313             : /// JSValue *jsEval(JSContext *ctx, const char *input, size_t input_len, const char *filename, int eval_flags)
+     314             : final Pointer<JSValue> Function(
+     315             :   Pointer<JSContext> ctx,
+     316             :   Pointer<Utf8> input,
+     317             :   int inputLen,
+     318             :   Pointer<Utf8> filename,
+     319             :   int evalFlags,
+     320           9 : ) _jsEval = _qjsLib
+     321           3 :     .lookup<
+     322             :         NativeFunction<
+     323             :             Pointer<JSValue> Function(
+     324             :       Pointer<JSContext>,
+     325             :       Pointer<Utf8>,
+     326             :       IntPtr,
+     327             :       Pointer<Utf8>,
+     328             :       Int32,
+     329             :     )>>('jsEval')
+     330             :     .asFunction();
+     331             : 
+     332           3 : Pointer<JSValue> jsEval(
+     333             :   Pointer<JSContext> ctx,
+     334             :   String input,
+     335             :   String filename,
+     336             :   int evalFlags,
+     337             : ) {
+     338           3 :   final utf8input = input.toNativeUtf8();
+     339           3 :   final utf8filename = filename.toNativeUtf8();
+     340           6 :   final val = _jsEval(
+     341             :     ctx,
+     342             :     utf8input,
+     343           3 :     utf8input.length,
+     344             :     utf8filename,
+     345             :     evalFlags,
+     346             :   );
+     347           3 :   malloc.free(utf8input);
+     348           3 :   malloc.free(utf8filename);
+     349          21 :   runtimeOpaques[jsGetRuntime(ctx)]?._port.sendPort.send(#eval);
+     350             :   return val;
+     351             : }
+     352             : 
+     353             : /// DLLEXPORT int32_t jsValueGetTag(JSValue *val)
+     354             : final int Function(
+     355             :   Pointer<JSValue> val,
+     356           9 : ) jsValueGetTag = _qjsLib
+     357           3 :     .lookup<
+     358             :         NativeFunction<
+     359             :             Int32 Function(
+     360             :       Pointer<JSValue>,
+     361             :     )>>('jsValueGetTag')
+     362             :     .asFunction();
+     363             : 
+     364             : /// void *jsValueGetPtr(JSValue *val)
+     365             : final int Function(
+     366             :   Pointer<JSValue> val,
+     367           9 : ) jsValueGetPtr = _qjsLib
+     368           3 :     .lookup<
+     369             :         NativeFunction<
+     370             :             IntPtr Function(
+     371             :       Pointer<JSValue>,
+     372             :     )>>('jsValueGetPtr')
+     373             :     .asFunction();
+     374             : 
+     375             : /// DLLEXPORT bool jsTagIsFloat64(int32_t tag)
+     376             : final int Function(
+     377             :   int val,
+     378           9 : ) jsTagIsFloat64 = _qjsLib
+     379           3 :     .lookup<
+     380             :         NativeFunction<
+     381             :             Int32 Function(
+     382             :       Int32,
+     383             :     )>>('jsTagIsFloat64')
+     384             :     .asFunction();
+     385             : 
+     386             : /// JSValue *jsNewBool(JSContext *ctx, int val)
+     387             : final Pointer<JSValue> Function(
+     388             :   Pointer<JSContext> ctx,
+     389             :   int val,
+     390           6 : ) jsNewBool = _qjsLib
+     391           2 :     .lookup<
+     392             :         NativeFunction<
+     393             :             Pointer<JSValue> Function(
+     394             :       Pointer<JSContext>,
+     395             :       Int32,
+     396             :     )>>('jsNewBool')
+     397             :     .asFunction();
+     398             : 
+     399             : /// JSValue *jsNewInt64(JSContext *ctx, int64_t val)
+     400             : final Pointer<JSValue> Function(
+     401             :   Pointer<JSContext> ctx,
+     402             :   int val,
+     403           6 : ) jsNewInt64 = _qjsLib
+     404           2 :     .lookup<
+     405             :         NativeFunction<
+     406             :             Pointer<JSValue> Function(
+     407             :       Pointer<JSContext>,
+     408             :       Int64,
+     409             :     )>>('jsNewInt64')
+     410             :     .asFunction();
+     411             : 
+     412             : /// JSValue *jsNewFloat64(JSContext *ctx, double val)
+     413             : final Pointer<JSValue> Function(
+     414             :   Pointer<JSContext> ctx,
+     415             :   double val,
+     416           6 : ) jsNewFloat64 = _qjsLib
+     417           2 :     .lookup<
+     418             :         NativeFunction<
+     419             :             Pointer<JSValue> Function(
+     420             :       Pointer<JSContext>,
+     421             :       Double,
+     422             :     )>>('jsNewFloat64')
+     423             :     .asFunction();
+     424             : 
+     425             : /// JSValue *jsNewString(JSContext *ctx, const char *str)
+     426             : final Pointer<JSValue> Function(
+     427             :   Pointer<JSContext> ctx,
+     428             :   Pointer<Utf8> str,
+     429           9 : ) _jsNewString = _qjsLib
+     430           3 :     .lookup<
+     431             :         NativeFunction<
+     432             :             Pointer<JSValue> Function(
+     433             :       Pointer<JSContext>,
+     434             :       Pointer<Utf8>,
+     435             :     )>>('jsNewString')
+     436             :     .asFunction();
+     437             : 
+     438           3 : Pointer<JSValue> jsNewString(
+     439             :   Pointer<JSContext> ctx,
+     440             :   String str,
+     441             : ) {
+     442           3 :   final utf8str = str.toNativeUtf8();
+     443           6 :   final jsStr = _jsNewString(ctx, utf8str);
+     444           3 :   malloc.free(utf8str);
+     445             :   return jsStr;
+     446             : }
+     447             : 
+     448             : /// JSValue *jsNewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len)
+     449             : final Pointer<JSValue> Function(
+     450             :   Pointer<JSContext> ctx,
+     451             :   Pointer<Uint8> buf,
+     452             :   int len,
+     453           0 : ) jsNewArrayBufferCopy = _qjsLib
+     454             :     .lookup<
+     455             :         NativeFunction<
+     456             :             Pointer<JSValue> Function(
+     457             :       Pointer<JSContext>,
+     458             :       Pointer<Uint8>,
+     459             :       IntPtr,
+     460             :     )>>('jsNewArrayBufferCopy')
+     461             :     .asFunction();
+     462             : 
+     463             : /// JSValue *jsNewArray(JSContext *ctx)
+     464             : final Pointer<JSValue> Function(
+     465             :   Pointer<JSContext> ctx,
+     466           6 : ) jsNewArray = _qjsLib
+     467           2 :     .lookup<
+     468             :         NativeFunction<
+     469             :             Pointer<JSValue> Function(
+     470             :       Pointer<JSContext>,
+     471             :     )>>('jsNewArray')
+     472             :     .asFunction();
+     473             : 
+     474             : /// JSValue *jsNewObject(JSContext *ctx)
+     475             : final Pointer<JSValue> Function(
+     476             :   Pointer<JSContext> ctx,
+     477           6 : ) jsNewObject = _qjsLib
+     478           2 :     .lookup<
+     479             :         NativeFunction<
+     480             :             Pointer<JSValue> Function(
+     481             :       Pointer<JSContext>,
+     482             :     )>>('jsNewObject')
+     483             :     .asFunction();
+     484             : 
+     485             : /// void jsFreeValue(JSContext *ctx, JSValue *val, int32_t free)
+     486             : final void Function(
+     487             :   Pointer<JSContext> ctx,
+     488             :   Pointer<JSValue> val,
+     489             :   int free,
+     490           9 : ) _jsFreeValue = _qjsLib
+     491           3 :     .lookup<
+     492             :         NativeFunction<
+     493             :             Void Function(
+     494             :       Pointer<JSContext>,
+     495             :       Pointer<JSValue>,
+     496             :       Int32,
+     497             :     )>>('jsFreeValue')
+     498             :     .asFunction();
+     499             : 
+     500           3 : void jsFreeValue(
+     501             :   Pointer<JSContext> ctx,
+     502             :   Pointer<JSValue> val, {
+     503             :   bool free = true,
+     504             : }) {
+     505           6 :   _jsFreeValue(ctx, val, free ? 1 : 0);
+     506             : }
+     507             : 
+     508             : /// void jsFreeValue(JSRuntime *rt, JSValue *val, int32_t free)
+     509             : final void Function(
+     510             :   Pointer<JSRuntime> rt,
+     511             :   Pointer<JSValue> val,
+     512             :   int free,
+     513           0 : ) _jsFreeValueRT = _qjsLib
+     514             :     .lookup<
+     515             :         NativeFunction<
+     516             :             Void Function(
+     517             :       Pointer<JSRuntime>,
+     518             :       Pointer<JSValue>,
+     519             :       Int32,
+     520             :     )>>('jsFreeValueRT')
+     521             :     .asFunction();
+     522             : 
+     523           0 : void jsFreeValueRT(
+     524             :   Pointer<JSRuntime> rt,
+     525             :   Pointer<JSValue> val, {
+     526             :   bool free = true,
+     527             : }) {
+     528           0 :   _jsFreeValueRT(rt, val, free ? 1 : 0);
+     529             : }
+     530             : 
+     531             : /// JSValue *jsDupValue(JSContext *ctx, JSValueConst *v)
+     532             : final Pointer<JSValue> Function(
+     533             :   Pointer<JSContext> ctx,
+     534             :   Pointer<JSValue> val,
+     535           9 : ) jsDupValue = _qjsLib
+     536           3 :     .lookup<
+     537             :         NativeFunction<
+     538             :             Pointer<JSValue> Function(
+     539             :       Pointer<JSContext>,
+     540             :       Pointer<JSValue>,
+     541             :     )>>('jsDupValue')
+     542             :     .asFunction();
+     543             : 
+     544             : /// JSValue *jsDupValueRT(JSRuntime *rt, JSValue *v)
+     545             : final Pointer<JSValue> Function(
+     546             :   Pointer<JSRuntime> rt,
+     547             :   Pointer<JSValue> val,
+     548           0 : ) jsDupValueRT = _qjsLib
+     549             :     .lookup<
+     550             :         NativeFunction<
+     551             :             Pointer<JSValue> Function(
+     552             :       Pointer<JSRuntime>,
+     553             :       Pointer<JSValue>,
+     554             :     )>>('jsDupValueRT')
+     555             :     .asFunction();
+     556             : 
+     557             : /// int32_t jsToBool(JSContext *ctx, JSValueConst *val)
+     558             : final int Function(
+     559             :   Pointer<JSContext> ctx,
+     560             :   Pointer<JSValue> val,
+     561           6 : ) jsToBool = _qjsLib
+     562           2 :     .lookup<
+     563             :         NativeFunction<
+     564             :             Int32 Function(
+     565             :       Pointer<JSContext>,
+     566             :       Pointer<JSValue>,
+     567             :     )>>('jsToBool')
+     568             :     .asFunction();
+     569             : 
+     570             : /// int64_t jsToFloat64(JSContext *ctx, JSValueConst *val)
+     571             : final int Function(
+     572             :   Pointer<JSContext> ctx,
+     573             :   Pointer<JSValue> val,
+     574           6 : ) jsToInt64 = _qjsLib
+     575           2 :     .lookup<
+     576             :         NativeFunction<
+     577             :             Int64 Function(
+     578             :       Pointer<JSContext>,
+     579             :       Pointer<JSValue>,
+     580             :     )>>('jsToInt64')
+     581             :     .asFunction();
+     582             : 
+     583             : /// double jsToFloat64(JSContext *ctx, JSValueConst *val)
+     584             : final double Function(
+     585             :   Pointer<JSContext> ctx,
+     586             :   Pointer<JSValue> val,
+     587           6 : ) jsToFloat64 = _qjsLib
+     588           2 :     .lookup<
+     589             :         NativeFunction<
+     590             :             Double Function(
+     591             :       Pointer<JSContext>,
+     592             :       Pointer<JSValue>,
+     593             :     )>>('jsToFloat64')
+     594             :     .asFunction();
+     595             : 
+     596             : /// const char *jsToCString(JSContext *ctx, JSValue *val)
+     597             : final Pointer<Utf8> Function(
+     598             :   Pointer<JSContext> ctx,
+     599             :   Pointer<JSValue> val,
+     600           9 : ) _jsToCString = _qjsLib
+     601           3 :     .lookup<
+     602             :         NativeFunction<
+     603             :             Pointer<Utf8> Function(
+     604             :       Pointer<JSContext>,
+     605             :       Pointer<JSValue>,
+     606             :     )>>('jsToCString')
+     607             :     .asFunction();
+     608             : 
+     609             : /// void jsFreeCString(JSContext *ctx, const char *ptr)
+     610             : final void Function(
+     611             :   Pointer<JSContext> ctx,
+     612             :   Pointer<Utf8> val,
+     613           9 : ) jsFreeCString = _qjsLib
+     614           3 :     .lookup<
+     615             :         NativeFunction<
+     616             :             Void Function(
+     617             :       Pointer<JSContext>,
+     618             :       Pointer<Utf8>,
+     619             :     )>>('jsFreeCString')
+     620             :     .asFunction();
+     621             : 
+     622           3 : String jsToCString(
+     623             :   Pointer<JSContext> ctx,
+     624             :   Pointer<JSValue> val,
+     625             : ) {
+     626           6 :   final ptr = _jsToCString(ctx, val);
+     627           6 :   if (ptr.address == 0) throw Exception('JSValue cannot convert to string');
+     628           3 :   final str = ptr.toDartString();
+     629           6 :   jsFreeCString(ctx, ptr);
+     630             :   return str;
+     631             : }
+     632             : 
+     633             : /// DLLEXPORT uint32_t jsNewClass(JSContext *ctx, const char *name)
+     634             : final int Function(
+     635             :   Pointer<JSContext> ctx,
+     636             :   Pointer<Utf8> name,
+     637           9 : ) _jsNewClass = _qjsLib
+     638           3 :     .lookup<
+     639             :         NativeFunction<
+     640             :             Uint32 Function(
+     641             :       Pointer<JSContext>,
+     642             :       Pointer<Utf8>,
+     643             :     )>>('jsNewClass')
+     644             :     .asFunction();
+     645             : 
+     646           3 : int jsNewClass(
+     647             :   Pointer<JSContext> ctx,
+     648             :   String name,
+     649             : ) {
+     650           3 :   final utf8name = name.toNativeUtf8();
+     651           6 :   final val = _jsNewClass(
+     652             :     ctx,
+     653             :     utf8name,
+     654             :   );
+     655           3 :   malloc.free(utf8name);
+     656             :   return val;
+     657             : }
+     658             : 
+     659             : /// DLLEXPORT JSValue *jsNewObjectClass(JSContext *ctx, uint32_t QJSClassId, void *opaque)
+     660             : final Pointer<JSValue> Function(
+     661             :   Pointer<JSContext> ctx,
+     662             :   int classId,
+     663             :   int opaque,
+     664           9 : ) jsNewObjectClass = _qjsLib
+     665           3 :     .lookup<
+     666             :         NativeFunction<
+     667             :             Pointer<JSValue> Function(
+     668             :       Pointer<JSContext>,
+     669             :       Uint32,
+     670             :       IntPtr,
+     671             :     )>>('jsNewObjectClass')
+     672             :     .asFunction();
+     673             : 
+     674             : /// DLLEXPORT void *jsGetObjectOpaque(JSValue *obj, uint32_t classid)
+     675             : final int Function(
+     676             :   Pointer<JSValue> obj,
+     677             :   int classid,
+     678           9 : ) jsGetObjectOpaque = _qjsLib
+     679           3 :     .lookup<
+     680             :         NativeFunction<
+     681             :             IntPtr Function(
+     682             :       Pointer<JSValue>,
+     683             :       Uint32,
+     684             :     )>>('jsGetObjectOpaque')
+     685             :     .asFunction();
+     686             : 
+     687             : /// uint8_t *jsGetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst *obj)
+     688             : final Pointer<Uint8> Function(
+     689             :   Pointer<JSContext> ctx,
+     690             :   Pointer<IntPtr> psize,
+     691             :   Pointer<JSValue> val,
+     692           9 : ) jsGetArrayBuffer = _qjsLib
+     693           3 :     .lookup<
+     694             :         NativeFunction<
+     695             :             Pointer<Uint8> Function(
+     696             :       Pointer<JSContext>,
+     697             :       Pointer<IntPtr>,
+     698             :       Pointer<JSValue>,
+     699             :     )>>('jsGetArrayBuffer')
+     700             :     .asFunction();
+     701             : 
+     702             : /// int32_t jsIsFunction(JSContext *ctx, JSValueConst *val)
+     703             : final int Function(
+     704             :   Pointer<JSContext> ctx,
+     705             :   Pointer<JSValue> val,
+     706           9 : ) jsIsFunction = _qjsLib
+     707           3 :     .lookup<
+     708             :         NativeFunction<
+     709             :             Int32 Function(
+     710             :       Pointer<JSContext>,
+     711             :       Pointer<JSValue>,
+     712             :     )>>('jsIsFunction')
+     713             :     .asFunction();
+     714             : 
+     715             : /// int32_t jsIsPromise(JSContext *ctx, JSValueConst *val)
+     716             : final int Function(
+     717             :   Pointer<JSContext> ctx,
+     718             :   Pointer<JSValue> val,
+     719           9 : ) jsIsPromise = _qjsLib
+     720           3 :     .lookup<
+     721             :         NativeFunction<
+     722             :             Int32 Function(
+     723             :       Pointer<JSContext>,
+     724             :       Pointer<JSValue>,
+     725             :     )>>('jsIsPromise')
+     726             :     .asFunction();
+     727             : 
+     728             : /// int32_t jsIsArray(JSContext *ctx, JSValueConst *val)
+     729             : final int Function(
+     730             :   Pointer<JSContext> ctx,
+     731             :   Pointer<JSValue> val,
+     732           6 : ) jsIsArray = _qjsLib
+     733           2 :     .lookup<
+     734             :         NativeFunction<
+     735             :             Int32 Function(
+     736             :       Pointer<JSContext>,
+     737             :       Pointer<JSValue>,
+     738             :     )>>('jsIsArray')
+     739             :     .asFunction();
+     740             : 
+     741             : /// DLLEXPORT int32_t jsIsError(JSContext *ctx, JSValueConst *val);
+     742             : final int Function(
+     743             :   Pointer<JSContext> ctx,
+     744             :   Pointer<JSValue> val,
+     745           9 : ) jsIsError = _qjsLib
+     746           3 :     .lookup<
+     747             :         NativeFunction<
+     748             :             Int32 Function(
+     749             :       Pointer<JSContext>,
+     750             :       Pointer<JSValue>,
+     751             :     )>>('jsIsError')
+     752             :     .asFunction();
+     753             : 
+     754             : /// DLLEXPORT JSValue *jsNewError(JSContext *ctx);
+     755             : final Pointer<JSValue> Function(
+     756             :   Pointer<JSContext> ctx,
+     757           6 : ) jsNewError = _qjsLib
+     758           2 :     .lookup<
+     759             :         NativeFunction<
+     760             :             Pointer<JSValue> Function(
+     761             :       Pointer<JSContext>,
+     762             :     )>>('jsNewError')
+     763             :     .asFunction();
+     764             : 
+     765             : /// JSValue *jsGetProperty(JSContext *ctx, JSValueConst *this_obj,
+     766             : ///                           JSAtom prop)
+     767             : final Pointer<JSValue> Function(
+     768             :   Pointer<JSContext> ctx,
+     769             :   Pointer<JSValue> thisObj,
+     770             :   int prop,
+     771           9 : ) jsGetProperty = _qjsLib
+     772           3 :     .lookup<
+     773             :         NativeFunction<
+     774             :             Pointer<JSValue> Function(
+     775             :       Pointer<JSContext>,
+     776             :       Pointer<JSValue>,
+     777             :       Uint32,
+     778             :     )>>('jsGetProperty')
+     779             :     .asFunction();
+     780             : 
+     781             : /// int jsDefinePropertyValue(JSContext *ctx, JSValueConst *this_obj,
+     782             : ///                           JSAtom prop, JSValue *val, int flags)
+     783             : final int Function(
+     784             :   Pointer<JSContext> ctx,
+     785             :   Pointer<JSValue> thisObj,
+     786             :   int prop,
+     787             :   Pointer<JSValue> val,
+     788             :   int flag,
+     789           6 : ) jsDefinePropertyValue = _qjsLib
+     790           2 :     .lookup<
+     791             :         NativeFunction<
+     792             :             Int32 Function(
+     793             :       Pointer<JSContext>,
+     794             :       Pointer<JSValue>,
+     795             :       Uint32,
+     796             :       Pointer<JSValue>,
+     797             :       Int32,
+     798             :     )>>('jsDefinePropertyValue')
+     799             :     .asFunction();
+     800             : 
+     801             : /// void jsFreeAtom(JSContext *ctx, JSAtom v)
+     802             : final void Function(
+     803             :   Pointer<JSContext> ctx,
+     804             :   int v,
+     805           9 : ) jsFreeAtom = _qjsLib
+     806           3 :     .lookup<
+     807             :         NativeFunction<
+     808             :             Void Function(
+     809             :       Pointer<JSContext>,
+     810             :       Uint32,
+     811             :     )>>('jsFreeAtom')
+     812             :     .asFunction();
+     813             : 
+     814             : /// JSAtom jsValueToAtom(JSContext *ctx, JSValueConst *val)
+     815             : final int Function(
+     816             :   Pointer<JSContext> ctx,
+     817             :   Pointer<JSValue> val,
+     818           9 : ) jsValueToAtom = _qjsLib
+     819           3 :     .lookup<
+     820             :         NativeFunction<
+     821             :             Uint32 Function(
+     822             :       Pointer<JSContext>,
+     823             :       Pointer<JSValue>,
+     824             :     )>>('jsValueToAtom')
+     825             :     .asFunction();
+     826             : 
+     827             : /// JSValue *jsAtomToValue(JSContext *ctx, JSAtom val)
+     828             : final Pointer<JSValue> Function(
+     829             :   Pointer<JSContext> ctx,
+     830             :   int val,
+     831           6 : ) jsAtomToValue = _qjsLib
+     832           2 :     .lookup<
+     833             :         NativeFunction<
+     834             :             Pointer<JSValue> Function(
+     835             :       Pointer<JSContext>,
+     836             :       Uint32,
+     837             :     )>>('jsAtomToValue')
+     838             :     .asFunction();
+     839             : 
+     840             : /// int jsGetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
+     841             : ///                           uint32_t *plen, JSValueConst *obj, int flags)
+     842             : final int Function(
+     843             :   Pointer<JSContext> ctx,
+     844             :   Pointer<Pointer<JSPropertyEnum>> ptab,
+     845             :   Pointer<Uint32> plen,
+     846             :   Pointer<JSValue> obj,
+     847             :   int flags,
+     848           6 : ) jsGetOwnPropertyNames = _qjsLib
+     849           2 :     .lookup<
+     850             :         NativeFunction<
+     851             :             Int32 Function(
+     852             :       Pointer<JSContext>,
+     853             :       Pointer<Pointer<JSPropertyEnum>>,
+     854             :       Pointer<Uint32>,
+     855             :       Pointer<JSValue>,
+     856             :       Int32,
+     857             :     )>>('jsGetOwnPropertyNames')
+     858             :     .asFunction();
+     859             : 
+     860             : /// JSAtom jsPropertyEnumGetAtom(JSPropertyEnum *ptab, int i)
+     861             : final int Function(
+     862             :   Pointer<JSPropertyEnum> ptab,
+     863             :   int i,
+     864           6 : ) jsPropertyEnumGetAtom = _qjsLib
+     865           2 :     .lookup<
+     866             :         NativeFunction<
+     867             :             Uint32 Function(
+     868             :       Pointer<JSPropertyEnum>,
+     869             :       Int32,
+     870             :     )>>('jsPropertyEnumGetAtom')
+     871             :     .asFunction();
+     872             : 
+     873             : /// uint32_t sizeOfJSValue()
+     874           9 : final int Function() _sizeOfJSValue = _qjsLib
+     875           3 :     .lookup<NativeFunction<Uint32 Function()>>('sizeOfJSValue')
+     876             :     .asFunction();
+     877             : 
+     878          12 : final sizeOfJSValue = _sizeOfJSValue();
+     879             : 
+     880             : /// void setJSValueList(JSValue *list, int i, JSValue *val)
+     881             : final void Function(
+     882             :   Pointer<JSValue> list,
+     883             :   int i,
+     884             :   Pointer<JSValue> val,
+     885           9 : ) setJSValueList = _qjsLib
+     886           3 :     .lookup<
+     887             :         NativeFunction<
+     888             :             Void Function(
+     889             :       Pointer<JSValue>,
+     890             :       Uint32,
+     891             :       Pointer<JSValue>,
+     892             :     )>>('setJSValueList')
+     893             :     .asFunction();
+     894             : 
+     895             : /// JSValue *jsCall(JSContext *ctx, JSValueConst *func_obj, JSValueConst *this_obj,
+     896             : ///                 int argc, JSValueConst *argv)
+     897             : final Pointer<JSValue> Function(
+     898             :   Pointer<JSContext> ctx,
+     899             :   Pointer<JSValue> funcObj,
+     900             :   Pointer<JSValue> thisObj,
+     901             :   int argc,
+     902             :   Pointer<JSValue> argv,
+     903           9 : ) _jsCall = _qjsLib
+     904           3 :     .lookup<
+     905             :         NativeFunction<
+     906             :             Pointer<JSValue> Function(
+     907             :       Pointer<JSContext>,
+     908             :       Pointer<JSValue>,
+     909             :       Pointer<JSValue>,
+     910             :       Int32,
+     911             :       Pointer<JSValue>,
+     912             :     )>>('jsCall')
+     913             :     .asFunction();
+     914             : 
+     915           3 : Pointer<JSValue> jsCall(
+     916             :   Pointer<JSContext> ctx,
+     917             :   Pointer<JSValue> funcObj,
+     918             :   Pointer<JSValue> thisObj,
+     919             :   List<Pointer<JSValue>> argv,
+     920             : ) {
+     921             :   final jsArgs = calloc<Uint8>(
+     922          15 :     argv.length > 0 ? sizeOfJSValue * argv.length : 1,
+     923           3 :   ).cast<JSValue>();
+     924           9 :   for (int i = 0; i < argv.length; ++i) {
+     925           3 :     Pointer<JSValue> jsArg = argv[i];
+     926           6 :     setJSValueList(jsArgs, i, jsArg);
+     927             :   }
+     928           6 :   final func1 = jsDupValue(ctx, funcObj);
+     929             :   final _thisObj = thisObj;
+     930           9 :   final jsRet = _jsCall(ctx, funcObj, _thisObj, argv.length, jsArgs);
+     931           3 :   jsFreeValue(ctx, func1);
+     932           3 :   malloc.free(jsArgs);
+     933          21 :   runtimeOpaques[jsGetRuntime(ctx)]?._port.sendPort.send(#call);
+     934             :   return jsRet;
+     935             : }
+     936             : 
+     937             : /// int jsIsException(JSValueConst *val)
+     938             : final int Function(
+     939             :   Pointer<JSValue> val,
+     940           9 : ) jsIsException = _qjsLib
+     941           3 :     .lookup<
+     942             :         NativeFunction<
+     943             :             Int32 Function(
+     944             :       Pointer<JSValue>,
+     945             :     )>>('jsIsException')
+     946             :     .asFunction();
+     947             : 
+     948             : /// JSValue *jsGetException(JSContext *ctx)
+     949             : final Pointer<JSValue> Function(
+     950             :   Pointer<JSContext> ctx,
+     951           3 : ) jsGetException = _qjsLib
+     952           1 :     .lookup<
+     953             :         NativeFunction<
+     954             :             Pointer<JSValue> Function(
+     955             :       Pointer<JSContext>,
+     956             :     )>>('jsGetException')
+     957             :     .asFunction();
+     958             : 
+     959             : /// int jsExecutePendingJob(JSRuntime *rt)
+     960             : final int Function(
+     961             :   Pointer<JSRuntime> ctx,
+     962           9 : ) jsExecutePendingJob = _qjsLib
+     963           3 :     .lookup<
+     964             :         NativeFunction<
+     965             :             Int32 Function(
+     966             :       Pointer<JSRuntime>,
+     967             :     )>>('jsExecutePendingJob')
+     968             :     .asFunction();
+     969             : 
+     970             : /// JSValue *jsNewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs)
+     971             : final Pointer<JSValue> Function(
+     972             :   Pointer<JSContext> ctx,
+     973             :   Pointer<JSValue> resolvingFuncs,
+     974           9 : ) jsNewPromiseCapability = _qjsLib
+     975           3 :     .lookup<
+     976             :         NativeFunction<
+     977             :             Pointer<JSValue> Function(
+     978             :       Pointer<JSContext>,
+     979             :       Pointer<JSValue>,
+     980             :     )>>('jsNewPromiseCapability')
+     981             :     .asFunction();
+     982             : 
+     983             : /// void jsFree(JSContext *ctx, void *ptab)
+     984             : final void Function(
+     985             :   Pointer<JSContext> ctx,
+     986             :   Pointer<JSPropertyEnum> ptab,
+     987           6 : ) jsFree = _qjsLib
+     988           2 :     .lookup<
+     989             :         NativeFunction<
+     990             :             Void Function(
+     991             :       Pointer<JSContext>,
+     992             :       Pointer<JSPropertyEnum>,
+     993             :     )>>('jsFree')
+     994             :     .asFunction();
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/index-sort-f.html b/coverage/src/index-sort-f.html new file mode 100644 index 0000000..2ed963b --- /dev/null +++ b/coverage/src/index-sort-f.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcov.infoLines:65273688.6 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
isolate.dart +
83.1%83.1%
+
83.1 %118 / 142-0 / 0
ffi.dart +
91.9%91.9%
+
91.9 %192 / 209-0 / 0
wrapper.dart +
94.3%94.3%
+
94.3 %149 / 158-0 / 0
engine.dart +
82.7%82.7%
+
82.7 %67 / 81-0 / 0
object.dart +
86.3%86.3%
+
86.3 %126 / 146-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/index-sort-l.html b/coverage/src/index-sort-l.html new file mode 100644 index 0000000..59dd075 --- /dev/null +++ b/coverage/src/index-sort-l.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcov.infoLines:65273688.6 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
engine.dart +
82.7%82.7%
+
82.7 %67 / 81-0 / 0
isolate.dart +
83.1%83.1%
+
83.1 %118 / 142-0 / 0
object.dart +
86.3%86.3%
+
86.3 %126 / 146-0 / 0
ffi.dart +
91.9%91.9%
+
91.9 %192 / 209-0 / 0
wrapper.dart +
94.3%94.3%
+
94.3 %149 / 158-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/index.html b/coverage/src/index.html new file mode 100644 index 0000000..59028d0 --- /dev/null +++ b/coverage/src/index.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcov.infoLines:65273688.6 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
engine.dart +
82.7%82.7%
+
82.7 %67 / 81-0 / 0
ffi.dart +
91.9%91.9%
+
91.9 %192 / 209-0 / 0
isolate.dart +
83.1%83.1%
+
83.1 %118 / 142-0 / 0
object.dart +
86.3%86.3%
+
86.3 %126 / 146-0 / 0
wrapper.dart +
94.3%94.3%
+
94.3 %149 / 158-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/isolate.dart.func-sort-c.html b/coverage/src/isolate.dart.func-sort-c.html new file mode 100644 index 0000000..32b5589 --- /dev/null +++ b/coverage/src/isolate.dart.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - lcov.info - src/isolate.dart - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - isolate.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:11814283.1 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/isolate.dart.func.html b/coverage/src/isolate.dart.func.html new file mode 100644 index 0000000..5d7ab04 --- /dev/null +++ b/coverage/src/isolate.dart.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - lcov.info - src/isolate.dart - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - isolate.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:11814283.1 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/isolate.dart.gcov.html b/coverage/src/isolate.dart.gcov.html new file mode 100644 index 0000000..a1164a2 --- /dev/null +++ b/coverage/src/isolate.dart.gcov.html @@ -0,0 +1,353 @@ + + + + + + + LCOV - lcov.info - src/isolate.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - isolate.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:11814283.1 %
Date:2021-03-31 22:28:15Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /*
+       2             :  * @Description: isolate
+       3             :  * @Author: ekibun
+       4             :  * @Date: 2020-10-02 13:49:03
+       5             :  * @LastEditors: ekibun
+       6             :  * @LastEditTime: 2020-10-03 22:21:31
+       7             :  */
+       8             : part of '../flutter_qjs.dart';
+       9             : 
+      10             : typedef dynamic _Decode(Map obj);
+      11           9 : List<_Decode> _decoders = [
+      12             :   JSError._decode,
+      13             :   IsolateFunction._decode,
+      14             : ];
+      15             : 
+      16             : abstract class _IsolateEncodable {
+      17             :   Map _encode();
+      18             : }
+      19             : 
+      20           3 : dynamic _encodeData(dynamic data, {Map<dynamic, dynamic>? cache}) {
+      21           3 :   if (cache == null) cache = Map();
+      22           5 :   if (cache.containsKey(data)) return cache[data];
+      23           6 :   if (data is _IsolateEncodable) return data._encode();
+      24           3 :   if (data is List) {
+      25           3 :     final ret = [];
+      26           3 :     cache[data] = ret;
+      27           9 :     for (int i = 0; i < data.length; ++i) {
+      28           9 :       ret.add(_encodeData(data[i], cache: cache));
+      29             :     }
+      30             :     return ret;
+      31             :   }
+      32           3 :   if (data is Map) {
+      33           2 :     final ret = {};
+      34           2 :     cache[data] = ret;
+      35           4 :     for (final entry in data.entries) {
+      36           6 :       ret[_encodeData(entry.key, cache: cache)] =
+      37           4 :           _encodeData(entry.value, cache: cache);
+      38             :     }
+      39             :     return ret;
+      40             :   }
+      41           3 :   if (data is Future) {
+      42           2 :     final futurePort = ReceivePort();
+      43           4 :     data.then((value) {
+      44           6 :       futurePort.first.then((port) {
+      45           2 :         futurePort.close();
+      46           4 :         (port as SendPort).send(_encodeData(value));
+      47             :       });
+      48           2 :     }, onError: (e) {
+      49           6 :       futurePort.first.then((port) {
+      50           2 :         futurePort.close();
+      51           6 :         (port as SendPort).send({#error: _encodeData(e)});
+      52             :       });
+      53             :     });
+      54           2 :     return {
+      55           2 :       #jsFuturePort: futurePort.sendPort,
+      56             :     };
+      57             :   }
+      58             :   return data;
+      59             : }
+      60             : 
+      61           3 : dynamic _decodeData(dynamic data, {Map<dynamic, dynamic>? cache}) {
+      62           3 :   if (cache == null) cache = Map();
+      63           5 :   if (cache.containsKey(data)) return cache[data];
+      64           3 :   if (data is List) {
+      65           3 :     final ret = [];
+      66           3 :     cache[data] = ret;
+      67           9 :     for (int i = 0; i < data.length; ++i) {
+      68           9 :       ret.add(_decodeData(data[i], cache: cache));
+      69             :     }
+      70             :     return ret;
+      71             :   }
+      72           3 :   if (data is Map) {
+      73           6 :     for (final decoder in _decoders) {
+      74           3 :       final decodeObj = decoder(data);
+      75             :       if (decodeObj != null) return decodeObj;
+      76             :     }
+      77           2 :     if (data.containsKey(#jsFuturePort)) {
+      78           2 :       SendPort port = data[#jsFuturePort];
+      79           2 :       final futurePort = ReceivePort();
+      80           4 :       port.send(futurePort.sendPort);
+      81           2 :       final futureCompleter = Completer();
+      82           6 :       futureCompleter.future.catchError((e) {});
+      83           6 :       futurePort.first.then((value) {
+      84           2 :         futurePort.close();
+      85           4 :         if (value is Map && value.containsKey(#error)) {
+      86           6 :           futureCompleter.completeError(_decodeData(value[#error]));
+      87             :         } else {
+      88           4 :           futureCompleter.complete(_decodeData(value));
+      89             :         }
+      90             :       });
+      91           2 :       return futureCompleter.future;
+      92             :     }
+      93           2 :     final ret = {};
+      94           2 :     cache[data] = ret;
+      95           4 :     for (final entry in data.entries) {
+      96           6 :       ret[_decodeData(entry.key, cache: cache)] =
+      97           4 :           _decodeData(entry.value, cache: cache);
+      98             :     }
+      99             :     return ret;
+     100             :   }
+     101             :   return data;
+     102             : }
+     103             : 
+     104           2 : void _runJsIsolate(Map spawnMessage) async {
+     105           2 :   SendPort sendPort = spawnMessage[#port];
+     106           2 :   ReceivePort port = ReceivePort();
+     107           4 :   sendPort.send(port.sendPort);
+     108           2 :   final qjs = FlutterQjs(
+     109           2 :     stackSize: spawnMessage[#stackSize],
+     110           1 :     hostPromiseRejectionHandler: (reason) {
+     111           2 :       sendPort.send({
+     112             :         #type: #hostPromiseRejection,
+     113           1 :         #reason: _encodeData(reason),
+     114             :       });
+     115             :     },
+     116           0 :     moduleHandler: (name) {
+     117             :       final ptr = calloc<Pointer<Utf8>>();
+     118           0 :       ptr.value = Pointer.fromAddress(ptr.address);
+     119           0 :       sendPort.send({
+     120             :         #type: #module,
+     121             :         #name: name,
+     122           0 :         #ptr: ptr.address,
+     123             :       });
+     124           0 :       while (ptr.value.address == ptr.address) sleep(Duration(microseconds: 1));
+     125           0 :       final ret = ptr.value;
+     126           0 :       malloc.free(ptr);
+     127           0 :       if (ret.address == -1) throw JSError('Module Not found');
+     128           0 :       final retString = ret.toDartString();
+     129           0 :       malloc.free(ret);
+     130             :       return retString;
+     131             :     },
+     132             :   );
+     133           4 :   port.listen((msg) async {
+     134             :     var data;
+     135           2 :     SendPort? msgPort = msg[#port];
+     136             :     try {
+     137           2 :       switch (msg[#type]) {
+     138           2 :         case #evaluate:
+     139           4 :           data = await qjs.evaluate(
+     140           2 :             msg[#command],
+     141           2 :             name: msg[#name],
+     142           2 :             evalFlags: msg[#flag],
+     143             :           );
+     144             :           break;
+     145           2 :         case #close:
+     146             :           data = false;
+     147           4 :           qjs.port.close();
+     148           2 :           qjs.close();
+     149           2 :           port.close();
+     150             :           data = true;
+     151             :           break;
+     152             :       }
+     153           4 :       if (msgPort != null) msgPort.send(_encodeData(data));
+     154             :     } catch (e) {
+     155             :       if (msgPort != null)
+     156           0 :         msgPort.send({
+     157           0 :           #error: _encodeData(e),
+     158             :         });
+     159             :     }
+     160             :   });
+     161           4 :   await qjs.dispatch();
+     162             : }
+     163             : 
+     164             : typedef _JsAsyncModuleHandler = Future<String> Function(String name);
+     165             : 
+     166             : class IsolateQjs {
+     167             :   Future<SendPort>? _sendPort;
+     168             : 
+     169             :   /// Max stack size for quickjs.
+     170             :   final int? stackSize;
+     171             : 
+     172             :   /// Asynchronously handler to manage js module.
+     173             :   final _JsAsyncModuleHandler? moduleHandler;
+     174             : 
+     175             :   /// Handler function to manage js module.
+     176             :   final _JsHostPromiseRejectionHandler? hostPromiseRejectionHandler;
+     177             : 
+     178             :   /// Quickjs engine runing on isolate thread.
+     179             :   ///
+     180             :   /// Pass handlers to implement js-dart interaction and resolving modules. The `methodHandler` is
+     181             :   /// used in isolate, so **the handler function must be a top-level function or a static method**.
+     182           1 :   IsolateQjs({
+     183             :     this.moduleHandler,
+     184             :     this.stackSize,
+     185             :     this.hostPromiseRejectionHandler,
+     186             :   });
+     187             : 
+     188           1 :   _ensureEngine() {
+     189           1 :     if (_sendPort != null) return;
+     190           1 :     ReceivePort port = ReceivePort();
+     191           1 :     Isolate.spawn(
+     192             :       _runJsIsolate,
+     193           1 :       {
+     194           1 :         #port: port.sendPort,
+     195           1 :         #stackSize: stackSize,
+     196             :       },
+     197             :       errorsAreFatal: true,
+     198             :     );
+     199           1 :     final completer = Completer<SendPort>();
+     200           2 :     port.listen((msg) async {
+     201           2 :       if (msg is SendPort && !completer.isCompleted) {
+     202           1 :         completer.complete(msg);
+     203             :         return;
+     204             :       }
+     205           1 :       switch (msg[#type]) {
+     206           1 :         case #hostPromiseRejection:
+     207             :           try {
+     208           2 :             final err = _decodeData(msg[#reason]);
+     209           1 :             if (hostPromiseRejectionHandler != null) {
+     210           2 :               hostPromiseRejectionHandler!(err);
+     211             :             } else {
+     212           0 :               print('unhandled promise rejection: $err');
+     213             :             }
+     214             :           } catch (e) {
+     215           0 :             print('host Promise Rejection Handler error: $e');
+     216             :           }
+     217             :           break;
+     218           0 :         case #module:
+     219           0 :           final ptr = Pointer<Pointer>.fromAddress(msg[#ptr]);
+     220             :           try {
+     221           0 :             ptr.value = (await moduleHandler!(msg[#name])).toNativeUtf8();
+     222             :           } catch (e) {
+     223           0 :             ptr.value = Pointer.fromAddress(-1);
+     224             :           }
+     225             :           break;
+     226             :       }
+     227           0 :     }, onDone: () {
+     228           0 :       close();
+     229           0 :       if (!completer.isCompleted)
+     230           0 :         completer.completeError(JSError('isolate close'));
+     231             :     });
+     232           2 :     _sendPort = completer.future;
+     233             :   }
+     234             : 
+     235             :   /// Free Runtime and close isolate thread that can be recreate when evaluate again.
+     236           1 :   close() {
+     237           1 :     final sendPort = _sendPort;
+     238           1 :     _sendPort = null;
+     239             :     if (sendPort == null) return;
+     240           2 :     final ret = sendPort.then((sendPort) async {
+     241           1 :       final closePort = ReceivePort();
+     242           2 :       sendPort.send({
+     243             :         #type: #close,
+     244           1 :         #port: closePort.sendPort,
+     245             :       });
+     246           2 :       final result = await closePort.first;
+     247           1 :       closePort.close();
+     248           1 :       if (result is Map && result.containsKey(#error))
+     249           0 :         throw _decodeData(result[#error]);
+     250           1 :       return _decodeData(result);
+     251             :     });
+     252             :     return ret;
+     253             :   }
+     254             : 
+     255             :   /// Evaluate js script.
+     256           1 :   Future<dynamic> evaluate(
+     257             :     String command, {
+     258             :     String? name,
+     259             :     int? evalFlags,
+     260             :   }) async {
+     261           1 :     _ensureEngine();
+     262           1 :     final evaluatePort = ReceivePort();
+     263           2 :     final sendPort = await _sendPort!;
+     264           2 :     sendPort.send({
+     265             :       #type: #evaluate,
+     266             :       #command: command,
+     267             :       #name: name,
+     268             :       #flag: evalFlags,
+     269           1 :       #port: evaluatePort.sendPort,
+     270             :     });
+     271           2 :     final result = await evaluatePort.first;
+     272           1 :     evaluatePort.close();
+     273           2 :     if (result is Map && result.containsKey(#error))
+     274           0 :       throw _decodeData(result[#error]);
+     275           1 :     return _decodeData(result);
+     276             :   }
+     277             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/object.dart.func-sort-c.html b/coverage/src/object.dart.func-sort-c.html new file mode 100644 index 0000000..dbc40a0 --- /dev/null +++ b/coverage/src/object.dart.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - lcov.info - src/object.dart - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - object.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:12614686.3 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/object.dart.func.html b/coverage/src/object.dart.func.html new file mode 100644 index 0000000..1848be6 --- /dev/null +++ b/coverage/src/object.dart.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - lcov.info - src/object.dart - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - object.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:12614686.3 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/object.dart.gcov.html b/coverage/src/object.dart.gcov.html new file mode 100644 index 0000000..f44a970 --- /dev/null +++ b/coverage/src/object.dart.gcov.html @@ -0,0 +1,390 @@ + + + + + + + LCOV - lcov.info - src/object.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - object.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:12614686.3 %
Date:2021-03-31 22:28:15Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /*
+       2             :  * @Description: wrap object
+       3             :  * @Author: ekibun
+       4             :  * @Date: 2020-10-02 13:49:03
+       5             :  * @LastEditors: ekibun
+       6             :  * @LastEditTime: 2020-10-03 22:21:31
+       7             :  */
+       8             : part of '../flutter_qjs.dart';
+       9             : 
+      10             : /// js invokable
+      11             : abstract class JSInvokable extends JSRef {
+      12             :   dynamic invoke(List args, [dynamic thisVal]);
+      13             : 
+      14           3 :   static dynamic _wrap(dynamic func) {
+      15           3 :     return func is JSInvokable
+      16             :         ? func
+      17           3 :         : func is Function
+      18           3 :             ? _DartFunction(func)
+      19             :             : func;
+      20             :   }
+      21             : }
+      22             : 
+      23             : class _DartFunction extends JSInvokable {
+      24             :   final Function _func;
+      25           3 :   _DartFunction(this._func);
+      26             : 
+      27           3 :   @override
+      28             :   invoke(List args, [thisVal]) {
+      29             :     /// wrap this into function
+      30             :     final passThis =
+      31          15 :         RegExp('{.*thisVal.*}').hasMatch(_func.runtimeType.toString());
+      32             :     final ret =
+      33           8 :         Function.apply(_func, args, passThis ? {#thisVal: thisVal} : null);
+      34           3 :     JSRef.freeRecursive(args);
+      35           3 :     JSRef.freeRecursive(thisVal);
+      36             :     return ret;
+      37             :   }
+      38             : 
+      39           0 :   @override
+      40             :   String toString() {
+      41           0 :     return _func.toString();
+      42             :   }
+      43             : 
+      44           0 :   @override
+      45             :   destroy() {}
+      46             : }
+      47             : 
+      48             : /// implement this to capture js object release.
+      49             : 
+      50             : class _DartObject extends JSRef implements JSRefLeakable {
+      51             :   Object? _obj;
+      52             :   Pointer<JSContext>? _ctx;
+      53           3 :   _DartObject(Pointer<JSContext> ctx, dynamic obj) {
+      54           3 :     _ctx = ctx;
+      55           3 :     _obj = obj;
+      56           6 :     if (obj is JSRef) obj.dup();
+      57          15 :     runtimeOpaques[jsGetRuntime(ctx)]?.addRef(this);
+      58             :   }
+      59             : 
+      60           3 :   static _DartObject? fromAddress(Pointer<JSRuntime> rt, int val) {
+      61          18 :     return runtimeOpaques[rt]?.getRef((e) => identityHashCode(e) == val)
+      62             :         as _DartObject?;
+      63             :   }
+      64             : 
+      65           0 :   @override
+      66             :   String toString() {
+      67           0 :     if (_ctx == null) return "DartObject(released)";
+      68           0 :     return _obj.toString();
+      69             :   }
+      70             : 
+      71           3 :   @override
+      72             :   void destroy() {
+      73           3 :     final ctx = _ctx;
+      74           3 :     final obj = _obj;
+      75           3 :     _ctx = null;
+      76           3 :     _obj = null;
+      77             :     if (ctx == null) return;
+      78          15 :     runtimeOpaques[jsGetRuntime(ctx)]?.removeRef(this);
+      79           6 :     if (obj is JSRef) obj.free();
+      80             :   }
+      81             : }
+      82             : 
+      83             : /// JS Error wrapper
+      84             : class JSError extends _IsolateEncodable {
+      85             :   late String message;
+      86             :   late String stack;
+      87           2 :   JSError(message, [stack]) {
+      88           2 :     if (message is JSError) {
+      89           0 :       this.message = message.message;
+      90           0 :       this.stack = message.stack;
+      91             :     } else {
+      92           4 :       this.message = message.toString();
+      93           5 :       this.stack = (stack ?? StackTrace.current).toString();
+      94             :     }
+      95             :   }
+      96             : 
+      97           0 :   @override
+      98             :   String toString() {
+      99           0 :     return stack.isEmpty ? message.toString() : "$message\n$stack";
+     100             :   }
+     101             : 
+     102           3 :   static JSError? _decode(Map obj) {
+     103           3 :     if (obj.containsKey(#jsError))
+     104           6 :       return JSError(obj[#jsError], obj[#jsErrorStack]);
+     105             :     return null;
+     106             :   }
+     107             : 
+     108           2 :   @override
+     109             :   Map _encode() {
+     110           2 :     return {
+     111           2 :       #jsError: message,
+     112           2 :       #jsErrorStack: stack,
+     113             :     };
+     114             :   }
+     115             : }
+     116             : 
+     117             : /// JS Object reference
+     118             : /// call [release] to release js object.
+     119             : class _JSObject extends JSRef {
+     120             :   Pointer<JSValue>? _val;
+     121             :   Pointer<JSContext>? _ctx;
+     122             : 
+     123             :   /// Create
+     124           3 :   _JSObject(Pointer<JSContext> ctx, Pointer<JSValue> val) {
+     125           3 :     this._ctx = ctx;
+     126           6 :     final rt = jsGetRuntime(ctx);
+     127           9 :     this._val = jsDupValue(ctx, val);
+     128           9 :     runtimeOpaques[rt]?.addRef(this);
+     129             :   }
+     130             : 
+     131           3 :   @override
+     132             :   void destroy() {
+     133           3 :     final ctx = _ctx;
+     134           3 :     final val = _val;
+     135           3 :     _val = null;
+     136           3 :     _ctx = null;
+     137             :     if (ctx == null || val == null) return;
+     138           6 :     final rt = jsGetRuntime(ctx);
+     139           9 :     runtimeOpaques[rt]?.removeRef(this);
+     140           3 :     jsFreeValue(ctx, val);
+     141             :   }
+     142             : 
+     143           1 :   @override
+     144             :   String toString() {
+     145           2 :     if (_ctx == null || _val == null) return "JSObject(released)";
+     146           3 :     return jsToCString(_ctx!, _val!);
+     147             :   }
+     148             : }
+     149             : 
+     150             : /// JS function wrapper
+     151             : class _JSFunction extends _JSObject implements JSInvokable, _IsolateEncodable {
+     152           6 :   _JSFunction(Pointer<JSContext> ctx, Pointer<JSValue> val) : super(ctx, val);
+     153             : 
+     154           3 :   @override
+     155             :   invoke(List<dynamic> arguments, [dynamic thisVal]) {
+     156           3 :     final jsRet = _invoke(arguments, thisVal);
+     157           3 :     final ctx = _ctx!;
+     158           9 :     bool isException = jsIsException(jsRet) != 0;
+     159             :     if (isException) {
+     160           0 :       jsFreeValue(ctx, jsRet);
+     161           0 :       throw _parseJSException(ctx);
+     162             :     }
+     163           3 :     final ret = _jsToDart(ctx, jsRet);
+     164           3 :     jsFreeValue(ctx, jsRet);
+     165             :     return ret;
+     166             :   }
+     167             : 
+     168           3 :   Pointer<JSValue> _invoke(List<dynamic> arguments, [dynamic thisVal]) {
+     169           3 :     final ctx = _ctx;
+     170           3 :     final val = _val;
+     171             :     if (ctx == null || val == null)
+     172           0 :       throw JSError("InternalError: JSValue released");
+     173             :     final args = arguments
+     174           3 :         .map(
+     175           6 :           (e) => _dartToJs(ctx, e),
+     176             :         )
+     177           3 :         .toList();
+     178           3 :     final jsThis = _dartToJs(ctx, thisVal);
+     179           3 :     final jsRet = jsCall(ctx, val, jsThis, args);
+     180           3 :     jsFreeValue(ctx, jsThis);
+     181           6 :     for (final jsArg in args) {
+     182           3 :       jsFreeValue(ctx, jsArg);
+     183             :     }
+     184             :     return jsRet;
+     185             :   }
+     186             : 
+     187           2 :   @override
+     188             :   Map _encode() {
+     189           4 :     return IsolateFunction._new(this)._encode();
+     190             :   }
+     191             : }
+     192             : 
+     193             : /// Dart function wrapper for isolate
+     194             : class IsolateFunction extends JSInvokable implements _IsolateEncodable {
+     195             :   int? _isolateId;
+     196             :   SendPort? _port;
+     197             :   JSInvokable? _invokable;
+     198           3 :   IsolateFunction._fromId(this._isolateId, this._port);
+     199             : 
+     200           3 :   IsolateFunction._new(this._invokable) {
+     201           6 :     _handlers.add(this);
+     202             :   }
+     203           3 :   IsolateFunction(Function func) : this._new(_DartFunction(func));
+     204             : 
+     205             :   static ReceivePort? _invokeHandler;
+     206           6 :   static Set<IsolateFunction> _handlers = Set();
+     207             : 
+     208           3 :   static get _handlePort {
+     209             :     if (_invokeHandler == null) {
+     210           3 :       _invokeHandler = ReceivePort();
+     211           6 :       _invokeHandler!.listen((msg) async {
+     212           3 :         final msgPort = msg[#port];
+     213             :         try {
+     214           6 :           final handler = _handlers.firstWhereOrNull(
+     215          12 :             (v) => identityHashCode(v) == msg[#handler],
+     216             :           );
+     217           0 :           if (handler == null) throw JSError('handler released');
+     218          12 :           final ret = _encodeData(await handler._handle(msg[#msg]));
+     219           3 :           if (msgPort != null) msgPort.send(ret);
+     220             :         } catch (e) {
+     221           0 :           final err = _encodeData(e);
+     222             :           if (msgPort != null)
+     223           0 :             msgPort.send({
+     224             :               #error: err,
+     225             :             });
+     226             :         }
+     227             :       });
+     228             :     }
+     229           3 :     return _invokeHandler!.sendPort;
+     230             :   }
+     231             : 
+     232           3 :   _send(msg) async {
+     233           3 :     final port = _port;
+     234           1 :     if (port == null) return _handle(msg);
+     235           3 :     final evaluatePort = ReceivePort();
+     236           6 :     port.send({
+     237           3 :       #handler: _isolateId,
+     238             :       #msg: msg,
+     239           3 :       #port: evaluatePort.sendPort,
+     240             :     });
+     241           6 :     final result = await evaluatePort.first;
+     242           5 :     if (result is Map && result.containsKey(#error))
+     243           0 :       throw _decodeData(result[#error]);
+     244           3 :     return _decodeData(result);
+     245             :   }
+     246             : 
+     247           2 :   _destroy() {
+     248           4 :     _handlers.remove(this);
+     249           4 :     _invokable?.free();
+     250           2 :     _invokable = null;
+     251             :   }
+     252             : 
+     253           3 :   _handle(msg) async {
+     254             :     switch (msg) {
+     255           3 :       case #dup:
+     256           6 :         _refCount++;
+     257             :         return null;
+     258           3 :       case #free:
+     259           6 :         _refCount--;
+     260           8 :         if (_refCount < 0) _destroy();
+     261             :         return null;
+     262           3 :       case #destroy:
+     263           0 :         _destroy();
+     264             :         return null;
+     265             :     }
+     266           6 :     final List args = _decodeData(msg[#args]);
+     267           6 :     final thisVal = _decodeData(msg[#thisVal]);
+     268           6 :     return _invokable?.invoke(args, thisVal);
+     269             :   }
+     270             : 
+     271             :   @override
+     272           3 :   Future invoke(List positionalArguments, [thisVal]) async {
+     273           3 :     final List dArgs = _encodeData(positionalArguments);
+     274           3 :     final dThisVal = _encodeData(thisVal);
+     275           6 :     return _send({
+     276             :       #args: dArgs,
+     277             :       #thisVal: dThisVal,
+     278             :     });
+     279             :   }
+     280             : 
+     281           3 :   static IsolateFunction? _decode(Map obj) {
+     282           3 :     if (obj.containsKey(#jsFunctionPort))
+     283           3 :       return IsolateFunction._fromId(
+     284           3 :         obj[#jsFunctionId],
+     285           3 :         obj[#jsFunctionPort],
+     286             :       );
+     287             :     return null;
+     288             :   }
+     289             : 
+     290           3 :   @override
+     291             :   Map _encode() {
+     292           3 :     return {
+     293           6 :       #jsFunctionId: _isolateId ?? identityHashCode(this),
+     294           6 :       #jsFunctionPort: _port ?? IsolateFunction._handlePort,
+     295             :     };
+     296             :   }
+     297             : 
+     298             :   int _refCount = 0;
+     299             : 
+     300           3 :   @override
+     301             :   dup() {
+     302           3 :     _send(#dup);
+     303             :   }
+     304             : 
+     305           3 :   @override
+     306             :   free() {
+     307           3 :     _send(#free);
+     308             :   }
+     309             : 
+     310           0 :   @override
+     311             :   void destroy() {
+     312           0 :     _send(#destroy);
+     313             :   }
+     314             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/wrapper.dart.func-sort-c.html b/coverage/src/wrapper.dart.func-sort-c.html new file mode 100644 index 0000000..18da546 --- /dev/null +++ b/coverage/src/wrapper.dart.func-sort-c.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - lcov.info - src/wrapper.dart - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - wrapper.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:14915894.3 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/wrapper.dart.func.html b/coverage/src/wrapper.dart.func.html new file mode 100644 index 0000000..aa7d018 --- /dev/null +++ b/coverage/src/wrapper.dart.func.html @@ -0,0 +1,72 @@ + + + + + + + LCOV - lcov.info - src/wrapper.dart - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - wrapper.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:14915894.3 %
Date:2021-03-31 22:28:15Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/wrapper.dart.gcov.html b/coverage/src/wrapper.dart.gcov.html new file mode 100644 index 0000000..d8b5850 --- /dev/null +++ b/coverage/src/wrapper.dart.gcov.html @@ -0,0 +1,325 @@ + + + + + + + LCOV - lcov.info - src/wrapper.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - wrapper.dart (source / functions)HitTotalCoverage
Test:lcov.infoLines:14915894.3 %
Date:2021-03-31 22:28:15Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /*
+       2             :  * @Description: wrapper
+       3             :  * @Author: ekibun
+       4             :  * @Date: 2020-09-19 22:07:47
+       5             :  * @LastEditors: ekibun
+       6             :  * @LastEditTime: 2020-12-02 11:14:03
+       7             :  */
+       8             : part of '../flutter_qjs.dart';
+       9             : 
+      10           2 : dynamic _parseJSException(Pointer<JSContext> ctx, [Pointer<JSValue>? perr]) {
+      11           2 :   final e = perr ?? jsGetException(ctx);
+      12             :   var err;
+      13             :   try {
+      14           2 :     err = _jsToDart(ctx, e);
+      15             :   } catch (exception) {
+      16             :     err = exception;
+      17             :   }
+      18           1 :   if (perr == null) jsFreeValue(ctx, e);
+      19             :   return err;
+      20             : }
+      21             : 
+      22           2 : void _definePropertyValue(
+      23             :   Pointer<JSContext> ctx,
+      24             :   Pointer<JSValue> obj,
+      25             :   dynamic key,
+      26             :   dynamic val, {
+      27             :   Map<dynamic, Pointer<JSValue>>? cache,
+      28             : }) {
+      29           2 :   final jsAtomVal = _dartToJs(ctx, key, cache: cache);
+      30           4 :   final jsAtom = jsValueToAtom(ctx, jsAtomVal);
+      31           4 :   jsDefinePropertyValue(
+      32             :     ctx,
+      33             :     obj,
+      34             :     jsAtom,
+      35           2 :     _dartToJs(ctx, val, cache: cache),
+      36             :     JSProp.C_W_E,
+      37             :   );
+      38           4 :   jsFreeAtom(ctx, jsAtom);
+      39           2 :   jsFreeValue(ctx, jsAtomVal);
+      40             : }
+      41             : 
+      42           3 : Pointer<JSValue> _jsGetPropertyValue(
+      43             :   Pointer<JSContext> ctx,
+      44             :   Pointer<JSValue> obj,
+      45             :   dynamic key, {
+      46             :   Map<dynamic, Pointer<JSValue>>? cache,
+      47             : }) {
+      48           3 :   final jsAtomVal = _dartToJs(ctx, key, cache: cache);
+      49           6 :   final jsAtom = jsValueToAtom(ctx, jsAtomVal);
+      50           6 :   final jsProp = jsGetProperty(ctx, obj, jsAtom);
+      51           6 :   jsFreeAtom(ctx, jsAtom);
+      52           3 :   jsFreeValue(ctx, jsAtomVal);
+      53             :   return jsProp;
+      54             : }
+      55             : 
+      56           3 : Pointer<JSValue> _dartToJs(Pointer<JSContext> ctx, dynamic val,
+      57             :     {Map<dynamic, Pointer<JSValue>>? cache}) {
+      58           6 :   if (val == null) return jsUNDEFINED();
+      59           3 :   if (val is Error) return _dartToJs(ctx, JSError(val, val.stackTrace));
+      60           3 :   if (val is Exception) return _dartToJs(ctx, JSError(val));
+      61           3 :   if (val is JSError) {
+      62           4 :     final ret = jsNewError(ctx);
+      63           2 :     _definePropertyValue(ctx, ret, "name", "");
+      64           4 :     _definePropertyValue(ctx, ret, "message", val.message);
+      65           4 :     _definePropertyValue(ctx, ret, "stack", val.stack);
+      66             :     return ret;
+      67             :   }
+      68          12 :   if (val is _JSObject) return jsDupValue(ctx, val._val!);
+      69           3 :   if (val is Future) {
+      70           9 :     final resolvingFunc = malloc<Uint8>(sizeOfJSValue * 2).cast<JSValue>();
+      71             :     final resolvingFunc2 =
+      72          12 :         Pointer<JSValue>.fromAddress(resolvingFunc.address + sizeOfJSValue);
+      73           6 :     final ret = jsNewPromiseCapability(ctx, resolvingFunc);
+      74           3 :     final _JSFunction res = _jsToDart(ctx, resolvingFunc);
+      75           3 :     final _JSFunction rej = _jsToDart(ctx, resolvingFunc2);
+      76           3 :     jsFreeValue(ctx, resolvingFunc, free: false);
+      77           3 :     jsFreeValue(ctx, resolvingFunc2, free: false);
+      78           3 :     malloc.free(resolvingFunc);
+      79           3 :     final refRes = _DartObject(ctx, res);
+      80           3 :     final refRej = _DartObject(ctx, rej);
+      81           3 :     res.free();
+      82           3 :     rej.free();
+      83           6 :     val.then((value) {
+      84           6 :       res.invoke([value]);
+      85           2 :     }, onError: (e) {
+      86           4 :       rej.invoke([e]);
+      87           6 :     }).whenComplete(() {
+      88           3 :       refRes.free();
+      89           3 :       refRej.free();
+      90             :     });
+      91             :     return ret;
+      92             :   }
+      93           3 :   if (cache == null) cache = Map();
+      94           7 :   if (val is bool) return jsNewBool(ctx, val ? 1 : 0);
+      95           7 :   if (val is int) return jsNewInt64(ctx, val);
+      96           7 :   if (val is double) return jsNewFloat64(ctx, val);
+      97           6 :   if (val is String) return jsNewString(ctx, val);
+      98           3 :   if (val is Uint8List) {
+      99           0 :     final ptr = malloc<Uint8>(val.length);
+     100           0 :     final byteList = ptr.asTypedList(val.length);
+     101           0 :     byteList.setAll(0, val);
+     102           0 :     final ret = jsNewArrayBufferCopy(ctx, ptr, val.length);
+     103           0 :     malloc.free(ptr);
+     104             :     return ret;
+     105             :   }
+     106           3 :   if (cache.containsKey(val)) {
+     107           6 :     return jsDupValue(ctx, cache[val]!);
+     108             :   }
+     109           3 :   if (val is List) {
+     110           4 :     final ret = jsNewArray(ctx);
+     111           2 :     cache[val] = ret;
+     112           6 :     for (int i = 0; i < val.length; ++i) {
+     113           4 :       _definePropertyValue(ctx, ret, i, val[i], cache: cache);
+     114             :     }
+     115             :     return ret;
+     116             :   }
+     117           3 :   if (val is Map) {
+     118           4 :     final ret = jsNewObject(ctx);
+     119           2 :     cache[val] = ret;
+     120           4 :     for (MapEntry<dynamic, dynamic> entry in val.entries) {
+     121           6 :       _definePropertyValue(ctx, ret, entry.key, entry.value, cache: cache);
+     122             :     }
+     123             :     return ret;
+     124             :   }
+     125             :   // wrap Function to JSInvokable
+     126           3 :   final valWrap = JSInvokable._wrap(val);
+     127             :   final dartObjectClassId =
+     128          15 :       runtimeOpaques[jsGetRuntime(ctx)]?.dartObjectClassId ?? 0;
+     129           3 :   if (dartObjectClassId == 0) return jsUNDEFINED();
+     130           6 :   final dartObject = jsNewObjectClass(
+     131             :     ctx,
+     132             :     dartObjectClassId,
+     133           6 :     identityHashCode(_DartObject(ctx, valWrap)),
+     134             :   );
+     135           3 :   if (valWrap is JSInvokable) {
+     136           6 :     final ret = jsNewCFunction(ctx, dartObject);
+     137           3 :     jsFreeValue(ctx, dartObject);
+     138             :     return ret;
+     139             :   }
+     140             :   return dartObject;
+     141             : }
+     142             : 
+     143           3 : dynamic _jsToDart(Pointer<JSContext> ctx, Pointer<JSValue> val,
+     144             :     {Map<int, dynamic>? cache}) {
+     145           3 :   if (cache == null) cache = Map();
+     146           6 :   final tag = jsValueGetTag(val);
+     147           9 :   if (jsTagIsFloat64(tag) != 0) {
+     148           4 :     return jsToFloat64(ctx, val);
+     149             :   }
+     150             :   switch (tag) {
+     151           3 :     case JSTag.BOOL:
+     152           6 :       return jsToBool(ctx, val) != 0;
+     153           3 :     case JSTag.INT:
+     154           4 :       return jsToInt64(ctx, val);
+     155           3 :     case JSTag.STRING:
+     156           3 :       return jsToCString(ctx, val);
+     157           3 :     case JSTag.OBJECT:
+     158           6 :       final rt = jsGetRuntime(ctx);
+     159           9 :       final dartObjectClassId = runtimeOpaques[rt]?.dartObjectClassId;
+     160             :       if (dartObjectClassId != null) {
+     161           3 :         final dartObject = _DartObject.fromAddress(
+     162           6 :             rt, jsGetObjectOpaque(val, dartObjectClassId));
+     163           3 :         if (dartObject != null) return dartObject._obj;
+     164             :       }
+     165             :       final psize = malloc<IntPtr>();
+     166           6 :       final buf = jsGetArrayBuffer(ctx, psize, val);
+     167           3 :       final size = psize.value;
+     168           3 :       malloc.free(psize);
+     169           6 :       if (buf.address != 0) {
+     170           0 :         return Uint8List.fromList(buf.asTypedList(size));
+     171             :       }
+     172           6 :       final valptr = jsValueGetPtr(val);
+     173           3 :       if (cache.containsKey(valptr)) {
+     174           2 :         return cache[valptr];
+     175             :       }
+     176           9 :       if (jsIsFunction(ctx, val) != 0) {
+     177           3 :         return _JSFunction(ctx, val);
+     178           9 :       } else if (jsIsError(ctx, val) != 0) {
+     179           2 :         final err = jsToCString(ctx, val);
+     180           2 :         final pstack = _jsGetPropertyValue(ctx, val, 'stack');
+     181             :         final stack =
+     182           8 :             jsToBool(ctx, pstack) != 0 ? jsToCString(ctx, pstack) : null;
+     183           2 :         jsFreeValue(ctx, pstack);
+     184           2 :         return JSError(err, stack);
+     185           9 :       } else if (jsIsPromise(ctx, val) != 0) {
+     186           3 :         final jsPromiseThen = _jsGetPropertyValue(ctx, val, 'then');
+     187             :         final _JSFunction promiseThen =
+     188           3 :             _jsToDart(ctx, jsPromiseThen, cache: cache);
+     189           3 :         jsFreeValue(ctx, jsPromiseThen);
+     190           3 :         final completer = Completer();
+     191           8 :         completer.future.catchError((e) {});
+     192           3 :         final jsPromise = _JSObject(ctx, val);
+     193           6 :         final jsRet = promiseThen._invoke([
+     194           3 :           (v) {
+     195           3 :             JSRef.dupRecursive(v);
+     196           6 :             if (!completer.isCompleted) completer.complete(v);
+     197             :           },
+     198           2 :           (e) {
+     199           2 :             JSRef.dupRecursive(e);
+     200           4 :             if (!completer.isCompleted) completer.completeError(e);
+     201             :           },
+     202             :         ], jsPromise);
+     203           3 :         jsPromise.free();
+     204           3 :         promiseThen.free();
+     205           9 :         final isException = jsIsException(jsRet) != 0;
+     206           3 :         jsFreeValue(ctx, jsRet);
+     207           0 :         if (isException) throw _parseJSException(ctx);
+     208           3 :         return completer.future;
+     209           6 :       } else if (jsIsArray(ctx, val) != 0) {
+     210           2 :         final jslength = _jsGetPropertyValue(ctx, val, 'length');
+     211           4 :         final length = jsToInt64(ctx, jslength);
+     212           2 :         final ret = [];
+     213           2 :         cache[valptr] = ret;
+     214           4 :         for (var i = 0; i < length; ++i) {
+     215           2 :           final jsProp = _jsGetPropertyValue(ctx, val, i);
+     216           4 :           ret.add(_jsToDart(ctx, jsProp, cache: cache));
+     217           2 :           jsFreeValue(ctx, jsProp);
+     218             :         }
+     219             :         return ret;
+     220             :       } else {
+     221             :         final ptab = malloc<Pointer<JSPropertyEnum>>();
+     222             :         final plen = malloc<Uint32>();
+     223           8 :         if (jsGetOwnPropertyNames(ctx, ptab, plen, val, -1) != 0) {
+     224           0 :           malloc.free(plen);
+     225           0 :           malloc.free(ptab);
+     226             :           return null;
+     227             :         }
+     228           2 :         final len = plen.value;
+     229           2 :         malloc.free(plen);
+     230           2 :         final ret = Map();
+     231           2 :         cache[valptr] = ret;
+     232           4 :         for (var i = 0; i < len; ++i) {
+     233           6 :           final jsAtom = jsPropertyEnumGetAtom(ptab.value, i);
+     234           4 :           final jsAtomValue = jsAtomToValue(ctx, jsAtom);
+     235           4 :           final jsProp = jsGetProperty(ctx, val, jsAtom);
+     236           4 :           ret[_jsToDart(ctx, jsAtomValue, cache: cache)] =
+     237           2 :               _jsToDart(ctx, jsProp, cache: cache);
+     238           2 :           jsFreeValue(ctx, jsAtomValue);
+     239           2 :           jsFreeValue(ctx, jsProp);
+     240           4 :           jsFreeAtom(ctx, jsAtom);
+     241             :         }
+     242           6 :         jsFree(ctx, ptab.value);
+     243           2 :         malloc.free(ptab);
+     244             :         return ret;
+     245             :       }
+     246             :     default:
+     247             :   }
+     248             :   return null;
+     249             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/updown.png b/coverage/updown.png new file mode 100644 index 0000000..aa56a23 Binary files /dev/null and b/coverage/updown.png differ diff --git a/cxx/prebuild.sh b/cxx/prebuild.sh index f98b5c0..dedef83 100644 --- a/cxx/prebuild.sh +++ b/cxx/prebuild.sh @@ -7,27 +7,11 @@ mkdir ./cxx sed 's/\#include \"quickjs\/quickjs.h\"/\#include \"quickjs.h\"/g' ../cxx/ffi.h > ./cxx/ffi.h cp ../cxx/ffi.cpp ./cxx/ffi.cpp +cp ../cxx/quickjs/*.h ./cxx/ +cp ../cxx/quickjs/*.c ./cxx/ + quickjs_version=$(cat ../cxx/quickjs/VERSION) sed '1i\ \#define CONFIG_VERSION \"'$quickjs_version'\"\ -' ../cxx/quickjs/quickjs.c > ./cxx/quickjs.c - -quickjs_src=( - "list.h" - "cutils.c" - "libregexp.c" - "libunicode.c" - "cutils.h" - "libregexp.h" - "libunicode.h" - "quickjs.h" - "quickjs-atom.h" - "quickjs-opcode.h" - "libregexp-opcode.h" - "libunicode-table.h" -) -for item in ${quickjs_src[*]} -do - cp ../cxx/quickjs/$item ./cxx/$item -done \ No newline at end of file +' ../cxx/quickjs/quickjs.c > ./cxx/quickjs.c \ No newline at end of file diff --git a/cxx/quickjs b/cxx/quickjs index d5bd943..9ac134f 160000 --- a/cxx/quickjs +++ b/cxx/quickjs @@ -1 +1 @@ -Subproject commit d5bd943ea93e901ea7a2f65462eaba062180be40 +Subproject commit 9ac134fd3f9e693f6b9c405139549681bf743580 diff --git a/example/pubspec.lock b/example/pubspec.lock index ac7d3d5..a457a5a 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,58 +5,58 @@ packages: dependency: transitive description: name: async - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "2.5.0" + version: "2.8.2" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.1.0" characters: dependency: transitive description: name: characters - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" charcode: dependency: transitive description: name: charcode - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.1" clock: dependency: transitive description: name: clock - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.1.0" collection: dependency: transitive description: name: collection - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.15.0" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.2.0" ffi: dependency: transitive description: name: ffi - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.1.2" flutter: dependency: "direct main" description: flutter @@ -66,7 +66,7 @@ packages: dependency: "direct main" description: name: flutter_highlight - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.6.0" flutter_qjs: @@ -85,28 +85,28 @@ packages: dependency: "direct main" description: name: highlight - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.6.0" matcher: dependency: transitive description: name: matcher - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "0.12.10" + version: "0.12.11" meta: dependency: transitive description: name: meta - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.7.0" path: dependency: transitive description: name: path - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.8.0" sky_engine: @@ -118,58 +118,58 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.8.1" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.2.0" test_api: dependency: transitive description: name: test_api - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "0.2.19" + version: "0.4.3" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.3.0" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" sdks: - dart: ">=2.12.0-259.9.beta <3.0.0" + dart: ">=2.14.0 <3.0.0" flutter: ">=1.20.0" diff --git a/example/windows/flutter/generated_plugin_registrant.cc b/example/windows/flutter/generated_plugin_registrant.cc index 5893996..1c0e883 100644 --- a/example/windows/flutter/generated_plugin_registrant.cc +++ b/example/windows/flutter/generated_plugin_registrant.cc @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" #include diff --git a/example/windows/flutter/generated_plugin_registrant.h b/example/windows/flutter/generated_plugin_registrant.h index 9846246..dc139d8 100644 --- a/example/windows/flutter/generated_plugin_registrant.h +++ b/example/windows/flutter/generated_plugin_registrant.h @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ diff --git a/pubspec.lock b/pubspec.lock index b5f6c6a..8120c44 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,58 +5,58 @@ packages: dependency: transitive description: name: async - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "2.5.0" + version: "2.8.2" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.1.0" characters: dependency: transitive description: name: characters - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" charcode: dependency: transitive description: name: charcode - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.1" clock: dependency: transitive description: name: clock - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.1.0" collection: dependency: transitive description: name: collection - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.15.0" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.2.0" ffi: dependency: "direct main" description: name: ffi - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.1.2" flutter: dependency: "direct main" description: flutter @@ -71,21 +71,21 @@ packages: dependency: transitive description: name: matcher - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "0.12.10" + version: "0.12.11" meta: dependency: transitive description: name: meta - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.7.0" path: dependency: transitive description: name: path - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.8.0" sky_engine: @@ -97,58 +97,58 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.8.1" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.2.0" test_api: dependency: transitive description: name: test_api - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "0.2.19" + version: "0.4.3" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.3.0" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.1.0" sdks: - dart: ">=2.12.0-259.9.beta <3.0.0" + dart: ">=2.12.0 <3.0.0" flutter: ">=1.20.0"