Browse Source

Merge branch 'master' into ast-interpreter

Conflicts:
	js/Compiler-IR.deploy.js
	js/Compiler-IR.js
	js/IDE.deploy.js
	js/IDE.js
	js/Kernel-Objects.deploy.js
	js/Kernel-Objects.js
Nicolas Petton 12 years ago
parent
commit
5fe3841359

+ 39 - 14
js/Compiler-AST.deploy.js

@@ -63,8 +63,8 @@ smalltalk.method({
 selector: "isImmutable",
 fn: function (){
 var self=this;
-return false;
-}
+return smalltalk.withContext(function($ctx1) { 
return false;
+}, self, "isImmutable", [], smalltalk.Node)}
 }),
 smalltalk.Node);
 
@@ -107,12 +107,13 @@ smalltalk.method({
 selector: "nodes",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@nodes"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@nodes"];
+if(($receiver = $2) == nil || $receiver == undefined){
 self["@nodes"]=_st((smalltalk.Array || Array))._new();
 $1=self["@nodes"];
 } else {
-$1=self["@nodes"];
+$1=$2;
 };
 return $1;
 }, self, "nodes", [], smalltalk.Node)}
@@ -136,12 +137,13 @@ smalltalk.method({
 selector: "position",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@position"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@position"];
+if(($receiver = $2) == nil || $receiver == undefined){
 self["@position"]=_st((0)).__at((0));
 $1=self["@position"];
 } else {
-$1=self["@position"];
+$1=$2;
 };
 return $1;
 }, self, "position", [], smalltalk.Node)}
@@ -165,11 +167,12 @@ smalltalk.method({
 selector: "shouldBeAliased",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@shouldBeAliased"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@shouldBeAliased"];
+if(($receiver = $2) == nil || $receiver == undefined){
 $1=false;
 } else {
-$1=self["@shouldBeAliased"];
+$1=$2;
 };
 return $1;
 }, self, "shouldBeAliased", [], smalltalk.Node)}
@@ -193,11 +196,12 @@ smalltalk.method({
 selector: "shouldBeInlined",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@shouldBeInlined"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@shouldBeInlined"];
+if(($receiver = $2) == nil || $receiver == undefined){
 $1=false;
 } else {
-$1=self["@shouldBeInlined"];
+$1=$2;
 };
 return $1;
 }, self, "shouldBeInlined", [], smalltalk.Node)}
@@ -215,6 +219,27 @@ return self}, self, "shouldBeInlined:", [aBoolean], smalltalk.Node)}
 }),
 smalltalk.Node);
 
+smalltalk.addMethod(
+"_subtreeNeedsAliasing",
+smalltalk.method({
+selector: "subtreeNeedsAliasing",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(_st(self)._shouldBeAliased())._or_((function(){
+return smalltalk.withContext(function($ctx2) { 
return _st(self)._shouldBeInlined();
+})})))._or_((function(){
+return smalltalk.withContext(function($ctx2) { 
return _st(_st(_st(self)._nodes())._detect_ifNone_((function(node){
+return smalltalk.withContext(function($ctx3) { 
return _st(node)._subtreeNeedsAliasing();
+})}),(function(){
+return smalltalk.withContext(function($ctx3) { 
return false;
+})}))).__tild_eq(false);
+})}));
+return $1;
+}, self, "subtreeNeedsAliasing", [], smalltalk.Node)}
+}),
+smalltalk.Node);
+
 
 
 smalltalk.addClass('AssignmentNode', smalltalk.Node, ['left', 'right'], 'Compiler-AST');

+ 44 - 14
js/Compiler-AST.js

@@ -90,8 +90,8 @@ selector: "isImmutable",
 category: 'testing',
 fn: function (){
 var self=this;
-return false;
-},
+return smalltalk.withContext(function($ctx1) { 
return false;
+}, self, "isImmutable", [], smalltalk.Node)},
 args: [],
 source: "isImmutable\x0a\x09^false",
 messageSends: [],
@@ -154,12 +154,13 @@ selector: "nodes",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@nodes"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@nodes"];
+if(($receiver = $2) == nil || $receiver == undefined){
 self["@nodes"]=_st((smalltalk.Array || Array))._new();
 $1=self["@nodes"];
 } else {
-$1=self["@nodes"];
+$1=$2;
 };
 return $1;
 }, self, "nodes", [], smalltalk.Node)},
@@ -193,12 +194,13 @@ selector: "position",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@position"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@position"];
+if(($receiver = $2) == nil || $receiver == undefined){
 self["@position"]=_st((0)).__at((0));
 $1=self["@position"];
 } else {
-$1=self["@position"];
+$1=$2;
 };
 return $1;
 }, self, "position", [], smalltalk.Node)},
@@ -232,11 +234,12 @@ selector: "shouldBeAliased",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@shouldBeAliased"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@shouldBeAliased"];
+if(($receiver = $2) == nil || $receiver == undefined){
 $1=false;
 } else {
-$1=self["@shouldBeAliased"];
+$1=$2;
 };
 return $1;
 }, self, "shouldBeAliased", [], smalltalk.Node)},
@@ -270,11 +273,12 @@ selector: "shouldBeInlined",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@shouldBeInlined"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@shouldBeInlined"];
+if(($receiver = $2) == nil || $receiver == undefined){
 $1=false;
 } else {
-$1=self["@shouldBeInlined"];
+$1=$2;
 };
 return $1;
 }, self, "shouldBeInlined", [], smalltalk.Node)},
@@ -301,6 +305,32 @@ referencedClasses: []
 }),
 smalltalk.Node);
 
+smalltalk.addMethod(
+"_subtreeNeedsAliasing",
+smalltalk.method({
+selector: "subtreeNeedsAliasing",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(_st(self)._shouldBeAliased())._or_((function(){
+return smalltalk.withContext(function($ctx2) { 
return _st(self)._shouldBeInlined();
+})})))._or_((function(){
+return smalltalk.withContext(function($ctx2) { 
return _st(_st(_st(self)._nodes())._detect_ifNone_((function(node){
+return smalltalk.withContext(function($ctx3) { 
return _st(node)._subtreeNeedsAliasing();
+})}),(function(){
+return smalltalk.withContext(function($ctx3) { 
return false;
+})}))).__tild_eq(false);
+})}));
+return $1;
+}, self, "subtreeNeedsAliasing", [], smalltalk.Node)},
+args: [],
+source: "subtreeNeedsAliasing\x0a    ^(self shouldBeAliased or: [ self shouldBeInlined ]) or: [\x0a        (self nodes detect: [ :node | node subtreeNeedsAliasing ] ifNone: [ false ]) ~= false\x0a    ]",
+messageSends: ["or:", "~=", "detect:ifNone:", "subtreeNeedsAliasing", "nodes", "shouldBeInlined", "shouldBeAliased"],
+referencedClasses: []
+}),
+smalltalk.Node);
+
 
 
 smalltalk.addClass('AssignmentNode', smalltalk.Node, ['left', 'right'], 'Compiler-AST');

+ 107 - 71
js/Compiler-IR.deploy.js

@@ -6,7 +6,7 @@ smalltalk.method({
 selector: "alias:",
 fn: function (aNode){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7;
 $ctx1.locals.variable=nil;
 $1=_st(aNode)._isImmutable();
 if(smalltalk.assert($1)){
@@ -23,7 +23,8 @@ _st($5)._add_(_st(self)._visit_(aNode));
 $6=_st($5)._yourself();
 _st(_st(self)._sequence())._add_($6);
 _st(_st(_st(self)._method())._internalVariables())._add_($ctx1.locals.variable);
-return $ctx1.locals.variable;
+$7=$ctx1.locals.variable;
+return $7;
 }, self, "alias:", [aNode], smalltalk.IRASTTranslator)}
 }),
 smalltalk.IRASTTranslator);
