title: Unprotected error in call to Lua API (attempt to call a null value)
body: <p>I am currently developing an application for my ESP32 for which I need to use the Lua-C-API.
  My goal would be to call a Lua function named "add" from C and flash the program on the ESP32. </p>
  
  <p>So, in the Lua code ("add.lua") I define function "add":</p>
  
  <pre><code>    -- add two numbers
      function add ( x, y )
      return x + y
      end    
  </code></pre>
  
  <p>My C code for calling the interface is the following:</p>
  
  <pre><code>/* Function luaadd */
  int luaadd (lua_State* L, int x, int y ) {
  
      int sum;
  
      /* the function name */
      lua_getglobal(L, "add");
  
      /* the first argument */
      lua_pushnumber(L, x);
  
      /* the second argument */
      lua_pushnumber(L, y);
  
      /* call the function with 2 arguments, return 1 result */
      lua_call(L, 2, 1);
  
      /* get the result */
      sum = (int)lua_tointeger(L, -1);
      lua_pop(L, 1);
      return sum;
      }
  
      /* Main function */
      void app_main()
      {
         initialize_nvs();
         #if CONFIG_STORE_HISTORY
             initialize_filesystem();
         #endif
         initialize_console();
  
         /* initialize Lua */
         lua_State* L = luaL_newstate();
         luaL_openlibs(L);
         openlibs(L);
         luaopen_base(L);            /* opens the basic library */
         luaopen_table(L);            /* opens the table library */
         luaopen_io(L);               /* opens the I/O library */
         luaopen_string(L);           /* opens the string lib. */
         luaopen_math(L);             /* opens the math lib. */
  
         /* load Lua file */
         if (luaL_loadfile(L, "add.lua")){
             printf("Error loading file: %s", lua_tostring(L, -1));
         }
  
         /* call the add function */
         int sum;
         sum = luaadd(L, 10, 15 );
  
         /* print the result */
         printf( "The sum is %d\n", sum );
  
         /* cleanup Lua */
         lua_close(L);
  
         /* print 'Finished' to console */
         printf("Finished");
     }
  </code></pre>
  
  <p>And this is the entire C file:</p>
  
  <pre><code>    #include &lt;modules.h&gt;
      #include &lt;stdio.h&gt;
      #include &lt;stdlib.h&gt;
      #include &lt;stdarg.h&gt;
      #include &lt;string.h&gt;
      #include "esp_system.h"
      #include "esp_log.h"
      #include "esp_console.h"
      #include "esp_vfs_dev.h"
      #include "driver/uart.h"
      #include "linenoise/linenoise.h"
      #include "argtable3/argtable3.h"
      #include "esp_vfs_fat.h"
      #include "nvs.h"
      #include "nvs_flash.h"
      #include "lua.h"
      #include "lauxlib.h"
      #include "lualib.h"
      #include "sb.h"
      #include &lt;unistd.h&gt;
      #include &lt;errno.h&gt;
      #include &lt;unistd.h&gt;
  
      static const char* TAG = "Console";
  
      /* Console command history can be stored to and loaded from a file.
       * The easiest way to do this is to use FATFS filesystem on top of
       * wear_levelling library.
       */
      #if CONFIG_STORE_HISTORY
  
      #define MOUNT_PATH "/data"
      #define HISTORY_PATH MOUNT_PATH "/history.txt"
  
      static void initialize_filesystem()
      {
          static wl_handle_t wl_handle;
          const esp_vfs_fat_mount_config_t mount_config = {
                  .max_files = 4,
                  .format_if_mount_failed = true
          };
          esp_err_t err = esp_vfs_fat_spiflash_mount(MOUNT_PATH,         "storage", &amp;mount_config, &amp;wl_handle);
          if (err != ESP_OK) {
              ESP_LOGE(TAG, "Failed to mount FATFS (0x%x)", err);
              return;
          }
      }
      #endif // CONFIG_STORE_HISTORY
  
      static void initialize_nvs()
      {
          esp_err_t err = nvs_flash_init();
          if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
              ESP_ERROR_CHECK( nvs_flash_erase() );
              err = nvs_flash_init();
          }
          ESP_ERROR_CHECK(err);
      }
  
      static void initialize_console()
      {
          /* Disable buffering on stdin and stdout */
          setvbuf(stdin, NULL, _IONBF, 0);
          setvbuf(stdout, NULL, _IONBF, 0);
  
          /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
          esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
          /* Move the caret to the beginning of the next line on '\n' */
          esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
  
          /* Install UART driver for interrupt-driven reads and writes */
          ESP_ERROR_CHECK( uart_driver_install(CONFIG_CONSOLE_UART_NUM,
          256, 0, 0, NULL, 0) );
  
          /* Tell VFS to use UART driver */
          esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM);
  
          /* Initialize the console */
          esp_console_config_t console_config = {
                  .max_cmdline_args = 8,
                  .max_cmdline_length = 256,
                  #if CONFIG_LOG_COLORS
                      .hint_color = atoi(LOG_COLOR_CYAN)
                  #endif
                  };
          ESP_ERROR_CHECK( esp_console_init(&amp;console_config) );
  
          /* Configure linenoise line completion library */
          /* Enable multiline editing. If not set, long commands will scroll within
           * single line.
           */
          linenoiseSetMultiLine(1);
  
          /* Tell linenoise where to get command completions and hints */
          linenoiseSetCompletionCallback(&amp;esp_console_get_completion);
          linenoiseSetHintsCallback((linenoiseHintsCallback*)  &amp;esp_console_get_hint);
  
          /* Set command history size */
          linenoiseHistorySetMaxLen(100);
  
          #if CONFIG_STORE_HISTORY
              /* Load command history from filesystem */
              linenoiseHistoryLoad(HISTORY_PATH);
          #endif
      }
  
      int luaadd (lua_State* L, int x, int y )
      {
          int sum;
  
          /* the function name */
          lua_getglobal(L, "add");
  
          /* the first argument */
          lua_pushnumber(L, x);
  
          /* the second argument */
          lua_pushnumber(L, y);
  
          /* call the function with 2 arguments, return 1 result */
          lua_call(L, 2, 1);
  
          /* get the result */
          sum = (int)lua_tointeger(L, -1);
          lua_pop(L, 1);
  
          return sum;
      }
  
      void app_main()
      {
         initialize_nvs();
         #if CONFIG_STORE_HISTORY
             initialize_filesystem();
         #endif
         initialize_console();
  
         /* initialize Lua */
         lua_State* L = luaL_newstate();
         luaL_openlibs(L);
         openlibs(L);
         luaopen_base(L);            /* opens the basic library */
         luaopen_table(L);            /* opens the table library */
         luaopen_io(L);               /* opens the I/O library */
         luaopen_string(L);           /* opens the string lib. */
         luaopen_math(L);             /* opens the math lib. */
  
         /* load Lua file */
         if (luaL_loadfile(L, "add.lua")){
             printf("Error loading file: %s", lua_tostring(L, -1));
         }
  
         /* call the add function */
         int sum;
         sum = luaadd(L, 10, 15 );
  
         /* print the result */
         printf( "The sum is %d\n", sum );
  
         /* cleanup Lua */
         lua_close(L);
  
         /* print 'Finished' to console */
         printf("Finished");
     }
  </code></pre>
  
  <p>When I now flash this onto my ESP32 I get the following message: </p>
  
  <blockquote>
    <p>Error loading file: cannot open add.lua: No such file or
    directoryPANIC: unprotected error in call to Lua API (attempt to call
    a nil value) abort() was called at PC 0x4016b808 on core 0</p>
  </blockquote>
  
  <p>Do you know how to solve the problem? My "add.lua" file is in the same directory as the C file.</p>