diff --git a/Objective-J/Runtime.js b/Objective-J/Runtime.js index 5a371e3aa..3d9e04440 100644 --- a/Objective-J/Runtime.js +++ b/Objective-J/Runtime.js @@ -504,9 +504,11 @@ var _class_initialize = function(/*Class*/ aClass) meta.objj_msgSend3 = objj_msgSendFast3; aClass.method_msgSend = aClass.method_dtable; - meta.method_msgSend = meta.method_dtable; + var metaMethodDTable = meta.method_msgSend = meta.method_dtable, + initializeImp = metaMethodDTable["initialize"]; - meta.objj_msgSend0(aClass, "initialize"); + if (initializeImp) + initializeImp(aClass, "initialize"); CHANGEINFO(meta, CLS_INITIALIZED, CLS_INITIALIZING); } @@ -583,7 +585,7 @@ GLOBAL(_objj_forward) = function(self, _cmd) if (implementation) return implementation(self, SEL_doesNotRecognizeSelector_, _cmd); - throw class_getName(isa) + " does not implement doesNotRecognizeSelector:. Did you forget a superclass for " + class_getName(isa) + "?"; + throw class_getName(isa) + " does not implement doesNotRecognizeSelector: when sending " + sel_getName(_cmd) + ". Did you forget a superclass for " + class_getName(isa) + "?"; }; // I think this forward:: may need to be a common method, instead of defined in CPObject. diff --git a/Tests/Objective-J/MethodDispatchTest.j b/Tests/Objective-J/MethodDispatchTest.j index 377d039eb..7e13b5264 100644 --- a/Tests/Objective-J/MethodDispatchTest.j +++ b/Tests/Objective-J/MethodDispatchTest.j @@ -13,6 +13,38 @@ @end +@implementation RootClassWithInitialize +{ +} + ++ (id)alloc +{ + return class_createInstance(self); +} + ++ (void)initialize +{ + throw "Initialize"; +} + +@end + +@implementation RootClassWithInitialize2 +{ +} + ++ (id)alloc +{ + return class_createInstance(self); +} + ++ (void)initialize +{ + throw "Initialize"; +} + +@end + @implementation RootClassWithDoesNotRecognizeSelector { } @@ -24,7 +56,7 @@ - (void)doesNotRecognizeSelector:(SEL)aSelector { - throw "ERROR"; + throw "ERROR: " + sel_getName(aSelector); } @end @@ -40,10 +72,6 @@ Class isa; } -+ (void)initialize -{ -} - + (id)alloc { return class_createInstance(self); @@ -88,10 +116,6 @@ { } -+ (void)initialize -{ -} - + (id)alloc { return class_createInstance(self); @@ -176,7 +200,7 @@ var GlobalMethodDispatchTest; } catch (anException) { - [self assert:anException equals:"RootClass does not implement doesNotRecognizeSelector:. Did you forget a superclass for RootClass?"]; + [self assert:anException equals:"RootClass does not implement doesNotRecognizeSelector: when sending doesNotExist. Did you forget a superclass for RootClass?"]; } } @@ -190,7 +214,34 @@ var GlobalMethodDispatchTest; } catch (anException) { - [self assert:anException equals:"RootClass does not implement doesNotRecognizeSelector:. Did you forget a superclass for RootClass?"]; + [self assert:anException equals:"RootClass does not implement doesNotRecognizeSelector: when sending doesNotExist. Did you forget a superclass for RootClass?"]; + } +} +- (void)test_RootClassWithInitialize_class_initialize +{ + try + { + [RootClassWithInitialize doesNotExist]; + } + catch (anException) + { + [self assert:anException equals:"Initialize"]; + } +} + +- (void)test_RootClassWithInitialize_instance_initialize +{ + // Here we create a new instance with Runtime function to not trigger the +initialize method. + // We also have to use a fresh new class or the +initialize method would have already been triggered. + var object = class_createInstance(RootClassWithInitialize2); + + try + { + [object doesNotExist]; + } + catch (anException) + { + [self assert:anException equals:"Initialize"]; } } @@ -202,7 +253,7 @@ var GlobalMethodDispatchTest; } catch (anException) { - [self assert:anException equals:"ERROR"]; + [self assert:anException equals:"ERROR: doesNotExist"]; } } @@ -216,7 +267,7 @@ var GlobalMethodDispatchTest; } catch (anException) { - [self assert:anException equals:"ERROR"]; + [self assert:anException equals:"ERROR: doesNotExist"]; } }