@powerlang/egg-js
Version:
A Smalltalk VM that runs on top of JavaScript
92 lines (84 loc) • 2.87 kB
JavaScript
import EggEvaluator from './EggEvaluator.js';
import JSSExpressionTranspiler from './JSSExpressionTranspiler.js';
import NativeJSEvaluationContext from './NativeJSEvaluationContext.js';
import SMessage from './SMessage.js';
let EggNativeJSEvaluator = class extends EggEvaluator {
initializeExecutableCodeOf_(method) {
let sexpressions, js, executable;
sexpressions = this._runtime.sexpressionsOf_(method);
js = _cascade(JSSExpressionTranspiler.new(), (_recv) => {
_recv.evaluator_(this);
return _recv.nativize_(sexpressions);});
executable = this._runtime.newExecutableCodeFor_(js);
this._runtime.methodExecutableCode_put_(method, executable);
return executable;
}
lookup_startingAt_(anSMessage, aBehavior) {
let method, symbol;
const _home = {};
try {
method = anSMessage.methodFor_(aBehavior);
if (nil !== method)
{
return method
}
;
symbol = anSMessage.selector();
this._undermessages.at_ifPresent_(symbol, (block) => {
anSMessage.cacheUndermessage_(block);
throw [_home, block]
});
symbol = this._runtime.symbolFrom_(symbol);
method = this._runtime.lookup_startingAt_(symbol, aBehavior);
this.ASSERT_(method.notNil());
_cascade(anSMessage, (_recv) => {
_recv.registerCacheWith_(this._runtime);
return _recv.cache_when_(method, aBehavior);});
return method;
} catch(e) { if (e[0] == _home) return e[1]; else throw(e); }
}
send_super_to_with_(anSMessage, aBoolean, receiver, _arguments) {
let behavior, method, code, prev, result, _condition;
_condition = anSMessage.cachedUndermessage();
if (nil !== _condition)
{
let block;
block = _condition;
return block.value_value_(receiver, _arguments)
}
;
if (aBoolean)
{
behavior = this._runtime.superBehaviorOf_(this._context.classBinding())
} else {
behavior = this._runtime.behaviorOf_(receiver)
}
;
method = this.lookup_startingAt_(anSMessage, behavior);
if (method.class()._equalEqual(Function))
{
return method.value_value_(receiver, _arguments)
}
;
this.ASSERT_(method.notNil());
prev = this._context;
this._context = _cascade(NativeJSEvaluationContext.new(), (_recv) => {
_recv.runtime_(this._runtime);
_recv.self_(receiver);
_recv.arguments_(_arguments);
_recv.parent_(prev);
return _recv.method_(method);});
code = this.prepareExecutableCode_(method);
result = code.executeFor_in_(this, this._context);
this._context = prev;
return result;
}
sendLocal_to_with_(aSymbol, receiver, anArray) {
let symbol, res, message;
symbol = this._runtime.symbolFromLocal_(aSymbol);
message = SMessage.new().selector_(symbol);
res = this.send_super_to_with_(message, false, receiver, anArray);
return res;
}
}
export default EggNativeJSEvaluator