(node, fn)
| 976 | } |
| 977 | |
| 978 | function setFunctionInstantiated(node, fn) { |
| 979 | // Disconnect the arg avals, so that we can add info to them without side effects |
| 980 | for (var i = 0; i < fn.args.length; ++i) fn.args[i] = new AVal; |
| 981 | fn.self = new AVal; |
| 982 | fn.computeRet = function(self, args) { |
| 983 | // Prevent recursion |
| 984 | return withDisabledComputing(fn, function() { |
| 985 | var oldOrigin = cx.curOrigin; |
| 986 | cx.curOrigin = fn.origin; |
| 987 | var scope = node.scope |
| 988 | var scopeCopy = new Scope(scope.prev, scope.originNode); |
| 989 | for (var v in scope.props) { |
| 990 | var local = scopeCopy.defProp(v, scope.props[v].originNode); |
| 991 | for (var i = 0; i < args.length; ++i) if (fn.argNames[i] == v && i < args.length) |
| 992 | args[i].propagate(local); |
| 993 | } |
| 994 | var argNames = fn.argNames.length != args.length ? fn.argNames.slice(0, args.length) : fn.argNames; |
| 995 | while (argNames.length < args.length) argNames.push("?"); |
| 996 | scopeCopy.fnType = new Fn(fn.name, self, args, argNames, ANull, fn.generator); |
| 997 | scopeCopy.fnType.originNode = fn.originNode; |
| 998 | if (fn.arguments) { |
| 999 | var argset = scopeCopy.fnType.arguments = new AVal; |
| 1000 | scopeCopy.defProp("arguments").addType(new Arr(argset)); |
| 1001 | for (var i = 0; i < args.length; ++i) args[i].propagate(argset); |
| 1002 | } |
| 1003 | node.scope = scopeCopy; |
| 1004 | walk.recursive(node.body, scopeCopy, null, scopeGatherer); |
| 1005 | walk.recursive(node.body, scopeCopy, null, inferWrapper); |
| 1006 | cx.curOrigin = oldOrigin; |
| 1007 | return scopeCopy.fnType.retval; |
| 1008 | }); |
| 1009 | }; |
| 1010 | } |
| 1011 | |
| 1012 | function maybeTagAsGeneric(fn) { |
| 1013 | var target = fn.retval; |
no test coverage detected