@@ -34,7 +35,9 @@ smalltalk.method({
 selector: "method",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self["@method"];
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@method"];
+return $1;
 }, self, "method", [], smalltalk.IRASTTranslator)}
 }),
 smalltalk.IRASTTranslator);
@@ -56,16 +59,17 @@ smalltalk.method({
 selector: "nextAlias",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@nextAlias"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=self["@nextAlias"];
+if(($receiver = $1) == nil || $receiver == undefined){
 self["@nextAlias"]=(0);
 self["@nextAlias"];
 } else {
-self["@nextAlias"];
+$1;
 };
 self["@nextAlias"]=_st(self["@nextAlias"]).__plus((1));
-$1=_st(self["@nextAlias"])._asString();
-return $1;
+$2=_st(self["@nextAlias"])._asString();
+return $2;
 }, self, "nextAlias", [], smalltalk.IRASTTranslator)}
 }),
 smalltalk.IRASTTranslator);
@@ -76,7 +80,9 @@ smalltalk.method({
 selector: "sequence",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self["@sequence"];
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@sequence"];
+return $1;
 }, self, "sequence", [], smalltalk.IRASTTranslator)}
 }),
 smalltalk.IRASTTranslator);
@@ -98,7 +104,9 @@ smalltalk.method({
 selector: "source",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self["@source"];
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@source"];
+return $1;
 }, self, "source", [], smalltalk.IRASTTranslator)}
 }),
 smalltalk.IRASTTranslator);
@@ -120,31 +128,34 @@ smalltalk.method({
 selector: "temporallyDependentList:",
 fn: function (nodes){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4,$6,$8,$7,$5,$9;
 $ctx1.locals.threshold=nil;
 $ctx1.locals.result=nil;
 $ctx1.locals.threshold=(0);
-_st(nodes)._withIndexDo_((function(each,i){
-return smalltalk.withContext(function($ctx2) { 
$1=_st(_st(each)._shouldBeInlined())._or_((function(){
-return smalltalk.withContext(function($ctx3) { 
return _st(each)._shouldBeAliased();
-})}));
-if(smalltalk.assert($1)){
+$1=nodes;
+$2=(function(each,i){
+return smalltalk.withContext(function($ctx2) { 
$3=_st(each)._subtreeNeedsAliasing();
+if(smalltalk.assert($3)){
 $ctx1.locals.threshold=i;
 return $ctx1.locals.threshold;
 };
-})}));
+})});
+_st($1)._withIndexDo_($2);
 $ctx1.locals.result=_st((smalltalk.OrderedCollection || OrderedCollection))._new();
-_st(nodes)._withIndexDo_((function(each,i){
-return smalltalk.withContext(function($ctx2) { 
$3=_st(i).__lt_eq($ctx1.locals.threshold);
-if(smalltalk.assert($3)){
-$2=_st(self)._alias_(each);
+$4=nodes;
+$5=(function(each,i){
+return smalltalk.withContext(function($ctx2) { 
$6=$ctx1.locals.result;
+$8=_st(i).__lt_eq($ctx1.locals.threshold);
+if(smalltalk.assert($8)){
+$7=_st(self)._alias_(each);
 } else {
-$2=_st(self)._visit_(each);
+$7=_st(self)._visit_(each);
 };
-return _st($ctx1.locals.result)._add_($2);
-})}));
-$4=$ctx1.locals.result;
-return $4;
+return _st($6)._add_($7);
+})});
+_st($4)._withIndexDo_($5);
+$9=$ctx1.locals.result;
+return $9;
 }, self, "temporallyDependentList:", [nodes], smalltalk.IRASTTranslator)}
 }),
 smalltalk.IRASTTranslator);
@@ -155,7 +166,9 @@ smalltalk.method({
 selector: "theClass",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self["@theClass"];
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@theClass"];
+return $1;
 }, self, "theClass", [], smalltalk.IRASTTranslator)}
 }),
 smalltalk.IRASTTranslator);
@@ -229,23 +242,28 @@ smalltalk.method({
 selector: "visitBlockSequenceNode:",
 fn: function (aNode){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$1;
-$1=_st(self)._withSequence_do_(_st((smalltalk.IRBlockSequence || IRBlockSequence))._new(),(function(){
-return smalltalk.withContext(function($ctx2) { 
return _st(_st(aNode)._nodes())._ifNotEmpty_((function(){
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$7,$8,$9,$6,$4,$1;
+$2=self;
+$3=_st((smalltalk.IRBlockSequence || IRBlockSequence))._new();
+$4=(function(){
+return smalltalk.withContext(function($ctx2) { 
$5=_st(aNode)._nodes();
+$6=(function(){
 return smalltalk.withContext(function($ctx3) { 
_st(_st(_st(aNode)._nodes())._allButLast())._do_((function(each){
 return smalltalk.withContext(function($ctx4) { 
return _st(_st(self)._sequence())._add_(_st(self)._visit_(each));
 })}));
-$2=_st(_st(_st(aNode)._nodes())._last())._isReturnNode();
-if(smalltalk.assert($2)){
+$7=_st(_st(_st(aNode)._nodes())._last())._isReturnNode();
+if(smalltalk.assert($7)){
 return _st(_st(self)._sequence())._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
 } else {
-$3=_st((smalltalk.IRBlockReturn || IRBlockReturn))._new();
-_st($3)._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
-$4=_st($3)._yourself();
-return _st(_st(self)._sequence())._add_($4);
+$8=_st((smalltalk.IRBlockReturn || IRBlockReturn))._new();
+_st($8)._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
+$9=_st($8)._yourself();
+return _st(_st(self)._sequence())._add_($9);
 };
-})}));
-})}));
+})});
+return _st($5)._ifNotEmpty_($6);
+})});
+$1=_st($2)._withSequence_do_($3,$4);
 return $1;
 }, self, "visitBlockSequenceNode:", [aNode], smalltalk.IRASTTranslator)}
 }),
@@ -285,8 +303,8 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $ctx1.locals.array=nil;
 $ctx1.locals.array=_st((smalltalk.IRDynamicArray || IRDynamicArray))._new();
