Browse Source

ProtoObject super send now ends with DNU. Fix #1206.

Herbert Vojčík 8 years ago
parent
commit
8d1e8b7487
5 changed files with 215 additions and 37 deletions
  1. 68 30
      src/Compiler-IR.js
  2. 16 6
      src/Compiler-IR.st
  3. 107 0
      src/Compiler-Tests.js
  4. 23 0
      src/Compiler-Tests.st
  5. 1 1
      support/boot.js

+ 68 - 30
src/Compiler-IR.js

@@ -2746,6 +2746,40 @@ messageSends: []
 }),
 $globals.IRSend);
 
+$core.addMethod(
+$core.method({
+selector: "initialize",
+protocol: 'initialization',
+fn: function (){
+var self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+(
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.supercall = true, 
+//>>excludeEnd("ctx");
+$globals.IRSend.superclass.fn.prototype._initialize.apply($recv(self), []));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.supercall = false;
+//>>excludeEnd("ctx");;
+self["@classSend"]=false;
+self["@index"]=nil;
+self["@selector"]=nil;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"initialize",{},$globals.IRSend)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x0a\x09classSend := false.\x0a\x09index := nil.\x0a\x09selector := nil",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["initialize"]
+}),
+$globals.IRSend);
+
 $core.addMethod(
 $core.method({
 selector: "isSend",
@@ -4182,14 +4216,14 @@ selector: "visitIRSend:",
 protocol: 'visiting',
 fn: function (anIRSend){
 var self=this;
-var sends;
+var sends,superclass;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-var $1,$2,$receiver;
+var $1,$2;
 sends=$recv($recv($recv($recv(anIRSend)._method())._sendIndexes())._at_($recv(anIRSend)._selector()))._size();
-$1=$recv(anIRSend)._classSend();
-if(($receiver = $1) == null || $receiver.isNil){
+$1=$recv($recv(anIRSend)._classSend()).__eq(false);
+if($core.assert($1)){
 self._visitSend_(anIRSend);
 } else {
 self._visitSuperSend_(anIRSend);
@@ -4208,15 +4242,15 @@ $recv(self._stream())._nextPutSendIndexFor_(anIRSend);
 };
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"visitIRSend:",{anIRSend:anIRSend,sends:sends},$globals.IRJSTranslator)});
+}, function($ctx1) {$ctx1.fill(self,"visitIRSend:",{anIRSend:anIRSend,sends:sends,superclass:superclass},$globals.IRJSTranslator)});
 //>>excludeEnd("ctx");
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["anIRSend"],
-source: "visitIRSend: anIRSend\x0a\x09| sends |\x0a\x09sends := (anIRSend method sendIndexes at: anIRSend selector) size.\x0a\x09\x0a\x09anIRSend classSend\x0a\x09\x09ifNil: [ self visitSend: anIRSend ]\x0a\x09\x09ifNotNil: [ self visitSuperSend: anIRSend ].\x0a\x09\x09\x0a\x09(sends > 1 and: [ anIRSend index < sends ])\x0a\x09\x09ifTrue: [ self stream nextPutSendIndexFor: anIRSend ]",
+source: "visitIRSend: anIRSend\x0a\x09| sends superclass |\x0a\x09sends := (anIRSend method sendIndexes at: anIRSend selector) size.\x0a\x09\x0a\x09anIRSend classSend = false\x0a\x09\x09ifTrue: [ self visitSend: anIRSend ]\x0a\x09\x09ifFalse: [ self visitSuperSend: anIRSend ].\x0a\x09\x09\x0a\x09(sends > 1 and: [ anIRSend index < sends ])\x0a\x09\x09ifTrue: [ self stream nextPutSendIndexFor: anIRSend ]",
 referencedClasses: [],
 //>>excludeEnd("ide");
