Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -1593,16 +1593,17 @@ export class Runtime extends EventEmitter {
if ('globalIndex' in indexedLoc.loc) {
// global location
const globalValue = moveCallStack.globals.get(indexedLoc.loc.globalIndex);
if (globalValue) {
const indexPath = [...indexedLoc.indexPath];
return this.valueToString(tabs, globalValue, name, indexPath, type);
if (!globalValue) {
return 'INCORRECT REF VALUE (NO GLOBAL VALUE)';
}
const indexPath = [...indexedLoc.indexPath];
return this.valueToString(tabs, globalValue, name, indexPath, type);
} else if ('frameID' in indexedLoc.loc && 'localIndex' in indexedLoc.loc) {
const frameID = indexedLoc.loc.frameID;
const frame = moveCallStack.frames.find(frame => frame.id === frameID);
let local = undefined;
if (!frame) {
return res;
return 'INCORRECT REF VALUE (NO FRAME)';
}
for (const scope of frame.locals) {
local = scope[indexedLoc.loc.localIndex];
Expand All @@ -1611,12 +1612,12 @@ export class Runtime extends EventEmitter {
}
}
if (!local) {
return res;
return 'INCORRECT REF VALUE (NO LOCAL)';
}
const indexPath = [...indexedLoc.indexPath];
return this.valueToString(tabs, local.value, name, indexPath, type);
}
return res;
return 'INCORRECT REF VALUE (NO GLOBAL OR LOCAL)';
}

/**
Expand All @@ -1638,16 +1639,20 @@ export class Runtime extends EventEmitter {
): string {
let res = '';
if (typeof value === 'string') {
if (indexPath.length > 0) {
return 'INCORRECT VALUE (INVALID INDEX FOR STRING)';
}
res += tabs + name + ' : ' + value + '\n';
if (type) {
res += tabs + 'type: ' + type + '\n';
}
} else if (Array.isArray(value)) {
if (indexPath.length > 0) {
const index = indexPath.pop();
if (index !== undefined) {
res += this.valueToString(tabs, value[index], name, indexPath, type);
if (index === undefined || index >= value.length) {
return 'INCORRECT VALUE (INVALID INDEX)';
}
res += this.valueToString(tabs, value[index], name, indexPath, type);
} else {
res += tabs + name + ' : [\n';
for (let i = 0; i < value.length; i++) {
Expand All @@ -1661,16 +1666,20 @@ export class Runtime extends EventEmitter {
} else if ('fields' in value) {
if (indexPath.length > 0) {
const index = indexPath.pop();
if (index !== undefined) {
res += this.valueToString(tabs, value.fields[index][1], name, indexPath, type);
if (index === undefined || index >= value.fields.length) {
return 'INCORRECT VALUE (INVALID INDEX)';
}
res += this.valueToString(tabs, value.fields[index][1], name, indexPath, type);
} else {
res += tabs + name + ' : ' + this.compoundValueToString(tabs, value);
if (type) {
res += tabs + 'type: ' + type + '\n';
}
}
} else {
if (indexPath.length > 0) {
return 'INCORRECT VALUE (INVALID INDEX FOR REFERENCE VALUE)';
}
res += this.refValueToString(tabs, value, name, type);
}
return res;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,42 +167,25 @@ interface JSONTraceReadEffect {
root_value_read: JSONTraceValue;
}

interface JSONTracePushEffect {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These were actually not necessary as they are subsumed by JSONTraceValue interface

RuntimeValue?: JSONTraceRuntimeValueContent;
MutRef?: {
location: JSONTraceLocation;
snapshot: any[];
};
}

interface JSONTracePopEffect {
RuntimeValue?: JSONTraceRuntimeValueContent;
MutRef?: {
location: JSONTraceLocation;
snapshot: any[];
};
}

interface JSONDataLoadEffect {
ref_type: JSONTraceRefType;
location: JSONTraceLocation;
snapshot: JSONTraceMoveValue;
}

interface JSONTraceEffect {
Push?: JSONTracePushEffect;
Pop?: JSONTracePopEffect;
Push?: JSONTraceValue;
Pop?: JSONTraceValue;
Write?: JSONTraceWriteEffect;
Read?: JSONTraceReadEffect;
DataLoad?: JSONDataLoadEffect;
ExecutionError?: string;

}

interface JSONTraceCloseFrame {
frame_id: number;
gas_left: number;
return_: JSONTraceRuntimeValueContent[];
return_: JSONTraceValue[];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unrelated fix (spotted when looking at trace format code...)

}

interface JSONExtMoveCallSummary {
Expand Down Expand Up @@ -582,6 +565,12 @@ export async function readTrace(
}
}
localLifetimeEnds.set(frame.frame_id, lifetimeEnds);
// Extend lifetimes of locals referenced by parameters
for (const param of frame.parameters) {
if (param) {
extendLifetimeIfReference(param, localLifetimeEnds);
}
}
// Trace v3 introduces `version_id` field in frame, which represents
// address of the on-chain package version that contains the function.
// It is different from `frame.module.address` if the package has been
Expand Down Expand Up @@ -659,6 +648,12 @@ export async function readTrace(
bcodeFunEntry
});
} else if (event.CloseFrame) {
// Extend lifetimes of locals referenced by return values
for (const returnValue of event.CloseFrame.return_) {
if (returnValue) {
extendLifetimeIfReference(returnValue, localLifetimeEnds);
}
}
events.push({
type: TraceEventKind.CloseFrame,
id: event.CloseFrame.frame_id
Expand Down Expand Up @@ -754,6 +749,13 @@ export async function readTrace(
localLifetimeEndsMax.set(nonInlinedFrameID, lifetimeEndsMax);
} else if (event.Effect) {
const effect = event.Effect;
// Process Push/Pop effects that contain references to extend local lifetimes
if (effect.Push) {
extendLifetimeIfReference(effect.Push, localLifetimeEnds);
}
if (effect.Pop) {
extendLifetimeIfReference(effect.Pop, localLifetimeEnds);
}
if (effect.Write || effect.Read || effect.DataLoad) {
const location = effect.Write
? effect.Write.location
Expand Down Expand Up @@ -1233,6 +1235,24 @@ function processJSONLocation(
}
}

/**
* Extends the lifetime of a local variable if it contains a reference.
*
* @param value JSON trace value that may contain a reference.
* @param localLifetimeEnds map of local variable lifetimes.
*/
function extendLifetimeIfReference(
value: JSONTraceValue,
localLifetimeEnds?: Map<number, number[]>
): void {
if ('MutRef' in value || 'ImmRef' in value) {
const refContent = 'MutRef' in value ? value.MutRef : value.ImmRef;
if (refContent && refContent.location) {
processJSONLocation(refContent.location, [], localLifetimeEnds);
}
}
}

/**
* Converts a JSON trace reference value to a runtime value.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "ref_after_lifetime"
edition = "2024.beta"

[dependencies]
MoveStdlib = { local = "../../../../move-stdlib" }

[addresses]
ref_after_lifetime = "0x0"
std = "0x1"

Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":2,"from_file_path":"/Users/adamwelc/sui/external-crates/move/crates/move-analyzer/trace-adapter/tests/ref_after_lifetime/sources/m.move","definition_location":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":161,"end":162},"module_name":["0000000000000000000000000000000000000000000000000000000000000000","m"],"struct_map":{},"enum_map":{},"function_map":{"0":{"location":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":307,"end":368},"definition_location":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":311,"end":327},"type_parameters":[],"parameters":[["value_ref#0#0",{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":328,"end":337}]],"returns":[{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":346,"end":350}],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":357,"end":366}},"is_native":false},"1":{"location":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":378,"end":896},"definition_location":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":382,"end":386},"type_parameters":[],"parameters":[],"returns":[],"locals":[["my_value#1#0",{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":399,"end":407}]],"nops":{},"code_map":{"0":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":410,"end":415},"1":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":399,"end":407},"2":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":558,"end":567},"3":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":541,"end":568},"4":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":525,"end":538},"5":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":568,"end":569}},"is_native":false},"2":{"location":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":134,"end":896},"definition_location":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":134,"end":896},"type_parameters":[],"parameters":[],"returns":[],"locals":[],"nops":{},"code_map":{"0":{"file_hash":[221,68,119,252,84,29,1,115,51,251,227,188,84,129,200,130,124,133,248,127,36,46,81,40,229,240,239,76,57,125,193,100],"start":134,"end":896}},"is_native":false}},"constant_map":{}}
Binary file not shown.
Loading
Loading