summaryrefslogtreecommitdiff
path: root/share
diff options
context:
space:
mode:
authorJan Lehnardt <jan@apache.org>2022-12-13 14:54:36 +0100
committerGitHub <noreply@github.com>2022-12-13 14:54:36 +0100
commit99a8f666c8b9d1f5a6ebbb09c83e59e1916c0205 (patch)
treefe4595e6b1bc63bbc9c979013968059d0a7b4bda /share
parent641586116fc6f78228f203c04e8eca9660e2027f (diff)
downloadcouchdb-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.js5
-rw-r--r--share/server/60/rewrite_fun_ast_bypass.js61
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);
+}