Function builder tracer

This commit is contained in:
Eugene Cheah 2016-02-15 04:54:54 +08:00
parent dfaeacac2d
commit 29404d49d7
5 changed files with 151 additions and 7 deletions

View File

@ -8,6 +8,81 @@
/// Properties:
/// nodeMap - {Object} Object map, where nodeMap[function] = functionNode;
///
function functionBuilder() {
this.nodeMap = {};
}
var functionBuilder = (function() {
///
/// Function: functionBuilder
///
/// [Constructor] Blank constructor, which initializes the properties
///
function functionBuilder() {
this.nodeMap = {};
}
///
/// Function: addFunction
///
/// Creates the functionNode, and add it to the nodeMap
///
/// Parameters:
/// 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 addFunction( functionName, jsFunction, paramTypeArray, returnType ) {
this.addFunctionNode( new functionNode( functionName, jsFunction, paramTypeArray, returnType ) );
}
functionBuilder.prototype.addFunction = addFunction;
///
/// Function: addFunctionNode
///
/// Add the funciton node directly
///
/// Parameters:
/// inNode - {functionNode} functionNode to add
///
function addFunctionNode( inNode ) {
this.nodeMap[ inNode.functionName ] = inNode;
}
functionBuilder.prototype.addFunctionNode = addFunctionNode;
///
/// Function: traceFunctionCalls
///
/// Trace all the depending functions being called, from a single function
///
/// This allow for "uneeded" functions to be automatically optimized out.
///
/// Parameters:
/// functionName - {String} Function name to trace from, default to "kernel"
/// retList - {[String,...]} Returning list of function names that is traced. Including itself.
///
/// Returns:
/// {[String,...]} Returning list of function names that is traced. Including itself.
function traceFunctionCalls( functionName, retList ) {
functionName = functionName || "kernel";
retList = retList || [];
var fNode = this.nodeMap[functionName];
if( fNode ) {
// Check if function already exists
if( retList.indexOf(functionName) >= 0 ) {
// Does nothing if already traced
} else {
retList.push(functionName);
fNode.getWebglFunctionString(); //ensure JS trace is done
for(var i=0; i<fNode.calledFunctions.length; ++i) {
this.traceFunctionCalls( fNode.calledFunctions[i], retList );
}
}
}
return retList;
}
functionBuilder.prototype.traceFunctionCalls = traceFunctionCalls;
return functionBuilder;
})();

View File

@ -6,6 +6,7 @@
/// This handles all the raw state, converted state, etc. Of a single function.
///
/// Properties:
/// functionName - {String} Name of the function
/// jsFunction - {JS Function} The JS Function the node represents
/// jsFunctionString - {String} jsFunction.toString()
/// paramNames - {[String,...]} Parameter names of the function
@ -30,10 +31,10 @@ var functionNode = (function() {
/// [Constructor] Builds the function with the given JS function, and argument type array.
///
/// Parameters:
/// functionName - {String} -Function name to assume, if its null, it attempts to extract from the function
/// 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 not given
/// returnType - {String} The return type, assumes "float" if not given
/// 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 ) {

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GPU.JS : FunctionBuilder unit testing</title>
<link rel="stylesheet" href="../../lib/qunit-1.20.0.css">
<!-- gpu.js scripts -->
<script src="../../../src/parser.js"></script>
<script src="../../../src/backend/functionNode_webgl.js"></script>
<script src="../../../src/backend/functionNode.js"></script>
<script src="../../../src/backend/functionBuilder.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="../../lib/qunit-1.20.0.js"></script>
<script src="../../src/internal/functionBuilder_test.js"></script>
</body>
</html>

View File

@ -0,0 +1,32 @@
///
/// Test the various basic functionality of functionBuilder
///
/// Test the function tracing of 3 layers
QUnit.test( "traceFunctionCalls: 3 layer test", function( assert ) {
assert.notEqual( functionBuilder, null, "script include check" );
function layerOne() {
return 42;
}
function layerTwo() {
return layerOne() * 2;
}
function layerThree() {
return layerTwo() * 2;
}
// Create a function hello node
var builder = new functionBuilder();
assert.notEqual( builder, null, "class creation check" );
builder.addFunction(null, layerOne);
builder.addFunction(null, layerTwo);
builder.addFunction(null, layerThree);
assert.deepEqual( builder.traceFunctionCalls("layerOne"), ["layerOne"] );
assert.deepEqual( builder.traceFunctionCalls("layerTwo"), ["layerTwo","layerOne"] );
assert.deepEqual( builder.traceFunctionCalls("layerThree"), ["layerThree","layerTwo","layerOne"] );
});

View File

@ -1,4 +1,3 @@
/// @file functionNode_test.js
///
/// Test the various basic functionality of functionNode
///
@ -49,6 +48,8 @@ QUnit.test( "hello_inner: call a funciton inside a function", function( assert )
"float hello_inner() { return inner(); }",
"webgl function conversion check"
);
assert.deepEqual( node.calledFunctions, ["inner"] );
});
/// Test creation of function, that calls another function, with ARGS
@ -69,6 +70,8 @@ QUnit.test( "Math.round implementation: A function with arguments", function( as
"float round(float a) { return floor(a+0.5); }",
"webgl function conversion check"
);
assert.deepEqual( node.calledFunctions, ["floor"] );
});
/// Test creation of function, that calls another function, with ARGS
@ -90,3 +93,16 @@ QUnit.test( "Two arguments test", function( assert ) {
"webgl function conversion check"
);
});
/// Test the creation of a hello_world function
QUnit.test( "Automatic naming support", function( assert ) {
assert.notEqual( functionNode, null, "script include check" );
function hello_world() {
return 42;
}
// Create a function hello node
var node = new functionNode(null, hello_world);
assert.notEqual( node, null, "class creation check" );
assert.equal( node.functionName, "hello_world" );
});