Skip to content

_lowerImport uses incorrect result pointer for async functions #1361

@ritalin

Description

@ritalin

Related to #1272.

After the fix in #1272, async subtasks now transition correctly. However, this exposes another issue in _lowerImport, where the return address is not handled correctly.

This is the generated code:

	function _lowerImport(args, exportFn) {
		const params = [...arguments].slice(2);
		_debugLog("[_lowerImport()] args", {
			args,
			params,
			exportFn
		});
		const { functionIdx, componentIdx, isAsync, paramLiftFns, resultLowerFns, metadata, memoryIdx, getMemoryFn, getReallocFn } = args;
		const parentTask = getCurrentTask(componentIdx)?.task;
		if (!parentTask) throw new Error("missing parent task during lower of import");
		const cstate = getOrCreateAsyncState(componentIdx);
		const subtask = parentTask.createSubtask({
			componentIdx,
			parentTask,
			callMetadata: {
				memoryIdx,
				memory: getMemoryFn(),
				realloc: getReallocFn(),
				resultPtr: params[0]
			}
		});
        // cont.

Actual behavior

  • resultPtr is always set to params[0]

In cases where the function has both parameters and a return value:

  • params[0] corresponds to the first argument
  • the return address is passed as a later parameter (e.g. params[1])

As a result, the argument value is incorrectly used as a memory address, leading to an incorrect return value.

Example

async function bar(v) { return v + 32; }

In this case:
params[0]: argument (v)
params[1]: return address

Expected behavior

  • resultPtr should point to the return address (e.g. params[1] in this case)

Suggestion

The return pointer should be taken from the last parameter, for example:

resultPtr: params.at(-1)

Using params.at(-1) for resultPtr seems to align with the canonical ABI, where the return pointer is typically passed as the last parameter.

This works correctly in the tested cases, although the exact conditions under which a return pointer is present may need to be handled explicitly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions