| | 1 | = Understanding the apply path in the interpreter = |
| | 2 | |
| | 3 | Because the interpreter deals with dynamic type inference and dynamic |
| | 4 | overloading resolution, the path for applying a function can be rather |
| | 5 | twisty. |
| | 6 | |
| | 7 | Note in particular that the class `DottedMethodApplication` is used to |
| | 8 | represent a pending method application (ie a pair of receiver and the |
| | 9 | method applied to that receiver); this substantially simplifies the |
| | 10 | code to handle e.g. juxtaposition in the interpreter, but it's worth |
| | 11 | understanding that these objects are only closures in the sense that |
| | 12 | they're waiting to be applied to arguments just as a top-level |
| | 13 | function might be. |
| | 14 | |
| | 15 | Most function application in the interpreter goes via |
| | 16 | `EvaluatorBase.functionInvocation`, and thence to |
| | 17 | `applyPossiblyGeneric`. This deals with tupling / un-tupling of |
| | 18 | arguments and then calls through to `applyInnerPossiblyGeneric`, which |
| | 19 | is the method that gets specialized for the various sorts of closure |
| | 20 | (overloaded, method, generic, etc.). |
| | 21 | |
| | 22 | A concrete interpreted method or function eventually constructs a new environment |
| | 23 | for its arguments using `buildEnvFrom[EnvAnd]Params`. If the method |
| | 24 | or function is built in, it instead calls the built-in version using |
| | 25 | `applyToArgs` or `applyMethod` rather than building an env. |
| | 26 | |
| | 27 | A generic function or method undergoes type inference using |
| | 28 | `EvaluatorBase.inferAndInstantiateGenericFunction`; this computes the |
| | 29 | actual type parameters and creates a non-generic monomorphic `Simple_fcn` |
| | 30 | that can be invoked directly. |
| | 31 | |
| | 32 | An overloaded function or method attempts to find the most specific |
| | 33 | applicable overloading using `bestMatch` (which in turn calls |
| | 34 | `bestMatchInternal`). This includes instantiating any generic |
| | 35 | overloadings that might apply. |
| | 36 | |
| | 37 | A functional method must extract its `self` parameter, then call the |
| | 38 | corresponding (specially-named) dotted method to resolve any |
| | 39 | overloading or overriding that might have occurred. |
| | 40 | |
| | 41 | == Summary of functions on apply path == |
| | 42 | |
| | 43 | === `applyPossiblyGeneric` === |
| | 44 | Uses |
| | 45 | * `Driver.runProgramTask` |
| | 46 | * `Evaluator.invokeGenericMethod` (on `DottedMethodApplication`) |
| | 47 | * `Evaluator.handleException` (construct `forbiddenException`) |
| | 48 | * `EvaluatorBase.functionInvocation` (surrounding `setContext`) |
| | 49 | * `LHSEvaluator.forLValue` (invoke array constructor) |
| | 50 | * `SpawnTask.compute` |
| | 51 | * `DottedMethodApplication.invokeMethod` |
| | 52 | * `GenericFunctionOrConstructor` (after `inferAndInstantiateGenericFunction`) |
| | 53 | * `GenericSingleton.make` (invoke nullary constructor on instantiation) |
| | 54 | * `NonPrimitive.buildEnvFromParams` (invoke varargs factory) |
| | 55 | * `OverloadedFunction.applyInnerPossiblyGeneric` (invoke best match) |
| | 56 | * `Reflect.makeReflectedType` (invoke nullary Reflect constructor after instantiation) |
| | 57 | Defs |
| | 58 | * `Fcn`: unwrap, handle `UnificationError`, call `applyInnerPossiblyGeneric`. |
| | 59 | |
| | 60 | === `applyInnerPossiblyGeneric` === |
| | 61 | Uses |
| | 62 | * `Fcn`: `applyPossiblyGeneric` |
| | 63 | Defs |
| | 64 | * `Fcn`: abstract |
| | 65 | * `Dummy_fcn`: NYI (testing only) |
| | 66 | * `Constructor`: call thru to `applyConstructor` |
| | 67 | * `DottedMethodApplication`: `applyMethod` with `setContext` |
| | 68 | * `FunctionalMethod`: pull out self, `DottedMethodApplication.invokeMethod` |
| | 69 | * `FunctionClosure`: `applyToArgs` of native, else eval |
| | 70 | * `GenericFunctionOrConstructor`: `inferAndInstantiate`, then `applyPossiblyGeneric` |
| | 71 | * `MethodClosure`: check for functional-ness, `applyMethod` |
| | 72 | * `OverloadedFunction`: find best match, `applyPossiblyGeneric` |
| | 73 | |
| | 74 | === `applyMethod` === |
| | 75 | Uses |
| | 76 | * `DottedMethodApplication`: `applyInnerPossiblyGeneric` with `setContext` |
| | 77 | * `MethodClosure.applyInnerPossiblyGeneric`: chain for |
| | 78 | functional method invocation. |
| | 79 | * `OverloadedMethod.applyMethod`: get applicable method, `applyMethod` |
| | 80 | * `IndexedArrayWrapper.put`,get: apply putter,getter |
| | 81 | Defs |
| | 82 | * interface `Method` |
| | 83 | * `MethodClosure`: check for native, `applyMethod` or `buildEnvFromEnvAndParams` and eval |
| | 84 | * `OverloadedMethod`: get applicable method, `applyMethod` |
| | 85 | * `TraitMethodInstance`: `buildEnvFromEnvAndParams` and eval (not called?) |
| | 86 | * `NativeMeth`: call thru to `applyMethod` (2 args, no site/`envForInference`) |
| | 87 | |
| | 88 | === `buildEnvFromEnvAndParams` === |
| | 89 | Uses |
| | 90 | * `Constructor.applyConstructor` (`methodsEnv`) |
| | 91 | * `MethodClosure.applyMethod` (`envForApplication`) |
| | 92 | * `TraitMethodInstance.applyMethod` (`evaluationEnv`) |
| | 93 | Defs |
| | 94 | * `NonPrimitive` `(extendAt(getAt())`, pass to `buildEnvFromParams`) |
| | 95 | |
| | 96 | === `buildEnvFromParams` === |
| | 97 | Uses |
| | 98 | * `FunctionClosure.applyInnerPossiblyGeneric` |
| | 99 | Defs |
| | 100 | * `NonPrimitive` (def with, without env; uses within by default) |
| | 101 | |
| | 102 | === `bestMatch` === |
| | 103 | Uses |
| | 104 | * `OverloadJUTest` |
| | 105 | * `OverloadedFunction.applyInnerPossiblyGeneric` |
| | 106 | * `MethodClosure.getApplicableMethod` |
| | 107 | Defs |
| | 108 | * `OverloadedFunction`: calls `bestMatchInternal`, twice if no index is found. |
| | 109 | |
| | 110 | === `bestMatchInternal` === |
| | 111 | Uses |
| | 112 | * `OverloadedFunction.bestMatch` chains to |
| | 113 | Defs |
| | 114 | * `OverloadedFunction`: `inferAndInstantiateGenericFunction` for generic |
| | 115 | |
| | 116 | === `inferAndInstantiateGenericFunction` === |
| | 117 | Uses |
| | 118 | * `GenericFunctionOrConstructor.applyInnerPossiblyGeneric` |
| | 119 | * `OverloadedFunction.applyInnerPossiblyGeneric` (redundant w/`bestMatchInternal`!) |
| | 120 | * `OverloadedFunction.bestMatchInternal` |
| | 121 | Defs |
| | 122 | * `EvaluatorBase` (HUGE wad of code) |
| | 123 | |