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

Disable internal function pointer decoding for contracts compiled with viaIR #5596

Merged
merged 3 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/codec/lib/compilations/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ export interface Compilation {
* specified on each source and contract, but please don't actually do that.
*/
compiler?: Compiler.CompilerVersion;
/**
* The settings used in the compilation. Works similarly to the compiler field.
* May be omitted.
*/
settings?: Compiler.Settings;
}

/**
Expand Down Expand Up @@ -78,6 +83,12 @@ export interface Source {
* compilation as a whole; please don't do that.)
*/
compiler?: Compiler.CompilerVersion; //compatibility hack!
/**
* This field is a compatibility hack only intended for internal use.
* (It allows the settings to be set on a source if none is set on the
* compilation as a whole; please don't do that.)
*/
settings?: Compiler.Settings; //compatibility hack!
}

/**
Expand Down Expand Up @@ -123,6 +134,12 @@ export interface Contract {
* compilation as a whole; please don't do that.)
*/
compiler?: Compiler.CompilerVersion; //compatibility hack!
/**
* This field is a compatibility hack only intended for internal use.
* (It allows the settings to be set on a source if none is set on the
* compilation as a whole; please don't do that.)
*/
settings?: Compiler.Settings; //compatibility hack!
/**
* The ID of the contract's primary source.
*/
Expand Down
28 changes: 26 additions & 2 deletions packages/codec/lib/compilations/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ interface CompilationOptions {
sources?: Common.Source[];
shimmedCompilationId?: string;
compiler?: Compiler.CompilerVersion;
settings?: Compiler.Settings;
}