-_st(_st(aNode)._nodes())._do_((function(each){
-return smalltalk.withContext(function($ctx2) { 
return _st($ctx1.locals.array)._add_(_st(self)._visit_(each));
+_st(_st(self)._temporallyDependentList_(_st(aNode)._nodes()))._do_((function(each){
+return smalltalk.withContext(function($ctx2) { 
return _st($ctx1.locals.array)._add_(each);
 })}));
 $1=$ctx1.locals.array;
 return $1;
@@ -303,8 +321,8 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $ctx1.locals.dictionary=nil;
 $ctx1.locals.dictionary=_st((smalltalk.IRDynamicDictionary || IRDynamicDictionary))._new();
-_st(_st(aNode)._nodes())._do_((function(each){
-return smalltalk.withContext(function($ctx2) { 
return _st($ctx1.locals.dictionary)._add_(_st(self)._visit_(each));
+_st(_st(self)._temporallyDependentList_(_st(aNode)._nodes()))._do_((function(each){
+return smalltalk.withContext(function($ctx2) { 
return _st($ctx1.locals.dictionary)._add_(each);
 })}));
 $1=$ctx1.locals.dictionary;
 return $1;
@@ -431,18 +449,23 @@ smalltalk.method({
 selector: "visitSequenceNode:",
 fn: function (aNode){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$1;
-$1=_st(self)._withSequence_do_(_st((smalltalk.IRSequence || IRSequence))._new(),(function(){
-return smalltalk.withContext(function($ctx2) { 
return _st(_st(aNode)._nodes())._do_((function(each){
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$7,$6,$4,$1;
+$2=self;
+$3=_st((smalltalk.IRSequence || IRSequence))._new();
+$4=(function(){
+return smalltalk.withContext(function($ctx2) { 
$5=_st(aNode)._nodes();
+$6=(function(each){
 return smalltalk.withContext(function($ctx3) { 
$ctx3.locals.instruction=nil;
 $ctx3.locals.instruction=_st(self)._visit_(each);
 $ctx3.locals.instruction;
-$2=_st($ctx3.locals.instruction)._isVariable();
-if(! smalltalk.assert($2)){
+$7=_st($ctx3.locals.instruction)._isVariable();
+if(! smalltalk.assert($7)){
 return _st(_st(self)._sequence())._add_($ctx3.locals.instruction);
 };
-})}));
-})}));
+})});
+return _st($5)._do_($6);
+})});
+$1=_st($2)._withSequence_do_($3,$4);
 return $1;
 }, self, "visitSequenceNode:", [aNode], smalltalk.IRASTTranslator)}
 }),
@@ -486,12 +509,14 @@ smalltalk.method({
 selector: "withSequence:do:",
 fn: function (aSequence,aBlock){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
$ctx1.locals.outerSequence=nil;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$ctx1.locals.outerSequence=nil;
 $ctx1.locals.outerSequence=_st(self)._sequence();
 _st(self)._sequence_(aSequence);
 _st(aBlock)._value();
 _st(self)._sequence_($ctx1.locals.outerSequence);
-return aSequence;
+$1=aSequence;
+return $1;
 }, self, "withSequence:do:", [aSequence,aBlock], smalltalk.IRASTTranslator)}
 }),
 smalltalk.IRASTTranslator);
@@ -543,12 +568,13 @@ smalltalk.method({
 selector: "instructions",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@instructions"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@instructions"];
+if(($receiver = $2) == nil || $receiver == undefined){
 self["@instructions"]=_st((smalltalk.OrderedCollection || OrderedCollection))._new();
 $1=self["@instructions"];
 } else {
-$1=self["@instructions"];
+$1=$2;
 };
 return $1;
 }, self, "instructions", [], smalltalk.IRInstruction)}
@@ -825,11 +851,12 @@ smalltalk.method({
 selector: "arguments",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@arguments"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@arguments"];
+if(($receiver = $2) == nil || $receiver == undefined){
 $1=[];
 } else {
-$1=self["@arguments"];
+$1=$2;
 };
 return $1;
 }, self, "arguments", [], smalltalk.IRClosure)}
@@ -953,12 +980,13 @@ smalltalk.method({
 selector: "internalVariables",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@internalVariables"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@internalVariables"];
+if(($receiver = $2) == nil || $receiver == undefined){
 self["@internalVariables"]=_st((smalltalk.Set || Set))._new();
 $1=self["@internalVariables"];
 } else {
-$1=self["@internalVariables"];
+$1=$2;
 };
 return $1;
 }, self, "internalVariables", [], smalltalk.IRMethod)}
@@ -1941,27 +1969,35 @@ smalltalk.method({
 selector: "visitIRMethod:",
 fn: function (anIRMethod){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
-_st(_st(self)._stream())._nextPutMethodDeclaration_with_(anIRMethod,(function(){
-return smalltalk.withContext(function($ctx2) { 
return _st(_st(self)._stream())._nextPutFunctionWith_arguments_((function(){
-return smalltalk.withContext(function($ctx3) { 
return _st(_st(self)._stream())._nextPutContextFor_during_(anIRMethod,(function(){
-return smalltalk.withContext(function($ctx4) { 
$1=_st(_st(anIRMethod)._internalVariables())._notEmpty();
-if(smalltalk.assert($1)){
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$6,$7,$9,$10,$8,$5,$3;
+$1=_st(self)._stream();
+$2=anIRMethod;
+$3=(function(){
+return smalltalk.withContext(function($ctx2) { 
$4=_st(self)._stream();
+$5=(function(){
+return smalltalk.withContext(function($ctx3) { 
$6=_st(self)._stream();
+$7=anIRMethod;
+$8=(function(){
+return smalltalk.withContext(function($ctx4) { 
$9=_st(_st(anIRMethod)._internalVariables())._notEmpty();
+if(smalltalk.assert($9)){
 _st(_st(self)._stream())._nextPutVars_(_st(_st(_st(anIRMethod)._internalVariables())._asArray())._collect_((function(each){
 return smalltalk.withContext(function($ctx5) { 
return _st(_st(each)._variable())._alias();
 })})));
 };
-$2=_st(_st(anIRMethod)._scope())._hasNonLocalReturn();
-if(smalltalk.assert($2)){
+$10=_st(_st(anIRMethod)._scope())._hasNonLocalReturn();
+if(smalltalk.assert($10)){
 return _st(_st(self)._stream())._nextPutNonLocalReturnHandlingWith_((function(){
 return smalltalk.withContext(function($ctx5) { 
return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 })}));
 } else {
 return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 };
-})}));
-})}),_st(anIRMethod)._arguments());
-})}));
+})});
+return _st($6)._nextPutContextFor_during_($7,$8);
+})});
+return _st($4)._nextPutFunctionWith_arguments_($5,_st(anIRMethod)._arguments());
+})});
+_st($1)._nextPutMethodDeclaration_with_($2,$3);
 return self}, self, "visitIRMethod:", [anIRMethod], smalltalk.IRJSTranslator)}
 }),
 smalltalk.IRJSTranslator);

+ 113 - 77
js/Compiler-IR.js

@@ -8,7 +8,7 @@ selector: "alias:",
 category: 'visiting',
 fn: function (aNode){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7;
 $ctx1.locals.variable=nil;
 $1=_st(aNode)._isImmutable();
 if(smalltalk.assert($1)){
@@ -25,7 +25,8 @@ _st($5)._add_(_st(self)._visit_(aNode));
 $6=_st($5)._yourself();
 _st(_st(self)._sequence())._add_($6);
 _st(_st(_st(self)._method())._internalVariables())._add_($ctx1.locals.variable);
-return $ctx1.locals.variable;
+$7=$ctx1.locals.variable;
+return $7;
 }, self, "alias:", [aNode], smalltalk.IRASTTranslator)},
 args: ["aNode"],
 source: "alias: aNode\x0a\x09| variable |\x0a\x0a\x09aNode isImmutable ifTrue: [ ^ self visit: aNode ].\x0a\x0a\x09variable := IRVariable new \x0a\x09\x09variable: (AliasVar new name: '$', self nextAlias); \x0a\x09\x09yourself.\x0a\x0a\x09self sequence add: (IRAssignment new\x0a\x09\x09add: variable;\x0a\x09\x09add: (self visit: aNode);\x0a\x09\x09yourself).\x0a\x0a\x09self method internalVariables add: variable.\x0a\x0a\x09^ variable",
@@ -41,7 +42,9 @@ selector: "method",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self["@method"];
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@method"];
+return $1;
 }, self, "method", [], smalltalk.IRASTTranslator)},
 args: [],
 source: "method\x0a\x09^ method",
