diff --git a/teavm-jso-impl/pom.xml b/teavm-jso-impl/pom.xml
index cfc991f5f..641ddd518 100644
--- a/teavm-jso-impl/pom.xml
+++ b/teavm-jso-impl/pom.xml
@@ -38,6 +38,11 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
teavm-jso
${project.version}
+
+ org.mozilla
+ rhino
+ 1.7.7
+
junit
junit
diff --git a/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java b/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java
index 0e496c4e7..4afc70de1 100644
--- a/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java
+++ b/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java
@@ -16,11 +16,22 @@
package org.teavm.jso.plugin;
import java.io.IOException;
+import java.io.StringReader;
import java.util.List;
+import org.mozilla.javascript.CompilerEnvirons;
+import org.mozilla.javascript.IRFactory;
+import org.mozilla.javascript.ast.AstNode;
+import org.mozilla.javascript.ast.AstRoot;
+import org.mozilla.javascript.ast.NodeVisitor;
import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.spi.Generator;
import org.teavm.javascript.spi.GeneratorContext;
-import org.teavm.model.*;
+import org.teavm.model.AnnotationReader;
+import org.teavm.model.AnnotationValue;
+import org.teavm.model.CallLocation;
+import org.teavm.model.ClassReader;
+import org.teavm.model.MethodReader;
+import org.teavm.model.MethodReference;
/**
*
@@ -37,51 +48,24 @@ public class JSBodyGenerator implements Generator {
int bodyParamCount = isStatic ? method.parameterCount() : method.parameterCount() - 1;
- writer.append("if (!").appendMethodBody(methodRef).append(".$native)").ws().append('{').indent().newLine();
- writer.appendMethodBody(methodRef).append(".$native").ws().append('=').ws().append("function(");
- int count = method.parameterCount();
- for (int i = 0; i < count; ++i) {
- if (i > 0) {
- writer.append(',').ws();
- }
- writer.append('_').append(context.getParameterName(i + 1));
+ CompilerEnvirons env = new CompilerEnvirons();
+ env.setRecoverFromErrors(true);
+ IRFactory factory = new IRFactory(env, new TeaVMErrorReporter(context.getDiagnostics(),
+ new CallLocation(methodRef)));
+ String script = annot.getValue("script").getString();
+ AstRoot rootNode;
+ try {
+ rootNode = factory.parse(new StringReader(script), null, 0);
+ } catch (IOException e) {
+ context.getDiagnostics().error(new CallLocation(methodRef), "IO error parsing JSBody script");
+ return;
}
- writer.append(')').ws().append('{').softNewLine().indent();
- writer.append("return (function(");
- for (int i = 0; i < bodyParamCount; ++i) {
- if (i > 0) {
- writer.append(',').ws();
+ rootNode.visit(new NodeVisitor() {
+ @Override
+ public boolean visit(AstNode node) {
+ return false;
}
- String name = paramNames.get(i).getString();
- writer.append(name);
- }
- writer.append(')').ws().append('{').softNewLine().indent();
- writer.append(annot.getValue("script").getString()).softNewLine();
- writer.outdent().append("})");
- if (!isStatic) {
- writer.append(".call");
- }
- writer.append('(');
- for (int i = 0; i < count; ++i) {
- if (i > 0) {
- writer.append(',').ws();
- }
- writer.append('_').append(context.getParameterName(i + 1));
- }
- writer.append(");").softNewLine();
- writer.outdent().append("};").softNewLine();
- writer.appendMethodBody(methodRef).ws().append('=').ws().appendMethodBody(methodRef).append(".$native;")
- .softNewLine();
- writer.outdent().append("}").softNewLine();
-
- writer.append("return ").appendMethodBody(methodRef).append('(');
- for (int i = 0; i < count; ++i) {
- if (i > 0) {
- writer.append(',').ws();
- }
- writer.append(context.getParameterName(i + 1));
- }
- writer.append(");").softNewLine();
+ });
}
}
diff --git a/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/TeaVMErrorReporter.java b/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/TeaVMErrorReporter.java
new file mode 100644
index 000000000..8a95374de
--- /dev/null
+++ b/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/TeaVMErrorReporter.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 Alexey Andreev.
+ *
+ * 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.
+ */
+package org.teavm.jso.plugin;
+
+import org.mozilla.javascript.ErrorReporter;
+import org.mozilla.javascript.EvaluatorException;
+import org.teavm.diagnostics.Diagnostics;
+import org.teavm.model.CallLocation;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public class TeaVMErrorReporter implements ErrorReporter {
+ private Diagnostics diagnostics;
+ private CallLocation location;
+
+ public TeaVMErrorReporter(Diagnostics diagnostics, CallLocation location) {
+ this.diagnostics = diagnostics;
+ this.location = location;
+ }
+
+ @Override
+ public void warning(String message, String sourceName, int line, String lineSource, int lineOffset) {
+ diagnostics.warning(location, "Error in @JSBody script line " + line + ", char " + lineOffset
+ + ": " + message);
+ }
+
+ @Override
+ public void error(String message, String sourceName, int line, String lineSource, int lineOffset) {
+ diagnostics.error(location, "Error in @JSBody script line " + line + ", char " + lineOffset
+ + ": " + message);
+ }
+
+ @Override
+ public EvaluatorException runtimeError(String message, String sourceName, int line, String lineSource,
+ int lineOffset) {
+ return null;
+ }
+}