interface CompilationAndContract {
Expand Down Expand Up @@ -108,7 +109,8 @@ export function shimContracts(
abi,
compiler,
generatedSources,
deployedGeneratedSources
deployedGeneratedSources,
metadata
} = artifact;

if ((<Artifact>artifact).contract_name) {
Expand Down Expand Up @@ -144,6 +146,18 @@ export function shimContracts(
};
//ast needs to be coerced because schema doesn't quite match our types here...

if (metadata) {
try {
const parsedMetadata: any = JSON.parse(metadata); //sorry
const settings: Compiler.Settings = parsedMetadata.settings;
const viaIR = settings.viaIR;
contractObject.settings = { viaIR };
sourceObject.settings = { viaIR };
} catch {
//if metadata doesn't parse, or we hit undefineds, ignore it
}
}

//if files or sources was passed, trust that to determine the source index
//(assuming we have a sourcePath! currently it will be absent when dealing with
//Solidity versions <0.4.9; presumably we will fix this if we ever properly
Expand Down Expand Up @@ -230,6 +244,15 @@ export function shimContracts(
compiler = contracts[0].compiler;
}

let settings: Compiler.Settings; //we'll do the same thing with settings
if (options.settings) {
settings = options.settings;
} else if (!unreliableSourceOrder && contracts.length > 0) {
//if things were actually compiled together, we should just be able
//to pick an arbitrary one
settings = contracts[0].settings;
}

//if input sources was passed, set up the sources object directly :)
if (inputSources) {
sources = inputSources.map(
Expand All @@ -249,7 +272,8 @@ export function shimContracts(
unreliableSourceOrder,
sources,
contracts,
compiler
compiler,
settings
};
}

Expand Down
7 changes: 7 additions & 0 deletions packages/codec/lib/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ export type SolidityFamily =
| "0.8.x"
| "0.8.7+"
| "0.8.9+";

export interface Settings {
//this type is deliberately incomplete,
//it only includes the settings that Codec cares about,
//of which at present this is the only one.
viaIR?: boolean;
}
6 changes: 3 additions & 3 deletions packages/debugger/lib/data/sagas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ export function* decode(definition, ref, compilationId) {
const contexts = yield select(data.views.contexts);
const currentContext = yield select(data.current.context);
const internalFunctionsTable = yield select(
data.current.functionsByProgramCounter
data.current.internalFunctionsTable
);

debug("definition: %o");
Expand Down Expand Up @@ -1105,7 +1105,7 @@ export function* decodeReturnValue() {
const returnAllocation = yield select(data.current.returnAllocation); //may be null
const errorId = yield select(data.current.errorId);
const internalFunctionsTable = yield select(
data.current.functionsByProgramCounter
data.current.internalFunctionsTable
);
debug("returnAllocation: %O", returnAllocation);

Expand Down Expand Up @@ -1218,7 +1218,7 @@ export function* decodeLog() {
const currentContext = yield select(data.current.context);
const eventId = yield select(data.current.eventId);
const internalFunctionsTable = yield select(
data.current.functionsByProgramCounter
data.current.internalFunctionsTable
);

const decoder = Codec.decodeEvent(
Expand Down
13 changes: 13 additions & 0 deletions packages/debugger/lib/data/selectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,19 @@ const data = createSelectorTree({
functions => functions
),

/**
* data.current.internalFunctionsTable
*/
internalFunctionsTable: createLeaf(
[evm.current.isIR, "./functionsByProgramCounter"],
//for Solidity compiled with IR turned on, internal function pointers
//are encoded by index rather than by PC value. unfortunately the
//indices are hard to predict and so at present we can't decode these
//(at least, not without a fair bit more effort). As such we won't set
//up an internal functions table if IR is turned on.
(isIR, byPC) => (isIR ? undefined : byPC)
),

/**
* data.current.context
*/
Expand Down
10 changes: 10 additions & 0 deletions packages/debugger/lib/evm/selectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,16 @@ const evm = createSelectorTree({
determineFullContext
),

/**
* evm.current.isIR
* was the current context compield with IR on?
* currently, this defaults to false; in the future the default
* may depend on the Solidity version
*/
isIR: createLeaf(["./context"], context =>
context.settings ? Boolean(context.settings.viaIR) : false
),

/**
* evm.current.state
*
Expand Down
7 changes: 7 additions & 0 deletions packages/debugger/lib/session/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export default class Session {
);
}
const compiler = compilation.compiler; //note: we'll prefer one listed on contract or source
const settings = compilation.settings; //same note
sources.user[compilation.id] = [];
contracts[compilation.id] = {};
for (let index in compilation.sources) {
Expand All @@ -157,6 +158,7 @@ export default class Session {
...source,
ast,
compiler: source.compiler || compiler,
settings: source.settings || settings,
compilationId: compilation.id,
index,
id: makeSourceId(compilation.id, null, index),
Expand All @@ -174,6 +176,7 @@ export default class Session {
immutableReferences,
abi,
compiler,
settings,
primarySourceId,
generatedSources,
deployedGeneratedSources
Expand Down Expand Up @@ -260,6 +263,7 @@ export default class Session {
primarySource: primarySourceIndex,
abi,
compiler,
settings,
compilationId: compilation.id,
contractId,
contractKind,
Expand All @@ -277,6 +281,7 @@ export default class Session {
sources.internal[contextHash][index] = {
...source,
compiler: source.compiler || compiler,
settings: source.settings || settings,
compilationId: compilation.id,
index,
id: makeSourceId(compilation.id, contextHash, index),
Expand Down Expand Up @@ -308,6 +313,7 @@ export default class Session {
immutableReferences,
abi,
compiler,
settings,
compilationId: compilation.id,
contractId,
contractKind,
Expand All @@ -325,6 +331,7 @@ export default class Session {
sources.internal[contextHash][index] = {
...source,
compiler: source.compiler || compiler,
settings: source.settings || settings,
compilationId: compilation.id,
index,
id: makeSourceId(compilation.id, contextHash, index),
Expand Down
5 changes: 5 additions & 0 deletions packages/decoder/lib/decoders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1499,9 +1499,14 @@ export class ContractInstanceDecoder {
//some sort of fake table if we don't have a source map, or if any ASTs are missing
//(if a whole *source* is missing, we'll consider that OK)
//note: we don't attempt to handle Vyper source maps!
//we also (for now) don't attempt this if viaIR is set, since we can't
//currently handle decoding by index
const compiler = this.compilation.compiler || this.contract.compiler;
const viaIR =
this.compilation?.settings?.viaIR || this.contract?.settings?.viaIR;
if (
!this.compilation.unreliableSourceOrder &&
!viaIR &&
this.contract.deployedSourceMap &&
compiler.name === "solc" &&
this.compilation.sources.every(source => !source || source.ast)
Expand Down
10 changes: 9 additions & 1 deletion packages/source-map-utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -450,13 +450,21 @@ var SourceMapUtils = {
return null;
}
index++;
while (instructions[index].name.match(/^PUSH\d*/)) {
while (
instructions[index] &&
instructions[index].name.match(/^PUSH\d*/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be /^PUSH\d+/ ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, it doesn't really matter in this context? There's no such instruction as plain PUSH.

) {
index++;
if (index > startingIndex + 3) {
//check: are there more than 2 PUSHes?
return null;
}
}
if (!instructions[index]) {
//covers both the case where we ran off already,
//and where we're about to run off
return null;
}
if (instructions[index].name === "JUMP") {
if (index === startingIndex + 1) {
//check: was there at least one push?
Expand Down