Skip to content

Commit

Permalink
Attempt to fix VariablesObject - still doesn't work!
Browse files Browse the repository at this point in the history
  • Loading branch information
skinny85 committed Dec 26, 2024
1 parent 2487d3e commit b111dc0
Show file tree
Hide file tree
Showing 11 changed files with 348 additions and 585 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public final class StmtBlockRootNode extends RootNode {
private final String name;

@CompilationFinal(dimensions = 1)
private RefObject[] funcArgRefObjects;
private RefObject[] findFuncArgRefsCache;

public StmtBlockRootNode(EasyScriptTruffleLanguage truffleLanguage,
FrameDescriptor frameDescriptor, BlockStmtNode blockStmt, String name) {
Expand Down Expand Up @@ -67,28 +67,30 @@ public String getName() {
}

public RefObject[] getFuncArgReferences(int argNr) {
if (this.funcArgRefObjects == null) {
if (this.findFuncArgRefsCache == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
this.funcArgRefObjects = this.findFuncArgReferences(argNr);
this.findFuncArgRefsCache = this.findFuncArgReferences(argNr);
}
return this.funcArgRefObjects;
return this.findFuncArgRefsCache;
}

private RefObject[] findFuncArgReferences(int argNr) {
RefObject[] funcArgs = new RefObject[argNr];
// The first argument is always special - it represents 'this'.
// We'll never encounter 'this' below, because we check for ReadFunctionArgExprNode,
// while 'this' has its own Node (ThisExprNode)
funcArgs[0] = new RefObject("this", null);
funcArgs[0] = new RefObject("this", 0, null);
NodeUtil.forEachChild(this.blockStmt, new NodeVisitor() {
@Override
public boolean visit(Node visitedNode) {
if (visitedNode instanceof ReadFunctionArgExprNode) {
ReadFunctionArgExprNode readFunctionArgExprNode = (ReadFunctionArgExprNode) visitedNode;
var readFunctionArgExprNode = (ReadFunctionArgExprNode) visitedNode;
if (funcArgs[readFunctionArgExprNode.index] == null) {
// only fill this the first time we encounter a reference to the given func argument
funcArgs[readFunctionArgExprNode.index] = new RefObject(
readFunctionArgExprNode.argName, readFunctionArgExprNode.getSourceSection());
readFunctionArgExprNode.argName,
readFunctionArgExprNode.index,
readFunctionArgExprNode.getSourceSection());
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.endoflineblog.truffle.part_15.nodes.root.StmtBlockRootNode;
import com.endoflineblog.truffle.part_15.nodes.stmts.blocks.BlockStmtNode;
import com.endoflineblog.truffle.part_15.runtime.nodes.FuncArgsScopeObject;
import com.endoflineblog.truffle.part_15.runtime.nodes.VariablesObject;
import com.endoflineblog.truffle.part_15.runtime.nodes.LocalVarsScopeObject;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.VirtualFrame;
Expand Down Expand Up @@ -65,7 +65,7 @@ public SourceSection getSourceSection() {
*
* @return the block node, always non-null. Either SLBlockNode, or SLRootNode.
*/
public final Node findBlock() {
public final Node findParentBlock() {
Node parent = getParent();
while (parent != null) {
if (parent instanceof BlockStmtNode) {
Expand All @@ -89,16 +89,13 @@ public final Node findBlock() {
@ExportMessage
Object getScope(
Frame frame, boolean nodeEnter,
@Cached(value = "this", adopt = false) EasyScriptStmtNode cachedNode,
@Cached(value = "this.findBlock()", adopt = false, allowUncached = true) Node blockNode) {
return blockNode instanceof BlockStmtNode
? new VariablesObject(frame, cachedNode, nodeEnter, (BlockStmtNode) blockNode)
: new FuncArgsScopeObject(frame, (StmtBlockRootNode) blockNode);
@Cached(value = "this", adopt = false) EasyScriptStmtNode thisCached,
@Cached(value = "this.findParentBlock()", adopt = false, allowUncached = true) Node thisParentBlock) {
return thisParentBlock instanceof BlockStmtNode
? new LocalVarsScopeObject(frame, nodeEnter, thisCached, (BlockStmtNode) thisParentBlock)
: new FuncArgsScopeObject(frame, (StmtBlockRootNode) thisParentBlock);
}

/**
* We do provide a scope.
*/
@ExportMessage
boolean hasScope(@SuppressWarnings("unused") Frame frame) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public final class ExprStmtNode extends EasyScriptStmtNode {
@Child
private EasyScriptExprNode expr;

private final boolean discardExpressionValue;
public final boolean discardExpressionValue;

/**
* Creates a new instance of the expression statement.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.endoflineblog.truffle.part_15.nodes.exprs.variables.LocalVarAssignmentExprNode;
import com.endoflineblog.truffle.part_15.nodes.stmts.EasyScriptStmtNode;
import com.endoflineblog.truffle.part_15.nodes.stmts.ExprStmtNode;
import com.endoflineblog.truffle.part_15.nodes.stmts.SkippedStmtNode;
import com.endoflineblog.truffle.part_15.runtime.Undefined;
import com.endoflineblog.truffle.part_15.runtime.nodes.RefObject;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.frame.VirtualFrame;
Expand All @@ -15,7 +17,6 @@
import com.oracle.truffle.api.nodes.NodeVisitor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
Expand All @@ -33,7 +34,7 @@ public final class BlockStmtNode extends SkippedStmtNode {
private final EasyScriptStmtNode[] stmts;

@CompilationFinal(dimensions = 1)
private LocalVarAssignmentExprNode[] writeNodesCache;
private RefObject[] findLocalVarRefsCache;

public BlockStmtNode(List<EasyScriptStmtNode> stmts) {
this.stmts = stmts.toArray(new EasyScriptStmtNode[]{});
Expand Down Expand Up @@ -61,70 +62,80 @@ public boolean hasTag(Class<? extends Tag> tag) {
return tag == StandardTags.RootTag.class;
}

public LocalVarAssignmentExprNode[] getDeclaredLocalVariables() {
LocalVarAssignmentExprNode[] writeNodes = this.writeNodesCache;
if (writeNodes == null) {
public RefObject[] getLocalVarRefs() {
if (this.findLocalVarRefsCache == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
writeNodesCache = writeNodes = this.findDeclaredLocalVariables();
this.findLocalVarRefsCache = this.findLocalVarRefs();
}
return writeNodes;
return this.findLocalVarRefsCache;
}

private LocalVarAssignmentExprNode[] findDeclaredLocalVariables() {
private RefObject[] findLocalVarRefs() {
// Search for those write nodes, which declare variables
List<LocalVarAssignmentExprNode> writeNodes = new ArrayList<>(4);
List<RefObject> localVarRefs = new ArrayList<>(4);
// int[] varsIndex = new int[]{0};
NodeUtil.forEachChild(this, new NodeVisitor() {
private boolean inDeclaration = false;

@Override
public boolean visit(Node visitedNode) {
if (visitedNode instanceof WrapperNode) {
NodeUtil.forEachChild(visitedNode, this);
return true;
}
// if (visitedNode instanceof SLScopedNode) {
// SLScopedNode scopedNode = (SLScopedNode) visitedNode;
public boolean visit(Node visistedNode) {
// if (visistedNode instanceof WrapperNode) {
// NodeUtil.forEachChild(visistedNode, this);
// return true;
// }
// if (visistedNode instanceof SLScopedNode) {
// SLScopedNode scopedNode = (SLScopedNode) visistedNode;
// scopedNode.setVisibleVariablesIndexOnEnter(varsIndex[0]);
// }
// Do not enter any nested blocks.
if (!(visitedNode instanceof BlockStmtNode)) {
NodeUtil.forEachChild(visitedNode, this);
if (visistedNode instanceof ExprStmtNode) {
var exprStmtNode = (ExprStmtNode) visistedNode;
if (exprStmtNode.discardExpressionValue) {
this.inDeclaration = true;
}
NodeUtil.forEachChild(visistedNode, this);
if (exprStmtNode.discardExpressionValue) {
this.inDeclaration = false;
}
return true;
}
// Write to a variable is a declaration unless it exists already in a parent scope.
if (visitedNode instanceof LocalVarAssignmentExprNode) {
LocalVarAssignmentExprNode wn = (LocalVarAssignmentExprNode) visitedNode;
// if (wn.isDeclaration()) {
writeNodes.add(wn);
// varsIndex[0]++;
// }
if (this.inDeclaration && visistedNode instanceof LocalVarAssignmentExprNode) {
LocalVarAssignmentExprNode lvaen = (LocalVarAssignmentExprNode) visistedNode;
localVarRefs.add(new RefObject(
lvaen.getSlotName(),
lvaen.getFrameSlot(),
lvaen.getSourceSection()));
return true;
}
// Recur into any Node except a block of statements.
if (!(visistedNode instanceof BlockStmtNode)) {
NodeUtil.forEachChild(visistedNode, this);
}
// if (visitedNode instanceof SLScopedNode) {
// SLScopedNode scopedNode = (SLScopedNode) visitedNode;
// if (visistedNode instanceof SLScopedNode) {
// SLScopedNode scopedNode = (SLScopedNode) visistedNode;
// scopedNode.setVisibleVariablesIndexOnExit(varsIndex[0]);
// }
return true;
}
});
LocalVarAssignmentExprNode[] variables = writeNodes.toArray(new LocalVarAssignmentExprNode[0]);
// this.parentBlockIndex = variables.length;

Node parentBlock = this.findBlock();
LocalVarAssignmentExprNode[] parentVariables = null;
Node parentBlock = this.findParentBlock();
RefObject[] parentVariables = null;
if (parentBlock instanceof BlockStmtNode) {
parentVariables = ((BlockStmtNode) parentBlock).getDeclaredLocalVariables();
parentVariables = ((BlockStmtNode) parentBlock).getLocalVarRefs();
}
RefObject[] variables = localVarRefs.toArray(new RefObject[0]);
// parentBlockIndex = variables.length;
if (parentVariables == null || parentVariables.length == 0) {
return variables;
} else {
// int parentVariablesIndex = ((BlockStmtNode) parentBlock).getParentBlockIndex();
// int parentVariablesIndex = ((SLBlockNode) parentBlock).getParentBlockIndex();
// int visibleVarsIndex = getVisibleVariablesIndexOnEnter();
// int allVarsLength = variables.length + visibleVarsIndex + parentVariables.length - parentVariablesIndex;
// LocalVarAssignmentExprNode[] allVariables = Arrays.copyOf(variables, allVarsLength);
// System.arraycopy(parentVariables, 0, allVariables, variables.length, visibleVarsIndex);
// System.arraycopy(parentVariables, parentVariablesIndex, allVariables, variables.length + visibleVarsIndex, parentVariables.length - parentVariablesIndex);

int allVarsLength = variables.length + parentVariables.length;
LocalVarAssignmentExprNode[] allVariables = Arrays.copyOf(variables, allVarsLength);
System.arraycopy(parentVariables, 0, allVariables, variables.length, allVarsLength - variables.length);
RefObject[] allVariables = new RefObject[variables.length + parentVariables.length];
System.arraycopy(variables, 0, allVariables, 0, variables.length);
System.arraycopy(parentVariables, 0, allVariables, variables.length, parentVariables.length);
return allVariables;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,22 @@ public final class FuncArgsScopeObject implements TruffleObject {
private final Frame frame;
final StmtBlockRootNode rootNode;

/**
* The arguments depend on the current frame and root node.
*/
public FuncArgsScopeObject(Frame frame, StmtBlockRootNode rootNode) {
this.frame = frame;
this.rootNode = rootNode;
}

/**
* For performance reasons, fix the library implementation for the particular root node.
*/
@ExportMessage
boolean accepts(
@Cached(value = "this.rootNode", adopt = false) StmtBlockRootNode cachedRoot) {
return this.rootNode == cachedRoot;
}

/**
* This is a scope object, providing arguments as members.
*/
@ExportMessage
boolean isScope() {
return true;
}

/**
* The scope must provide an associated language.
*/
@ExportMessage
boolean hasLanguage() {
return true;
Expand All @@ -61,41 +49,26 @@ Class<? extends TruffleLanguage<?>> getLanguage() {
return EasyScriptTruffleLanguage.class;
}

/**
* Provide the function name as the scope's display string.
*/
@ExportMessage
Object toDisplayString(@SuppressWarnings("unused") boolean allowSideEffects) {
return rootNode.getName();
}

/**
* We provide a source section of this scope.
*/
@ExportMessage
boolean hasSourceLocation() {
return true;
}

/**
* @return Source section of the function.
*/
@ExportMessage
SourceSection getSourceLocation() {
return rootNode.getSourceSection();
}

/**
* Scope must provide scope members.
*/
@ExportMessage
boolean hasMembers() {
return true;
}

/**
* We return an array of argument objects as scope members.
*/
@ExportMessage
Object getMembers(@SuppressWarnings("unused") boolean includeInternal) {
RefObject[] refObjects = rootNode.getFuncArgReferences(this.frame.getArguments().length);
Expand Down Expand Up @@ -125,7 +98,7 @@ static boolean isMemberReadableUncached(FuncArgsScopeObject receiver, String mem
static final class MemberModifiable {
@Specialization(limit = "MEMBER_CACHE_LIMIT", guards = {"cachedMember.equals(member)"})
static boolean isMemberModifiableCached(
FuncArgsScopeObject receiver,
@SuppressWarnings("unused") FuncArgsScopeObject receiver,
@SuppressWarnings("unused") String member,
@Cached("member") @SuppressWarnings("unused") String cachedMember,
// We cache the member existence for fast-path access
Expand All @@ -140,14 +113,6 @@ static boolean isMemberModifiableUncached(FuncArgsScopeObject receiver, String m
}
}

/**
* We can not insert new arguments.
*/
@ExportMessage
boolean isMemberInsertable(@SuppressWarnings("unused") String member) {
return false;
}

@ExportMessage(name = "readMember")
static final class ReadMember {
@Specialization(limit = "MEMBER_CACHE_LIMIT", guards = {"cachedMember.equals(member)"})
Expand Down Expand Up @@ -207,6 +172,11 @@ private static void writeMember(FuncArgsScopeObject receiver, String member, int
}
}

@ExportMessage
boolean isMemberInsertable(@SuppressWarnings("unused") String member) {
return false;
}

private boolean hasArgCalled(String member) {
return this.findArgumentIndex(member) >= 0;
}
Expand Down
Loading

0 comments on commit b111dc0

Please sign in to comment.