mirror of
https://github.com/gpujs/gpu.js.git
synced 2026-01-25 16:08:02 +00:00
Automatic inner functions
This commit is contained in:
parent
0f4de2c3e0
commit
c2cbe2a1c4
@ -15,8 +15,9 @@ var functionBuilder = (function() {
|
||||
///
|
||||
/// [Constructor] Blank constructor, which initializes the properties
|
||||
///
|
||||
function functionBuilder() {
|
||||
function functionBuilder(gpu) {
|
||||
this.nodeMap = {};
|
||||
this.gpu = gpu;
|
||||
}
|
||||
|
||||
///
|
||||
@ -24,14 +25,15 @@ var functionBuilder = (function() {
|
||||
///
|
||||
/// Creates the functionNode, and add it to the nodeMap
|
||||
///
|
||||
/// Parameters:
|
||||
/// Parameters:
|
||||
/// gpu - {GPU} The GPU instance
|
||||
/// functionName - {String} Function name to assume, if its null, it attempts to extract from the function
|
||||
/// jsFunction - {JS Function} JS Function to do conversion
|
||||
/// jsFunction - {JS Function} JS Function to do conversion
|
||||
/// paramTypeArray - {[String,...]} Parameter type array, assumes all parameters are "float" if null
|
||||
/// returnType - {String} The return type, assumes "float" if null
|
||||
///
|
||||
function addFunction( functionName, jsFunction, paramTypeArray, returnType ) {
|
||||
this.addFunctionNode( new functionNode( functionName, jsFunction, paramTypeArray, returnType ) );
|
||||
this.addFunctionNode( new functionNode( this.gpu, functionName, jsFunction, paramTypeArray, returnType ) );
|
||||
}
|
||||
functionBuilder.prototype.addFunction = addFunction;
|
||||
|
||||
@ -40,7 +42,7 @@ var functionBuilder = (function() {
|
||||
///
|
||||
/// Add the funciton node directly
|
||||
///
|
||||
/// Parameters:
|
||||
/// Parameters:
|
||||
/// inNode - {functionNode} functionNode to add
|
||||
///
|
||||
function addFunctionNode( inNode ) {
|
||||
@ -56,7 +58,7 @@ var functionBuilder = (function() {
|
||||
/// This allow for "uneeded" functions to be automatically optimized out.
|
||||
/// Note that the 0-index, is the starting function trace.
|
||||
///
|
||||
/// Parameters:
|
||||
/// Parameters:
|
||||
/// functionName - {String} Function name to trace from, default to "kernel"
|
||||
/// retList - {[String,...]} Returning list of function names that is traced. Including itself.
|
||||
///
|
||||
@ -88,7 +90,7 @@ var functionBuilder = (function() {
|
||||
///
|
||||
/// Function: webglString_fromFunctionNames
|
||||
///
|
||||
/// Parameters:
|
||||
/// Parameters:
|
||||
/// functionList - {[String,...]} List of function to build the webgl string.
|
||||
///
|
||||
/// Returns:
|
||||
@ -109,7 +111,7 @@ var functionBuilder = (function() {
|
||||
///
|
||||
/// Function: webglString
|
||||
///
|
||||
/// Parameters:
|
||||
/// Parameters:
|
||||
/// functionName - {String} Function name to trace from. If null, it returns the WHOLE builder stack
|
||||
///
|
||||
/// Returns:
|
||||
@ -118,7 +120,7 @@ var functionBuilder = (function() {
|
||||
function webglString(functionName) {
|
||||
if(functionName) {
|
||||
return this.webglString_fromFunctionNames( this.traceFunctionCalls(functionName, []).reverse() );
|
||||
}
|
||||
}
|
||||
return this.webglString_fromFunctionNames(Object.keys(this.nodeMap));
|
||||
}
|
||||
functionBuilder.prototype.webglString = webglString;
|
||||
|
||||
@ -31,12 +31,15 @@ var functionNode = (function() {
|
||||
/// [Constructor] Builds the function with the given JS function, and argument type array.
|
||||
///
|
||||
/// Parameters:
|
||||
/// gpu - {GPU} The GPU instance
|
||||
/// functionName - {String} Function name to assume, if its null, it attempts to extract from the function
|
||||
/// jsFunction - {JS Function} JS Function to do conversion
|
||||
/// paramTypeArray - {[String,...]} Parameter type array, assumes all parameters are "float" if null
|
||||
/// returnType - {String} The return type, assumes "float" if null
|
||||
///
|
||||
function functionNode( functionName, jsFunction, paramTypeArray, returnType ) {
|
||||
function functionNode( gpu, functionName, jsFunction, paramTypeArray, returnType ) {
|
||||
|
||||
this.gpu = gpu;
|
||||
|
||||
//
|
||||
// Internal vars setup
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
// Closure capture for the ast function, prevent collision with existing AST functions
|
||||
var functionNode_webgl = (function() {
|
||||
|
||||
var gpu, jsFunctionString;
|
||||
|
||||
///
|
||||
/// Function: functionNode_webgl
|
||||
///
|
||||
@ -13,6 +15,8 @@ var functionNode_webgl = (function() {
|
||||
/// the converted webGL function string
|
||||
///
|
||||
function functionNode_webgl( inNode ) {
|
||||
gpu = inNode.gpu;
|
||||
jsFunctionString = inNode.jsFunctionString;
|
||||
inNode.webglFunctionString_array = ast_generic( inNode.getJS_AST(), [], inNode );
|
||||
inNode.webglFunctionString = inNode.webglFunctionString_array.join("").trim();
|
||||
return inNode.webglFunctionString;
|
||||
@ -49,6 +53,8 @@ var functionNode_webgl = (function() {
|
||||
}
|
||||
|
||||
switch(ast.type) {
|
||||
case "FunctionDeclaration":
|
||||
return ast_FunctionDeclaration(ast, retArr, funcParam);
|
||||
case "FunctionExpression":
|
||||
return ast_FunctionExpression(ast, retArr, funcParam);
|
||||
case "ReturnStatement":
|
||||
@ -99,6 +105,38 @@ var functionNode_webgl = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Prases the abstract syntax tree, to its named function declartion
|
||||
///
|
||||
/// @param ast the AST object to parse
|
||||
/// @param retArr return array string
|
||||
/// @param funcParam FunctionNode, that tracks compilation state
|
||||
///
|
||||
/// @returns the appened retArr
|
||||
function ast_FunctionDeclaration(ast, retArr, funcParam) {
|
||||
// TODO: make this less hacky?
|
||||
var lines = jsFunctionString.split(/\r?\n/);
|
||||
|
||||
var start = ast.loc.start;
|
||||
var end = ast.loc.end;
|
||||
|
||||
var funcArr = [];
|
||||
|
||||
funcArr.push(lines[start.line-1].slice(start.column));
|
||||
for (var i=start.line; i<end.line-1; i++) {
|
||||
funcArr.push(lines[i]);
|
||||
}
|
||||
funcArr.push(lines[end.line-1].slice(0,end.column));
|
||||
|
||||
var funcStr = funcArr.join('\n');
|
||||
|
||||
// TODO: fix this evil!
|
||||
eval('var funcObj = ' + funcStr);
|
||||
|
||||
gpu.addFunction(funcObj);
|
||||
|
||||
return retArr;
|
||||
}
|
||||
|
||||
/// Prases the abstract syntax tree, to its named function
|
||||
///
|
||||
/// @param ast the AST object to parse
|
||||
@ -126,6 +164,7 @@ var functionNode_webgl = (function() {
|
||||
|
||||
retArr.push( funcParam.paramType[i] );
|
||||
retArr.push(" ");
|
||||
retArr.push("user_");
|
||||
retArr.push( funcParam.paramNames[i] );
|
||||
}
|
||||
|
||||
@ -251,10 +290,8 @@ var functionNode_webgl = (function() {
|
||||
retArr.push('uOutputDim.y');
|
||||
} else if (idtNode.name == "gpu_dimensionsZ") {
|
||||
retArr.push('uOutputDim.z');
|
||||
} else if(funcParam.isRootKernel) {
|
||||
retArr.push("user_"+idtNode.name);
|
||||
} else {
|
||||
retArr.push(idtNode.name);
|
||||
retArr.push("user_"+idtNode.name);
|
||||
}
|
||||
|
||||
return retArr;
|
||||
|
||||
@ -150,7 +150,7 @@
|
||||
var builder = this.functionBuilder;
|
||||
var endianness = this.endianness;
|
||||
|
||||
var kernelNode = new functionNode("kernel", kernel);
|
||||
var kernelNode = new functionNode(gpu, "kernel", kernel);
|
||||
kernelNode.paramNames = [];
|
||||
kernelNode.paramType = [];
|
||||
kernelNode.isRootKernel = true;
|
||||
|
||||
@ -43,7 +43,7 @@ var GPU = (function() {
|
||||
this.programCache = {};
|
||||
this.endianness = endianness();
|
||||
|
||||
this.functionBuilder = new functionBuilder();
|
||||
this.functionBuilder = new functionBuilder(this);
|
||||
this.functionBuilder.polyfillStandardFunctions();
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ QUnit.test( "hello_world: just return magic 42", function( assert ) {
|
||||
|
||||
// Create a function hello node
|
||||
var node = new functionNode(
|
||||
null,
|
||||
"hello_world",
|
||||
function() {
|
||||
return 42;
|
||||
@ -17,7 +18,7 @@ QUnit.test( "hello_world: just return magic 42", function( assert ) {
|
||||
assert.notEqual( node, null, "class creation check" );
|
||||
assert.notEqual( node.getJS_AST(), null, "AST fetch check" );
|
||||
|
||||
assert.equal(
|
||||
assert.equal(
|
||||
node.getWebglFunctionString().replace(/\s+/g,' '),
|
||||
"float hello_world() { return 42.0; }",
|
||||
"webgl function conversion check"
|
||||
@ -34,6 +35,7 @@ QUnit.test( "hello_inner: call a funciton inside a function", function( assert )
|
||||
|
||||
// Create a function hello node
|
||||
var node = new functionNode(
|
||||
null,
|
||||
"hello_inner",
|
||||
function() {
|
||||
return inner();
|
||||
@ -43,7 +45,7 @@ QUnit.test( "hello_inner: call a funciton inside a function", function( assert )
|
||||
assert.notEqual( node, null, "class creation check" );
|
||||
assert.notEqual( node.getJS_AST(), null, "AST fetch check" );
|
||||
|
||||
assert.equal(
|
||||
assert.equal(
|
||||
node.getWebglFunctionString().replace(/\s+/g,' '),
|
||||
"float hello_inner() { return inner(); }",
|
||||
"webgl function conversion check"
|
||||
@ -56,6 +58,7 @@ QUnit.test( "hello_inner: call a funciton inside a function", function( assert )
|
||||
QUnit.test( "Math.round implementation: A function with arguments", function( assert ) {
|
||||
// Math.round node
|
||||
var node = new functionNode(
|
||||
null,
|
||||
"round",
|
||||
function(a) {
|
||||
return Math.floor( a + 0.5 );
|
||||
@ -65,7 +68,7 @@ QUnit.test( "Math.round implementation: A function with arguments", function( as
|
||||
assert.notEqual( node, null, "class creation check" );
|
||||
assert.notEqual( node.getJS_AST(), null, "AST fetch check" );
|
||||
|
||||
assert.equal(
|
||||
assert.equal(
|
||||
node.getWebglFunctionString().replace(/\s+/g,' '),
|
||||
"float round(float a) { return floor(a+0.5); }",
|
||||
"webgl function conversion check"
|
||||
@ -78,6 +81,7 @@ QUnit.test( "Math.round implementation: A function with arguments", function( as
|
||||
QUnit.test( "Two arguments test", function( assert ) {
|
||||
|
||||
var node = new functionNode(
|
||||
null,
|
||||
"add_together",
|
||||
function(a,b) {
|
||||
return a+b;
|
||||
@ -87,7 +91,7 @@ QUnit.test( "Two arguments test", function( assert ) {
|
||||
assert.notEqual( node, null, "class creation check" );
|
||||
assert.notEqual( node.getJS_AST(), null, "AST fetch check" );
|
||||
|
||||
assert.equal(
|
||||
assert.equal(
|
||||
node.getWebglFunctionString().replace(/\s+/g,' '),
|
||||
"float add_together(float a, float b) { return a+b; }",
|
||||
"webgl function conversion check"
|
||||
@ -102,7 +106,7 @@ QUnit.test( "Automatic naming support", function( assert ) {
|
||||
return 42;
|
||||
}
|
||||
// Create a function hello node
|
||||
var node = new functionNode(null, hello_world);
|
||||
var node = new functionNode(null, null, hello_world);
|
||||
assert.notEqual( node, null, "class creation check" );
|
||||
assert.equal( node.functionName, "hello_world" );
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user