Object callChunk(ScriptContext context) throws ScriptException {
		try {
			// Apply context
			Object[] argv;
			if (context != null) {
				// Global bindings
				Bindings bindings;
				bindings = context.getBindings(ScriptContext.GLOBAL_SCOPE);
				if (bindings != null) {
					applyBindings(bindings);
				}

				// Engine bindings
				bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);
				if (bindings != null) {
					if (bindings instanceof LuaBindings
							&& ((LuaBindings) bindings).getScriptEngine() == this) {
						// No need to apply our own live bindings
					} else {
						applyBindings(bindings);
					}
				}

				// Readers and writers
				put(READER, context.getReader());
				put(WRITER, context.getWriter());
				put(ERROR_WRITER, context.getErrorWriter());

				// Arguments
				argv = (Object[]) context.getAttribute(ARGV);
			} else {
				argv = null;
			}

			// Push arguments
			int argCount = argv != null ? argv.length : 0;
			for (int i = 0; i < argCount; i++) {
				luaState.pushJavaObject(argv[i]);
			}

			// Call
			luaState.call(argCount, 1);

			// Return
			try {
				return luaState.toJavaObject(1, Object.class);
			} finally {
				luaState.pop(1);
			}
		} catch (LuaException e) {
			throw getScriptException(e);
		}
	}