mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
JS: add null check in strict mode
This commit is contained in:
parent
bffb50f0cd
commit
6f50eefaf9
|
@ -55,10 +55,10 @@ public class ClassGenerator implements Generator, Injector, DependencyPlugin {
|
|||
public void generate(InjectorContext context, MethodReference methodRef) throws IOException {
|
||||
switch (methodRef.getName()) {
|
||||
case "newEmptyInstance":
|
||||
context.getWriter().append("new ");
|
||||
context.getWriter().append("new (");
|
||||
context.writeExpr(context.getArgument(0), Precedence.MEMBER_ACCESS);
|
||||
context.getWriter().append('.').appendField(platformClassField);
|
||||
context.getWriter().append("()");
|
||||
context.getWriter().append(")");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,10 +109,11 @@ import org.teavm.model.lowlevel.Characteristics;
|
|||
import org.teavm.model.lowlevel.ClassInitializerEliminator;
|
||||
import org.teavm.model.lowlevel.ClassInitializerTransformer;
|
||||
import org.teavm.model.lowlevel.ExportDependencyListener;
|
||||
import org.teavm.model.lowlevel.NullCheckInsertion;
|
||||
import org.teavm.model.lowlevel.LowLevelNullCheckFilter;
|
||||
import org.teavm.model.lowlevel.NullCheckTransformation;
|
||||
import org.teavm.model.lowlevel.ShadowStackTransformer;
|
||||
import org.teavm.model.transformation.ClassPatch;
|
||||
import org.teavm.model.transformation.NullCheckInsertion;
|
||||
import org.teavm.model.util.AsyncMethodFinder;
|
||||
import org.teavm.runtime.Allocator;
|
||||
import org.teavm.runtime.CallSite;
|
||||
|
@ -220,7 +221,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
|
|||
classInitializerEliminator = new ClassInitializerEliminator(controller.getUnprocessedClassSource());
|
||||
classInitializerTransformer = new ClassInitializerTransformer();
|
||||
shadowStackTransformer = new ShadowStackTransformer(characteristics, !longjmpUsed);
|
||||
nullCheckInsertion = new NullCheckInsertion(characteristics);
|
||||
nullCheckInsertion = new NullCheckInsertion(new LowLevelNullCheckFilter(characteristics));
|
||||
nullCheckTransformation = new NullCheckTransformation();
|
||||
|
||||
controller.addVirtualMethods(VIRTUAL_METHODS::contains);
|
||||
|
|
|
@ -95,7 +95,9 @@ import org.teavm.model.instructions.InvocationType;
|
|||
import org.teavm.model.instructions.InvokeInstruction;
|
||||
import org.teavm.model.instructions.RaiseInstruction;
|
||||
import org.teavm.model.instructions.StringConstantInstruction;
|
||||
import org.teavm.model.lowlevel.BoundCheckInsertion;
|
||||
import org.teavm.model.transformation.BoundCheckInsertion;
|
||||
import org.teavm.model.transformation.NullCheckFilter;
|
||||
import org.teavm.model.transformation.NullCheckInsertion;
|
||||
import org.teavm.model.util.AsyncMethodFinder;
|
||||
import org.teavm.model.util.ProgramUtils;
|
||||
import org.teavm.vm.BuildTarget;
|
||||
|
@ -128,6 +130,8 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
|||
private int topLevelNameLimit = 10000;
|
||||
private AstDependencyExtractor dependencyExtractor = new AstDependencyExtractor();
|
||||
private boolean strict;
|
||||
private BoundCheckInsertion boundCheckInsertion = new BoundCheckInsertion();
|
||||
private NullCheckInsertion nullCheckInsertion = new NullCheckInsertion(NullCheckFilter.EMPTY);
|
||||
|
||||
@Override
|
||||
public List<ClassHolderTransformer> getTransformers() {
|
||||
|
@ -339,7 +343,8 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
|||
@Override
|
||||
public void beforeOptimizations(Program program, MethodReader method) {
|
||||
if (strict) {
|
||||
new BoundCheckInsertion().transformProgram(program, method.getReference());
|
||||
boundCheckInsertion.transformProgram(program, method.getReference());
|
||||
nullCheckInsertion.transformProgram(program, method.getReference());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ public enum Precedence {
|
|||
ADDITION,
|
||||
MULTIPLICATION,
|
||||
UNARY,
|
||||
NEW,
|
||||
FUNCTION_CALL,
|
||||
MEMBER_ACCESS,
|
||||
GROUPING;
|
||||
|
|
|
@ -1113,6 +1113,11 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
|
|||
if (injector != null) {
|
||||
injector.generate(new InjectorContextImpl(expr.getArguments()), expr.getMethod());
|
||||
} else {
|
||||
Precedence outerPrecedence = precedence;
|
||||
if (outerPrecedence.ordinal() > Precedence.FUNCTION_CALL.ordinal()) {
|
||||
writer.append('(');
|
||||
}
|
||||
|
||||
if (expr.getType() == InvocationType.DYNAMIC) {
|
||||
precedence = Precedence.MEMBER_ACCESS;
|
||||
expr.getArguments().get(0).acceptVisitor(this);
|
||||
|
@ -1184,6 +1189,10 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
|
|||
if (shouldEraseCallSite) {
|
||||
lastCallSite = null;
|
||||
}
|
||||
|
||||
if (outerPrecedence.ordinal() > Precedence.FUNCTION_CALL.ordinal()) {
|
||||
writer.append(')');
|
||||
}
|
||||
}
|
||||
if (expr.getLocation() != null) {
|
||||
popLocation();
|
||||
|
@ -1224,14 +1233,14 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
|
|||
}
|
||||
|
||||
Precedence outerPrecedence = precedence;
|
||||
if (outerPrecedence.ordinal() > Precedence.FUNCTION_CALL.ordinal()) {
|
||||
if (outerPrecedence.ordinal() > Precedence.NEW.ordinal()) {
|
||||
writer.append('(');
|
||||
}
|
||||
|
||||
precedence = Precedence.FUNCTION_CALL;
|
||||
precedence = Precedence.NEW;
|
||||
|
||||
writer.append("new ").appendClass(expr.getConstructedClass());
|
||||
if (outerPrecedence.ordinal() > Precedence.FUNCTION_CALL.ordinal()) {
|
||||
if (outerPrecedence.ordinal() > Precedence.NEW.ordinal()) {
|
||||
writer.append(')');
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2019 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.model.lowlevel;
|
||||
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.transformation.NullCheckFilter;
|
||||
|
||||
public class LowLevelNullCheckFilter implements NullCheckFilter {
|
||||
private Characteristics characteristics;
|
||||
|
||||
public LowLevelNullCheckFilter(Characteristics characteristics) {
|
||||
this.characteristics = characteristics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(FieldReference field) {
|
||||
return !characteristics.isStructure(field.getClassName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(MethodReference method) {
|
||||
return characteristics.isManaged(method.getClassName()) && characteristics.isManaged(method);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2019 konsoletyper.
|
||||
* Copyright 2019 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.model.lowlevel;
|
||||
package org.teavm.model.transformation;
|
||||
|
||||
import com.carrotsearch.hppc.IntArrayList;
|
||||
import com.carrotsearch.hppc.IntHashSet;
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2019 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.model.transformation;
|
||||
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
public interface NullCheckFilter {
|
||||
boolean apply(FieldReference field);
|
||||
|
||||
boolean apply(MethodReference method);
|
||||
|
||||
NullCheckFilter EMPTY = new NullCheckFilter() {
|
||||
@Override
|
||||
public boolean apply(FieldReference field) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(MethodReference method) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2018 Alexey Andreev.
|
||||
* Copyright 2019 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.model.lowlevel;
|
||||
package org.teavm.model.transformation;
|
||||
|
||||
import com.carrotsearch.hppc.IntHashSet;
|
||||
import com.carrotsearch.hppc.IntSet;
|
||||
|
@ -39,14 +39,14 @@ import org.teavm.model.util.DominatorWalkerCallback;
|
|||
import org.teavm.model.util.PhiUpdater;
|
||||
|
||||
public class NullCheckInsertion {
|
||||
private Characteristics characteristics;
|
||||
private NullCheckFilter filter;
|
||||
|
||||
public NullCheckInsertion(Characteristics characteristics) {
|
||||
this.characteristics = characteristics;
|
||||
public NullCheckInsertion(NullCheckFilter filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public void transformProgram(Program program, MethodReference methodReference) {
|
||||
if (!characteristics.isManaged(methodReference) || program.basicBlockCount() == 0) {
|
||||
if (!filter.apply(methodReference) || program.basicBlockCount() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -99,14 +99,14 @@ public class NullCheckInsertion {
|
|||
|
||||
@Override
|
||||
public void visit(GetFieldInstruction insn) {
|
||||
if (!characteristics.isStructure(insn.getField().getClassName())) {
|
||||
if (filter.apply(insn.getField())) {
|
||||
addGuard(insn, GetFieldInstruction::getInstance, GetFieldInstruction::setInstance);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(PutFieldInstruction insn) {
|
||||
if (!characteristics.isStructure(insn.getField().getClassName())) {
|
||||
if (filter.apply(insn.getField())) {
|
||||
addGuard(insn, PutFieldInstruction::getInstance, PutFieldInstruction::setInstance);
|
||||
}
|
||||
}
|
||||
|
@ -123,8 +123,7 @@ public class NullCheckInsertion {
|
|||
|
||||
@Override
|
||||
public void visit(InvokeInstruction insn) {
|
||||
if (!characteristics.isStructure(insn.getMethod().getClassName())
|
||||
&& characteristics.isManaged(insn.getMethod())) {
|
||||
if (filter.apply(insn.getMethod())) {
|
||||
addGuard(insn, InvokeInstruction::getInstance, InvokeInstruction::setInstance);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user