mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-08 07:54:11 -08:00
Add support of JSBody
This commit is contained in:
parent
f138c837cf
commit
b731687c3e
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.dom.browser;
|
package org.teavm.dom.browser;
|
||||||
|
|
||||||
import org.teavm.dom.ajax.XMLHttpRequest;
|
import org.teavm.dom.ajax.XMLHttpRequest;
|
||||||
|
import org.teavm.dom.events.EventTarget;
|
||||||
import org.teavm.dom.html.HTMLDocument;
|
import org.teavm.dom.html.HTMLDocument;
|
||||||
import org.teavm.dom.json.JSON;
|
import org.teavm.dom.json.JSON;
|
||||||
import org.teavm.dom.typedarrays.*;
|
import org.teavm.dom.typedarrays.*;
|
||||||
|
@ -28,7 +29,7 @@ import org.teavm.jso.JSProperty;
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public interface Window extends JSGlobal {
|
public interface Window extends JSGlobal, EventTarget {
|
||||||
@JSProperty
|
@JSProperty
|
||||||
HTMLDocument getDocument();
|
HTMLDocument getDocument();
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,10 @@ package org.teavm.jso;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import org.teavm.dependency.PluggableDependency;
|
import org.teavm.dependency.PluggableDependency;
|
||||||
import org.teavm.javascript.ni.InjectedBy;
|
import org.teavm.javascript.ni.InjectedBy;
|
||||||
|
import org.teavm.jso.plugin.JSNativeGenerator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* <p>Container of static methods to manipulate over {@link JSObject}s.</p>
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
|
@ -56,6 +58,10 @@ public final class JS {
|
||||||
@InjectedBy(JSNativeGenerator.class)
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
public static native JSObject getTypeName(JSObject obj);
|
public static native JSObject getTypeName(JSObject obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets global JavaScript object, that is similar to the <code>window</code> object in the browser.
|
||||||
|
* @return global object.
|
||||||
|
*/
|
||||||
@InjectedBy(JSNativeGenerator.class)
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
public static native JSObject getGlobal();
|
public static native JSObject getGlobal();
|
||||||
|
|
||||||
|
|
44
teavm-jso/src/main/java/org/teavm/jso/JSBody.java
Normal file
44
teavm-jso/src/main/java/org/teavm/jso/JSBody.java
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Indicates that method is to have native JavaScript implementation.
|
||||||
|
* Method only can take and return primitive values and {@link JSObject}s.
|
||||||
|
* JSBody script can't call Java methods, but you can pass callbacks wrapped into {@link JSFunctor}.
|
||||||
|
* Note that unless method is static, it must belong to class that implements {@link JSObject}.
|
||||||
|
* If applied to non-native method, original Java body will be overwritten by JavaScript.</p>
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface JSBody {
|
||||||
|
/**
|
||||||
|
* <p>How method parameters are named inside JavaScript implementation.</p>
|
||||||
|
*/
|
||||||
|
String[] params();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>JavaScript implementation.</p>
|
||||||
|
*/
|
||||||
|
String script();
|
||||||
|
}
|
|
@ -37,17 +37,15 @@ public interface JSFunction extends JSObject {
|
||||||
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c,
|
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c,
|
||||||
JSObject d);
|
JSObject d);
|
||||||
|
|
||||||
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c,
|
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e);
|
||||||
JSObject d, JSObject e);
|
|
||||||
|
|
||||||
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c,
|
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f);
|
||||||
JSObject d, JSObject e, JSObject f);
|
|
||||||
|
|
||||||
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c,
|
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f,
|
||||||
JSObject d, JSObject e, JSObject f, JSObject g);
|
JSObject g);
|
||||||
|
|
||||||
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c,
|
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f,
|
||||||
JSObject d, JSObject e, JSObject f, JSObject g, JSObject h);
|
JSObject g, JSObject h);
|
||||||
|
|
||||||
JSObject apply(JSObject thisArg, JSObject[] arguments);
|
JSObject apply(JSObject thisArg, JSObject[] arguments);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* 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 java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import org.teavm.codegen.SourceWriter;
|
||||||
|
import org.teavm.javascript.ni.Generator;
|
||||||
|
import org.teavm.javascript.ni.GeneratorContext;
|
||||||
|
import org.teavm.model.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public class JSBodyGenerator implements Generator {
|
||||||
|
@Override
|
||||||
|
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
|
||||||
|
ClassReader cls = context.getClassSource().get(methodRef.getClassName());
|
||||||
|
MethodReader method = cls.getMethod(methodRef.getDescriptor());
|
||||||
|
AnnotationReader annot = method.getAnnotations().get(JSBodyImpl.class.getName());
|
||||||
|
boolean isStatic = annot.getValue("isStatic").getBoolean();
|
||||||
|
List<AnnotationValue> paramNames = annot.getValue("params").getList();
|
||||||
|
|
||||||
|
int bodyParamCount = method.parameterCount();
|
||||||
|
int offset = isStatic ? 1 : 0;
|
||||||
|
|
||||||
|
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() + (isStatic ? 0 : 1);
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
if (i > 0) {
|
||||||
|
writer.append(',').ws();
|
||||||
|
}
|
||||||
|
writer.append('_').append(context.getParameterName(i + offset));
|
||||||
|
}
|
||||||
|
writer.append(')').ws().append('{').softNewLine().indent();
|
||||||
|
|
||||||
|
writer.append("return (function(");
|
||||||
|
for (int i = 0; i < bodyParamCount; ++i) {
|
||||||
|
if (i > 0) {
|
||||||
|
writer.append(',').ws();
|
||||||
|
}
|
||||||
|
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 + offset));
|
||||||
|
}
|
||||||
|
writer.append(");").softNewLine();
|
||||||
|
writer.outdent().append("};").softNewLine();
|
||||||
|
writer.appendMethodBody(methodRef).ws().append('=').ws().appendMethodBody(methodRef).append(".$native;")
|
||||||
|
.softNewLine();
|
||||||
|
writer.outdent().append("}").softNewLine();
|
||||||
|
|
||||||
|
writer.appendMethodBody(methodRef).append('(');
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
if (i > 0) {
|
||||||
|
writer.append(',').ws();
|
||||||
|
}
|
||||||
|
writer.append(context.getParameterName(i + offset));
|
||||||
|
}
|
||||||
|
writer.append(");").softNewLine();
|
||||||
|
}
|
||||||
|
}
|
35
teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyImpl.java
Normal file
35
teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyImpl.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* 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 java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@interface JSBodyImpl {
|
||||||
|
String[] params();
|
||||||
|
|
||||||
|
String script();
|
||||||
|
|
||||||
|
boolean isStatic();
|
||||||
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.jso;
|
package org.teavm.jso.plugin;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.teavm.codegen.SourceWriter;
|
import org.teavm.codegen.SourceWriter;
|
||||||
|
@ -23,6 +23,7 @@ import org.teavm.javascript.ast.Expr;
|
||||||
import org.teavm.javascript.ast.InvocationExpr;
|
import org.teavm.javascript.ast.InvocationExpr;
|
||||||
import org.teavm.javascript.ni.Injector;
|
import org.teavm.javascript.ni.Injector;
|
||||||
import org.teavm.javascript.ni.InjectorContext;
|
import org.teavm.javascript.ni.InjectorContext;
|
||||||
|
import org.teavm.jso.JS;
|
||||||
import org.teavm.model.CallLocation;
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.MethodReader;
|
import org.teavm.model.MethodReader;
|
|
@ -16,31 +16,28 @@
|
||||||
package org.teavm.jso.plugin;
|
package org.teavm.jso.plugin;
|
||||||
|
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
|
import org.teavm.jso.JSBody;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
class JSObjectClassTransformer implements ClassHolderTransformer {
|
public class JSObjectClassTransformer implements ClassHolderTransformer {
|
||||||
private ThreadLocal<JavascriptNativeProcessor> processor = new ThreadLocal<>();
|
private JavascriptNativeProcessor processor;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transformClass(ClassHolder cls, ClassReaderSource innerSource, Diagnostics diagnostics) {
|
public void transformClass(ClassHolder cls, ClassReaderSource innerSource, Diagnostics diagnostics) {
|
||||||
JavascriptNativeProcessor processor = getProcessor(innerSource);
|
processor = new JavascriptNativeProcessor(innerSource);
|
||||||
processor.setDiagnostics(diagnostics);
|
processor.setDiagnostics(diagnostics);
|
||||||
processor.processClass(cls);
|
processor.processClass(cls);
|
||||||
for (MethodHolder method : cls.getMethods()) {
|
for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) {
|
||||||
if (method.getProgram() != null) {
|
if (method.getAnnotations().get(JSBody.class.getName()) != null) {
|
||||||
|
processor.processJSBody(cls, method);
|
||||||
|
} else if (method.getProgram() != null &&
|
||||||
|
method.getAnnotations().get(JSBodyImpl.class.getName()) == null) {
|
||||||
processor.processProgram(method);
|
processor.processProgram(method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private JavascriptNativeProcessor getProcessor(ClassReaderSource innerSource) {
|
|
||||||
if (processor.get() == null) {
|
|
||||||
processor.set(new JavascriptNativeProcessor(innerSource));
|
|
||||||
}
|
|
||||||
return processor.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.jso.plugin;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
|
import org.teavm.javascript.ni.GeneratedBy;
|
||||||
import org.teavm.javascript.ni.PreserveOriginalName;
|
import org.teavm.javascript.ni.PreserveOriginalName;
|
||||||
import org.teavm.jso.*;
|
import org.teavm.jso.*;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
|
@ -32,6 +33,7 @@ class JavascriptNativeProcessor {
|
||||||
private List<Instruction> replacement = new ArrayList<>();
|
private List<Instruction> replacement = new ArrayList<>();
|
||||||
private NativeJavascriptClassRepository nativeRepos;
|
private NativeJavascriptClassRepository nativeRepos;
|
||||||
private Diagnostics diagnostics;
|
private Diagnostics diagnostics;
|
||||||
|
private int methodIndexGenerator;
|
||||||
|
|
||||||
public JavascriptNativeProcessor(ClassReaderSource classSource) {
|
public JavascriptNativeProcessor(ClassReaderSource classSource) {
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
|
@ -209,6 +211,101 @@ class JavascriptNativeProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void processJSBody(ClassHolder cls, MethodHolder methodToProcess) {
|
||||||
|
CallLocation location = new CallLocation(methodToProcess.getReference());
|
||||||
|
boolean isStatic = methodToProcess.hasModifier(ElementModifier.STATIC);
|
||||||
|
|
||||||
|
// validate parameter names
|
||||||
|
AnnotationHolder bodyAnnot = methodToProcess.getAnnotations().get(JSBody.class.getName());
|
||||||
|
int jsParamCount = bodyAnnot.getValue("params").getList().size();
|
||||||
|
if (methodToProcess.parameterCount() != jsParamCount) {
|
||||||
|
diagnostics.error(location, "JSBody method {{m0}} declares " + methodToProcess.parameterCount() +
|
||||||
|
" parameters, but annotation specifies " + jsParamCount, methodToProcess);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove annotation and make non-native
|
||||||
|
methodToProcess.getAnnotations().remove(JSBody.class.getName());
|
||||||
|
methodToProcess.getModifiers().remove(ElementModifier.NATIVE);
|
||||||
|
|
||||||
|
// generate parameter types for original method and validate
|
||||||
|
int paramCount = methodToProcess.parameterCount();
|
||||||
|
if (!isStatic) {
|
||||||
|
++paramCount;
|
||||||
|
}
|
||||||
|
ValueType[] paramTypes = new ValueType[paramCount];
|
||||||
|
int offset = 0;
|
||||||
|
if (!isStatic) {
|
||||||
|
ValueType paramType = ValueType.object(cls.getName());
|
||||||
|
paramTypes[offset++] = paramType;
|
||||||
|
if (!isSupportedType(paramType)) {
|
||||||
|
diagnostics.error(location, "Non-static JSBody method {{m0}} is owned by non-JS class {{c1}}",
|
||||||
|
methodToProcess.getReference(), cls.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (methodToProcess.getResultType() != ValueType.VOID && !isSupportedType(methodToProcess.getResultType())) {
|
||||||
|
diagnostics.error(location, "JSBody method {{m0}} returns unsupported type {{t1}}",
|
||||||
|
methodToProcess.getReference(), methodToProcess.getResultType());
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate parameter types for proxy method
|
||||||
|
for (int i = 0; i < methodToProcess.parameterCount(); ++i) {
|
||||||
|
paramTypes[offset++] = methodToProcess.parameterType(i);
|
||||||
|
}
|
||||||
|
ValueType[] proxyParamTypes = new ValueType[paramCount + 1];
|
||||||
|
for (int i = 0; i < paramCount; ++i) {
|
||||||
|
proxyParamTypes[i] = ValueType.parse(JSObject.class);
|
||||||
|
}
|
||||||
|
proxyParamTypes[paramCount] = methodToProcess.getResultType() == ValueType.VOID ? ValueType.VOID :
|
||||||
|
ValueType.parse(JSObject.class);
|
||||||
|
|
||||||
|
// create proxy method
|
||||||
|
MethodHolder proxyMethod = new MethodHolder("$js_body$_" + methodIndexGenerator++, proxyParamTypes);
|
||||||
|
proxyMethod.getModifiers().add(ElementModifier.NATIVE);
|
||||||
|
proxyMethod.getModifiers().add(ElementModifier.STATIC);
|
||||||
|
AnnotationHolder genBodyAnnot = new AnnotationHolder(JSBodyImpl.class.getName());
|
||||||
|
genBodyAnnot.getValues().put("script", bodyAnnot.getValue("script"));
|
||||||
|
genBodyAnnot.getValues().put("params", bodyAnnot.getValue("params"));
|
||||||
|
genBodyAnnot.getValues().put("isStatic", new AnnotationValue(isStatic));
|
||||||
|
AnnotationHolder generatorAnnot = new AnnotationHolder(GeneratedBy.class.getName());
|
||||||
|
generatorAnnot.getValues().put("value", new AnnotationValue(ValueType.parse(JSBodyGenerator.class)));
|
||||||
|
proxyMethod.getAnnotations().add(genBodyAnnot);
|
||||||
|
proxyMethod.getAnnotations().add(generatorAnnot);
|
||||||
|
cls.addMethod(proxyMethod);
|
||||||
|
|
||||||
|
// create program that invokes proxy method
|
||||||
|
program = new Program();
|
||||||
|
BasicBlock block = program.createBasicBlock();
|
||||||
|
List<Variable> params = new ArrayList<>();
|
||||||
|
for (int i = 0; i < paramCount; ++i) {
|
||||||
|
params.add(program.createVariable());
|
||||||
|
}
|
||||||
|
methodToProcess.setProgram(program);
|
||||||
|
|
||||||
|
// Generate invoke instruction
|
||||||
|
replacement.clear();
|
||||||
|
InvokeInstruction invoke = new InvokeInstruction();
|
||||||
|
invoke.setType(InvocationType.SPECIAL);
|
||||||
|
invoke.setMethod(proxyMethod.getReference());
|
||||||
|
for (int i = 0; i < paramCount; ++i) {
|
||||||
|
Variable var = program.createVariable();
|
||||||
|
invoke.getArguments().add(wrapArgument(location, var, paramTypes[i]));
|
||||||
|
}
|
||||||
|
block.getInstructions().addAll(replacement);
|
||||||
|
block.getInstructions().add(invoke);
|
||||||
|
|
||||||
|
// Generate return
|
||||||
|
ExitInstruction exit = new ExitInstruction();
|
||||||
|
if (methodToProcess.getResultType() != ValueType.VOID) {
|
||||||
|
replacement.clear();
|
||||||
|
Variable result = program.createVariable();
|
||||||
|
invoke.setReceiver(result);
|
||||||
|
exit.setValueToReturn(unwrap(location, result, methodToProcess.getResultType()));
|
||||||
|
block.getInstructions().addAll(replacement);
|
||||||
|
}
|
||||||
|
block.getInstructions().add(exit);
|
||||||
|
}
|
||||||
|
|
||||||
private void addPropertyGet(String propertyName, Variable instance, Variable receiver,
|
private void addPropertyGet(String propertyName, Variable instance, Variable receiver,
|
||||||
InstructionLocation location) {
|
InstructionLocation location) {
|
||||||
Variable nameVar = addStringWrap(addString(propertyName, location), location);
|
Variable nameVar = addStringWrap(addString(propertyName, location), location);
|
||||||
|
@ -373,8 +470,7 @@ class JavascriptNativeProcessor {
|
||||||
}
|
}
|
||||||
Variable result = program.createVariable();
|
Variable result = program.createVariable();
|
||||||
InvokeInstruction insn = new InvokeInstruction();
|
InvokeInstruction insn = new InvokeInstruction();
|
||||||
insn.setMethod(new MethodReference(JS.class.getName(), "wrap", type,
|
insn.setMethod(new MethodReference(JS.class.getName(), "wrap", type, ValueType.parse(JSObject.class)));
|
||||||
ValueType.object(JSObject.class.getName())));
|
|
||||||
insn.getArguments().add(var);
|
insn.getArguments().add(var);
|
||||||
insn.setReceiver(result);
|
insn.setReceiver(result);
|
||||||
insn.setType(InvocationType.SPECIAL);
|
insn.setType(InvocationType.SPECIAL);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user