diff options
author | Jan Lehnardt <jan@apache.org> | 2022-12-13 14:54:36 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-13 14:54:36 +0100 |
commit | 99a8f666c8b9d1f5a6ebbb09c83e59e1916c0205 (patch) | |
tree | fe4595e6b1bc63bbc9c979013968059d0a7b4bda /share | |
parent | 641586116fc6f78228f203c04e8eca9660e2027f (diff) | |
download | couchdb-99a8f666c8b9d1f5a6ebbb09c83e59e1916c0205.tar.gz |
fix(3517): super-simplistic fix to avoid costly AST transforms when t… (#4292)
* fix(3517): super-simplistic fix to avoid costly AST transforms when they are not needed
Co-authored-by: Ronny Berndt <ronny@apache.org>
Diffstat (limited to 'share')
-rw-r--r-- | share/server/60/rewrite_fun.js | 5 | ||||
-rw-r--r-- | share/server/60/rewrite_fun_ast_bypass.js | 61 |
2 files changed, 63 insertions, 3 deletions
diff --git a/share/server/60/rewrite_fun.js b/share/server/60/rewrite_fun.js index 1b27a9d14..436fd3da1 100644 --- a/share/server/60/rewrite_fun.js +++ b/share/server/60/rewrite_fun.js @@ -28,7 +28,7 @@ function rewriteFunInt(fun) { // If we have a function declaration without an Id, wrap it // in an ExpressionStatement and change it into - // a FuntionExpression + // a FunctionExpression if (decl.type == "FunctionDeclaration" && decl.id == null) { decl.type = "FunctionExpression"; ast.body[idx] = { @@ -41,7 +41,6 @@ function rewriteFunInt(fun) { return escodegen.generate(ast); } - function rewriteFun(funJSON) { const fun = JSON.parse(funJSON); return JSON.stringify(rewriteFunInt(fun)); @@ -53,4 +52,4 @@ function rewriteFuns(funsJSON) { return rewriteFunInt(fun); }); return JSON.stringify(results); -}
\ No newline at end of file +} diff --git a/share/server/60/rewrite_fun_ast_bypass.js b/share/server/60/rewrite_fun_ast_bypass.js new file mode 100644 index 000000000..d2c43caf1 --- /dev/null +++ b/share/server/60/rewrite_fun_ast_bypass.js @@ -0,0 +1,61 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +// +// Based on the normalizeFunction which can be +// found here: +// +// https://github.com/dmunch/couch-chakra/blob/master/js/normalizeFunction.js + +function rewriteFunInt(fun) { + // Skip lengthy AST transforms if the function passed can be + // safely wrapped in parentheses. + if (fun.startsWith('function') && fun.endsWith('}')) { + return '(' + fun + ')' + } + + const ast = esprima.parse(fun); + let idx = ast.body.length - 1; + let decl = {}; + + // Search for the first FunctionDeclaration beginning from the end + do { + decl = ast.body[idx--]; + } while (idx >= 0 && decl.type !== "FunctionDeclaration"); + idx++; + + // If we have a function declaration without an Id, wrap it + // in an ExpressionStatement and change it into + // a FunctionExpression + if (decl.type == "FunctionDeclaration" && decl.id == null) { + decl.type = "FunctionExpression"; + ast.body[idx] = { + type: "ExpressionStatement", + expression: decl + }; + } + + // Generate source from the rewritten AST + return escodegen.generate(ast); +} + +function rewriteFun(funJSON) { + const fun = JSON.parse(funJSON); + return JSON.stringify(rewriteFunInt(fun)); +} + +function rewriteFuns(funsJSON) { + let funs = JSON.parse(funsJSON); + const results = Array.from(funs, (fun) => { + return rewriteFunInt(fun); + }); + return JSON.stringify(results); +} |