Skip to content

Commit 201542d

Browse files
authored
bugfix: workaround for 200 local variables limitation in luajit (#41)
* fix: workaround for 200 local variables limitation in luajit * style: fix some style problems fix #40
1 parent d9b742f commit 201542d

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ test:
3131
LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/draft6.lua
3232
LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/draft7.lua
3333
LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/default.lua
34+
LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/200more_variables.lua
3435

3536

3637
### clean: Clean the test case

lib/jsonschema.lua

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,28 @@ function codectx_mt:localvar(init, nres)
111111
local names = {}
112112
local nloc = self._nloc
113113
nres = nres or 1
114-
for i=1, nres do
115-
names[i] = sformat('var_%d_%d', self._idx, nloc+i)
114+
for i = 1, nres do
115+
names[i] = sformat('var_%d_%d', self._idx, nloc + i)
116116
end
117117

118118
self:stmt(sformat('local %s = ', tab_concat(names, ', ')), init or 'nil')
119119
self._nloc = nloc + nres
120120
return unpack(names)
121121
end
122122

123+
function codectx_mt:localvartab(init, nres)
124+
local names = {}
125+
local nloc = self._nloc
126+
nres = nres or 1
127+
for i = 1, nres do
128+
names[i] = sformat('locals.var_%d_%d', self._idx, nloc + i)
129+
end
130+
131+
self:stmt(sformat('%s = ', tab_concat(names, ', ')), init or 'nil')
132+
self._nloc = nloc + nres
133+
return unpack(names)
134+
end
135+
123136
function codectx_mt:param(n)
124137
self._nparams = mmax(n, self._nparams)
125138
return 'p_' .. n
@@ -148,7 +161,7 @@ function codectx_mt:validator(path, schema)
148161
local root = self._root
149162
local var = root._validators[resolved]
150163
if not var then
151-
var = root:localvar('nil')
164+
var = root:localvartab('nil')
152165
root._validators[resolved] = var
153166
root:stmt(sformat('%s = ', var), generate_validator(root:child(ref), resolved))
154167
end
@@ -513,9 +526,9 @@ end
513526

514527
generate_validator = function(ctx, schema)
515528
-- get type informations as they will be necessary anyway
516-
local datatype = ctx:localvar(sformat('%s(%s)',
529+
local datatype = ctx:localvartab(sformat('%s(%s)',
517530
ctx:libfunc('type'), ctx:param(1)))
518-
local datakind = ctx:localvar(sformat('%s == "table" and %s(%s)',
531+
local datakind = ctx:localvartab(sformat('%s == "table" and %s(%s)',
519532
datatype, ctx:libfunc('lib.tablekind'), ctx:param(1)))
520533

521534
if type(schema) == "table" and schema._org_val ~= nil then
@@ -661,7 +674,7 @@ generate_validator = function(ctx, schema)
661674
local propset, addprop_validator -- all properties defined in the object
662675
if schema.additionalProperties ~= nil and schema.additionalProperties ~= true then
663676
-- TODO: can be optimized with a static table expression
664-
propset = ctx._root:localvar('{}')
677+
propset = ctx._root:localvartab('{}')
665678
if schema.properties then
666679
for prop, _ in pairs(schema.properties) do
667680
ctx._root:stmt(sformat('%s[%q] = true', propset, prop))
@@ -1122,6 +1135,7 @@ local function generate_main_validator_ctx(schema, options)
11221135
-- * the custom callbacks (used to customize various aspects of validation
11231136
-- or for dependency injection)
11241137
ctx:preface('local uservalues, lib, custom = ...')
1138+
ctx:preface('local locals = {}')
11251139
ctx:stmt('return ', ctx:validator(nil, schema))
11261140
return ctx
11271141
end

t/200more_variables.lua

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
local jsonschema = require 'jsonschema'
2+
3+
----------------------------------------------------- test case 1
4+
local rule = {
5+
type = "object",
6+
properties = {}
7+
}
8+
9+
for i = 1, 256 do
10+
rule.properties["key" .. i] = {
11+
type = "string"
12+
}
13+
end
14+
15+
local status, err = pcall(jsonschema.generate_validator, rule)
16+
if not status then
17+
ngx.say("fail: check 200 more variables: ", err)
18+
end
19+
ngx.say("passed: check 200 more variables")

0 commit comments

Comments
 (0)