44 *
55 * GPU Accelerated JavaScript
66 *
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)
99 *
1010 * @license MIT
1111 * The MIT License
@@ -1179,18 +1179,19 @@ class FunctionBuilder {
11791179
11801180 const onNestedFunction = ( fnString , returnType ) => {
11811181 functionBuilder . addFunctionNode ( new FunctionNode ( fnString , Object . assign ( { } , nodeOptions , {
1182- returnType
1182+ returnType : returnType || 'Number' ,
1183+ lookupReturnType
11831184 } ) ) ) ;
11841185 } ;
11851186
11861187 const parsedReturnTypes = { } ;
1187- const lookupReturnType = ( functionName ) => {
1188+ const lookupReturnType = ( functionName , ast , requestingNode ) => {
11881189 if ( parsedReturnTypes [ functionName ] ) return parsedReturnTypes [ functionName ] ;
11891190 const source = functionBuilder . nativeFunctions [ functionName ] ;
11901191 if ( source ) {
11911192 return parsedReturnTypes [ functionName ] = kernel . constructor . nativeFunctionReturnType ( source ) ;
11921193 }
1193- return functionBuilder . lookupReturnType ( functionName ) ;
1194+ return functionBuilder . lookupReturnType ( functionName , ast , requestingNode ) ;
11941195 } ;
11951196
11961197 const nativeFunctionReturnTypes = { } ;
@@ -1241,6 +1242,7 @@ class FunctionBuilder {
12411242 plugins,
12421243 constants,
12431244 constantTypes,
1245+ lookupReturnType,
12441246 } ) ) ;
12451247 }
12461248
@@ -1254,7 +1256,9 @@ class FunctionBuilder {
12541256 return new FunctionNode ( source , Object . assign ( { } , nodeOptions , {
12551257 name,
12561258 isSubKernel : true ,
1257- isRootKernel : false
1259+ isRootKernel : false ,
1260+ returnType : 'Number' ,
1261+ lookupReturnType,
12581262 } ) ) ;
12591263 } ) ;
12601264 }
@@ -1414,11 +1418,16 @@ class FunctionBuilder {
14141418 return this . getStringFromFunctionNames ( Object . keys ( this . functionMap ) ) ;
14151419 }
14161420
1417- lookupReturnType ( functionName ) {
1421+ lookupReturnType ( functionName , ast , requestingNode ) {
14181422 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+ }
14211429 }
1430+
14221431 return null ;
14231432 }
14241433}
@@ -1474,7 +1483,7 @@ class FunctionNode {
14741483 }
14751484 }
14761485
1477- if ( ! this . returnType ) {
1486+ if ( this . isRootKernel && ! this . returnType ) {
14781487 this . returnType = 'Number' ;
14791488 }
14801489
@@ -1691,16 +1700,26 @@ class FunctionNode {
16911700 if ( this . isAstMathFunction ( ast ) ) {
16921701 return 'Number' ;
16931702 }
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+ }
16951709 if ( this . nativeFunctionReturnTypes && this . nativeFunctionReturnTypes [ ast . callee . name ] ) {
16961710 return this . nativeFunctionReturnTypes [ ast . callee . name ] ;
16971711 }
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 ) ;
16991716 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' ;
17041723 }
17051724 const type = this . getType ( ast . left ) ;
17061725 return typeLookupMap [ type ] || type ;
@@ -1726,6 +1745,10 @@ class FunctionNode {
17261745 if ( ast . name === 'Infinity' ) {
17271746 return 'Number' ;
17281747 }
1748+ const origin = this . findIdentifierOrigin ( ast ) ;
1749+ if ( origin && origin . init ) {
1750+ return this . getType ( origin . init ) ;
1751+ }
17291752 return null ;
17301753 case 'ReturnStatement' :
17311754 return this . getType ( ast . argument ) ;
@@ -1782,6 +1805,9 @@ class FunctionNode {
17821805 case 'a' :
17831806 return typeLookupMap [ this . getVariableType ( ast . object . name ) ] ;
17841807 }
1808+ if ( ast . object . name === '_' + ast . property . name && this . lookupReturnType ) {
1809+ return this . lookupReturnType ( ast . property . name , ast , this ) ;
1810+ }
17851811 }
17861812 throw this . astErrorOutput ( 'Unhandled getType MemberExpression' , ast ) ;
17871813 }
@@ -1790,6 +1816,8 @@ class FunctionNode {
17901816 return this . getType ( ast . body ) ;
17911817 case 'ConditionalExpression' :
17921818 return this . getType ( ast . consequent ) ;
1819+ case 'FunctionExpression' :
1820+ return this . getType ( ast . body ) ;
17931821 default :
17941822 throw this . astErrorOutput ( `Unhandled getType Type "${ ast . type } "` , ast ) ;
17951823 }
@@ -2428,6 +2456,53 @@ class FunctionNode {
24282456 }
24292457 }
24302458
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+
24312506 getInternalVariableName ( name ) {
24322507 if ( ! this . _internalVariableNames . hasOwnProperty ( name ) ) {
24332508 this . _internalVariableNames [ name ] = 0 ;
@@ -3226,18 +3301,31 @@ class WebGLFunctionNode extends FunctionNode {
32263301 }
32273302
32283303 astFunctionExpression ( ast , retArr ) {
3229-
32303304 if ( this . isRootKernel ) {
32313305 retArr . push ( 'void' ) ;
32323306 } 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+
32333317 const {
32343318 returnType
32353319 } = 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 ) ;
32393328 }
3240- retArr . push ( type ) ;
32413329 }
32423330 retArr . push ( ' ' ) ;
32433331 retArr . push ( this . name ) ;
@@ -3282,7 +3370,16 @@ class WebGLFunctionNode extends FunctionNode {
32823370
32833371 const result = [ ] ;
32843372
3373+ if ( ! this . returnType ) {
3374+ if ( this . isRootKernel ) {
3375+ this . returnType = 'Number' ;
3376+ } else {
3377+ this . returnType = type ;
3378+ }
3379+ }
3380+
32853381 switch ( this . returnType ) {
3382+ case 'LiteralInteger' :
32863383 case 'Number' :
32873384 case 'Float' :
32883385 switch ( type ) {
@@ -3345,7 +3442,6 @@ class WebGLFunctionNode extends FunctionNode {
33453442 }
33463443
33473444 astLiteral ( ast , retArr ) {
3348-
33493445 if ( isNaN ( ast . value ) ) {
33503446 throw this . astErrorOutput (
33513447 'Non-numeric literal not supported : ' + ast . value ,
@@ -5342,9 +5438,9 @@ class WebGLKernel extends GLKernel {
53425438 formatArrayTransfer ( value , length ) {
53435439 let bitRatio = 1 ;
53445440 let valuesFlat = value ;
5345- if ( this . floatTextures ) {
5346- length *= 4 ;
5347- }
5441+ if ( this . floatTextures ) {
5442+ length *= 4 ;
5443+ }
53485444 if ( utils . isArray ( value [ 0 ] ) || this . floatTextures ) {
53495445 valuesFlat = new Float32Array ( length ) ;
53505446 utils . flattenTo ( value , valuesFlat ) ;
@@ -5744,7 +5840,6 @@ class WebGLKernel extends GLKernel {
57445840module . exports = {
57455841 WebGLKernel
57465842} ;
5747-
57485843} , { "../../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 ) {
57495844const vertexShader = `precision highp float;
57505845precision highp int;
@@ -6885,7 +6980,6 @@ class WebGL2Kernel extends WebGLKernel {
68856980module . exports = {
68866981 WebGL2Kernel
68876982} ;
6888-
68896983} , { "../../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 ) {
68906984const vertexShader = `#version 300 es
68916985precision highp float;
0 commit comments