Added file 'testes/heavy.lua'

This file is not part of the regular tests. It tests error conditions
that demand too much memory or too much time to create:

* string with too many characters
* control structure with body too large
* chunk with too many lines
* identifier with too many characters
* chunks with too many instructions
* function with too many constants
* too many strings internalized
* table with too many entries

In machines with limited memory (less than 150 GB), many tests run up
to a "not enough memory" error. We need some memory (~256 GB) to
run all tests up to their intrinsic limits.
diff --git a/testes/heavy.lua b/testes/heavy.lua
new file mode 100644
index 0000000..4731c74
--- /dev/null
+++ b/testes/heavy.lua
@@ -0,0 +1,173 @@
+-- $Id: heavy.lua,v 1.7 2017/12/29 15:42:15 roberto Exp $
+-- See Copyright Notice in file all.lua
+
+local function teststring ()
+  print("creating a string too long")
+  do
+    local a = "x"
+    local st, msg = pcall(function ()
+      while true do
+        a = a .. a.. a.. a.. a.. a.. a.. a.. a.. a
+         .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
+         .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
+         .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
+         .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
+         .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
+         .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
+         .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
+         .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
+         .. a .. a.. a.. a.. a.. a.. a.. a.. a.. a
+         print(string.format("string with %d bytes", #a))
+      end
+    end)
+    assert(not st and
+      (string.find(msg, "string length overflow") or
+       string.find(msg, "not enough memory")))
+    print("string length overflow with " .. #a * 100)
+  end
+  print('+')
+end
+
+local function loadrep (x, what)
+  local p = 1<<20
+  local s = string.rep(x, p)
+  local count = 0
+  local function f()
+    count = count + p
+    if count % (0x80*p) == 0 then
+      io.stderr:write("(", count // 2^20, " M)")
+    end
+    return s
+  end
+  local st, msg = load(f, "=big")
+  print("\nmemory: ", collectgarbage'count' * 1024)
+  msg = string.match(msg, "^[^\n]+")    -- get only first line
+  print(string.format("total: 0x%x %s ('%s')", count, what, msg))
+  return st, msg
+end
+
+
+function controlstruct ()
+  print("control structure too long")
+  local lim = ((1 << 24) - 2) // 3
+  local s = string.rep("a = a + 1\n", lim)
+  s = "while true do " .. s .. "end"
+  assert(load(s))
+  print("ok with " .. lim .. " lines")
+  lim = lim + 3
+  s = string.rep("a = a + 1\n", lim)
+  s = "while true do " .. s .. "end"
+  local st, msg = load(s)
+  assert(not st and string.find(msg, "too long"))
+  print(msg)
+end
+
+
+function manylines ()
+  print("loading chunk with too many lines")
+  local st, msg = loadrep("\n", "lines")
+  assert(not st and string.find(msg, "too many lines"))
+  print('+')
+end
+
+
+function hugeid ()
+  print("loading chunk with huge identifier")
+  local st, msg = loadrep("a", "chars")
+  assert(not st and 
+    (string.find(msg, "lexical element too long") or
+     string.find(msg, "not enough memory")))
+  print('+')
+end
+
+function toomanyinst ()
+  print("loading chunk with too many instructions")
+  local st, msg = loadrep("a = 10; ", "instructions")
+  print('+')
+end
+
+
+local function loadrepfunc (prefix, f)
+  local count = -1
+  local function aux ()
+    count = count + 1
+    if count == 0 then
+      return prefix
+    else
+      if count % (0x100000) == 0 then
+        io.stderr:write("(", count // 2^20, " M)")
+      end
+      return f(count)
+    end
+  end
+  local st, msg = load(aux, "k")
+  print("\nmemory: ", collectgarbage'count' * 1024)
+  msg = string.match(msg, "^[^\n]+")    -- get only first line
+  print("expected error: ", msg)
+end
+
+
+function toomanyconst ()
+  print("loading function with too many constants")
+  loadrepfunc("function foo () return {0,",
+      function (n)
+        -- convert 'n' to a string in the format [["...",]],
+        -- where '...' is a kind of number in base 128
+        -- (in a range that does not include either the double quote
+        -- and the escape.)
+        return string.char(34,
+          ((n // 128^0) & 127) + 128,
+          ((n // 128^1) & 127) + 128,
+          ((n // 128^2) & 127) + 128,
+          ((n // 128^3) & 127) + 128,
+          ((n // 128^4) & 127) + 128,
+          34, 44)
+      end)
+end
+
+
+function toomanystr ()
+  local a = {}
+  local st, msg = pcall(function ()
+    for i = 1, math.huge do
+      if i % (0x100000) == 0 then
+        io.stderr:write("(", i // 2^20, " M)")
+      end
+      a[i] = string.pack("I", i)
+     end
+  end)
+  local size = #a
+  a = collectgarbage'count'
+  print("\nmemory:", a * 1024)
+  print("expected error:", msg)
+  print("size:", size)
+end
+
+
+function toomanyidx ()
+  local a = {}
+  local st, msg = pcall(function ()
+    for i = 1, math.huge do
+      if i % (0x100000) == 0 then
+        io.stderr:write("(", i // 2^20, " M)")
+      end
+      a[i] = i
+     end
+  end)
+  print("\nmemory: ", collectgarbage'count' * 1024)
+  print("expected error: ", msg)
+  print("size:", #a)
+end
+  
+
+
+-- teststring()
+-- controlstruct()
+-- manylines()
+-- hugeid()
+-- toomanyinst()
+-- toomanyconst()
+-- toomanystr()
+toomanyidx()
+
+print "OK"