@@ -73,16 +76,17 @@ selector: "nextAlias",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@nextAlias"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=self["@nextAlias"];
+if(($receiver = $1) == nil || $receiver == undefined){
 self["@nextAlias"]=(0);
 self["@nextAlias"];
 } else {
-self["@nextAlias"];
+$1;
 };
 self["@nextAlias"]=_st(self["@nextAlias"]).__plus((1));
-$1=_st(self["@nextAlias"])._asString();
-return $1;
+$2=_st(self["@nextAlias"])._asString();
+return $2;
 }, self, "nextAlias", [], smalltalk.IRASTTranslator)},
 args: [],
 source: "nextAlias\x0a\x09nextAlias ifNil: [ nextAlias := 0 ].\x0a\x09nextAlias := nextAlias + 1.\x0a\x09^ nextAlias asString",
@@ -98,7 +102,9 @@ selector: "sequence",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self["@sequence"];
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@sequence"];
+return $1;
 }, self, "sequence", [], smalltalk.IRASTTranslator)},
 args: [],
 source: "sequence\x0a\x09^ sequence",
@@ -130,7 +136,9 @@ selector: "source",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self["@source"];
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@source"];
+return $1;
 }, self, "source", [], smalltalk.IRASTTranslator)},
 args: [],
 source: "source\x0a\x09^ source",
@@ -162,35 +170,38 @@ selector: "temporallyDependentList:",
 category: 'visiting',
 fn: function (nodes){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4,$6,$8,$7,$5,$9;
 $ctx1.locals.threshold=nil;
 $ctx1.locals.result=nil;
 $ctx1.locals.threshold=(0);
-_st(nodes)._withIndexDo_((function(each,i){
-return smalltalk.withContext(function($ctx2) { 
$1=_st(_st(each)._shouldBeInlined())._or_((function(){
-return smalltalk.withContext(function($ctx3) { 
return _st(each)._shouldBeAliased();
-})}));
-if(smalltalk.assert($1)){
+$1=nodes;
+$2=(function(each,i){
+return smalltalk.withContext(function($ctx2) { 
$3=_st(each)._subtreeNeedsAliasing();
+if(smalltalk.assert($3)){
 $ctx1.locals.threshold=i;
 return $ctx1.locals.threshold;
 };
-})}));
+})});
+_st($1)._withIndexDo_($2);
 $ctx1.locals.result=_st((smalltalk.OrderedCollection || OrderedCollection))._new();
-_st(nodes)._withIndexDo_((function(each,i){
-return smalltalk.withContext(function($ctx2) { 
$3=_st(i).__lt_eq($ctx1.locals.threshold);
-if(smalltalk.assert($3)){
-$2=_st(self)._alias_(each);
+$4=nodes;
+$5=(function(each,i){
+return smalltalk.withContext(function($ctx2) { 
$6=$ctx1.locals.result;
+$8=_st(i).__lt_eq($ctx1.locals.threshold);
+if(smalltalk.assert($8)){
+$7=_st(self)._alias_(each);
 } else {
-$2=_st(self)._visit_(each);
+$7=_st(self)._visit_(each);
 };
-return _st($ctx1.locals.result)._add_($2);
-})}));
-$4=$ctx1.locals.result;
-return $4;
+return _st($6)._add_($7);
+})});
+_st($4)._withIndexDo_($5);
+$9=$ctx1.locals.result;
+return $9;
 }, self, "temporallyDependentList:", [nodes], smalltalk.IRASTTranslator)},
 args: ["nodes"],
-source: "temporallyDependentList: nodes\x0a\x09| threshold result |\x0a    threshold := 0.\x0a    \x0a    nodes withIndexDo: [ :each :i |\x0a        (each shouldBeInlined or: [ each shouldBeAliased ])\x0a\x09\x09    ifTrue: [ threshold := i ]].\x0a\x0a\x09result := OrderedCollection new.\x0a\x09nodes withIndexDo: [ :each :i | \x0a\x09\x09result add: (i <= threshold\x0a\x09\x09\x09ifTrue: [ self alias: each ]\x0a\x09\x09\x09ifFalse: [ self visit: each ])].\x0a\x0a    ^result",
-messageSends: ["withIndexDo:", "ifTrue:", "or:", "shouldBeAliased", "shouldBeInlined", "new", "add:", "ifTrue:ifFalse:", "alias:", "visit:", "<="],
+source: "temporallyDependentList: nodes\x0a\x09| threshold result |\x0a    threshold := 0.\x0a    \x0a    nodes withIndexDo: [ :each :i |\x0a        each subtreeNeedsAliasing\x0a\x09\x09    ifTrue: [ threshold := i ]].\x0a\x0a\x09result := OrderedCollection new.\x0a\x09nodes withIndexDo: [ :each :i | \x0a\x09\x09result add: (i <= threshold\x0a\x09\x09\x09ifTrue: [ self alias: each ]\x0a\x09\x09\x09ifFalse: [ self visit: each ])].\x0a\x0a    ^result",
+messageSends: ["withIndexDo:", "ifTrue:", "subtreeNeedsAliasing", "new", "add:", "ifTrue:ifFalse:", "alias:", "visit:", "<="],
 referencedClasses: ["OrderedCollection"]
 }),
 smalltalk.IRASTTranslator);
@@ -202,7 +213,9 @@ selector: "theClass",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self["@theClass"];
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@theClass"];
+return $1;
 }, self, "theClass", [], smalltalk.IRASTTranslator)},
 args: [],
 source: "theClass\x0a\x09^ theClass",
@@ -296,23 +309,28 @@ selector: "visitBlockSequenceNode:",
 category: 'visiting',
 fn: function (aNode){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$1;
-$1=_st(self)._withSequence_do_(_st((smalltalk.IRBlockSequence || IRBlockSequence))._new(),(function(){
-return smalltalk.withContext(function($ctx2) { 
return _st(_st(aNode)._nodes())._ifNotEmpty_((function(){
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$7,$8,$9,$6,$4,$1;
+$2=self;
+$3=_st((smalltalk.IRBlockSequence || IRBlockSequence))._new();
+$4=(function(){
+return smalltalk.withContext(function($ctx2) { 
$5=_st(aNode)._nodes();
+$6=(function(){
 return smalltalk.withContext(function($ctx3) { 
_st(_st(_st(aNode)._nodes())._allButLast())._do_((function(each){
 return smalltalk.withContext(function($ctx4) { 
return _st(_st(self)._sequence())._add_(_st(self)._visit_(each));
 })}));
-$2=_st(_st(_st(aNode)._nodes())._last())._isReturnNode();
-if(smalltalk.assert($2)){
+$7=_st(_st(_st(aNode)._nodes())._last())._isReturnNode();
+if(smalltalk.assert($7)){
 return _st(_st(self)._sequence())._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
 } else {
-$3=_st((smalltalk.IRBlockReturn || IRBlockReturn))._new();
-_st($3)._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
-$4=_st($3)._yourself();
-return _st(_st(self)._sequence())._add_($4);
+$8=_st((smalltalk.IRBlockReturn || IRBlockReturn))._new();
+_st($8)._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
+$9=_st($8)._yourself();
+return _st(_st(self)._sequence())._add_($9);
 };
-})}));
-})}));
+})});
+return _st($5)._ifNotEmpty_($6);
+})});
+$1=_st($2)._withSequence_do_($3,$4);
 return $1;
 }, self, "visitBlockSequenceNode:", [aNode], smalltalk.IRASTTranslator)},
 args: ["aNode"],