-messageSends: ["size", "at:", "sendIndexes", "method", "selector", "ifNil:ifNotNil:", "classSend", "visitSend:", "visitSuperSend:", "ifTrue:", "and:", ">", "<", "index", "nextPutSendIndexFor:", "stream"]
+messageSends: ["size", "at:", "sendIndexes", "method", "selector", "ifTrue:ifFalse:", "=", "classSend", "visitSend:", "visitSuperSend:", "ifTrue:", "and:", ">", "<", "index", "nextPutSendIndexFor:", "stream"]
 }),
 $globals.IRJSTranslator);
 
@@ -4504,7 +4538,7 @@ var self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-var $1,$4,$3,$2,$5,$6,$8,$7,$9,$10,$11;
+var $1,$4,$3,$2,$5,$6,$7,$9,$8,$10,$11,$12;
 $1=self._stream();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["stream"]=1;
@@ -4553,40 +4587,44 @@ $recv($1)._lf();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["lf"]=4;
 //>>excludeEnd("ctx");
-$recv($1)._nextPutAll_($recv(self._currentClass())._asJavascript());
+$5="(".__comma($recv(self._currentClass())._asJavascript());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx[","]=2;
+//>>excludeEnd("ctx");
+$recv($1)._nextPutAll_($5);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=5;
 //>>excludeEnd("ctx");
-$recv($1)._nextPutAll_(".superclass.fn.prototype.");
+$recv($1)._nextPutAll_(".superclass||$boot.dnu).fn.prototype.");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=6;
 //>>excludeEnd("ctx");
-$5=$recv($recv($recv(anIRSend)._selector())._asJavaScriptMethodName()).__comma(".apply(");
+$6=$recv($recv($recv(anIRSend)._selector())._asJavaScriptMethodName()).__comma(".apply(");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx[","]=2;
+$ctx1.sendIdx[","]=3;
 //>>excludeEnd("ctx");
-$recv($1)._nextPutAll_($5);
+$recv($1)._nextPutAll_($6);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=7;
 //>>excludeEnd("ctx");
-$6=$recv($1)._nextPutAll_("$recv(");
+$7=$recv($1)._nextPutAll_("$recv(");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=8;
 //>>excludeEnd("ctx");
-$8=$recv(anIRSend)._instructions();
+$9=$recv(anIRSend)._instructions();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["instructions"]=1;
 //>>excludeEnd("ctx");
-$7=$recv($8)._first();
-self._visit_($7);
+$8=$recv($9)._first();
+self._visit_($8);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["visit:"]=1;
 //>>excludeEnd("ctx");
-$9=self._stream();
+$10=self._stream();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["stream"]=2;
 //>>excludeEnd("ctx");
-$recv($9)._nextPutAll_("), [");
+$recv($10)._nextPutAll_("), [");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=9;
 //>>excludeEnd("ctx");
@@ -4602,11 +4640,11 @@ return self._visit_(each);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx2) {
 //>>excludeEnd("ctx");
-$10=self._stream();
+$11=self._stream();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx2.sendIdx["stream"]=3;
 //>>excludeEnd("ctx");
-return $recv($10)._nextPutAll_(",");
+return $recv($11)._nextPutAll_(",");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx2.sendIdx["nextPutAll:"]=10;
 //>>excludeEnd("ctx");
@@ -4614,29 +4652,29 @@ $ctx2.sendIdx["nextPutAll:"]=10;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)});
 //>>excludeEnd("ctx");
 }));
-$11=self._stream();
-$recv($11)._nextPutAll_("]));");
+$12=self._stream();
+$recv($12)._nextPutAll_("]));");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=11;
 //>>excludeEnd("ctx");
-$recv($11)._lf();
+$recv($12)._lf();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["lf"]=5;
 //>>excludeEnd("ctx");
-$recv($11)._nextPutAll_("//>>excludeStart(\x22ctx\x22, pragmas.excludeDebugContexts);");
+$recv($12)._nextPutAll_("//>>excludeStart(\x22ctx\x22, pragmas.excludeDebugContexts);");
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=12;
 //>>excludeEnd("ctx");
-$recv($11)._lf();
+$recv($12)._lf();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["lf"]=6;
 //>>excludeEnd("ctx");
