Skip to content

Commit f48409c

Browse files
fix: Web side tests
Also cleanup moving methods around for reuse and so code can be more concise. Removed some older references, where now we use `this.thread.x` or `this.output.x`. Removed some older methods we no longer use (astFunctionPrototype). Removed some overloaded functions from webgl1 and webgl2 glsl. We no longer need them. Removed some references to `=== null` in favor of truthy. `if (undefined === null)` is true, and can lead to unexpected results, where we really wanted truthy, and is simpler to write.
1 parent 734eddc commit f48409c

File tree

12 files changed

+1192
-1735
lines changed

12 files changed

+1192
-1735
lines changed

bin/gpu-browser-core.js

Lines changed: 443 additions & 589 deletions
Large diffs are not rendered by default.

bin/gpu-browser.js

Lines changed: 442 additions & 588 deletions
Large diffs are not rendered by default.

src/backend/cpu/function-node.js

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,37 +36,6 @@ class CPUFunctionNode extends FunctionNode {
3636
return this._string = this.astGeneric(this.getJsAST(), []).join('').trim();
3737
}
3838

39-
/**
40-
* @desc Parses the abstract syntax tree for to its *named function prototype*
41-
* @param {Object} ast - the AST object to parse
42-
* @param {Array} retArr - return array string
43-
* @returns {Array} the append retArr
44-
*/
45-
astFunctionPrototype(ast, retArr) {
46-
// Setup function return type and name
47-
if (this.isRootKernel || this.isSubKernel) {
48-
return retArr;
49-
}
50-
51-
retArr.push(this.returnType);
52-
retArr.push(' ');
53-
retArr.push(this.name);
54-
retArr.push('(');
55-
56-
// Arguments handling
57-
for (let i = 0; i < this.argumentNames.length; ++i) {
58-
if (i > 0) {
59-
retArr.push(', ');
60-
}
61-
retArr.push('user_');
62-
retArr.push(this.argumentNames[i]);
63-
}
64-
65-
retArr.push(');\n');
66-
67-
return retArr;
68-
}
69-
7039
/**
7140
* @desc Parses the abstract syntax tree for to its *named function*
7241
* @param {Object} ast - the AST object to parse
@@ -217,7 +186,7 @@ class CPUFunctionNode extends FunctionNode {
217186
retArr.push('constants_' + idtNode.name);
218187
} else {
219188
const userArgumentName = this.getUserArgumentName(idtNode.name);
220-
if (userArgumentName !== null) {
189+
if (userArgumentName) {
221190
retArr.push('user_' + userArgumentName);
222191
} else {
223192
retArr.push('user_' + idtNode.name);

src/backend/function-node.js

Lines changed: 224 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ class FunctionNode {
176176
throw 'Missing JS to AST parser';
177177
}
178178

179-
const ast = Object.freeze(inParser.parse('var ' + this.name + ' = ' + this.source + ';', {
179+
const ast = Object.freeze(inParser.parse('const ' + this.name + ' = ' + this.source + ';', {
180180
locations: true
181181
}));
182182
if (ast === null) {
@@ -248,7 +248,7 @@ class FunctionNode {
248248
for (let i = 0; i < calledFunctionArguments.length; i++) {
249249
const calledFunctionArgument = calledFunctionArguments[i];
250250
const argument = calledFunctionArgument[argumentIndex];
251-
if (argument !== null && argument.type !== 'Integer') {
251+
if (argument && argument.type !== 'Integer' && argument.type !== 'LiteralInteger' && argument.type !== 'Number') {
252252
return argument.name;
253253
}
254254
}
@@ -282,6 +282,215 @@ class FunctionNode {
282282
};
283283
}
284284

285+
firstAvailableTypeFromAst(ast) {
286+
switch (ast.type) {
287+
case 'ArrayExpression':
288+
return `Array(${ ast.elements.length })`;
289+
case 'Literal':
290+
if (Number.isInteger(ast.value)) {
291+
return 'LiteralInteger';
292+
} else {
293+
return 'Number';
294+
}
295+
case 'Identifier':
296+
if (this.isAstVariable(ast)) {
297+
if (this.getVariableSignature(ast) === 'value') {
298+
return this.getVariableType(ast.name)
299+
}
300+
}
301+
throw this.astErrorOutput('Unhandled Identifier', ast);
302+
case 'MemberExpression':
303+
if (this.isAstMathFunction(ast)) {
304+
switch (ast.property.name) {
305+
case 'ceil':
306+
return 'Integer';
307+
case 'floor':
308+
return 'Integer';
309+
case 'round':
310+
return 'Integer';
311+
}
312+
return 'Number';
313+
}
314+
if (this.isAstVariable(ast)) {
315+
const variableSignature = this.getVariableSignature(ast);
316+
switch (variableSignature) {
317+
case 'value[]':
318+
return typeLookupMap[this.getVariableType(ast.object.name)];
319+
case 'value[][]':
320+
return typeLookupMap[this.getVariableType(ast.object.object.name)];
321+
case 'value[][][]':
322+
return typeLookupMap[this.getVariableType(ast.object.object.object.name)];
323+
case 'value.value':
324+
if (this.isAstMathVariable(ast)) {
325+
return 'Number';
326+
}
327+
switch (ast.property.name) {
328+
case 'r':
329+
return typeLookupMap[this.getVariableType(ast.object.name)];
330+
case 'g':
331+
return typeLookupMap[this.getVariableType(ast.object.name)];
332+
case 'b':
333+
return typeLookupMap[this.getVariableType(ast.object.name)];
334+
case 'a':
335+
return typeLookupMap[this.getVariableType(ast.object.name)];
336+
default:
337+
throw this.astErrorOutput('Unhandled MemberExpression', ast);
338+
}
339+
case 'this.thread.value':
340+
return 'Integer';
341+
case 'this.output.value':
342+
return 'Integer';
343+
case 'this.constants.value':
344+
return this.getConstantType(ast.property.name);
345+
case 'this.constants.value[]':
346+
return typeLookupMap[this.getConstantType(ast.object.property.name)];
347+
case 'this.constants.value[][]':
348+
return typeLookupMap[this.getConstantType(ast.object.object.property.name)];
349+
case 'this.constants.value[][][]':
350+
return typeLookupMap[this.getConstantType(ast.object.object.object.property.name)];
351+
}
352+
throw this.astErrorOutput('Unhandled MemberExpression', ast);
353+
}
354+
throw this.astErrorOutput('Unhandled MemberExpression', ast);
355+
case 'CallExpression':
356+
if (this.isAstMathFunction(ast)) {
357+
return 'Number';
358+
}
359+
return ast.callee && ast.callee.name && this.lookupReturnType ? this.lookupReturnType(ast.callee.name) : null;
360+
case 'BinaryExpression':
361+
// modulos is Number
362+
if (ast.operator === '%') {
363+
return 'Number';
364+
}
365+
return this.firstAvailableTypeFromAst(ast.left);
366+
case 'UpdateExpression':
367+
return this.firstAvailableTypeFromAst(ast.argument);
368+
case 'UnaryExpression':
369+
return this.firstAvailableTypeFromAst(ast.argument);
370+
default:
371+
throw this.astErrorOutput(`Unhandled Type "${ ast.type }"`, ast);
372+
}
373+
}
374+
375+
isAstMathVariable(ast) {
376+
const mathProperties = [
377+
'E',
378+
'PI',
379+
'SQRT2',
380+
'SQRT1_2',
381+
'LN2',
382+
'LN10',
383+
'LOG2E',
384+
'LOG10E',
385+
];
386+
return ast.type === 'MemberExpression' &&
387+
ast.object && ast.object.type === 'Identifier' &&
388+
ast.object.name === 'Math' &&
389+
ast.property &&
390+
ast.property.type === 'Identifier' &&
391+
mathProperties.indexOf(ast.property.name) > -1;
392+
}
393+
394+
isAstMathFunction(ast) {
395+
const mathFunctions = [
396+
'abs',
397+
'acos',
398+
'asin',
399+
'atan',
400+
'atan2',
401+
'ceil',
402+
'cos',
403+
'exp',
404+
'floor',
405+
'log',
406+
'log2',
407+
'max',
408+
'min',
409+
'pow',
410+
'random',
411+
'round',
412+
'sign',
413+
'sin',
414+
'sqrt',
415+
'tan',
416+
];
417+
return ast.type === 'CallExpression' &&
418+
ast.callee &&
419+
ast.callee.type === 'MemberExpression' &&
420+
ast.callee.object &&
421+
ast.callee.object.type === 'Identifier' &&
422+
ast.callee.object.name === 'Math' &&
423+
ast.callee.property &&
424+
ast.callee.property.type === 'Identifier' &&
425+
mathFunctions.indexOf(ast.callee.property.name) > -1;
426+
}
427+
428+
isAstVariable(ast) {
429+
return ast.type === 'Identifier' || ast.type === 'MemberExpression';
430+
}
431+
432+
getVariableSignature(ast) {
433+
if (!this.isAstVariable(ast)) {
434+
throw new Error(`ast of type "${ ast.type }" is not a variable signature`);
435+
}
436+
if (ast.type === 'Identifier') {
437+
return 'value';
438+
}
439+
const signature = [];
440+
while (true) {
441+
if (!ast) break;
442+
if (ast.computed) {
443+
signature.push('[]');
444+
} else if (ast.type === 'ThisExpression') {
445+
signature.unshift('this');
446+
} else if (ast.property && ast.property.name) {
447+
if (
448+
ast.property.name === 'x' ||
449+
ast.property.name === 'y' ||
450+
ast.property.name === 'z'
451+
) {
452+
signature.unshift('.value');
453+
} else if (
454+
ast.property.name === 'constants' ||
455+
ast.property.name === 'thread' ||
456+
ast.property.name === 'output'
457+
) {
458+
signature.unshift('.' + ast.property.name);
459+
} else {
460+
signature.unshift('.value');
461+
}
462+
} else if (ast.name) {
463+
signature.unshift('value');
464+
} else {
465+
signature.unshift('unknown');
466+
}
467+
ast = ast.object;
468+
}
469+
470+
const signatureString = signature.join('');
471+
const allowedExpressions = [
472+
'value',
473+
'value[]',
474+
'value[][]',
475+
'value[][][]',
476+
'value.value',
477+
'this.thread.value',
478+
'this.output.value',
479+
'this.constants.value',
480+
'this.constants.value[]',
481+
'this.constants.value[][]',
482+
'this.constants.value[][][]',
483+
];
484+
if (allowedExpressions.indexOf(signatureString) > -1) {
485+
return signatureString;
486+
}
487+
return null;
488+
}
489+
490+
build() {
491+
return this.toString().length > 0;
492+
}
493+
285494
/**
286495
* @desc Parses the abstract syntax tree for generically to its respective function
287496
* @param {Object} ast - the AST object to parse
@@ -461,23 +670,21 @@ class FunctionNode {
461670
astArrayExpression(ast, retArr) {
462671
return retArr;
463672
}
464-
465-
/**
466-
* @function
467-
* @name pushParameter
468-
*
469-
* @desc [INTERNAL] pushes a source parameter onto retArr and 'casts' to int if necessary
470-
* i.e. deal with force-int-parameter state
471-
*
472-
* @param {Array} retArr - return array string
473-
* @param {String} name - the parameter name
474-
*
475-
*/
476-
pushParameter(retArr, name) {
477-
retArr.push(`user_${name}`);
478-
}
479673
}
480674

