Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
Unify Solidity/Yul variable handling
Browse files Browse the repository at this point in the history
  • Loading branch information
haltman-at committed May 22, 2020
1 parent 01b4505 commit be9bbe4
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 274 deletions.
11 changes: 11 additions & 0 deletions packages/codec/lib/ast/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export function typeString(definition: AstNode): string {
* @category Definition Reading
*/
export function typeStringWithoutLocation(definition: AstNode): string {
if (definition.nodeType === "YulTypedName") {
//for handling Yul variables
return "bytes32";
}
return typeString(definition).replace(
/ (storage|memory|calldata)( slice)?$/,
""
Expand All @@ -37,6 +41,10 @@ export function typeStringWithoutLocation(definition: AstNode): string {
* @category Definition Reading
*/
export function typeClass(definition: AstNode): string {
if (definition.nodeType === "YulTypedName") {
//for handling Yul variables
return "bytes";
}
return typeIdentifier(definition).match(/t_([^$_0-9]+)/)[1];
}

Expand Down Expand Up @@ -85,6 +93,9 @@ export function visibility(definition: AstNode): Common.Visibility {
* @category Definition Reading
*/
export function specifiedSize(definition: AstNode): number {
if (definition.nodeType === "YulTypedName") {
return 32; //for handling Yul variables
}
let specified = typeIdentifier(definition).match(/t_[a-z]+([0-9]+)/);

if (!specified) {
Expand Down
24 changes: 4 additions & 20 deletions packages/debugger/lib/data/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,12 @@ export function scope(id, pointer, parentId, sourceId, compilationId) {
}

export const DECLARE = "DATA_DECLARE_VARIABLE";
export function declare(node, compilationId) {
export function declare(name, idOrPath, scopeIdOrPath, compilationId) {
return {
type: DECLARE,
node,
compilationId
};
}

export const YUL_DECLARE = "DATA_YUL_DECLARE";
export function yulDeclare(
node,
pointer,
scopePointer,
sourceId,
compilationId
) {
return {
type: YUL_DECLARE,
node,
pointer,
scopePointer,
sourceId,
name,
idOrPath,
scopeIdOrPath,
compilationId
};
}
Expand Down
216 changes: 55 additions & 161 deletions packages/debugger/lib/data/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,145 +19,66 @@ function scopes(state = DEFAULT_SCOPES, action) {

switch (action.type) {
case actions.SCOPE: {
let { compilationId, id, sourceId, parentId, pointer } = action;
if (id !== null) {
newState = {
byCompilationId: {
...state.byCompilationId,
[compilationId]: {
...state.byCompilationId[compilationId] //just setting this up to avoid errors later
}
}
};

//apologies for this multi-stage setup, but JS is like that...

newState.byCompilationId[compilationId] = {
...newState.byCompilationId[compilationId],
byId: {
...newState.byCompilationId[compilationId].byId
}
};

scope = newState.byCompilationId[compilationId].byId[id];

newState.byCompilationId[compilationId].byId[id] = {
...scope,
id,
sourceId,
parentId, //may be null
pointer,
compilationId
};

return newState;
} else {
debug("scoping by pointer!");
newState = {
byCompilationId: {
...state.byCompilationId,
[compilationId]: {
...state.byCompilationId[compilationId] //just setting this up to avoid errors later
}
}
};

//apologies for this multi-stage setup, but JS is like that...

newState.byCompilationId[compilationId] = {
...newState.byCompilationId[compilationId],
bySourceAndPointer: {
...newState.byCompilationId[compilationId].bySourceAndPointer
}
};

let sourceAndPointer = sourceId + ":" + pointer;
debug("sourceAndPointer: %s", sourceAndPointer);

scope =
newState.byCompilationId[compilationId].bySourceAndPointer[
sourceAndPointer
];

newState.byCompilationId[compilationId].bySourceAndPointer[
sourceAndPointer
] = {
...scope,
parentId, //is usually undefined
sourceId,
pointer,
compilationId
};

return newState;
}
}

case actions.DECLARE: {
let { compilationId, node } = action;

//note: we can assume the compilation already exists!
scope =
state.byCompilationId[compilationId].byId[action.node.scope] || {};
variables = scope.variables || [];
const { compilationId, id, sourceId, parentId, pointer } = action;
const idOrPath = id !== undefined ? id : sourceId + ":" + pointer;

return {
newState = {
byCompilationId: {
...state.byCompilationId,
[compilationId]: {
...state.byCompilationId[compilationId],
byId: {
...state.byCompilationId[compilationId].byId,

[node.scope]: {
...scope,
...state.byCompilationId[compilationId] //just setting this up to avoid errors later
}
}
};

variables: [
...variables,
//apologies for this multi-stage setup, but JS is like that...

{
name: node.name,
id: node.id,
compilationId
}
]
}
}
}
newState.byCompilationId[compilationId] = {
...newState.byCompilationId[compilationId],
byIdOrPath: {
...newState.byCompilationId[compilationId].byIdOrPath
}
};

scope = newState.byCompilationId[compilationId].byIdOrPath[idOrPath];

newState.byCompilationId[compilationId].byIdOrPath[idOrPath] = {
...scope,
id,
sourceId,
parentId, //may be null or undefined
pointer,
compilationId
};

return newState;
}

case actions.YUL_DECLARE: {
debug("yul declaration!");
let { node, pointer, scopePointer, sourceId, compilationId } = action;
case actions.DECLARE: {
let { compilationId, name, idOrPath, scopeIdOrPath } = action;

//note: we can assume the compilation already exists!
let sourceAndPointer = sourceId + ":" + scopePointer;
scope =
state.byCompilationId[compilationId].bySourceAndPointer[
sourceAndPointer
] || {};
state.byCompilationId[compilationId].byIdOrPath[scopeIdOrPath] || {};
variables = scope.variables || [];
debug("node: %o", node);

return {
byCompilationId: {
...state.byCompilationId,
[compilationId]: {
...state.byCompilationId[compilationId],
bySourceAndPointer: {
...state.byCompilationId[compilationId].bySourceAndPointer,
byIdOrPath: {
...state.byCompilationId[compilationId].byIdOrPath,

[sourceAndPointer]: {
[scopeIdOrPath]: {
...scope,

variables: [
...variables,

{
name: node.name,
sourceAndPointer: sourceId + ":" + pointer,
name,
idOrPath,
compilationId
}
]
Expand Down Expand Up @@ -247,59 +168,32 @@ function assignments(state = DEFAULT_ASSIGNMENTS, action) {
debug("action.type %O", action.type);
debug("action.assignments %O", action.assignments);
return Object.values(action.assignments).reduce((acc, assignment) => {
let { id, astId, sourceAndPointer, compilationId } = assignment;
let { id, idOrPath, compilationId } = assignment;
//we assume for now that only ordinary variables will be assigned this
//way, and not globals; globals are handled in DEFAULT_ASSIGNMENTS
if (astId !== undefined) {
return {
...acc,
byId: {
...acc.byId,
[id]: assignment
},
byCompilationId: {
...acc.byCompilationId,
[compilationId]: {
...acc.byCompilationId[compilationId],
byAstId: {
...(acc.byCompilationId[compilationId] || {}).byAstId,
[astId]: [
...new Set([
...(((acc.byCompilationId[compilationId] || {}).byAstId ||
{})[astId] || []),
id
])
]
}
}
}
};
} else {
return {
...acc,
byId: {
...acc.byId,
[id]: assignment
},
byCompilationId: {
...acc.byCompilationId,
[compilationId]: {
...acc.byCompilationId[compilationId],
bySourceAndPointer: {
...(acc.byCompilationId[compilationId] || {})
.bySourceAndPointer,
[sourceAndPointer]: [
...new Set([
...(((acc.byCompilationId[compilationId] || {})
.bySourceAndPointer || {})[sourceAndPointer] || []),
id
])
]
}
return {
...acc,
byId: {
...acc.byId,
[id]: assignment
},
byCompilationId: {
...acc.byCompilationId,
[compilationId]: {
...acc.byCompilationId[compilationId],
byIdOrPath: {
...(acc.byCompilationId[compilationId] || {}).byIdOrPath,
[idOrPath]: [
...new Set([
...(((acc.byCompilationId[compilationId] || {})
.byIdOrPath || {})[idOrPath] || []),
id
])
]
}
}
};
}
}
};
}, state);

case actions.RESET:
Expand Down
Loading

0 comments on commit be9bbe4

Please sign in to comment.