mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Fixes bugs with variable mapping
This commit is contained in:
parent
bc911a661a
commit
cbe2ccb499
|
@ -4,9 +4,7 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Exchanger;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
|
@ -277,26 +275,47 @@ public class ChromeRDPDebugger implements JavaScriptDebugger, ChromeRDPExchangeC
|
|||
params.setObjectId(scopeId);
|
||||
params.setOwnProperties(true);
|
||||
message.setParams(mapper.valueToTree(params));
|
||||
final Exchanger<List<RDPLocalVariable>> exchanger = new Exchanger<>();
|
||||
final BlockingQueue<List<RDPLocalVariable>> sync = new LinkedTransferQueue<>();
|
||||
responseHandlers.put(message.getId(), new ResponseHandler() {
|
||||
@Override public void received(JsonNode node) throws IOException {
|
||||
GetPropertiesResponse response = mapper.reader(GetPropertiesResponse.class).readValue(node);
|
||||
// TODO: parse response
|
||||
try {
|
||||
exchanger.exchange(new ArrayList<RDPLocalVariable>());
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
sync.add(parseProperties(response.getResult()));
|
||||
}
|
||||
});
|
||||
sendMessage(message);
|
||||
try {
|
||||
return exchanger.exchange(null);
|
||||
return sync.take();
|
||||
} catch (InterruptedException e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private List<RDPLocalVariable> parseProperties(PropertyDescriptorDTO[] properties) {
|
||||
List<RDPLocalVariable> variables = new ArrayList<>();
|
||||
if (properties != null) {
|
||||
for (PropertyDescriptorDTO property : properties) {
|
||||
RemoteObjectDTO remoteValue = property.getValue();
|
||||
RDPValue value;
|
||||
switch (remoteValue.getType()) {
|
||||
case "undefined":
|
||||
value = new RDPValue("undefined");
|
||||
break;
|
||||
case "object":
|
||||
case "function":
|
||||
value = new RDPValue(remoteValue.getObjectId());
|
||||
break;
|
||||
default:
|
||||
value = new RDPValue(remoteValue.getValue().asText());
|
||||
break;
|
||||
}
|
||||
|
||||
RDPLocalVariable var = new RDPLocalVariable(property.getName(), value);
|
||||
variables.add(var);
|
||||
}
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
private <T> T parseJson(Class<T> type, JsonNode node) throws IOException {
|
||||
return mapper.reader(type).readValue(node);
|
||||
}
|
||||
|
@ -316,7 +335,7 @@ public class ChromeRDPDebugger implements JavaScriptDebugger, ChromeRDPExchangeC
|
|||
String scopeId = null;
|
||||
for (ScopeDTO scope : dto.getScopeChain()) {
|
||||
if (scope.getType().equals("local")) {
|
||||
scopeId = scope.getObject();
|
||||
scopeId = scope.getObject().getObjectId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,14 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties;
|
|||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ScopeDTO {
|
||||
private String object;
|
||||
private RemoteObjectDTO object;
|
||||
private String type;
|
||||
|
||||
public String getObject() {
|
||||
public RemoteObjectDTO getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public void setObject(String object) {
|
||||
public void setObject(RemoteObjectDTO object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,13 +9,13 @@ import org.teavm.chromerdp.data.PropertyDescriptorDTO;
|
|||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class GetPropertiesResponse {
|
||||
private PropertyDescriptorDTO[] properties;
|
||||
private PropertyDescriptorDTO[] result;
|
||||
|
||||
public PropertyDescriptorDTO[] getProperties() {
|
||||
return properties;
|
||||
public PropertyDescriptorDTO[] getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setProperties(PropertyDescriptorDTO[] properties) {
|
||||
this.properties = properties;
|
||||
public void setResult(PropertyDescriptorDTO[] properties) {
|
||||
this.result = properties;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,9 +26,9 @@ import org.teavm.model.MethodReference;
|
|||
public class CallFrame {
|
||||
private SourceLocation location;
|
||||
private MethodReference method;
|
||||
private Map<String, LocalVariable> variables;
|
||||
private Map<String, Variable> variables;
|
||||
|
||||
CallFrame(SourceLocation location, MethodReference method, Map<String, LocalVariable> variables) {
|
||||
CallFrame(SourceLocation location, MethodReference method, Map<String, Variable> variables) {
|
||||
this.location = location;
|
||||
this.method = method;
|
||||
this.variables = Collections.unmodifiableMap(variables);
|
||||
|
@ -42,7 +42,7 @@ public class CallFrame {
|
|||
return method;
|
||||
}
|
||||
|
||||
public Map<String, LocalVariable> getVariables() {
|
||||
public Map<String, Variable> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,12 +50,10 @@ class DebugInformationReader {
|
|||
private DebugInformation.Mapping[] readVariableMappings(int count) throws IOException {
|
||||
DebugInformation.Mapping[] mappings = new DebugInformation.Mapping[count];
|
||||
int varCount = readUnsignedNumber();
|
||||
int lastVar = 0;
|
||||
while (varCount-- > 0) {
|
||||
int lastVar = 0;
|
||||
for (int i = 0; i < mappings.length; ++i) {
|
||||
lastVar += readUnsignedNumber();
|
||||
mappings[lastVar] = readMapping();
|
||||
}
|
||||
lastVar += readUnsignedNumber();
|
||||
mappings[lastVar] = readMapping();
|
||||
}
|
||||
return mappings;
|
||||
}
|
||||
|
|
|
@ -40,12 +40,12 @@ class DebugInformationWriter {
|
|||
writeMapping(debugInfo.lineMapping);
|
||||
writeMapping(debugInfo.classMapping);
|
||||
writeMapping(debugInfo.methodMapping);
|
||||
writeUnsignedNumber(nonNullVariableMappings(debugInfo));
|
||||
writeVariableMappings(debugInfo);
|
||||
}
|
||||
|
||||
private void writeVariableMappings(DebugInformation debugInfo) throws IOException {
|
||||
int lastVar = 0;
|
||||
writeUnsignedNumber(nonNullVariableMappings(debugInfo));
|
||||
for (int i = 0; i < debugInfo.variableMappings.length; ++i) {
|
||||
DebugInformation.Mapping mapping = debugInfo.variableMappings[i];
|
||||
if (mapping == null) {
|
||||
|
|
|
@ -186,7 +186,8 @@ public class Debugger {
|
|||
MethodReference method = !empty ? debugInformation.getMethodAt(jsFrame.getLocation().getLine(),
|
||||
jsFrame.getLocation().getColumn()) : null;
|
||||
if (!empty || !wasEmpty) {
|
||||
frames.add(new CallFrame(loc, method, new HashMap<String, LocalVariable>()));
|
||||
VariableMap vars = new VariableMap(jsFrame.getVariables(), this, jsFrame.getLocation());
|
||||
frames.add(new CallFrame(loc, method, vars));
|
||||
}
|
||||
wasEmpty = empty;
|
||||
}
|
||||
|
@ -279,6 +280,14 @@ public class Debugger {
|
|||
}
|
||||
}
|
||||
|
||||
public String mapVariable(String variable, JavaScriptLocation location) {
|
||||
DebugInformation debugInfo = debugInformationMap.get(location.getScript());
|
||||
if (debugInfo == null) {
|
||||
return null;
|
||||
}
|
||||
return debugInfo.getVariableMeaningAt(location.getLine(), location.getColumn(), variable);
|
||||
}
|
||||
|
||||
private JavaScriptDebuggerListener javaScriptListener = new JavaScriptDebuggerListener() {
|
||||
@Override
|
||||
public void resumed() {
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
* Copyright 2014 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.debugging;
|
||||
|
||||
import java.util.Map;
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
* Copyright 2014 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.debugging;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
package org.teavm.debugging;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class LocalVariable {
|
||||
private String name;
|
||||
private WatchedValue value;
|
||||
|
||||
LocalVariable(String name, WatchedValue value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public WatchedValue getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2014 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.debugging;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
class SimpleValue extends Value {
|
||||
private String representation;
|
||||
|
||||
public SimpleValue(String representation) {
|
||||
this.representation = representation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRepresentation() {
|
||||
return representation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Variable> getProperties() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
28
teavm-core/src/main/java/org/teavm/debugging/Value.java
Normal file
28
teavm-core/src/main/java/org/teavm/debugging/Value.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2014 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.debugging;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public abstract class Value {
|
||||
public abstract String getRepresentation();
|
||||
|
||||
public abstract Map<String, Variable> getProperties();
|
||||
}
|
38
teavm-core/src/main/java/org/teavm/debugging/Variable.java
Normal file
38
teavm-core/src/main/java/org/teavm/debugging/Variable.java
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2014 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.debugging;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class Variable {
|
||||
private String name;
|
||||
private Value value;
|
||||
|
||||
Variable(String name, Value value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Value getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2014 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.debugging;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
class VariableMap extends AbstractMap<String, Variable> {
|
||||
private AtomicReference<Map<String, Variable>> backingMap = new AtomicReference<>();
|
||||
private Map<String, JavaScriptVariable> jsVariables;
|
||||
private Debugger debugger;
|
||||
private JavaScriptLocation location;
|
||||
|
||||
public VariableMap(Map<String, JavaScriptVariable> jsVariables, Debugger debugger, JavaScriptLocation location) {
|
||||
this.jsVariables = jsVariables;
|
||||
this.debugger = debugger;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<String, Variable>> entrySet() {
|
||||
updateBackingMap();
|
||||
return backingMap.get().entrySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Variable get(Object key) {
|
||||
updateBackingMap();
|
||||
return backingMap.get().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
updateBackingMap();
|
||||
return backingMap.get().size();
|
||||
}
|
||||
|
||||
private void updateBackingMap() {
|
||||
if (backingMap.get() != null) {
|
||||
return;
|
||||
}
|
||||
Map<String, Variable> vars = new HashMap<>();
|
||||
for (Map.Entry<String, JavaScriptVariable> entry : jsVariables.entrySet()) {
|
||||
JavaScriptVariable jsVar = entry.getValue();
|
||||
String name = debugger.mapVariable(entry.getKey(), location);
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
SimpleValue value = new SimpleValue(jsVar.getValue().getRepresentation());
|
||||
vars.put(entry.getKey(), new Variable(name, value));
|
||||
}
|
||||
backingMap.compareAndSet(null, vars);
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package org.teavm.debugging;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public abstract class WatchedValue {
|
||||
public abstract String getRepresentation();
|
||||
|
||||
public abstract Map<String, LocalVariable> getProperties();
|
||||
}
|
|
@ -119,13 +119,16 @@ public class ProgramParser implements VariableDebugInformation {
|
|||
while (program.variableCount() <= signatureVars) {
|
||||
program.createVariable(getVariableDebugName(program.variableCount(), 0));
|
||||
}
|
||||
for (int i = 0; i < signatureVars; ++i) {
|
||||
for (int i = 0; i <= signatureVars; ++i) {
|
||||
parameterNames.put(i, getVariableDebugName(i, 0));
|
||||
}
|
||||
return program;
|
||||
}
|
||||
|
||||
private String getVariableDebugName(int var, int location) {
|
||||
if (var < 0) {
|
||||
return null;
|
||||
}
|
||||
List<LocalVariableNode> nodes = localVariableMap.get(var);
|
||||
if (nodes == null) {
|
||||
return null;
|
||||
|
@ -293,10 +296,13 @@ public class ProgramParser implements VariableDebugInformation {
|
|||
DefinitionExtractor defExtractor = new DefinitionExtractor();
|
||||
for (int i = 0; i < targetInstructions.size(); ++i) {
|
||||
List<Instruction> instructionList = targetInstructions.get(i);
|
||||
if (instructionList == null) {
|
||||
continue;
|
||||
}
|
||||
for (Instruction insn : instructionList) {
|
||||
insn.acceptVisitor(defExtractor);
|
||||
for (Variable var : defExtractor.getDefinedVariables()) {
|
||||
String debugName = getVariableDebugName(var.getIndex(), i);
|
||||
String debugName = getVariableDebugName(var.getIndex() - minLocal, i);
|
||||
if (debugName != null) {
|
||||
variableDebugNames.put(insn, debugName);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
* Copyright 2014 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.parsing;
|
||||
|
||||
import org.teavm.model.Instruction;
|
||||
|
|
Loading…
Reference in New Issue
Block a user