@@ -941,23 +941,6 @@ export class JSBuilder extends ExportsWalker {
941941 return moduleId ;
942942 }
943943
944- isPlainObject ( clazz : Class ) : bool {
945- // A plain object does not inherit and does not have a constructor or private properties
946- if ( clazz . base ) return false ;
947- var members = clazz . members ;
948- if ( members ) {
949- for ( let _values = Map_values ( members ) , i = 0 , k = _values . length ; i < k ; ++ i ) {
950- let member = _values [ i ] ;
951- if ( member . isAny ( CommonFlags . PRIVATE | CommonFlags . PROTECTED ) ) return false ;
952- if ( member . is ( CommonFlags . CONSTRUCTOR ) ) {
953- // a generated constructor is ok
954- if ( member . declaration . range != this . program . nativeRange ) return false ;
955- }
956- }
957- }
958- return true ;
959- }
960-
961944 /** Lifts a WebAssembly value to a JavaScript value. */
962945 makeLiftFromValue ( name : string , type : Type , sb : string [ ] = this . sb ) : void {
963946 if ( type . isInternalReference ) {
@@ -996,7 +979,7 @@ export class JSBuilder extends ExportsWalker {
996979 }
997980 sb . push ( ", " ) ;
998981 this . needsLiftTypedArray = true ;
999- } else if ( this . isPlainObject ( clazz ) ) {
982+ } else if ( isPlainObject ( clazz ) ) {
1000983 sb . push ( "__liftRecord" ) ;
1001984 sb . push ( clazz . id . toString ( ) ) ;
1002985 sb . push ( "(" ) ;
@@ -1076,7 +1059,7 @@ export class JSBuilder extends ExportsWalker {
10761059 sb . push ( clazz . getArrayValueType ( ) . alignLog2 . toString ( ) ) ;
10771060 sb . push ( ", " ) ;
10781061 this . needsLowerTypedArray = true ;
1079- } else if ( this . isPlainObject ( clazz ) ) {
1062+ } else if ( isPlainObject ( clazz ) ) {
10801063 sb . push ( "__lowerRecord" ) ;
10811064 sb . push ( clazz . id . toString ( ) ) ;
10821065 sb . push ( "(" ) ;
@@ -1237,7 +1220,7 @@ export class JSBuilder extends ExportsWalker {
12371220 }
12381221
12391222 makeLiftRecord ( clazz : Class ) : string {
1240- assert ( this . isPlainObject ( clazz ) ) ;
1223+ assert ( isPlainObject ( clazz ) ) ;
12411224 var sb = new Array < string > ( ) ;
12421225 indent ( sb , this . indentLevel ) ;
12431226 sb . push ( "function __liftRecord" ) ;
@@ -1275,7 +1258,7 @@ export class JSBuilder extends ExportsWalker {
12751258 }
12761259
12771260 makeLowerRecord ( clazz : Class ) : string {
1278- assert ( this . isPlainObject ( clazz ) ) ;
1261+ assert ( isPlainObject ( clazz ) ) ;
12791262 var sb = new Array < string > ( ) ;
12801263 indent ( sb , this . indentLevel ) ;
12811264 sb . push ( "function __lowerRecord" ) ;
@@ -1350,6 +1333,23 @@ function isPlainFunction(signature: Signature, mode: Mode): bool {
13501333 return true ;
13511334}
13521335
1336+ function isPlainObject ( clazz : Class ) : bool {
1337+ // A plain object does not inherit and does not have a constructor or private properties
1338+ if ( clazz . base ) return false ;
1339+ var members = clazz . members ;
1340+ if ( members ) {
1341+ for ( let _values = Map_values ( members ) , i = 0 , k = _values . length ; i < k ; ++ i ) {
1342+ let member = _values [ i ] ;
1343+ if ( member . isAny ( CommonFlags . PRIVATE | CommonFlags . PROTECTED ) ) return false ;
1344+ if ( member . is ( CommonFlags . CONSTRUCTOR ) ) {
1345+ // a generated constructor is ok
1346+ if ( member . declaration . range != member . program . nativeRange ) return false ;
1347+ }
1348+ }
1349+ }
1350+ return true ;
1351+ }
1352+
13531353function indentText ( text : string , indentLevel : i32 , sb : string [ ] , butFirst : bool = false ) : void {
13541354 var lineStart = 0 ;
13551355 var length = text . length ;
@@ -1367,3 +1367,56 @@ function indentText(text: string, indentLevel: i32, sb: string[], butFirst: bool
13671367 sb . push ( text . substring ( lineStart ) ) ;
13681368 }
13691369}
1370+
1371+ export function liftRequiresExportRuntime ( type : Type ) : bool {
1372+ if ( ! type . isInternalReference ) return false ;
1373+ let clazz = type . classReference ;
1374+ if ( ! clazz ) {
1375+ // functions lift as internref using __pin
1376+ assert ( type . signatureReference ) ;
1377+ return true ;
1378+ }
1379+ let program = clazz . program ;
1380+ // flat collections lift via memory copy
1381+ if (
1382+ clazz . extends ( program . arrayBufferInstance . prototype ) ||
1383+ clazz . extends ( program . stringInstance . prototype ) ||
1384+ clazz . extends ( program . arrayBufferViewInstance . prototype )
1385+ ) {
1386+ return false ;
1387+ }
1388+ // nested collections lift depending on element type
1389+ if (
1390+ clazz . extends ( program . arrayPrototype ) ||
1391+ clazz . extends ( program . staticArrayPrototype )
1392+ ) {
1393+ return liftRequiresExportRuntime ( clazz . getArrayValueType ( ) ) ;
1394+ }
1395+ // complex objects lift as internref using __pin. plain objects may or may not
1396+ // involve the runtime: assume that they do to avoid potentially costly checks
1397+ return true ;
1398+ }
1399+
1400+ export function lowerRequiresExportRuntime ( type : Type ) : bool {
1401+ if ( ! type . isInternalReference ) return false ;
1402+ let clazz = type . classReference ;
1403+ if ( ! clazz ) {
1404+ // lowers by reference
1405+ assert ( type . signatureReference ) ;
1406+ return false ;
1407+ }
1408+ // lowers using __new
1409+ let program = clazz . program ;
1410+ if (
1411+ clazz . extends ( program . arrayBufferInstance . prototype ) ||
1412+ clazz . extends ( program . stringInstance . prototype ) ||
1413+ clazz . extends ( program . arrayBufferViewInstance . prototype ) ||
1414+ clazz . extends ( program . arrayPrototype ) ||
1415+ clazz . extends ( program . staticArrayPrototype )
1416+ ) {
1417+ return true ;
1418+ }
1419+ // complex objects lower via internref by reference,
1420+ // while plain objects lower using __new
1421+ return isPlainObject ( clazz ) ;
1422+ }
0 commit comments