@@ -362,15 +380,15 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $ctx1.locals.array=nil;
 $ctx1.locals.array=_st((smalltalk.IRDynamicArray || IRDynamicArray))._new();
-_st(_st(aNode)._nodes())._do_((function(each){
-return smalltalk.withContext(function($ctx2) { 
return _st($ctx1.locals.array)._add_(_st(self)._visit_(each));
+_st(_st(self)._temporallyDependentList_(_st(aNode)._nodes()))._do_((function(each){
+return smalltalk.withContext(function($ctx2) { 
return _st($ctx1.locals.array)._add_(each);
 })}));
 $1=$ctx1.locals.array;
 return $1;
 }, self, "visitDynamicArrayNode:", [aNode], smalltalk.IRASTTranslator)},
 args: ["aNode"],
-source: "visitDynamicArrayNode: aNode\x0a\x09| array |\x0a\x09array := IRDynamicArray new.\x0a\x09aNode nodes do: [ :each | array add: (self visit: each) ].\x0a\x09^ array",
-messageSends: ["new", "do:", "add:", "visit:", "nodes"],
+source: "visitDynamicArrayNode: aNode\x0a\x09| array |\x0a\x09array := IRDynamicArray new.\x0a\x09(self temporallyDependentList: aNode nodes) do: [:each | array add: each].\x0a\x09^ array",
+messageSends: ["new", "do:", "add:", "temporallyDependentList:", "nodes"],
 referencedClasses: ["IRDynamicArray"]
 }),
 smalltalk.IRASTTranslator);
@@ -385,15 +403,15 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $ctx1.locals.dictionary=nil;
 $ctx1.locals.dictionary=_st((smalltalk.IRDynamicDictionary || IRDynamicDictionary))._new();
-_st(_st(aNode)._nodes())._do_((function(each){
-return smalltalk.withContext(function($ctx2) { 
return _st($ctx1.locals.dictionary)._add_(_st(self)._visit_(each));
+_st(_st(self)._temporallyDependentList_(_st(aNode)._nodes()))._do_((function(each){
+return smalltalk.withContext(function($ctx2) { 
return _st($ctx1.locals.dictionary)._add_(each);
 })}));
 $1=$ctx1.locals.dictionary;
 return $1;
 }, self, "visitDynamicDictionaryNode:", [aNode], smalltalk.IRASTTranslator)},
 args: ["aNode"],
-source: "visitDynamicDictionaryNode: aNode\x0a\x09| dictionary |\x0a\x09dictionary := IRDynamicDictionary new.\x0a\x09aNode nodes do: [ :each | dictionary add: (self visit: each) ].\x0a\x09^ dictionary",
-messageSends: ["new", "do:", "add:", "visit:", "nodes"],
+source: "visitDynamicDictionaryNode: aNode\x0a\x09| dictionary |\x0a\x09dictionary := IRDynamicDictionary new.\x0a    (self temporallyDependentList: aNode nodes) do: [:each | dictionary add: each].\x0a\x09^ dictionary",
+messageSends: ["new", "do:", "add:", "temporallyDependentList:", "nodes"],
 referencedClasses: ["IRDynamicDictionary"]
 }),
 smalltalk.IRASTTranslator);
@@ -538,18 +556,23 @@ selector: "visitSequenceNode:",
 category: 'visiting',
 fn: function (aNode){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$1;
-$1=_st(self)._withSequence_do_(_st((smalltalk.IRSequence || IRSequence))._new(),(function(){
-return smalltalk.withContext(function($ctx2) { 
return _st(_st(aNode)._nodes())._do_((function(each){
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$7,$6,$4,$1;
+$2=self;
+$3=_st((smalltalk.IRSequence || IRSequence))._new();
+$4=(function(){
+return smalltalk.withContext(function($ctx2) { 
$5=_st(aNode)._nodes();
+$6=(function(each){
 return smalltalk.withContext(function($ctx3) { 
$ctx3.locals.instruction=nil;
 $ctx3.locals.instruction=_st(self)._visit_(each);
 $ctx3.locals.instruction;
-$2=_st($ctx3.locals.instruction)._isVariable();
-if(! smalltalk.assert($2)){
+$7=_st($ctx3.locals.instruction)._isVariable();
+if(! smalltalk.assert($7)){
 return _st(_st(self)._sequence())._add_($ctx3.locals.instruction);
 };
-})}));
-})}));
+})});
+return _st($5)._do_($6);
+})});
+$1=_st($2)._withSequence_do_($3,$4);
 return $1;
 }, self, "visitSequenceNode:", [aNode], smalltalk.IRASTTranslator)},
 args: ["aNode"],
@@ -608,12 +631,14 @@ selector: "withSequence:do:",
 category: 'accessing',
 fn: function (aSequence,aBlock){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
$ctx1.locals.outerSequence=nil;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$ctx1.locals.outerSequence=nil;
 $ctx1.locals.outerSequence=_st(self)._sequence();
 _st(self)._sequence_(aSequence);
 _st(aBlock)._value();
 _st(self)._sequence_($ctx1.locals.outerSequence);
-return aSequence;
+$1=aSequence;
+return $1;
 }, self, "withSequence:do:", [aSequence,aBlock], smalltalk.IRASTTranslator)},
 args: ["aSequence", "aBlock"],
 source: "withSequence: aSequence do: aBlock\x0a\x09| outerSequence |\x0a\x09outerSequence := self sequence.\x0a\x09self sequence: aSequence.\x0a\x09aBlock value.\x0a\x09self sequence: outerSequence.\x0a\x09^ aSequence",
@@ -686,12 +711,13 @@ selector: "instructions",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@instructions"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@instructions"];
+if(($receiver = $2) == nil || $receiver == undefined){
 self["@instructions"]=_st((smalltalk.OrderedCollection || OrderedCollection))._new();
 $1=self["@instructions"];
 } else {
-$1=self["@instructions"];
+$1=$2;
 };
 return $1;
 }, self, "instructions", [], smalltalk.IRInstruction)},
@@ -1078,11 +1104,12 @@ selector: "arguments",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@arguments"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@arguments"];
+if(($receiver = $2) == nil || $receiver == undefined){
 $1=[];
 } else {
-$1=self["@arguments"];
+$1=$2;
 };
 return $1;
 }, self, "arguments", [], smalltalk.IRClosure)},
@@ -1257,12 +1284,13 @@ selector: "internalVariables",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-if(($receiver = self["@internalVariables"]) == nil || $receiver == undefined){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@internalVariables"];
+if(($receiver = $2) == nil || $receiver == undefined){
 self["@internalVariables"]=_st((smalltalk.Set || Set))._new();
 $1=self["@internalVariables"];
 } else {
-$1=self["@internalVariables"];
+$1=$2;
 };
 return $1;
 }, self, "internalVariables", [], smalltalk.IRMethod)},