675+
const typeLookupMap = {
676+
'Array': 'Number',
677+
'Array(2)': 'Number',
678+
'Array(3)': 'Number',
679+
'Array(4)': 'Number',
680+
'Array2D': 'Number',
681+
'Array3D': 'Number',
682+
'HTMLImage': 'Array(4)',
683+
'HTMLImageArray': 'Array(4)',
684+
'NumberTexture': 'Number',
685+
'ArrayTexture(4)': 'Array(4)',
686+
};
687+
481688
module.exports = {
482689
FunctionNode
483690
};

src/backend/web-gl/fragment-shader.js

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -125,26 +125,6 @@ float get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, int z, int y
125125
126126
}
127127
128-
float get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, float z, float y, float x) {
129-
return get(tex, texSize, texDim, bitRatio, int(z), int(y), int(x));
130-
}
131-
132-
float get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, int y, int x) {
133-
return get(tex, texSize, texDim, bitRatio, 0, y, x);
134-
}
135-
136-
float get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, float y, float x) {
137-
return get(tex, texSize, texDim, bitRatio, 0, int(y), int(x));
138-
}
139-
140-
float get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, int x) {
141-
return get(tex, texSize, texDim, bitRatio, 0, 0, x);
142-
}
143-
144-
float get(sampler2D tex, ivec2 texSize, ivec3 texDim, int bitRatio, float x) {
145-
return get(tex, texSize, texDim, bitRatio, 0, 0, int(x));
146-
}
147-
148128
vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {
149129
ivec3 xyz = ivec3(x, y, z);
150130
__GET_WRAPAROUND__;
@@ -156,14 +136,6 @@ vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x)
156136
return texture2D(tex, st / vec2(texSize));
157137
}
158138
159-
vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int y, int x) {
160-
return getImage2D(tex, texSize, texDim, 0, y, x);
161-
}
162-
163-
vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int x) {
164-
return getImage2D(tex, texSize, texDim, 0, 0, x);
165-
}
166-
167139
vec4 actualColor;
168140
void color(float r, float g, float b, float a) {
169141
actualColor = vec4(r,g,b,a);

0 commit comments

Comments
 (0)