|
@@ -313,15 +313,13 @@ function Smalltalk(){
|
|
|
If the receiver does not understand the selector, call its #doesNotUnderstand: method */
|
|
|
|
|
|
sendWithoutContext = function(receiver, selector, args, klass) {
|
|
|
- if(receiver === undefined || receiver === null) {
|
|
|
+ if(receiver == null) {
|
|
|
receiver = nil;
|
|
|
}
|
|
|
- if(!klass && receiver.klass && receiver[selector]) {
|
|
|
- return receiver[selector].apply(receiver, args);
|
|
|
- } else if(klass && klass.fn.prototype[selector]) {
|
|
|
- return klass.fn.prototype[selector].apply(receiver, args)
|
|
|
- }
|
|
|
- return messageNotUnderstood(receiver, selector, args);
|
|
|
+ var imp = klass ? klass.fn.prototype[selector] : receiver.klass && receiver[selector];
|
|
|
+ return imp
|
|
|
+ ? imp.apply(receiver, args)
|
|
|
+ : messageNotUnderstood(receiver, selector, args);
|
|
|
};
|
|
|
|
|
|
|
|
@@ -346,24 +344,23 @@ function Smalltalk(){
|
|
|
|
|
|
/* Same as sendWithoutContext but creates a methodContext. */
|
|
|
|
|
|
- withContextSend = function(receiver, selector, args, klass) {
|
|
|
- var call, context;
|
|
|
- if(receiver === undefined || receiver === null) {
|
|
|
+ function withContextSend(receiver, selector, args, klass) {
|
|
|
+ var call, context, imp;
|
|
|
+ if(receiver == null) {
|
|
|
receiver = nil;
|
|
|
}
|
|
|
- if(!klass && receiver.klass && receiver[selector]) {
|
|
|
- context = pushContext(receiver, selector, args);
|
|
|
- call = receiver[selector].apply(receiver, args);
|
|
|
- popContext(context);
|
|
|
- return call;
|
|
|
- } else if(klass && klass.fn.prototype[selector]) {
|
|
|
+ imp = klass ? klass.fn.prototype[selector] : receiver.klass && receiver[selector];
|
|
|
+ if(imp) {
|
|
|
context = pushContext(receiver, selector, args);
|
|
|
- call = klass.fn.prototype[selector].apply(receiver, args);
|
|
|
- popContext(context);
|
|
|
+ call = imp.apply(receiver, args);
|
|
|
+ st.thisContext = context.homeContext;
|
|
|
+ context.homeContext = undefined;
|
|
|
+ st.oldContext = context;
|
|
|
return call;
|
|
|
+ } else {
|
|
|
+ return messageNotUnderstood(receiver, selector, args);
|
|
|
}
|
|
|
- return messageNotUnderstood(receiver, selector, args);
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
/* Handles Smalltalk errors. Triggers the registered ErrorHandler
|
|
|
(See the Smalltalk class ErrorHandler and its subclasses */
|
|
@@ -424,9 +421,9 @@ function Smalltalk(){
|
|
|
};
|
|
|
|
|
|
|
|
|
- /* Reuse old contexts stored in oldContexts */
|
|
|
+ /* Reuse one old context stored in oldContext */
|
|
|
|
|
|
- st.oldContexts = [];
|
|
|
+ st.oldContext = null;
|
|
|
|
|
|
|
|
|
/* Handle thisContext pseudo variable */
|
|
@@ -434,24 +431,23 @@ function Smalltalk(){
|
|
|
st.getThisContext = function() {
|
|
|
if(st.thisContext) {
|
|
|
return st.thisContext.copy();
|
|
|
- } else {
|
|
|
+ }/* else { // this is the default
|
|
|
return undefined;
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
- pushContext = function(receiver, selector, temps) {
|
|
|
- if(st.thisContext) {
|
|
|
- return st.thisContext = st.thisContext.newContext(receiver, selector, temps);
|
|
|
- } else {
|
|
|
- return st.thisContext = new SmalltalkMethodContext(receiver, selector, temps);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- popContext = function(context) {
|
|
|
- if(context) {
|
|
|
- context.removeYourself();
|
|
|
+ function pushContext(receiver, selector, temps) {
|
|
|
+ var c = st.oldContext, tc = st.thisContext;
|
|
|
+ if (!c) {
|
|
|
+ return st.thisContext = new SmalltalkMethodContext(receiver, selector, temps, tc);
|
|
|
}
|
|
|
- };
|
|
|
+ st.oldContext = null;
|
|
|
+ c.homeContext = tc;
|
|
|
+ c.receiver = receiver;
|
|
|
+ c.selector = selector;
|
|
|
+ c.temps = temps || {};
|
|
|
+ return st.thisContext = c;
|
|
|
+ }
|
|
|
|
|
|
/* Convert a string to a valid smalltalk selector.
|
|
|
if you modify the following functions, also change String>>asSelector
|
|
@@ -517,43 +513,23 @@ function Smalltalk(){
|
|
|
}
|
|
|
|
|
|
function SmalltalkMethodContext(receiver, selector, temps, home) {
|
|
|
- var that = this;
|
|
|
- that.receiver = receiver;
|
|
|
- that.selector = selector;
|
|
|
- that.temps = temps || {};
|
|
|
- that.homeContext = home;
|
|
|
-
|
|
|
- that.copy = function() {
|
|
|
- var home = that.homeContext;
|
|
|
- if(home) {home = home.copy()}
|
|
|
- return new SmalltalkMethodContext(
|
|
|
- that.receiver,
|
|
|
- that.selector,
|
|
|
- that.temps,
|
|
|
- home
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- that.newContext = function(receiver, selector, temps) {
|
|
|
- var c = smalltalk.oldContexts.pop();
|
|
|
- if(c) {
|
|
|
- c.homeContext = that;
|
|
|
- c.receiver = receiver;
|
|
|
- c.selector = selector;
|
|
|
- c.temps = temps || {};
|
|
|
- } else {
|
|
|
- c = new SmalltalkMethodContext(receiver, selector, temps, that);
|
|
|
- }
|
|
|
- return c;
|
|
|
- }
|
|
|
-
|
|
|
- that.removeYourself = function() {
|
|
|
- smalltalk.thisContext = that.homeContext;
|
|
|
- that.homeContext = undefined;
|
|
|
- smalltalk.oldContexts.push(that);
|
|
|
- }
|
|
|
+ this.receiver = receiver;
|
|
|
+ this.selector = selector;
|
|
|
+ this.temps = temps || {};
|
|
|
+ this.homeContext = home;
|
|
|
}
|
|
|
|
|
|
+SmalltalkMethodContext.prototype.copy = function() {
|
|
|
+ var home = this.homeContext;
|
|
|
+ if(home) {home = home.copy()}
|
|
|
+ return new SmalltalkMethodContext(
|
|
|
+ this.receiver,
|
|
|
+ this.selector,
|
|
|
+ this.temps,
|
|
|
+ home
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
/* Global Smalltalk objects. */
|
|
|
|
|
|
var nil = new SmalltalkNil();
|