@@ -2626,27 +2654,35 @@ selector: "visitIRMethod:",
 category: 'visiting',
 fn: function (anIRMethod){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
-_st(_st(self)._stream())._nextPutMethodDeclaration_with_(anIRMethod,(function(){
-return smalltalk.withContext(function($ctx2) { 
return _st(_st(self)._stream())._nextPutFunctionWith_arguments_((function(){
-return smalltalk.withContext(function($ctx3) { 
return _st(_st(self)._stream())._nextPutContextFor_during_(anIRMethod,(function(){
-return smalltalk.withContext(function($ctx4) { 
$1=_st(_st(anIRMethod)._internalVariables())._notEmpty();
-if(smalltalk.assert($1)){
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$6,$7,$9,$10,$8,$5,$3;
+$1=_st(self)._stream();
+$2=anIRMethod;
+$3=(function(){
+return smalltalk.withContext(function($ctx2) { 
$4=_st(self)._stream();
+$5=(function(){
+return smalltalk.withContext(function($ctx3) { 
$6=_st(self)._stream();
+$7=anIRMethod;
+$8=(function(){
+return smalltalk.withContext(function($ctx4) { 
$9=_st(_st(anIRMethod)._internalVariables())._notEmpty();
+if(smalltalk.assert($9)){
 _st(_st(self)._stream())._nextPutVars_(_st(_st(_st(anIRMethod)._internalVariables())._asArray())._collect_((function(each){
 return smalltalk.withContext(function($ctx5) { 
return _st(_st(each)._variable())._alias();
 })})));
 };
-$2=_st(_st(anIRMethod)._scope())._hasNonLocalReturn();
-if(smalltalk.assert($2)){
+$10=_st(_st(anIRMethod)._scope())._hasNonLocalReturn();
+if(smalltalk.assert($10)){
 return _st(_st(self)._stream())._nextPutNonLocalReturnHandlingWith_((function(){
 return smalltalk.withContext(function($ctx5) { 
return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 })}));
 } else {
 return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 };
-})}));
-})}),_st(anIRMethod)._arguments());
-})}));
+})});
+return _st($6)._nextPutContextFor_during_($7,$8);
+})});
+return _st($4)._nextPutFunctionWith_arguments_($5,_st(anIRMethod)._arguments());
+})});
+_st($1)._nextPutMethodDeclaration_with_($2,$3);
 return self}, self, "visitIRMethod:", [anIRMethod], smalltalk.IRJSTranslator)},
 args: ["anIRMethod"],
 source: "visitIRMethod: anIRMethod\x0a\x09self stream\x0a\x09\x09nextPutMethodDeclaration: anIRMethod \x0a\x09\x09with: [ self stream \x0a\x09\x09\x09nextPutFunctionWith: [ \x0a            \x09self stream nextPutContextFor: anIRMethod during: [\x0a\x09\x09\x09\x09anIRMethod internalVariables notEmpty ifTrue: [\x0a\x09\x09\x09\x09\x09self stream nextPutVars: (anIRMethod internalVariables asArray collect: [ :each |\x0a\x09\x09\x09\x09\x09\x09each variable alias ]) ].\x0a\x09\x09\x09\x09anIRMethod scope hasNonLocalReturn \x0a\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09self stream nextPutNonLocalReturnHandlingWith: [\x0a\x09\x09\x09\x09\x09\x09\x09super visitIRMethod: anIRMethod ]]\x0a\x09\x09\x09\x09\x09ifFalse: [ super visitIRMethod: anIRMethod ]]]\x0a\x09\x09\x09arguments: anIRMethod arguments ]",

+ 36 - 0
js/Compiler-Tests.deploy.js

@@ -112,6 +112,42 @@ return self}, self, "testCascades", [], smalltalk.CodeGeneratorTest)}
 }),
 smalltalk.CodeGeneratorTest);
 
+smalltalk.addMethod(
+"_testDynamicArrayElementsOrdered",
+smalltalk.method({
+selector: "testDynamicArrayElementsOrdered",
+fn: function (){
+var self=this;
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := 1.\x0a  ^ { x. true ifTrue: [ x := 2 ] }\x0a",[(1), (2)]]);
+return self}
+}),
+smalltalk.CodeGeneratorTest);
+
+smalltalk.addMethod(
+"_testDynamicDictionaryElementsOrdered",
+smalltalk.method({
+selector: "testDynamicDictionaryElementsOrdered",
+fn: function (){
+var self=this;
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := 'foo'->1.\x0a  ^ #{ x. (true ifTrue: [ x := 'bar'->2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[(1)]),smalltalk.send("bar","__minus_gt",[(2)])])]);
+return self}
+}),
+smalltalk.CodeGeneratorTest);
+
+smalltalk.addMethod(
+"_testInnerTemporalDependentElementsOrdered",
+smalltalk.method({
+selector: "testInnerTemporalDependentElementsOrdered",
+fn: function (){
+var self=this;
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := Array.\x0a  ^ x with: 'foo'->x with: 'bar'->(true ifTrue: [ x := 2 ])\x0a",[smalltalk.send("foo","__minus_gt",[(smalltalk.Array || Array)]),smalltalk.send("bar","__minus_gt",[(2)])]]);
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := 1.\x0a  ^ Array with: 'foo'->x with: 'bar'->(true ifTrue: [ x := 2 ])\x0a",[smalltalk.send("foo","__minus_gt",[(1)]),smalltalk.send("bar","__minus_gt",[(2)])]]);
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := 1.\x0a  ^ { 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",[smalltalk.send("foo","__minus_gt",[(1)]),smalltalk.send("bar","__minus_gt",[(2)])]]);
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := 1.\x0a  ^ #{ 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[(1)]),smalltalk.send("bar","__minus_gt",[(2)])])]);
+return self}
+}),
+smalltalk.CodeGeneratorTest);
+
 smalltalk.addMethod(
 "_testLiterals",
 smalltalk.method({

+ 51 - 0
js/Compiler-Tests.js

@@ -157,6 +157,57 @@ referencedClasses: []
 }),
 smalltalk.CodeGeneratorTest);
 
+smalltalk.addMethod(
+"_testDynamicArrayElementsOrdered",
+smalltalk.method({
+selector: "testDynamicArrayElementsOrdered",
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := 1.\x0a  ^ { x. true ifTrue: [ x := 2 ] }\x0a",[(1), (2)]]);
+return self},
+args: [],
+source: "testDynamicArrayElementsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ { x. true ifTrue: [ x := 2 ] }\x0a' return: #(1 2).\x0a",
+messageSends: ["should:return:"],
+referencedClasses: []
+}),
+smalltalk.CodeGeneratorTest);
+
+smalltalk.addMethod(
+"_testDynamicDictionaryElementsOrdered",
+smalltalk.method({
+selector: "testDynamicDictionaryElementsOrdered",
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := 'foo'->1.\x0a  ^ #{ x. (true ifTrue: [ x := 'bar'->2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[(1)]),smalltalk.send("bar","__minus_gt",[(2)])])]);
+return self},
+args: [],
+source: "testDynamicDictionaryElementsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := ''foo''->1.\x0a  ^ #{ x. (true ifTrue: [ x := ''bar''->2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.\x0a",
+messageSends: ["should:return:", "->"],
+referencedClasses: []
+}),
+smalltalk.CodeGeneratorTest);
+
+smalltalk.addMethod(
+"_testInnerTemporalDependentElementsOrdered",
+smalltalk.method({
+selector: "testInnerTemporalDependentElementsOrdered",
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := Array.\x0a  ^ x with: 'foo'->x with: 'bar'->(true ifTrue: [ x := 2 ])\x0a",[smalltalk.send("foo","__minus_gt",[(smalltalk.Array || Array)]),smalltalk.send("bar","__minus_gt",[(2)])]]);
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := 1.\x0a  ^ Array with: 'foo'->x with: 'bar'->(true ifTrue: [ x := 2 ])\x0a",[smalltalk.send("foo","__minus_gt",[(1)]),smalltalk.send("bar","__minus_gt",[(2)])]]);
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := 1.\x0a  ^ { 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",[smalltalk.send("foo","__minus_gt",[(1)]),smalltalk.send("bar","__minus_gt",[(2)])]]);
+smalltalk.send(self,"_should_return_",["foo\x0a  | x |\x0a  x := 1.\x0a  ^ #{ 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_([smalltalk.send("foo","__minus_gt",[(1)]),smalltalk.send("bar","__minus_gt",[(2)])])]);
+return self},
+args: [],
+source: "testInnerTemporalDependentElementsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := Array.\x0a  ^ x with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])\x0a' return: {'foo'->Array. 'bar'->2}.\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ Array with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])\x0a' return: {'foo'->1. 'bar'->2}.\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ { ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }\x0a' return: {'foo'->1. 'bar'->2}.\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ #{ ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.\x0a",
+messageSends: ["should:return:", "->"],
+referencedClasses: ["Array"]
+}),
+smalltalk.CodeGeneratorTest);
+
 smalltalk.addMethod(
 "_testLiterals",
 smalltalk.method({

+ 0 - 22
js/IDE.deploy.js

@@ -2801,28 +2801,6 @@ return self}, self, "updateTabsList", [], smalltalk.Browser)}
 smalltalk.Browser);
 
 
-smalltalk.addMethod(
-"_commitPathJs",
-smalltalk.method({
-selector: "commitPathJs",
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
return "js";
-}, self, "commitPathJs", [], smalltalk.Browser.klass)}
-}),
-smalltalk.Browser.klass);
-
-smalltalk.addMethod(
-"_commitPathSt",
-smalltalk.method({
-selector: "commitPathSt",
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
return "st";
-}, self, "commitPathSt", [], smalltalk.Browser.klass)}
-}),
-smalltalk.Browser.klass);
-
 smalltalk.addMethod(
 "_open",
 smalltalk.method({

+ 0 - 32
js/IDE.js

@@ -3541,38 +3541,6 @@ referencedClasses: []
 smalltalk.Browser);
 
 
-smalltalk.addMethod(
-"_commitPathJs",
-smalltalk.method({
-selector: "commitPathJs",
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
return "js";
-}, self, "commitPathJs", [], smalltalk.Browser.klass)},
-args: [],
-source: "commitPathJs\x0a\x09^'js'",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Browser.klass);
-
-smalltalk.addMethod(
-"_commitPathSt",
-smalltalk.method({
-selector: "commitPathSt",
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
return "st";
-}, self, "commitPathSt", [], smalltalk.Browser.klass)},
-args: [],
-source: "commitPathSt\x0a\x09^'st'",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Browser.klass);
-
 smalltalk.addMethod(
 "_open",
 smalltalk.method({

+ 72 - 0
js/Kernel-Tests.deploy.js

@@ -261,6 +261,65 @@ return self}, self, "testIfTrueIfFalse", [], smalltalk.BooleanTest)}
 }),
 smalltalk.BooleanTest);
 
