Browse Source

Fixes #945

- Adds `nil.isNil` to be able to easily compare nil objects from
different JS environments
- Fixes `ifNil:` inlining
Nicolas Petton 10 years ago
parent
commit
ca6c7d7e71
3 changed files with 13 additions and 3 deletions
  1. 2 2
      src/Compiler-Inlining.js
  2. 1 1
      src/Compiler-Inlining.st
  3. 10 0
      support/boot.js

+ 2 - 2
src/Compiler-Inlining.js

@@ -716,7 +716,7 @@ $ctx2.sendIdx["instructions"]=1;
 $4=_st($5)._first();
 self._visit_($4);
 $ctx2.sendIdx["visit:"]=1;
-return _st(self._stream())._nextPutAll_(") == nil || $receiver == null");
+return _st(self._stream())._nextPutAll_(") == null || $receiver.isNil");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}),(function(){
 return smalltalk.withContext(function($ctx2) {
 $7=_st(anIRInlinedIfNilIfNotNil)._instructions();
@@ -730,7 +730,7 @@ return self._visit_(_st(_st(anIRInlinedIfNilIfNotNil)._instructions())._third())
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,3)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRInlinedIfNilIfNotNil:",{anIRInlinedIfNilIfNotNil:anIRInlinedIfNilIfNotNil},globals.IRInliningJSTranslator)})},
 args: ["anIRInlinedIfNilIfNotNil"],
-source: "visitIRInlinedIfNilIfNotNil: anIRInlinedIfNilIfNotNil\x0a\x09self stream\x0a\x09\x09nextPutIfElse: [\x0a\x09\x09\x09self stream nextPutAll: '(', anIRInlinedIfNilIfNotNil receiverInternalVariableName, ' = '.\x0a\x09\x09\x09self visit: anIRInlinedIfNilIfNotNil instructions first.\x0a\x09\x09\x09self stream nextPutAll: ') == nil || $receiver == null' ]\x0a\x09\x09with: [ self visit: anIRInlinedIfNilIfNotNil instructions second ]\x0a\x09\x09with: [ self visit: anIRInlinedIfNilIfNotNil instructions third ]",
+source: "visitIRInlinedIfNilIfNotNil: anIRInlinedIfNilIfNotNil\x0a\x09self stream\x0a\x09\x09nextPutIfElse: [\x0a\x09\x09\x09self stream nextPutAll: '(', anIRInlinedIfNilIfNotNil receiverInternalVariableName, ' = '.\x0a\x09\x09\x09self visit: anIRInlinedIfNilIfNotNil instructions first.\x0a\x09\x09\x09self stream nextPutAll: ') == null || $receiver.isNil' ]\x0a\x09\x09with: [ self visit: anIRInlinedIfNilIfNotNil instructions second ]\x0a\x09\x09with: [ self visit: anIRInlinedIfNilIfNotNil instructions third ]",
 messageSends: ["nextPutIfElse:with:with:", "stream", "nextPutAll:", ",", "receiverInternalVariableName", "visit:", "first", "instructions", "second", "third"],
 referencedClasses: []
 }),

+ 1 - 1
src/Compiler-Inlining.st

@@ -281,7 +281,7 @@ visitIRInlinedIfNilIfNotNil: anIRInlinedIfNilIfNotNil
 		nextPutIfElse: [
 			self stream nextPutAll: '(', anIRInlinedIfNilIfNotNil receiverInternalVariableName, ' = '.
 			self visit: anIRInlinedIfNilIfNotNil instructions first.
-			self stream nextPutAll: ') == nil || $receiver == null' ]
+			self stream nextPutAll: ') == null || $receiver.isNil' ]
 		with: [ self visit: anIRInlinedIfNilIfNotNil instructions second ]
 		with: [ self visit: anIRInlinedIfNilIfNotNil instructions third ]
 !

+ 10 - 0
support/boot.js

@@ -114,6 +114,16 @@ define("amber_vm/boot", [ 'require', './browser-compatibility' ], function (requ
 		this.Object = SmalltalkObject;
 		this.nil = new SmalltalkNil();
 
+		// Adds an `isNil` property to the `nil` object.  When sending
+		// nil objects from one environment to another, doing
+		// `anObject == nil` (in JavaScript) does not always answer
+		// true as the referenced nil object might come from the other
+		// environment.
+		Object.defineProperty(this.nil, 'isNil', {
+			value: true,
+			enumerable: false, configurable: false, writable: false
+		});
+
 		// Hidden root class of the system.
 		this.rootAsClass = {fn: SmalltalkRoot};