Skip to content

Commit ef17f8f

Browse files
fix: #556 followup fix, not all declared types need to be integers
1 parent fbb8538 commit ef17f8f

16 files changed

+369
-145
lines changed

dist/gpu-browser-core.js

Lines changed: 94 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
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+
38363844
class 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

dist/gpu-browser-core.min.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)