44 *
55 * GPU Accelerated JavaScript
66 *
7- * @version 2.4.3
8- * @date Fri Dec 27 2019 16:33:11 GMT-0500 (Eastern Standard Time)
7+ * @version 2.4.4
8+ * @date Thu Jan 02 2020 12:26:36 GMT-0500 (Eastern Standard Time)
99 *
1010 * @license MIT
1111 * The MIT License
1212 *
13- * Copyright (c) 2019 gpu.js Team
13+ * Copyright (c) 2020 gpu.js Team
1414 */ ( function ( f ) { if ( typeof exports === "object" && typeof module !== "undefined" ) { module . exports = f ( ) } else if ( typeof define === "function" && define . amd ) { define ( [ ] , f ) } else { var g ; if ( typeof window !== "undefined" ) { g = window } else if ( typeof global !== "undefined" ) { g = global } else if ( typeof self !== "undefined" ) { g = self } else { g = this } g . GPU = f ( ) } } ) ( function ( ) { var define , module , exports ; return ( function ( ) { function r ( e , n , t ) { function o ( i , f ) { if ( ! n [ i ] ) { if ( ! e [ i ] ) { var c = "function" == typeof require && require ; if ( ! f && c ) return c ( i , ! 0 ) ; if ( u ) return u ( i , ! 0 ) ; var a = new Error ( "Cannot find module '" + i + "'" ) ; throw a . code = "MODULE_NOT_FOUND" , a } var p = n [ i ] = { exports :{ } } ; e [ i ] [ 0 ] . call ( p . exports , function ( r ) { var n = e [ i ] [ 1 ] [ r ] ; return o ( n || r ) } , p , p . exports , r , e , n , t ) } return n [ i ] . exports } for ( var u = "function" == typeof require && require , i = 0 ; i < t . length ; i ++ ) o ( t [ i ] ) ; return o } return r } ) ( ) ( { 1 :[ function ( require , module , exports ) {
1515
1616} , { } ] , 2 :[ function ( require , module , exports ) {
@@ -2596,12 +2596,12 @@ class FunctionNode {
25962596 this . functions = functions ;
25972597 for ( let i = 0 ; i < declarations . length ; i ++ ) {
25982598 const declaration = declarations [ i ] ;
2599- const { ast, context, name, origin, forceInteger , assignable } = declaration ;
2599+ const { ast, context, name, origin, inForLoopInit , inForLoopTest , assignable } = declaration ;
26002600 const { init } = ast ;
26012601 const dependencies = this . getDependencies ( init ) ;
26022602 let valueType = null ;
26032603
2604- if ( forceInteger ) {
2604+ if ( inForLoopInit && inForLoopTest ) {
26052605 valueType = 'Integer' ;
26062606 } else {
26072607 if ( init ) {
@@ -2626,6 +2626,8 @@ class FunctionNode {
26262626 }
26272627 this . declarations . push ( {
26282628 valueType,
2629+ inForLoopInit,
2630+ inForLoopTest,
26292631 dependencies,
26302632 isSafe : this . isSafeDependencies ( dependencies ) ,
26312633 ast,
@@ -3833,6 +3835,12 @@ function last(array) {
38333835 return array . length > 0 ? array [ array . length - 1 ] : null ;
38343836}
38353837
3838+ const states = {
3839+ trackIdentifiers : 'trackIdentifiers' ,
3840+ memberExpression : 'memberExpression' ,
3841+ inForLoopInit : 'inForLoopInit'
3842+ } ;
3843+
38363844class FunctionTracer {
38373845 constructor ( ast ) {
38383846 this . runningContexts = [ ] ;
@@ -3843,11 +3851,32 @@ class FunctionTracer {
38433851 this . identifiers = [ ] ;
38443852 this . functions = [ ] ;
38453853 this . returnStatements = [ ] ;
3846- this . inLoopInit = false ;
3854+ this . trackedIdentifiers = null ;
3855+ this . states = [ ] ;
38473856 this . newFunctionContext ( ) ;
38483857 this . scan ( ast ) ;
38493858 }
38503859
3860+ isState ( state ) {
3861+ return this . states [ this . states . length - 1 ] === state ;
3862+ }
3863+
3864+ hasState ( state ) {
3865+ return this . states . indexOf ( state ) > - 1 ;
3866+ }
3867+
3868+ pushState ( state ) {
3869+ this . states . push ( state ) ;
3870+ }
3871+
3872+ popState ( state ) {
3873+ if ( this . isState ( state ) ) {
3874+ this . states . pop ( ) ;
3875+ } else {
3876+ throw new Error ( `Cannot pop the non-active state "${ state } "` ) ;
3877+ }
3878+ }
3879+
38513880 get currentFunctionContext ( ) {
38523881 return last ( this . functionContexts ) ;
38533882 }
@@ -3857,13 +3886,13 @@ class FunctionTracer {
38573886 }
38583887
38593888 newFunctionContext ( ) {
3860- const newContext = { '@contextType' : 'var ' } ;
3889+ const newContext = { '@contextType' : 'function ' } ;
38613890 this . contexts . push ( newContext ) ;
38623891 this . functionContexts . push ( newContext ) ;
38633892 }
38643893
38653894 newContext ( run ) {
3866- const newContext = Object . assign ( { '@contextType' : 'var/ const/let' } , this . currentContext ) ;
3895+ const newContext = Object . assign ( { '@contextType' : 'const/let' } , this . currentContext ) ;
38673896 this . contexts . push ( newContext ) ;
38683897 this . runningContexts . push ( newContext ) ;
38693898 run ( ) ;
@@ -3873,6 +3902,7 @@ class FunctionTracer {
38733902 newContext [ p ] = currentFunctionContext [ p ] ;
38743903 }
38753904 this . runningContexts . pop ( ) ;
3905+ return newContext ;
38763906 }
38773907
38783908 useFunctionContext ( run ) {
@@ -3882,6 +3912,15 @@ class FunctionTracer {
38823912 this . runningContexts . pop ( ) ;
38833913 }
38843914
3915+ getIdentifiers ( run ) {
3916+ const trackedIdentifiers = this . trackedIdentifiers = [ ] ;
3917+ this . pushState ( states . trackIdentifiers ) ;
3918+ run ( ) ;
3919+ this . trackedIdentifiers = null ;
3920+ this . popState ( states . trackIdentifiers ) ;
3921+ return trackedIdentifiers ;
3922+ }
3923+
38853924 scan ( ast ) {
38863925 if ( ! ast ) return ;
38873926 if ( Array . isArray ( ast ) ) {
@@ -3892,7 +3931,9 @@ class FunctionTracer {
38923931 }
38933932 switch ( ast . type ) {
38943933 case 'Program' :
3895- this . scan ( ast . body ) ;
3934+ this . useFunctionContext ( ( ) => {
3935+ this . scan ( ast . body ) ;
3936+ } ) ;
38963937 break ;
38973938 case 'BlockStatement' :
38983939 this . newContext ( ( ) => {
@@ -3925,13 +3966,15 @@ class FunctionTracer {
39253966 break ;
39263967 case 'VariableDeclarator' :
39273968 const { currentContext } = this ;
3969+ const inForLoopInit = this . hasState ( states . inForLoopInit ) ;
39283970 const declaration = {
39293971 ast : ast ,
39303972 context : currentContext ,
39313973 name : ast . id . name ,
39323974 origin : 'declaration' ,
3933- forceInteger : this . inLoopInit ,
3934- assignable : currentContext === this . currentFunctionContext || ( ! this . inLoopInit && ! currentContext . hasOwnProperty ( ast . id . name ) ) ,
3975+ inForLoopInit,
3976+ inForLoopTest : null ,
3977+ assignable : currentContext === this . currentFunctionContext || ( ! inForLoopInit && ! currentContext . hasOwnProperty ( ast . id . name ) ) ,
39353978 } ;
39363979 currentContext [ ast . id . name ] = declaration ;
39373980 this . declarations . push ( declaration ) ;
@@ -3952,16 +3995,30 @@ class FunctionTracer {
39523995 if ( ast . alternate ) this . scan ( ast . alternate ) ;
39533996 break ;
39543997 case 'ForStatement' :
3955- this . newContext ( ( ) => {
3956- this . inLoopInit = true ;
3998+ let testIdentifiers ;
3999+ const context = this . newContext ( ( ) => {
4000+ testIdentifiers = this . getIdentifiers ( ( ) => {
4001+ this . scan ( ast . test ) ;
4002+ } ) ;
4003+
4004+ this . pushState ( states . inForLoopInit ) ;
39574005 this . scan ( ast . init ) ;
3958- this . inLoopInit = false ;
3959- this . scan ( ast . test ) ;
4006+ this . popState ( states . inForLoopInit ) ;
4007+
39604008 this . scan ( ast . update ) ;
39614009 this . newContext ( ( ) => {
39624010 this . scan ( ast . body ) ;
39634011 } ) ;
39644012 } ) ;
4013+
4014+ if ( testIdentifiers ) {
4015+ for ( const p in context ) {
4016+ if ( p === '@contextType' ) continue ;
4017+ if ( testIdentifiers . indexOf ( p ) > - 1 ) {
4018+ context [ p ] . inForLoopTest = true ;
4019+ }
4020+ }
4021+ }
39654022 break ;
39664023 case 'DoWhileStatement' :
39674024 case 'WhileStatement' :
@@ -3971,6 +4028,9 @@ class FunctionTracer {
39714028 } ) ;
39724029 break ;
39734030 case 'Identifier' :
4031+ if ( this . isState ( states . trackIdentifiers ) ) {
4032+ this . trackedIdentifiers . push ( ast . name ) ;
4033+ }
39744034 this . identifiers . push ( {
39754035 context : this . currentContext ,
39764036 ast,
@@ -3981,8 +4041,10 @@ class FunctionTracer {
39814041 this . scan ( ast . argument ) ;
39824042 break ;
39834043 case 'MemberExpression' :
4044+ this . pushState ( states . memberExpression ) ;
39844045 this . scan ( ast . object ) ;
39854046 this . scan ( ast . property ) ;
4047+ this . popState ( states . memberExpression ) ;
39864048 break ;
39874049 case 'ExpressionStatement' :
39884050 this . scan ( ast . expression ) ;
@@ -7489,7 +7551,11 @@ class WebGLFunctionNode extends FunctionNode {
74897551 const actualType = this . getType ( declaration . init ) ;
74907552 let type = inForLoopInit ? 'Integer' : actualType ;
74917553 if ( type === 'LiteralInteger' ) {
7492- type = 'Number' ;
7554+ if ( info . inForLoopInit && info . inForLoopTest ) {
7555+ type = 'Integer' ;
7556+ } else {
7557+ type = 'Number' ;
7558+ }
74937559 }
74947560 const markupType = typeMap [ type ] ;
74957561 if ( ! markupType ) {
@@ -7530,6 +7596,8 @@ class WebGLFunctionNode extends FunctionNode {
75307596 this . astGeneric ( init , declarationResult ) ;
75317597 declarationResult . push ( ')' ) ;
75327598 }
7599+ } else if ( actualType === 'LiteralInteger' && type === 'Integer' ) {
7600+ this . castLiteralToInteger ( init , declarationResult ) ;
75337601 } else {
75347602 this . astGeneric ( init , declarationResult ) ;
75357603 }
@@ -13031,7 +13099,8 @@ class GPU {
1303113099 createKernelMap ( ) {
1303213100 let fn ;
1303313101 let settings ;
13034- if ( typeof arguments [ arguments . length - 2 ] === 'function' ) {
13102+ const argument2Type = typeof arguments [ arguments . length - 2 ] ;
13103+ if ( argument2Type === 'function' || argument2Type === 'string' ) {
1303513104 fn = arguments [ arguments . length - 2 ] ;
1303613105 settings = arguments [ arguments . length - 1 ] ;
1303713106 } else {
@@ -14339,6 +14408,14 @@ const utils = {
1433914408 visualKernelB . canvas ,
1434014409 visualKernelA . canvas ,
1434114410 ] ;
14411+ } ,
14412+
14413+ getMinifySafeName : ( fn ) => {
14414+ const ast = acorn . parse ( fn . toString ( ) ) ;
14415+ if ( ! ast . body || ! ast . body [ 0 ] || ! ast . body [ 0 ] . expression || ! ast . body [ 0 ] . expression . body || ! ast . body [ 0 ] . expression . body . name ) {
14416+ throw new Error ( 'Unrecognized function type. Please use `() => yourFunctionVariableHere`' ) ;
14417+ }
14418+ return ast . body [ 0 ] . expression . body . name ;
1434214419 }
1434314420} ;
1434414421
0 commit comments