@powerlang/egg-js
Version:
A Smalltalk VM that runs on top of JavaScript
299 lines (247 loc) • 6.16 kB
JavaScript
import ClosureElementTypes from './ClosureElementTypes.js';
import EggIterativeStackedInterpreter from './EggIterativeStackedInterpreter.js';
import TreecodeDecoder from './TreecodeDecoder.js';
let EggRuntime = class {
constructor() {
this._methodCache = nil;
this._falseObj = nil;
this._trueObj = nil;
this._nilObj = nil;
this._interpreter = nil;
this._overrides = nil;
this._symbolCache = nil;
this._doesNotUnderstandMethod = nil;
}
argumentCountOf_(code) {
let _retval;
if (this.isBlock_(code))
{
_retval = this.blockArgumentCount_(code)
} else {
_retval = this.methodArgumentCount_(code)
}
;
return _retval;
}
behaviorOf_(anObject) {
return this.subclassResponsibility();
}
booleanFor_(aBoolean) {
let _retval;
if (aBoolean)
{
_retval = this._trueObj
} else {
_retval = this._falseObj
}
;
return _retval;
}
booleanFrom_(anObject) {
if (anObject._equalEqual(this._falseObj))
{
return false
}
;
if (anObject._equalEqual(this._trueObj))
{
return true
}
;
this.error_("not a boolean");
return this;
}
doesNotUnderstandMethod() {
return this._doesNotUnderstandMethod;
}
evaluatePrimitiveHash_(receiver) {
let hash;
hash = receiver.headerHash();
if (hash._equal(0))
{
hash = this.nextHash();
receiver.headerHash_(hash)
}
;
return this.newInteger_(hash);
}
executableCodeWork_(code) {
return this.subclassResponsibility();
}
extensionMethodModule_(method) {
this.subclassResponsibility();
return this;
}
false() {
return this._falseObj;
}
flushDispatchCache_(aSymbol) {
let cached;
this._symbolCache.at_ifPresent_(aSymbol, (messages) => {
return messages.do_((m) => {
return m.flushCache()
})
});
cached = this._methodCache.keys().select_((key) => {
return key.key()._equalEqual(aSymbol)
});
cached.do_((key) => {
return this._methodCache.removeKey_(key)
});
return this;
}
flushDispatchCache_in_(aSymbol, _class) {
let behavior;
behavior = this.speciesInstanceBehavior_(_class);
this._symbolCache.at_ifPresent_(aSymbol, (messages) => {
return messages.do_((m) => {
return m.flushCache()
})
});
return this._methodCache.removeKey_ifAbsent_(aSymbol._arrow(behavior), () => {
return nil
});
}
initialize() {
this._methodCache = Map.new();
this._symbolCache = Map.new();
this._overrides = Map.new();
return this;
}
initializeInterpreter() {
this._interpreter = EggIterativeStackedInterpreter.new().runtime_(this);
return this;
}
instanceVarOf_at_(receiver, anInteger) {
return receiver.slotAt_(anInteger);
}
instanceVarOf_at_put_(receiver, anInteger, value) {
return receiver.slotAt_put_(anInteger, value);
}
interpreter() {
return this._interpreter;
}
isClosure_(anObject) {
return this.subclassResponsibility();
}
literalFor_(anObject) {
return anObject;
}
localMethodTreecodes_(method) {
return this.subclassResponsibility();
}
localSymbolFrom_(anObject) {
return anObject.bytes().allButLast().asString().asSymbol();
}
lookup_startingAt_(aSymbol, aBehavior) {
return this._methodCache.at_ifAbsentPut_(aSymbol._arrow(aBehavior), () => {
return this.doLookup_startingAt_(aSymbol, aBehavior)
});
}
methodClassBinding_(method) {
return this.subclassResponsibility();
}
methodEnvironmentSize_(anObject) {
return this.subclassResponsibility();
}
methodIsExtension_(method) {
this.subclassResponsibility();
return this;
}
methodModule_(method) {
let species, _retval;
if (this.methodIsExtension_(method))
{
_retval = this.extensionMethodModule_(method)
} else {
species = this.methodClassBinding_(method);
_retval = this.speciesModule_(species)
}
;
return _retval;
}
methodTreecodes_(method) {
return this.subclassResponsibility();
}
newBootstrapDictionaryOf_(receiver) {
return this.subclassResponsibility();
}
newBytesOf_sized_(receiver, size) {
return this.subclassResponsibility();
}
newClosureFor_(compiledBlock) {
return this.subclassResponsibility();
}
newEnvironmentSized_(anInteger) {
return this.subclassResponsibility();
}
newExecutableCodeFor_(anObject) {
return this.subclassResponsibility();
}
newInteger_(anInteger) {
return this.subclassResponsibility();
}
newOf_sized_(receiver, size) {
return this.subclassResponsibility();
}
newSlotsOf_(receiver) {
return this.subclassResponsibility();
}
nil() {
return this._nilObj;
}
registerCache_for_(anSMessage, symbol) {
let messages;
messages = this._symbolCache.at_ifAbsentPut_(symbol, () => {
return Array.new()
});
messages.add_(anSMessage);
return this;
}
sendLocal_to_(aSymbol, receiver) {
return this.sendLocal_to_with_(aSymbol, receiver, []);
}
sendLocal_to_with_(aSymbol, receiver, anArray) {
return this._interpreter.sendLocal_to_with_(aSymbol, receiver, anArray);
}
sexpressionsOf_(method) {
let treecodes, decoder;
treecodes = this.localMethodTreecodes_(method);
decoder = _cascade(TreecodeDecoder.new(), (_recv) => {
_recv.stream_(treecodes.readStream());
_recv.method_(method);
return _recv.builder_(this);});
return decoder.decodeMethod();
}
speciesFor_(anObject) {
return this.subclassResponsibility();
}
speciesInstanceBehavior_(_class) {
return this.subclassResponsibility();
}
speciesModule_(method) {
this.subclassResponsibility();
return this;
}
symbolFrom_(anObject) {
return anObject;
}
symbolFromLocal_(aSymbol) {
return this.subclassResponsibility();
}
temporaryCountOf_(anEggObject) {
let _retval;
if (this.isBlock_(anEggObject))
{
_retval = this.blockTempCount_(anEggObject)
} else {
_retval = this.methodTempCount_(anEggObject)
}
;
return _retval;
}
true() {
return this._trueObj;
}
}
export default EggRuntime