Browse Source

Merge pull request #213 from nodemcu/cross

add node.compile() api
zeroday 9 years ago
parent
commit
7e524f7dd4

+ 8 - 0
README.md

@@ -28,6 +28,13 @@ Tencent QQ group: 309957875<br />
 - cross compiler
 
 # Change log
+2015-02-13<br />
+add node.compile() api to compile lua text file into lua bytecode file.<br />
+this will reduce memory usage noticeably when require modules into NodeMCU.<br />
+raise internal LUA_BUFFERSIZE from 1024 to 4096.<br />
+lua require("mod") will load "mod.lc" file first if exist.<br />
+build latest pre_build bin.
+
 2015-02-12<br />
 fix float print.<br />
 update spiffs, add file.rename api to file module.<br />
@@ -297,6 +304,7 @@ cu:send("hello")
 ####Use DS18B20 module extends your esp8266
 ```lua
     -- read temperature with DS18B20
+    node.compile("ds18b20.lua")   --  run this only once to compile and save to "ds18b20.lc"
     t=require("ds18b20")
     t.setup(9)
     addrs=t.addrs()

+ 1 - 1
app/include/user_config.h

@@ -7,7 +7,7 @@
 #define NODE_VERSION_INTERNAL   0U
 
 #define NODE_VERSION	"NodeMCU 0.9.5"
-#define BUILD_DATE	    "build 20150212"
+#define BUILD_DATE	    "build 20150213"
 
 // #define DEVKIT_VERSION_0_9 1 	// define this only if you use NodeMCU devkit v0.9
 

+ 2 - 2
app/lua/luaconf.h

@@ -108,7 +108,7 @@
 #define LUA_CDIR	LUA_ROOT "lib/lua/5.1/"
 
 #ifndef LUA_RPC
-#define LUA_PATH_DEFAULT  "?.lua;?.lc"
+#define LUA_PATH_DEFAULT  "?.lc;?.lua"
 #define LUA_CPATH_DEFAULT ""
 #else // #ifndef LUA_RPC
 #define LUA_PATH_DEFAULT  \
@@ -542,7 +542,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
 /*
 @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
 */
-#define LUAL_BUFFERSIZE		BUFSIZ
+#define LUAL_BUFFERSIZE		(BUFSIZ*4)
 
 /* }================================================================== */
 

+ 79 - 2
app/modules/node.c

@@ -1,8 +1,16 @@
 // Module for interfacing with system
 
-//#include "lua.h"
-#include "lualib.h"
+#include "lua.h"
 #include "lauxlib.h"
+
+#include "ldo.h"
+#include "lfunc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstring.h"
+#include "lundump.h"
+
 #include "platform.h"
 #include "auxmods.h"
 #include "lrotable.h"
@@ -14,6 +22,7 @@
 //#include "spi_flash.h"
 #include "user_interface.h"
 #include "flash_api.h"
+#include "flash_fs.h"
 
 // Lua: restart()
 static int node_restart( lua_State* L )
@@ -311,6 +320,73 @@ static int node_output( lua_State* L )
   return 0; 
 }
 
+static int writer(lua_State* L, const void* p, size_t size, void* u)
+{
+  UNUSED(L);
+  int file_fd = *( (int *)u );
+  if((FS_OPEN_OK - 1)==file_fd)
+    return 1;
+  NODE_DBG("get fd:%d,size:%d\n",file_fd,size);
+  
+  if(size!=0 && (size!=fs_write(file_fd, (const char *)p, size)) )
+    return 1;
+  NODE_DBG("write fd:%d,size:%d\n",file_fd,size);
+  return 0;
+}
+
+#define toproto(L,i) (clvalue(L->top+(i))->l.p)
+// Lua: compile(filename) -- compile lua file into lua bytecode, and save to .lc
+static int node_compile( lua_State* L )
+{
+  Proto* f;
+  int file_fd = FS_OPEN_OK - 1;
+  size_t len;
+  const char *fname = luaL_checklstring( L, 1, &len );
+  if( len > FS_NAME_MAX_LENGTH )
+    return luaL_error(L, "filename too long");
+
+  char output[FS_NAME_MAX_LENGTH];
+  c_strcpy(output, fname);
+  // check here that filename end with ".lua".
+  if(len<4 || (c_strcmp( output+len-4,".lua")!=0) )
+    return luaL_error(L, "not a .lua file");
+
+  output[c_strlen(output)-2] = 'c';
+  output[c_strlen(output)-1] = '\0';
+  NODE_DBG(output);
+  NODE_DBG("\n");
+  if (luaL_loadfsfile(L,fname)!=0){
+    return luaL_error(L, lua_tostring(L,-1));
+  }
+
+  f = toproto(L,-1);
+
+  int stripping = 1;      /* strip debug information? */
+
+  file_fd = fs_open(output, fs_mode2flag("w+"));
+  if(file_fd < FS_OPEN_OK)
+  {
+    return luaL_error(L, "cannot open/write to file");
+  }
+
+  lua_lock(L);
+  int result=luaU_dump(L,f,writer,&file_fd,stripping);
+  lua_unlock(L);
+
+  fs_flush(file_fd);
+  fs_close(file_fd);
+  file_fd = FS_OPEN_OK - 1;
+
+  if (result==LUA_ERR_CC_INTOVERFLOW){
+    return luaL_error(L, "value too big or small for target integer type");
+  }
+  if (result==LUA_ERR_CC_NOTINTEGER){
+    return luaL_error(L, "target lua_Number is integral but fractional value found");
+  }
+
+  return 0;
+}
+
 // Module function map
 #define MIN_OPT_LEVEL 2
 #include "lrodefs.h"
@@ -330,6 +406,7 @@ const LUA_REG_TYPE node_map[] =
   { LSTRKEY( "input" ), LFUNCVAL( node_input ) },
   { LSTRKEY( "output" ), LFUNCVAL( node_output ) },
   { LSTRKEY( "readvdd33" ), LFUNCVAL( node_readvdd33) },
+  { LSTRKEY( "compile" ), LFUNCVAL( node_compile) },
 // Combined to dsleep(us, option)  
 // { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) },
 #if LUA_OPTIMIZE_MEMORY > 0

+ 8 - 0
examples/fragment.lua

@@ -339,3 +339,11 @@ uart.on("data",4, function(data)
 	end
 end, 0)
 
+file.open("hello.lua","w+")
+file.writeline([[print("hello nodemcu")]])
+file.writeline([[print(node.heap())]])
+file.close()
+
+node.compile("hello.lua")
+dofile("hello.lua")
+dofile("hello.lc")

BIN
pre_build/0.9.5/nodemcu_20150212.bin


BIN
pre_build/latest/nodemcu_latest.bin