Object <- CodeHandler |
|
|
CodeBuffer CodePackage DataInitializationScript GlobalDataSize KeepMethodInformation MethodInformation |
| Field | Type | |
|---|---|---|
| CodeHandler: | codePackage: | CodePackageCluster |
Define Class CodeHandler; abstract; inherits from Object; field codePackage: CodePackageCluster, getter, setter, weak; attribute GlobalDataSize: Unsigned, readOnly; attribute CodePackage: CodePackageCluster; attribute CodeBuffer: Buffer, readOnly; attribute DataInitializationScript: Buffer, readOnly; attribute MethodInformation: Buffer, readOnly; attribute KeepMethodInformation: Boolean, readOnly; // returns false by default. Override and return true to prevent // the method information buffers from being destroyed. intrinsic CreateCodeHandler(package: CodePackageCluster; codeTypeFlags: Unsigned): CodeHandler; // This routine is called by package activation to create the appropriate t // type of code handler for the package. intrinsic FindUnresolvedCodeImports(packageCluster: CodePackageCluster): Text, noFail; // Look through the data-initialization script for any unresolved // imports. Return a new-line-separated list of clique names for // the imports that can't be resolved or nil if there are no missing // imports. It's legal to call this even when the code is not locked. // If a subclass adds additional data-initialization scripts that can have // unresolved imports, it needs to override this to process those as well. operation LockCode(), noFail; // This routine is used to lock down the code and allocate any additional // space needed, such as space for the code globals. Also, this routine // must use the EachCodeAddressInPackage routine to fix up classes and intrinsics to // point to the code in the new address it's locked down at. It may also // initialize some of the code globals. After calling this routine, the // package activation code can add the classes and intrinsics to the system // lists. Once that's done -- but no earlier -- we can initialize the special //?? // globals too, inside the InitializeCodeGlobals routine. // following four operations are the high level interface to initialize various categories // of package globals. This differentiation is necessary to insure patch package references // to methods being patched and intrinsics are correct. operation InitializeCodeGlobals(), noFail; // This routine initializes the special globals for the code. It may also //?? what should this comment say? // initialize the other globals as well -- they can be set up here or in // ActivateCode, whichever is more convenient to the implementation. operation InitializeGlobalsForReplacementPatchPass(), noFail; // This routine initializes only the special globals and replacement patched // globals, used by replacement patches to call through to the existing method or // prior patch. operation InitializeGlobalsForAugmentationPatchPass(), noFail; // This routine initializes only the special globals and augmentation patched // globals, used by augmentation patches to call through to the existing method or // prior patch. operation InitializeGlobalsForFinalPatchPass(), noFail; // This routine initializes only the special globals, and is called after all // patches to update their references to intrinsic methods that may have been // patched. // the following two operations are platform specific, to be overridden in subclasses. operation InitializePlatformSpecificGlobals(), noFail; // This routine is called by InitializeCodeGlobals to inititialize platform // specific globals, and is meant to be overridden by the subclass to perfrom // the actual work. operation SpecialGlobalsBaseAddress(): Pointer, noMethod; // This routine is called by each of the higher level global initialization // routines to get the operation UnlockCode(), noFail; // This routine is used to unlock the code. It calls DeactivateCode // to perform platform specific actions. operation EachPotentialObjectInCodeGlobals(function: EachFunction; parameters: Pointer): Object, noFail, noMethod; // Used by garbage collection to iterate through the globals of this code object. // Implemented by subclasses to call EachPotentialObjectInMemoryRange for each // range of globals. It's illegal to call this routine if the code is not locked. // The following operations are private and should only be used by subclasses. intrinsic LargestMethodIndex(methodInformation: Buffer): Unsigned; // returns a number as large or larger than the largest method index // found in the method information buffer. Used by fixup to tell // if the range of indexes overlaps with the range formed by the // target address and size of actual code. // currently this returns a constant, although it could be changed // to calculate the actual largest index if the constant value // causes there to always be an overlap and thus require two // pass renumbering in every case. operation TranslateMethodInformation(targetAddress: Pointer), noMethod; // called by LockCode to do the one-time translation of method information to // code addresses. operation ActivateCode(); // called by LockCode after the code buffer is locked down to do any platform specific // activation needed for the code. Default implementation does nothing and // does not need to be called in an override. operation DeactivateCode(); // called by UnlockCode before the code buffer is unlocked to do any platform specific // deactivation needed for the code. Default implementation does nothing and // does not need to be called in an override. operation TellDebuggerAboutPackage(); // called by LockCode after the code buffer is locked down to do any platform specific // debugger setup. Default implementation does nothing and // does not need to be called in an override. operation DestroyMethodInformation(); // called by LockCode once the method information is no longer needed and can be // destroyed. Override to do any platform specific cleanup of the method information // buffer. intrinsic InterpretDataInitializationScript( packageCluster: CodePackageCluster; filter: Unsigned; globalsBase: Pointer; codeBase: Pointer; constantsBase: Pointer; localLinkingPrefix: HasText; exportTable: PackageExportTable; eachCodeImportFunction: EachCodeImportFunction; parameters: Pointer): Boolean; // Low-level interface to the the data-initialization script interpreter. // Interprets the script. If <globalsBase> is nil, then it just // does an unresolved-imports check, putting the clique names of any // unresolved imports in the new-line separated list <missingCliqueNameList>. // If <globalsBase> is non-nil, then it actually initializes the globals. // If code or constant relocations are included in the script, then // <codeBase> or <constantBase> have to be passed in. Nil values // indicate that we don't expect those opcodes in the script, and make // such opcodes be considered errors. If the script is interpreted // successfully, the function returns true. If the script is being // run to check for unresolved imports, then the function still returns // true unless there are any other errors in the script. Existence of // unresolved imports can be detected by checking if <missingCliqueNameList> // is touched or not. The <exportTable> parameter can be used to check // for unresolved imports even before the package's own export table // has been added to the system. It will be checked after checking the // system so that imports that could be resolved within the same package // will not appear to be errors. This feature is normally used only when // checking a script, not when actually using it. operation AdjustCodeAddresses(codeAddress: Pointer; codeSize: Unsigned; oldCodeAddress: Pointer); // Subclasses call this to adjust all the code addresses in a package by a delta. // This is often useful after re-locking a package after moving it to a new address. // This uses the EachCodeAddressInPackage routine to do its work. overrides Init; // Store the data initialization script passed in as a New parameter. end class;