4
4
*
5
5
* GPU Accelerated JavaScript
6
6
*
7
- * @version 2.0.0-rc.5
8
- * @date Tue Mar 19 2019 08:40:39 GMT-0400 (Eastern Daylight Time)
7
+ * @version 2.0.0-rc.6
8
+ * @date Tue Mar 19 2019 19:50:06 GMT-0400 (Eastern Daylight Time)
9
9
*
10
10
* @license MIT
11
11
* The MIT License
@@ -1179,18 +1179,19 @@ class FunctionBuilder {
1179
1179
1180
1180
const onNestedFunction = ( fnString , returnType ) => {
1181
1181
functionBuilder . addFunctionNode ( new FunctionNode ( fnString , Object . assign ( { } , nodeOptions , {
1182
- returnType
1182
+ returnType : returnType || 'Number' ,
1183
+ lookupReturnType
1183
1184
} ) ) ) ;
1184
1185
} ;
1185
1186
1186
1187
const parsedReturnTypes = { } ;
1187
- const lookupReturnType = ( functionName ) => {
1188
+ const lookupReturnType = ( functionName , ast , requestingNode ) => {
1188
1189
if ( parsedReturnTypes [ functionName ] ) return parsedReturnTypes [ functionName ] ;
1189
1190
const source = functionBuilder . nativeFunctions [ functionName ] ;
1190
1191
if ( source ) {
1191
1192
return parsedReturnTypes [ functionName ] = kernel . constructor . nativeFunctionReturnType ( source ) ;
1192
1193
}
1193
- return functionBuilder . lookupReturnType ( functionName ) ;
1194
+ return functionBuilder . lookupReturnType ( functionName , ast , requestingNode ) ;
1194
1195
} ;
1195
1196
1196
1197
const nativeFunctionReturnTypes = { } ;
@@ -1241,6 +1242,7 @@ class FunctionBuilder {
1241
1242
plugins,
1242
1243
constants,
1243
1244
constantTypes,
1245
+ lookupReturnType,
1244
1246
} ) ) ;
1245
1247
}
1246
1248
@@ -1254,7 +1256,9 @@ class FunctionBuilder {
1254
1256
return new FunctionNode ( source , Object . assign ( { } , nodeOptions , {
1255
1257
name,
1256
1258
isSubKernel : true ,
1257
- isRootKernel : false
1259
+ isRootKernel : false ,
1260
+ returnType : 'Number' ,
1261
+ lookupReturnType,
1258
1262
} ) ) ;
1259
1263
} ) ;
1260
1264
}
@@ -1414,11 +1418,16 @@ class FunctionBuilder {
1414
1418
return this . getStringFromFunctionNames ( Object . keys ( this . functionMap ) ) ;
1415
1419
}
1416
1420
1417
- lookupReturnType ( functionName ) {
1421
+ lookupReturnType ( functionName , ast , requestingNode ) {
1418
1422
const node = this . functionMap [ functionName ] ;
1419
- if ( node && node . returnType ) {
1420
- return node . returnType ;
1423
+ if ( node ) {
1424
+ if ( node . returnType ) {
1425
+ return node . returnType ;
1426
+ } else {
1427
+ return node . getType ( node . getJsAST ( ) ) ;
1428
+ }
1421
1429
}
1430
+
1422
1431
return null ;
1423
1432
}
1424
1433
}
@@ -1474,7 +1483,7 @@ class FunctionNode {
1474
1483
}
1475
1484
}
1476
1485
1477
- if ( ! this . returnType ) {
1486
+ if ( this . isRootKernel && ! this . returnType ) {
1478
1487
this . returnType = 'Number' ;
1479
1488
}
1480
1489
@@ -1691,16 +1700,26 @@ class FunctionNode {
1691
1700
if ( this . isAstMathFunction ( ast ) ) {
1692
1701
return 'Number' ;
1693
1702
}
1694
- if ( ! ast . callee || ! ast . callee . name ) return null ;
1703
+ if ( ! ast . callee || ! ast . callee . name ) {
1704
+ if ( ast . callee . type === 'SequenceExpression' ) {
1705
+ return this . getType ( ast . callee . expressions [ ast . callee . expressions . length - 1 ] ) ;
1706
+ }
1707
+ throw this . astErrorOutput ( 'Unknown call expression' , ast ) ;
1708
+ }
1695
1709
if ( this . nativeFunctionReturnTypes && this . nativeFunctionReturnTypes [ ast . callee . name ] ) {
1696
1710
return this . nativeFunctionReturnTypes [ ast . callee . name ] ;
1697
1711
}
1698
- return ast . callee && ast . callee . name && this . lookupReturnType ? this . lookupReturnType ( ast . callee . name ) : null ;
1712
+ if ( ast . callee && ast . callee . name && this . lookupReturnType ) {
1713
+ return this . lookupReturnType ( ast . callee . name , ast , this ) ;
1714
+ }
1715
+ throw this . astErrorOutput ( `Unhandled getType Type "${ ast . type } "` , ast ) ;
1699
1716
case 'BinaryExpression' :
1700
- if ( ast . operator === '%' ) {
1701
- return 'Number' ;
1702
- } else if ( ast . operator === '>' || ast . operator === '<' ) {
1703
- return 'Boolean' ;
1717
+ switch ( ast . operator ) {
1718
+ case '%' :
1719
+ return 'Number' ;
1720
+ case '>' :
1721
+ case '<' :
1722
+ return 'Boolean' ;
1704
1723
}
1705
1724
const type = this . getType ( ast . left ) ;
1706
1725
return typeLookupMap [ type ] || type ;
@@ -1726,6 +1745,10 @@ class FunctionNode {
1726
1745
if ( ast . name === 'Infinity' ) {
1727
1746
return 'Number' ;
1728
1747
}
1748
+ const origin = this . findIdentifierOrigin ( ast ) ;
1749
+ if ( origin && origin . init ) {
1750
+ return this . getType ( origin . init ) ;
1751
+ }
1729
1752
return null ;
1730
1753
case 'ReturnStatement' :
1731
1754
return this . getType ( ast . argument ) ;
@@ -1782,6 +1805,9 @@ class FunctionNode {
1782
1805
case 'a' :
1783
1806
return typeLookupMap [ this . getVariableType ( ast . object . name ) ] ;
1784
1807
}
1808
+ if ( ast . object . name === '_' + ast . property . name && this . lookupReturnType ) {
1809
+ return this . lookupReturnType ( ast . property . name , ast , this ) ;
1810
+ }
1785
1811
}
1786
1812
throw this . astErrorOutput ( 'Unhandled getType MemberExpression' , ast ) ;
1787
1813
}
@@ -1790,6 +1816,8 @@ class FunctionNode {
1790
1816
return this . getType ( ast . body ) ;
1791
1817
case 'ConditionalExpression' :
1792
1818
return this . getType ( ast . consequent ) ;
1819
+ case 'FunctionExpression' :
1820
+ return this . getType ( ast . body ) ;
1793
1821
default :
1794
1822
throw this . astErrorOutput ( `Unhandled getType Type "${ ast . type } "` , ast ) ;
1795
1823
}
@@ -2428,6 +2456,53 @@ class FunctionNode {
2428
2456
}
2429
2457
}
2430
2458
2459
+ findIdentifierOrigin ( astToFind ) {
2460
+ const stack = [ this . ast ] ;
2461
+
2462
+ while ( stack . length > 0 ) {
2463
+ const atNode = stack [ 0 ] ;
2464
+ if ( atNode . type === 'VariableDeclarator' && atNode . id && atNode . id . name && atNode . id . name === astToFind . name ) {
2465
+ return atNode ;
2466
+ }
2467
+ stack . shift ( ) ;
2468
+ if ( atNode . argument ) {
2469
+ stack . push ( atNode . argument ) ;
2470
+ } else if ( atNode . body ) {
2471
+ stack . push ( atNode . body ) ;
2472
+ } else if ( atNode . declarations ) {
2473
+ stack . push ( atNode . declarations ) ;
2474
+ } else if ( Array . isArray ( atNode ) ) {
2475
+ for ( let i = 0 ; i < atNode . length ; i ++ ) {
2476
+ stack . push ( atNode [ i ] ) ;
2477
+ }
2478
+ }
2479
+ }
2480
+ return null ;
2481
+ }
2482
+
2483
+ findLastReturn ( ) {
2484
+ const stack = [ this . ast ] ;
2485
+
2486
+ while ( stack . length > 0 ) {
2487
+ const atNode = stack . pop ( ) ;
2488
+ if ( atNode . type === 'ReturnStatement' ) {
2489
+ return atNode ;
2490
+ }
2491
+ if ( atNode . argument ) {
2492
+ stack . push ( atNode . argument ) ;
2493
+ } else if ( atNode . body ) {
2494
+ stack . push ( atNode . body ) ;
2495
+ } else if ( atNode . declarations ) {
2496
+ stack . push ( atNode . declarations ) ;
2497
+ } else if ( Array . isArray ( atNode ) ) {
2498
+ for ( let i = 0 ; i < atNode . length ; i ++ ) {
2499
+ stack . push ( atNode [ i ] ) ;
2500
+ }
2501
+ }
2502
+ }
2503
+ return null ;
2504
+ }
2505
+
2431
2506
getInternalVariableName ( name ) {
2432
2507
if ( ! this . _internalVariableNames . hasOwnProperty ( name ) ) {
2433
2508
this . _internalVariableNames [ name ] = 0 ;
@@ -3226,18 +3301,31 @@ class WebGLFunctionNode extends FunctionNode {
3226
3301
}
3227
3302
3228
3303
astFunctionExpression ( ast , retArr ) {
3229
-
3230
3304
if ( this . isRootKernel ) {
3231
3305
retArr . push ( 'void' ) ;
3232
3306
} else {
3307
+ if ( ! this . returnType ) {
3308
+ const lastReturn = this . findLastReturn ( ) ;
3309
+ if ( lastReturn ) {
3310
+ this . returnType = this . getType ( ast . body ) ;
3311
+ if ( this . returnType === 'LiteralInteger' ) {
3312
+ this . returnType = 'Number' ;
3313
+ }
3314
+ }
3315
+ }
3316
+
3233
3317
const {
3234
3318
returnType
3235
3319
} = this ;
3236
- const type = typeMap [ returnType ] ;
3237
- if ( ! type ) {
3238
- throw new Error ( `unknown type ${ returnType } ` ) ;
3320
+ if ( ! returnType ) {
3321
+ retArr . push ( 'void' ) ;
3322
+ } else {
3323
+ const type = typeMap [ returnType ] ;
3324
+ if ( ! type ) {
3325
+ throw new Error ( `unknown type ${ returnType } ` ) ;
3326
+ }
3327
+ retArr . push ( type ) ;
3239
3328
}
3240
- retArr . push ( type ) ;
3241
3329
}
3242
3330
retArr . push ( ' ' ) ;
3243
3331
retArr . push ( this . name ) ;
@@ -3282,7 +3370,16 @@ class WebGLFunctionNode extends FunctionNode {
3282
3370
3283
3371
const result = [ ] ;
3284
3372
3373
+ if ( ! this . returnType ) {
3374
+ if ( this . isRootKernel ) {
3375
+ this . returnType = 'Number' ;
3376
+ } else {
3377
+ this . returnType = type ;
3378
+ }
3379
+ }
3380
+
3285
3381
switch ( this . returnType ) {
3382
+ case 'LiteralInteger' :
3286
3383
case 'Number' :
3287
3384
case 'Float' :
3288
3385
switch ( type ) {
@@ -3345,7 +3442,6 @@ class WebGLFunctionNode extends FunctionNode {
3345
3442
}
3346
3443
3347
3444
astLiteral ( ast , retArr ) {
3348
-
3349
3445
if ( isNaN ( ast . value ) ) {
3350
3446
throw this . astErrorOutput (
3351
3447
'Non-numeric literal not supported : ' + ast . value ,
@@ -5342,9 +5438,9 @@ class WebGLKernel extends GLKernel {
5342
5438
formatArrayTransfer ( value , length ) {
5343
5439
let bitRatio = 1 ;
5344
5440
let valuesFlat = value ;
5345
- if ( this . floatTextures ) {
5346
- length *= 4 ;
5347
- }
5441
+ if ( this . floatTextures ) {
5442
+ length *= 4 ;
5443
+ }
5348
5444
if ( utils . isArray ( value [ 0 ] ) || this . floatTextures ) {
5349
5445
valuesFlat = new Float32Array ( length ) ;
5350
5446
utils . flattenTo ( value , valuesFlat ) ;
@@ -5744,7 +5840,6 @@ class WebGLKernel extends GLKernel {
5744
5840
module . exports = {
5745
5841
WebGLKernel
5746
5842
} ;
5747
-
5748
5843
} , { "../../plugins/triangle-noise" :26 , "../../texture" :27 , "../../utils" :28 , "../function-builder" :7 , "../gl-kernel" :9 , "./fragment-shader" :12 , "./function-node" :13 , "./kernel-string" :14 , "./vertex-shader" :16 } ] , 16 :[ function ( require , module , exports ) {
5749
5844
const vertexShader = `precision highp float;
5750
5845
precision highp int;
@@ -6885,7 +6980,6 @@ class WebGL2Kernel extends WebGLKernel {
6885
6980
module . exports = {
6886
6981
WebGL2Kernel
6887
6982
} ;
6888
-
6889
6983
} , { "../../texture" :27 , "../../utils" :28 , "../function-builder" :7 , "../web-gl/kernel" :15 , "./fragment-shader" :17 , "./function-node" :18 , "./vertex-shader" :20 } ] , 20 :[ function ( require , module , exports ) {
6890
6984
const vertexShader = `#version 300 es
6891
6985
precision highp float;
0 commit comments