-$recv($11)._nextPutAll_($recv($recv($recv(anIRSend)._scope())._alias()).__comma(".supercall = false;"));
+$recv($12)._nextPutAll_($recv($recv($recv(anIRSend)._scope())._alias()).__comma(".supercall = false;"));
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nextPutAll:"]=13;
 //>>excludeEnd("ctx");
-$recv($11)._lf();
-$recv($11)._nextPutAll_("//>>excludeEnd(\x22ctx\x22);");
+$recv($12)._lf();
+$recv($12)._nextPutAll_("//>>excludeEnd(\x22ctx\x22);");
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 }, function($ctx1) {$ctx1.fill(self,"visitSuperSend:",{anIRSend:anIRSend},$globals.IRJSTranslator)});
@@ -4644,7 +4682,7 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["anIRSend"],
-source: "visitSuperSend: anIRSend\x0a\x09self stream\x0a\x09\x09nextPutAll: '('; lf;\x0a\x09\x09nextPutAll: '//>>excludeStart(\x22ctx\x22, pragmas.excludeDebugContexts);'; lf;\x0a\x09\x09nextPutAll: anIRSend scope alias, '.supercall = true, '; lf;\x0a\x09\x09nextPutAll: '//>>excludeEnd(\x22ctx\x22);'; lf;\x0a\x09\x09nextPutAll: self currentClass asJavascript;\x0a\x09\x09nextPutAll: '.superclass.fn.prototype.';\x0a\x09\x09nextPutAll: anIRSend selector asJavaScriptMethodName, '.apply(';\x0a\x09\x09nextPutAll: '$recv('.\x0a\x09self visit: anIRSend instructions first.\x0a\x09self stream nextPutAll: '), ['.\x0a\x09anIRSend instructions allButFirst\x0a\x09\x09do: [ :each | self visit: each ]\x0a\x09\x09separatedBy: [ self stream nextPutAll: ',' ].\x0a\x09self stream \x0a\x09\x09nextPutAll: ']));'; lf;\x0a\x09\x09nextPutAll: '//>>excludeStart(\x22ctx\x22, pragmas.excludeDebugContexts);'; lf;\x0a\x09\x09nextPutAll: anIRSend scope alias, '.supercall = false;'; lf;\x0a\x09\x09nextPutAll: '//>>excludeEnd(\x22ctx\x22);'",
+source: "visitSuperSend: anIRSend\x0a\x09self stream\x0a\x09\x09nextPutAll: '('; lf;\x0a\x09\x09nextPutAll: '//>>excludeStart(\x22ctx\x22, pragmas.excludeDebugContexts);'; lf;\x0a\x09\x09nextPutAll: anIRSend scope alias, '.supercall = true, '; lf;\x0a\x09\x09nextPutAll: '//>>excludeEnd(\x22ctx\x22);'; lf;\x0a\x09\x09nextPutAll: '(', self currentClass asJavascript;\x0a\x09\x09nextPutAll: '.superclass||$boot.dnu).fn.prototype.';\x0a\x09\x09nextPutAll: anIRSend selector asJavaScriptMethodName, '.apply(';\x0a\x09\x09nextPutAll: '$recv('.\x0a\x09self visit: anIRSend instructions first.\x0a\x09self stream nextPutAll: '), ['.\x0a\x09anIRSend instructions allButFirst\x0a\x09\x09do: [ :each | self visit: each ]\x0a\x09\x09separatedBy: [ self stream nextPutAll: ',' ].\x0a\x09self stream \x0a\x09\x09nextPutAll: ']));'; lf;\x0a\x09\x09nextPutAll: '//>>excludeStart(\x22ctx\x22, pragmas.excludeDebugContexts);'; lf;\x0a\x09\x09nextPutAll: anIRSend scope alias, '.supercall = false;'; lf;\x0a\x09\x09nextPutAll: '//>>excludeEnd(\x22ctx\x22);'",
 referencedClasses: [],
 //>>excludeEnd("ide");
 messageSends: ["nextPutAll:", "stream", "lf", ",", "alias", "scope", "asJavascript", "currentClass", "asJavaScriptMethodName", "selector", "visit:", "first", "instructions", "do:separatedBy:", "allButFirst"]