+smalltalk.addMethod(
+"_testIfTrueIfFalseWithBoxing",
+smalltalk.method({
+selector: "testIfTrueIfFalseWithBoxing",
+fn: function (){
+var self=this;
+var $2,$1,$4,$3,$6,$5,$8,$7,$10,$9,$12,$11,$14,$13,$16,$15;
+$2=smalltalk.send(true,"_boxed",[]);
+if(smalltalk.assert($2)){
+$1="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($1,"__eq",["alternative block"])]);
+$4=smalltalk.send(true,"_boxed",[]);
+if(! smalltalk.assert($4)){
+$3="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($3,"__eq",[nil])]);
+$6=smalltalk.send(false,"_boxed",[]);
+if(smalltalk.assert($6)){
+$5="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($5,"__eq",[nil])]);
+$8=smalltalk.send(false,"_boxed",[]);
+if(! smalltalk.assert($8)){
+$7="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($7,"__eq",["alternative block"])]);
+$10=smalltalk.send(false,"_boxed",[]);
+if(smalltalk.assert($10)){
+$9="alternative block";
+} else {
+$9="alternative block2";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($9,"__eq",["alternative block2"])]);
+$12=smalltalk.send(false,"_boxed",[]);
+if(smalltalk.assert($12)){
+$11="alternative block2";
+} else {
+$11="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($11,"__eq",["alternative block"])]);
+$14=smalltalk.send(true,"_boxed",[]);
+if(smalltalk.assert($14)){
+$13="alternative block";
+} else {
+$13="alternative block2";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($13,"__eq",["alternative block"])]);
+$16=smalltalk.send(true,"_boxed",[]);
+if(smalltalk.assert($16)){
+$15="alternative block2";
+} else {
+$15="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($15,"__eq",["alternative block2"])]);
+return self}
+}),
+smalltalk.BooleanTest);
+
 smalltalk.addMethod(
 "_testLogic",
 smalltalk.method({
@@ -2727,3 +2786,16 @@ smalltalk.UndefinedTest);
 
 
 
+smalltalk.addMethod(
+"_boxed",
+smalltalk.method({
+selector: "boxed",
+fn: function (){
+var self=this;
+var $1;
+$1=self;
+return $1;
+}
+}),
+smalltalk.Boolean);
+

+ 82 - 0
js/Kernel-Tests.js

@@ -321,6 +321,70 @@ referencedClasses: []
 }),
 smalltalk.BooleanTest);
 
+smalltalk.addMethod(
+"_testIfTrueIfFalseWithBoxing",
+smalltalk.method({
+selector: "testIfTrueIfFalseWithBoxing",
+category: 'tests',
+fn: function (){
+var self=this;
+var $2,$1,$4,$3,$6,$5,$8,$7,$10,$9,$12,$11,$14,$13,$16,$15;
+$2=smalltalk.send(true,"_boxed",[]);
+if(smalltalk.assert($2)){
+$1="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($1,"__eq",["alternative block"])]);
+$4=smalltalk.send(true,"_boxed",[]);
+if(! smalltalk.assert($4)){
+$3="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($3,"__eq",[nil])]);
+$6=smalltalk.send(false,"_boxed",[]);
+if(smalltalk.assert($6)){
+$5="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($5,"__eq",[nil])]);
+$8=smalltalk.send(false,"_boxed",[]);
+if(! smalltalk.assert($8)){
+$7="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($7,"__eq",["alternative block"])]);
+$10=smalltalk.send(false,"_boxed",[]);
+if(smalltalk.assert($10)){
+$9="alternative block";
+} else {
+$9="alternative block2";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($9,"__eq",["alternative block2"])]);
+$12=smalltalk.send(false,"_boxed",[]);
+if(smalltalk.assert($12)){
+$11="alternative block2";
+} else {
+$11="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($11,"__eq",["alternative block"])]);
+$14=smalltalk.send(true,"_boxed",[]);
+if(smalltalk.assert($14)){
+$13="alternative block";
+} else {
+$13="alternative block2";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($13,"__eq",["alternative block"])]);
+$16=smalltalk.send(true,"_boxed",[]);
+if(smalltalk.assert($16)){
+$15="alternative block2";
+} else {
+$15="alternative block";
+};
+smalltalk.send(self,"_assert_",[smalltalk.send($15,"__eq",["alternative block2"])]);
+return self},
+args: [],
+source: "testIfTrueIfFalseWithBoxing\x0a \x0a\x09self assert: (true boxed ifTrue: ['alternative block']) = 'alternative block'.\x0a\x09self assert: (true boxed ifFalse: ['alternative block']) = nil.\x0a\x0a\x09self assert: (false boxed ifTrue: ['alternative block']) = nil.\x0a\x09self assert: (false boxed ifFalse: ['alternative block']) = 'alternative block'.\x0a\x0a\x09self assert: (false boxed ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block2'.\x0a\x09self assert: (false boxed ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block'.\x0a\x0a\x09self assert: (true boxed ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block'.\x0a\x09self assert: (true boxed ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block2'.",
+messageSends: ["assert:", "=", "ifTrue:", "boxed", "ifFalse:", "ifTrue:ifFalse:", "ifFalse:ifTrue:"],
+referencedClasses: []
+}),
+smalltalk.BooleanTest);
+
 smalltalk.addMethod(
 "_testLogic",
 smalltalk.method({
@@ -3537,3 +3601,21 @@ smalltalk.UndefinedTest);
 
 
 
+smalltalk.addMethod(
+"_boxed",
+smalltalk.method({
+selector: "boxed",
+category: '*Kernel-Tests',
+fn: function (){
+var self=this;
+var $1;
+$1=self;
+return $1;
+},
+args: [],
+source: "boxed\x0a\x09^self",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Boolean);
+

+ 13 - 3
js/amber.js

@@ -103,13 +103,14 @@ amber = (function() {
 		}
 
 		var additionalFiles = spec.packages || spec.files;
+        var commitPathForInit = null;
 		if (additionalFiles) {
-			loadPackages(additionalFiles, spec.prefix, spec.packageHome);
+			commitPathForInit = loadPackages(additionalFiles, spec.prefix, spec.packageHome);
 		}
 
 		// Be sure to setup & initialize smalltalk classes
 		addJSToLoad('init.js');
-		initializeSmalltalk();
+		initializeSmalltalk(commitPathForInit);
 	};
 
 	function loadPackages(names, prefix, urlHome){
@@ -121,6 +122,11 @@ amber = (function() {
 			name = names[i].split(/\.js$/)[0];
 			addJSToLoad(name + '.js', prefix, urlHome);
 		}
+
+        return  {
+            js: urlHome+prefix,
+            st: urlHome+'st'
+        };
 	};
 
 	function addJSToLoad(name, prefix, urlHome) {
@@ -175,8 +181,12 @@ amber = (function() {
 	};
 
 	// This will be called after JS files have been loaded
-	function initializeSmalltalk() {
+	function initializeSmalltalk(commitPath) {
 		window.smalltalkReady = function() {
+            if (commitPath) {
+                smalltalk['@@commitPath'] = commitPath;
+                smalltalk.Package._commitPathsFromLoader();
+            }
 			if (spec.ready) {
 				spec.ready();
 			};

+ 1 - 1
js/boot.js

@@ -738,7 +738,7 @@ function Smalltalk() {
     /* Boolean assertion */
     st.assert = function(shouldBeBoolean) {
         if ((undefined !== shouldBeBoolean) && (shouldBeBoolean.klass === smalltalk.Boolean)) {
-            return shouldBeBoolean;
+            return shouldBeBoolean == true;
         } else {
             smalltalk.NonBooleanReceiver._new()._object_(shouldBeBoolean)._signal();
         }

+ 6 - 0
st/Compiler-AST.st

@@ -35,6 +35,12 @@ shouldBeInlined
 
 shouldBeInlined: aBoolean
 	shouldBeInlined := aBoolean
+!
+
+subtreeNeedsAliasing
+    ^(self shouldBeAliased or: [ self shouldBeInlined ]) or: [
+        (self nodes detect: [ :node | node subtreeNeedsAliasing ] ifNone: [ false ]) ~= false
+    ]
 ! !
 
 !Node methodsFor: 'building'!

+ 3 - 3
st/Compiler-IR.st

@@ -81,7 +81,7 @@ temporallyDependentList: nodes
     threshold := 0.
     
     nodes withIndexDo: [ :each :i |
-        (each shouldBeInlined or: [ each shouldBeAliased ])
+        each subtreeNeedsAliasing
 		    ifTrue: [ threshold := i ]].
 
 	result := OrderedCollection new.
@@ -148,14 +148,14 @@ visitCascadeNode: aNode
 visitDynamicArrayNode: aNode
 	| array |
 	array := IRDynamicArray new.
-	aNode nodes do: [ :each | array add: (self visit: each) ].
+	(self temporallyDependentList: aNode nodes) do: [:each | array add: each].
 	^ array
 !
 
 visitDynamicDictionaryNode: aNode
 	| dictionary |
 	dictionary := IRDynamicDictionary new.
-	aNode nodes do: [ :each | dictionary add: (self visit: each) ].
+    (self temporallyDependentList: aNode nodes) do: [:each | dictionary add: each].
 	^ dictionary
 !
 

+ 39 - 0
st/Compiler-Tests.st

@@ -62,6 +62,45 @@ testCascades
 	self should: 'foo ^ Array new add: 3; add: 4; yourself' return: #(3 4)
 !
 
+testDynamicArrayElementsOrdered
+	self should: 'foo
+  | x |
+  x := 1.
+  ^ { x. true ifTrue: [ x := 2 ] }
+' return: #(1 2).
+!
+
+testDynamicDictionaryElementsOrdered
+	self should: 'foo
+  | x |
+  x := ''foo''->1.
+  ^ #{ x. (true ifTrue: [ x := ''bar''->2 ]) }
+' return: #{'foo'->1. 'bar'->2}.
+!
+
+testInnerTemporalDependentElementsOrdered
+	self should: 'foo
+  | x |
+  x := Array.
+  ^ x with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])
+' return: {'foo'->Array. 'bar'->2}.
+	self should: 'foo
+  | x |
+  x := 1.
+  ^ Array with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])
+' return: {'foo'->1. 'bar'->2}.
+	self should: 'foo
+  | x |
+  x := 1.
+  ^ { ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }
+' return: {'foo'->1. 'bar'->2}.
+	self should: 'foo
+  | x |
+  x := 1.
+  ^ #{ ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }
+' return: #{'foo'->1. 'bar'->2}.
+!
+
 testLiterals
 	self should: 'foo ^ 1' return: 1.
 	self should: 'foo ^ ''hello''' return: 'hello'.

+ 0 - 10
st/IDE.st

@@ -1292,16 +1292,6 @@ updateTabsList
 	    onClick: [self selectTab: #comment]]
 ! !
 
-!Browser class methodsFor: 'accessing'!
-
-commitPathJs
-	^'js'
-!
-
-commitPathSt
-	^'st'
-! !
-
 !Browser class methodsFor: 'convenience'!
 
 open

+ 21 - 0
st/Kernel-Tests.st

@@ -121,6 +121,21 @@ testIfTrueIfFalse
 	self assert: (true ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block2'.
 !
 
+testIfTrueIfFalseWithBoxing
+ 
+	self assert: (true boxed ifTrue: ['alternative block']) = 'alternative block'.
+	self assert: (true boxed ifFalse: ['alternative block']) = nil.
+
+	self assert: (false boxed ifTrue: ['alternative block']) = nil.
+	self assert: (false boxed ifFalse: ['alternative block']) = 'alternative block'.
+
+	self assert: (false boxed ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block2'.
+	self assert: (false boxed ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block'.
+
+	self assert: (true boxed ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block'.
+	self assert: (true boxed ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block2'.
+!
+
 testLogic
  
 	"Trivial logic table"
@@ -1413,3 +1428,9 @@ testIsNil
 	self deny: nil notNil.
 ! !
 
+!Boolean methodsFor: '*Kernel-Tests'!
+
+boxed
+	^self
+! !
+