 				var propertyHost:Object;
 				var propertyName:String;
 				
-				if (bindThis === null)
-					builtInSymbolTable['this'] = this;
+				// initialize top-level function and push it onto the stack
+				call = recursiveCalls[recursion] as CompiledFunctionCall;
+				allSymbolTables = recursiveCallSymbolTables[recursion] as Array;
+				
+				// if recursion has not been this deep before, initialize a copy of the top-level function call structures
+				if (!call)
+				{
+					call = compiledObject as CompiledFunctionCall;
+					if (recursion)
+						call = call.clone();
+					allSymbolTables = [];
+					
+					recursiveCalls[recursion] = call;
+					recursiveCallSymbolTables[recursion] = allSymbolTables;
+					
+					// set up Array of symbol tables in the correct scope order: built-in, local, params, this, global
+					allSymbolTables[BUILT_IN_SYMBOL_TABLE_INDEX] = {};
+					allSymbolTables[LOCAL_SYMBOL_TABLE_INDEX] = null; // placeholder
+					
+					// add custom symbol table(s)
+					if (symbolTable is Array)
+					{
+						for each (var _symbolTable:Object in symbolTable)
+							allSymbolTables.push(_symbolTable);
+					}
+					else
+					{
+						allSymbolTables.push(symbolTable);
+					}
+					
+					allSymbolTables[THIS_SYMBOL_TABLE_INDEX] = null; // placeholder
+					
+					// add libraries in reverse order so the last one will be checked first
+					i = libraries.length;
+					while (i--)
+						allSymbolTables.push(libraries[i]);
+					// check globals last
+					allSymbolTables.push(globals);
+				}
+				recursion++;
+
+				// initialize built-in symbol table
+				builtInSymbolTable = allSymbolTables[BUILT_IN_SYMBOL_TABLE_INDEX];
+				builtInSymbolTable['eval'] = EVAL;
+				builtInSymbolTable['this'] = bindThis !== null ? bindThis : this;
 				builtInSymbolTable['arguments'] = arguments;
 				
+				// initialize local symbol table
 				allSymbolTables[LOCAL_SYMBOL_TABLE_INDEX] = localSymbolTable;
 				if (useThisScope)
 					allSymbolTables[THIS_SYMBOL_TABLE_INDEX] = builtInSymbolTable['this'];

							throw e;
						
						if (errorHandler(e))
							result = undefined; // ignore and continue
						else
							return undefined; // halt
					}

			// Each recursive call must use a clone of the CompiledFunctionCall,
			// so we keep track of recursion depth and re-use copies of the CompiledFunctionCall.
			var recursion:int = 0;
			var recursiveCalls:Array = [];
			var recursiveCallSymbolTables:Array = [];
			
			// this function avoids unnecessary function call overhead by keeping its own call stack rather than using recursion.
			var wrapperFunction:Function = function():*
			{
				const stack:Array = []; // used as a queue of function calls
				const localSymbolTable:Object = {}; // new local symbol table for each invocation
				var call:CompiledFunctionCall;
				var allSymbolTables:Array;
				var builtInSymbolTable:Object;
				var subCall:CompiledFunctionCall;
				var compiledParams:Array;
				var method:Object;