+ 16 - 6
src/Compiler-IR.st

@@ -691,6 +691,16 @@ selector: aString
 	selector := aString
 ! !
 
+!IRSend methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+
+	classSend := false.
+	index := nil.
+	selector := nil
+! !
+
 !IRSend methodsFor: 'testing'!
 
 isSend
@@ -996,12 +1006,12 @@ visitIRReturn: anIRReturn
 !
 
 visitIRSend: anIRSend
-	| sends |
+	| sends superclass |
 	sends := (anIRSend method sendIndexes at: anIRSend selector) size.
 	
-	anIRSend classSend
-		ifNil: [ self visitSend: anIRSend ]
-		ifNotNil: [ self visitSuperSend: anIRSend ].
+	anIRSend classSend = false
+		ifTrue: [ self visitSend: anIRSend ]
+		ifFalse: [ self visitSuperSend: anIRSend ].
 		
 	(sends > 1 and: [ anIRSend index < sends ])
 		ifTrue: [ self stream nextPutSendIndexFor: anIRSend ]
@@ -1057,8 +1067,8 @@ visitSuperSend: anIRSend
 		nextPutAll: '//>>excludeStart("ctx", pragmas.excludeDebugContexts);'; lf;
 		nextPutAll: anIRSend scope alias, '.supercall = true, '; lf;
 		nextPutAll: '//>>excludeEnd("ctx");'; lf;
-		nextPutAll: self currentClass asJavascript;
-		nextPutAll: '.superclass.fn.prototype.';
+		nextPutAll: '(', self currentClass asJavascript;
+		nextPutAll: '.superclass||$boot.dnu).fn.prototype.';
 		nextPutAll: anIRSend selector asJavaScriptMethodName, '.apply(';
 		nextPutAll: '$recv('.
 	self visit: anIRSend instructions first.

+ 107 - 0
src/Compiler-Tests.js

@@ -508,6 +508,69 @@ messageSends: ["new"]
 }),
 $globals.CodeGeneratorTest);
 
+$core.addMethod(
+$core.method({
+selector: "should:receiver:raise:",
+protocol: 'testing',
+fn: function (aString,anObject,anErrorClass){
+var self=this;
+var method,result;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$2,$3,$receiver;
+self["@receiver"]=anObject;
+$recv((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return self._should_raise_((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx3) {
+//>>excludeEnd("ctx");
+$1=self._compiler();
+$2=$recv(anObject)._class();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx3.sendIdx["class"]=1;
+//>>excludeEnd("ctx");
+method=$recv($1)._install_forClass_protocol_(aString,$2,"tests");
+method;
+return $recv(self["@receiver"])._perform_($recv(method)._selector());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)});
+//>>excludeEnd("ctx");
+}),anErrorClass);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
+//>>excludeEnd("ctx");
+}))._ensure_((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+$3=method;
+if(($receiver = $3) == null || $receiver.isNil){
+return $3;
+} else {
+return $recv($recv(anObject)._class())._removeCompiledMethod_(method);
+};
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,3)});
+//>>excludeEnd("ctx");
+}));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"should:receiver:raise:",{aString:aString,anObject:anObject,anErrorClass:anErrorClass,method:method,result:result},$globals.CodeGeneratorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aString", "anObject", "anErrorClass"],
+source: "should: aString receiver: anObject raise: anErrorClass\x0a\x09| method result |\x0a\x0a\x09receiver := anObject.\x0a\x09[ self should: [\x0a\x09\x09method := self compiler install: aString forClass: anObject class protocol: 'tests'.\x0a\x09\x09receiver perform: method selector ] raise: anErrorClass ]\x0a\x09ensure: [ method ifNotNil: [ anObject class removeCompiledMethod: method ] ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["ensure:", "should:raise:", "install:forClass:protocol:", "compiler", "class", "perform:", "selector", "ifNotNil:", "removeCompiledMethod:"]
+}),
+$globals.CodeGeneratorTest);
+
 $core.addMethod(
 $core.method({
 selector: "should:receiver:return:",
@@ -1284,6 +1347,32 @@ messageSends: ["should:return:", "at:", "globals"]
 }),
 $globals.CodeGeneratorTest);
 
