From 81235ac7143164d92d3efeed389f066f202a8b0c Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 2 Mar 2020 11:50:45 +0300 Subject: [PATCH] JS: reduce size of wrapped virtual methods --- .../javascript/rendering/Renderer.java | 22 ++++++++++++---- .../org/teavm/backend/javascript/runtime.js | 25 +++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java b/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java index 2b4a18616..6778c79a7 100644 --- a/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java +++ b/core/src/main/java/org/teavm/backend/javascript/rendering/Renderer.java @@ -251,7 +251,8 @@ public class Renderer implements RenderingManager { String[] names = { "$rt_throw", "$rt_compare", "$rt_nullCheck", "$rt_cls", "$rt_createArray", "$rt_isInstance", "$rt_nativeThread", "$rt_suspending", "$rt_resuming", "$rt_invalidPointer", "$rt_s", "$rt_eraseClinit", "$rt_imul", "$rt_wrapException", "$rt_checkBounds", - "$rt_checkUpperBound", "$rt_checkLowerBound" }; + "$rt_checkUpperBound", "$rt_checkLowerBound", "$rt_wrapFunction0", "$rt_wrapFunction1", + "$rt_wrapFunction2", "$rt_wrapFunction3", "$rt_wrapFunction4" }; boolean first = true; for (String name : names) { if (!first) { @@ -789,9 +790,20 @@ public class Renderer implements RenderingManager { private void emitVirtualDeclaration(MethodReference ref) throws IOException { String methodName = naming.getNameFor(ref.getDescriptor()); writer.append("\"").append(methodName).append("\""); - writer.append(",").ws().append("function("); + writer.append(",").ws(); + emitVirtualFunctionWrapper(ref); + } + + private void emitVirtualFunctionWrapper(MethodReference method) throws IOException { + if (method.parameterCount() <= 4) { + writer.appendFunction("$rt_wrapFunction" + method.parameterCount()); + writer.append("(").appendMethodBody(method).append(")"); + return; + } + + writer.append("function("); List args = new ArrayList<>(); - for (int i = 1; i <= ref.parameterCount(); ++i) { + for (int i = 1; i <= method.parameterCount(); ++i) { args.add(variableNameForInitializer(i)); } for (int i = 0; i < args.size(); ++i) { @@ -801,10 +813,10 @@ public class Renderer implements RenderingManager { writer.append(args.get(i)); } writer.append(")").ws().append("{").ws(); - if (ref.getDescriptor().getResultType() != ValueType.VOID) { + if (method.getDescriptor().getResultType() != ValueType.VOID) { writer.append("return "); } - writer.appendMethodBody(ref).append("("); + writer.appendMethodBody(method).append("("); writer.append("this"); for (String arg : args) { writer.append(",").ws().append(arg); diff --git a/core/src/main/resources/org/teavm/backend/javascript/runtime.js b/core/src/main/resources/org/teavm/backend/javascript/runtime.js index b317fc8f5..08747a60d 100644 --- a/core/src/main/resources/org/teavm/backend/javascript/runtime.js +++ b/core/src/main/resources/org/teavm/backend/javascript/runtime.js @@ -500,6 +500,31 @@ function $rt_metadata(data) { cls.$array = null; } } +function $rt_wrapFunction0(f) { + return function() { + return f(this); + } +} +function $rt_wrapFunction1(f) { + return function(p1) { + return f(this, p1); + } +} +function $rt_wrapFunction2(f) { + return function(p1, p2) { + return f(this, p1, p2); + } +} +function $rt_wrapFunction3(f) { + return function(p1, p2, p3) { + return f(this, p1, p2, p3, p3); + } +} +function $rt_wrapFunction4(f) { + return function(p1, p2, p3, p4) { + return f(this, p1, p2, p3, p4); + } +} function $rt_threadStarter(f) { return function() { var args = Array.prototype.slice.apply(arguments);