From a083fec209d820c4e351a27efbf8f1df942d866b Mon Sep 17 00:00:00 2001 From: RocFang Date: Wed, 18 Nov 2020 08:15:43 +0000 Subject: [PATCH 1/2] fix: workaround for 200 local variables limitation in luajit --- Makefile | 1 + lib/jsonschema.lua | 22 ++++++++++++++++++---- t/200more_variables.lua | 19 +++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 t/200more_variables.lua diff --git a/Makefile b/Makefile index 5a64310..7ebc585 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ test: LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/draft6.lua LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/draft7.lua LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/default.lua + LUA_PATH=$(LUA_PATH) LUA_CPATH=$(LUA_CPATH) resty t/200more_variables.lua ### clean: Clean the test case diff --git a/lib/jsonschema.lua b/lib/jsonschema.lua index 1ab5352..5786b38 100644 --- a/lib/jsonschema.lua +++ b/lib/jsonschema.lua @@ -120,6 +120,19 @@ function codectx_mt:localvar(init, nres) return unpack(names) end +function codectx_mt:localvartab(init, nres) + local names = {} + local nloc = self._nloc + nres = nres or 1 + for i=1, nres do + names[i] = sformat('locals.var_%d_%d', self._idx, nloc+i) + end + + self:stmt(sformat('%s = ', tab_concat(names, ', ')), init or 'nil') + self._nloc = nloc + nres + return unpack(names) + end + function codectx_mt:param(n) self._nparams = mmax(n, self._nparams) return 'p_' .. n @@ -148,7 +161,7 @@ function codectx_mt:validator(path, schema) local root = self._root local var = root._validators[resolved] if not var then - var = root:localvar('nil') + var = root:localvartab('nil') root._validators[resolved] = var root:stmt(sformat('%s = ', var), generate_validator(root:child(ref), resolved)) end @@ -513,9 +526,9 @@ end generate_validator = function(ctx, schema) -- get type informations as they will be necessary anyway - local datatype = ctx:localvar(sformat('%s(%s)', + local datatype = ctx:localvartab(sformat('%s(%s)', ctx:libfunc('type'), ctx:param(1))) - local datakind = ctx:localvar(sformat('%s == "table" and %s(%s)', + local datakind = ctx:localvartab(sformat('%s == "table" and %s(%s)', datatype, ctx:libfunc('lib.tablekind'), ctx:param(1))) if type(schema) == "table" and schema._org_val ~= nil then @@ -661,7 +674,7 @@ generate_validator = function(ctx, schema) local propset, addprop_validator -- all properties defined in the object if schema.additionalProperties ~= nil and schema.additionalProperties ~= true then -- TODO: can be optimized with a static table expression - propset = ctx._root:localvar('{}') + propset = ctx._root:localvartab('{}') if schema.properties then for prop, _ in pairs(schema.properties) do ctx._root:stmt(sformat('%s[%q] = true', propset, prop)) @@ -1122,6 +1135,7 @@ local function generate_main_validator_ctx(schema, options) -- * the custom callbacks (used to customize various aspects of validation -- or for dependency injection) ctx:preface('local uservalues, lib, custom = ...') + ctx:preface('local locals = {}') ctx:stmt('return ', ctx:validator(nil, schema)) return ctx end diff --git a/t/200more_variables.lua b/t/200more_variables.lua new file mode 100644 index 0000000..d625e91 --- /dev/null +++ b/t/200more_variables.lua @@ -0,0 +1,19 @@ +local jsonschema = require 'jsonschema' + +----------------------------------------------------- test case 1 +local rule = { + type = "object", + properties = {} +} + +for i = 1, 256 do + rule.properties["key" .. i] = { + type = "string" + } +end + +local status, err = pcall(jsonschema.generate_validator, rule) +if not status then + ngx.say("fail: check 200 more variables: ", err) +end +ngx.say("passed: check 200 more variables") From 13147c78b3294bd22e9b551202eb5d277bdccd19 Mon Sep 17 00:00:00 2001 From: RocFang Date: Thu, 19 Nov 2020 00:47:05 +0000 Subject: [PATCH 2/2] style: fix some style problems --- lib/jsonschema.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/jsonschema.lua b/lib/jsonschema.lua index 5786b38..239c76e 100644 --- a/lib/jsonschema.lua +++ b/lib/jsonschema.lua @@ -111,8 +111,8 @@ function codectx_mt:localvar(init, nres) local names = {} local nloc = self._nloc nres = nres or 1 - for i=1, nres do - names[i] = sformat('var_%d_%d', self._idx, nloc+i) + for i = 1, nres do + names[i] = sformat('var_%d_%d', self._idx, nloc + i) end self:stmt(sformat('local %s = ', tab_concat(names, ', ')), init or 'nil') @@ -124,14 +124,14 @@ function codectx_mt:localvartab(init, nres) local names = {} local nloc = self._nloc nres = nres or 1 - for i=1, nres do - names[i] = sformat('locals.var_%d_%d', self._idx, nloc+i) + for i = 1, nres do + names[i] = sformat('locals.var_%d_%d', self._idx, nloc + i) end self:stmt(sformat('%s = ', tab_concat(names, ', ')), init or 'nil') self._nloc = nloc + nres return unpack(names) - end +end function codectx_mt:param(n) self._nparams = mmax(n, self._nparams)