callExternalFunction method
void
callExternalFunction(
- String funcName,
- int numberOfArguments
)
Implementation
void callExternalFunction(String funcName, int numberOfArguments) {
ExternalFunctionDef? funcDef;
Container? fallbackFunctionContainer;
var foundExternal = _externals.containsKey(funcName);
if (foundExternal) {
funcDef = _externals[funcName];
}
if (foundExternal &&
funcDef?.lookaheadSafe == false &&
_stateSnapshotAtLastNewline != null) {
_sawLookaheadUnsafeFunctionAfterNewline = true;
return;
}
// Try to use fallback function?
if (!foundExternal) {
if (allowExternalFunctionFallbacks) {
fallbackFunctionContainer = knotContainerWithName(funcName);
assert(
fallbackFunctionContainer != null,
"Trying to call EXTERNAL function '" +
funcName +
"' which has not been bound, and fallback ink function could not be found.");
// Divert direct into fallback function and we're done
state.callStack.push(PushPopType.Function,
outputStreamLengthWithPushed: state.outputStream.length);
state.divertedPointer = Pointer.startOf(fallbackFunctionContainer);
return;
} else {
assert(
false,
"Trying to call EXTERNAL function '" +
funcName +
"' which has not been bound (and ink fallbacks disabled).");
}
}
// Pop arguments
var arguments = <Object>[];
for (var i = 0; i < numberOfArguments; ++i) {
var poppedObj = state.popEvaluationStack() as Value;
var valueObj = poppedObj.valueObject;
arguments.add(valueObj);
}
// Reverse arguments from the order they were popped,
// so they're the right way round again.
arguments = arguments.reversed.toList();
// Run the function!
var funcResult = funcDef!.function?.call(arguments.toList());
// Convert return value (if any) to the a type that the ink engine can use
RuntimeObject? returnObj;
if (funcResult != null) {
returnObj = Value.create(funcResult);
assert(
returnObj != null,
'Could not create ink value from returned object of type ' +
funcResult.runtimeType.toString());
} else {
returnObj = RuntimeVoid();
}
state.pushEvaluationStack(returnObj!);
}