+$core.addMethod(
+$core.method({
+selector: "testRootSuperSend",
+protocol: 'tests',
+fn: function (){
+var self=this;
+function $ProtoObject(){return $globals.ProtoObject||(typeof ProtoObject=="undefined"?nil:ProtoObject)}
+function $MessageNotUnderstood(){return $globals.MessageNotUnderstood||(typeof MessageNotUnderstood=="undefined"?nil:MessageNotUnderstood)}
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+self._should_receiver_raise_("foo ^ super class",$recv($ProtoObject())._new(),$MessageNotUnderstood());
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testRootSuperSend",{},$globals.CodeGeneratorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootSuperSend\x0a\x09self \x0a\x09\x09should: 'foo ^ super class' \x0a\x09\x09receiver: ProtoObject new\x0a\x09\x09raise: MessageNotUnderstood",
+referencedClasses: ["ProtoObject", "MessageNotUnderstood"],
+//>>excludeEnd("ide");
+messageSends: ["should:receiver:raise:", "new"]
+}),
+$globals.CodeGeneratorTest);
+
 $core.addMethod(
 $core.method({
 selector: "testSendReceiverAndArgumentsOrdered",
@@ -1865,6 +1954,24 @@ messageSends: ["assert:equals:", "interpret:receiver:withArguments:"]
 }),
 $globals.ASTInterpreterTest);
 
+$core.addMethod(
+$core.method({
+selector: "testRootSuperSend",
+protocol: 'tests',
+fn: function (){
+var self=this;
+return self;
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testRootSuperSend\x0a\x09\x22TODO make this test work for ASTInterpreter\x22",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.ASTInterpreterTest);
+
 
 
 $core.addClass('ASTDebuggerTest', $globals.ASTInterpreterTest, [], 'Compiler-Tests');

+ 23 - 0
src/Compiler-Tests.st

@@ -157,6 +157,16 @@ tearDown
 
 !CodeGeneratorTest methodsFor: 'testing'!
 
+should: aString receiver: anObject raise: anErrorClass
+	| method result |
+
+	receiver := anObject.
+	[ self should: [
+		method := self compiler install: aString forClass: anObject class protocol: 'tests'.
+		receiver perform: method selector ] raise: anErrorClass ]
+	ensure: [ method ifNotNil: [ anObject class removeCompiledMethod: method ] ]
+!
+
 should: aString receiver: anObject return: aResult
 	| method result |
 
@@ -347,6 +357,13 @@ testPascalCaseGlobal
 	self should: 'foo ^NonExistent' return: nil
 !
 
+testRootSuperSend
+	self 
+		should: 'foo ^ super class' 
+		receiver: ProtoObject new
+		raise: MessageNotUnderstood
+!
+
 testSendReceiverAndArgumentsOrdered
 	self should: 'foo
 	| x |
@@ -508,6 +525,12 @@ should: aString receiver: anObject return: aResult
 		equals: aResult
 ! !
 
+!ASTInterpreterTest methodsFor: 'tests'!
+
+testRootSuperSend
+	"TODO make this test work for ASTInterpreter"
+! !
+
 ASTInterpreterTest subclass: #ASTDebuggerTest
 	instanceVariableNames: ''
 	package: 'Compiler-Tests'!

+ 1 - 1
support/boot.js

@@ -1196,5 +1196,5 @@ define("amber/boot", ['require', './browser-compatibility'], function (require)
         brikz.rebuild();
     }
 
-    return {api: api, nil: brikz.root.nil, globals: globals, asReceiver: brikz.asReceiver.asReceiver};
+    return {api: api, nil: brikz.root.nil, dnu: brikz.root.rootAsClass, globals: globals, asReceiver: brikz.asReceiver.asReceiver};
 });