rk towards the JavaScript ObjC bindings. The bindings now work for
authorrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Feb 2004 22:39:36 +0000 (22:39 +0000)
committerrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Feb 2004 22:39:36 +0000 (22:39 +0000)
simple scalar types.  testbindings.mm is an illustration of how the
bindings work.

        Reviewed by Ken.

        * JavaScriptCore.pbproj/project.pbxproj:
        * Makefile.am:
        * bindings/jni/jni_class.cpp:
        (JavaClass::methodsNamed):
        * bindings/jni/jni_class.h:
        * bindings/jni/jni_instance.cpp:
        (JavaInstance::invokeMethod):
        * bindings/jni/jni_instance.h:
        * bindings/jni/jni_runtime.h:
        (KJS::Bindings::JavaMethod::returnType):
        * bindings/make_testbindings: Added.
        * bindings/objc/objc_class.h: Added.
        (KJS::Bindings::ObjcClass::~ObjcClass):
        (KJS::Bindings::ObjcClass::ObjcClass):
        (KJS::Bindings::ObjcClass::operator=):
        (KJS::Bindings::ObjcClass::constructorAt):
        (KJS::Bindings::ObjcClass::numConstructors):
        * bindings/objc/objc_class.mm: Added.
        (ObjcClass::_commonDelete):
        (ObjcClass::_commonCopy):
        (ObjcClass::_commonInit):
        (_createClassesByIsAIfNecessary):
        (ObjcClass::classForIsA):
        (ObjcClass::ObjcClass):
        (ObjcClass::name):
        (ObjcClass::methodsNamed):
        (ObjcClass::fieldNamed):
        * bindings/objc/objc_header.h: Added.
        * bindings/objc/objc_instance.h: Added.
        (KJS::Bindings::ObjcInstance::getObject):
        * bindings/objc/objc_instance.mm: Added.
        (ObjcInstance::ObjcInstance):
        (ObjcInstance::~ObjcInstance):
        (ObjcInstance::operator=):
        (ObjcInstance::begin):
        (ObjcInstance::end):
        (ObjcInstance::getClass):
        (ObjcInstance::invokeMethod):
        (ObjcInstance::defaultValue):
        (ObjcInstance::stringValue):
        (ObjcInstance::numberValue):
        (ObjcInstance::booleanValue):
        (ObjcInstance::valueOf):
        * bindings/objc/objc_jsobject.h: Added.
        * bindings/objc/objc_jsobject.mm: Added.
        * bindings/objc/objc_runtime.h:
        (KJS::Bindings::ObjcField::~ObjcField):
        (KJS::Bindings::ObjcField::ObjcField):
        (KJS::Bindings::ObjcField::operator=):
        (KJS::Bindings::ObjcMethod::ObjcMethod):
        (KJS::Bindings::ObjcMethod::~ObjcMethod):
        (KJS::Bindings::ObjcMethod::operator=):
        * bindings/objc/objc_runtime.mm: Added.
        (ObjcMethod::ObjcMethod):
        (ObjcMethod::name):
        (ObjcMethod::numParameters):
        (ObjcMethod::getMethodSignature):
        (ObjcField::ObjcField):
        (ObjcField::name):
        (ObjcField::type):
        (ObjcField::valueFromInstance):
        (ObjcField::setValueToInstance):
        * bindings/objc/objc_utility.h: Added.
        (KJS::Bindings::):
        * bindings/objc/objc_utility.mm: Added.
        (KJS::Bindings::JSMethodNameToObjCMethodName):
        (KJS::Bindings::convertValueToObjcValue):
        (KJS::Bindings::convertObjcValueToValue):
        (KJS::Bindings::objcValueTypeForType):
        * bindings/runtime.cpp:
        (MethodList::MethodList):
        (MethodList::operator=):
        (Instance::setValueOfField):
        (Instance::createBindingForLanguageInstance):
        (Instance::createRuntimeObject):
        * bindings/runtime.h:
        * bindings/runtime_method.cpp:
        (RuntimeMethodImp::RuntimeMethodImp):
        (RuntimeMethodImp::get):
        (RuntimeMethodImp::call):
        * bindings/runtime_method.h:
        * bindings/runtime_object.cpp:
        (RuntimeObjectImp::get):
        (RuntimeObjectImp::hasProperty):
        * bindings/test.js: Added.
        * bindings/testbindings.mm: Added.
        (-[MySecondInterface init]):
        (-[MyFirstInterface init]):
        (-[MyFirstInterface dealloc]):
        (+[MyFirstInterface JavaScriptNameForSelector:]):
        (-[MyFirstInterface getInt]):
        (-[MyFirstInterface setInt:]):
        (-[MyFirstInterface getMySecondInterface]):
        (-[MyFirstInterface logMessage:]):
        (GlobalImp::className):
        (readJavaScriptFromFile):
        (main):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@6086 268f45cc-cd09-0410-ab3c-d52691b4dbfc

27 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.pbproj/project.pbxproj
JavaScriptCore/Makefile.am
JavaScriptCore/bindings/jni/jni_class.cpp
JavaScriptCore/bindings/jni/jni_class.h
JavaScriptCore/bindings/jni/jni_instance.cpp
JavaScriptCore/bindings/jni/jni_instance.h
JavaScriptCore/bindings/jni/jni_runtime.h
JavaScriptCore/bindings/make_testbindings [new file with mode: 0755]
JavaScriptCore/bindings/objc/objc_class.h [new file with mode: 0644]
JavaScriptCore/bindings/objc/objc_class.mm [new file with mode: 0644]
JavaScriptCore/bindings/objc/objc_header.h [new file with mode: 0644]
JavaScriptCore/bindings/objc/objc_instance.h [new file with mode: 0644]
JavaScriptCore/bindings/objc/objc_instance.mm [new file with mode: 0644]
JavaScriptCore/bindings/objc/objc_jsobject.h [new file with mode: 0644]
JavaScriptCore/bindings/objc/objc_jsobject.mm [new file with mode: 0644]
JavaScriptCore/bindings/objc/objc_runtime.h
JavaScriptCore/bindings/objc/objc_runtime.mm [new file with mode: 0644]
JavaScriptCore/bindings/objc/objc_utility.h [new file with mode: 0644]
JavaScriptCore/bindings/objc/objc_utility.mm [new file with mode: 0644]
JavaScriptCore/bindings/runtime.cpp
JavaScriptCore/bindings/runtime.h
JavaScriptCore/bindings/runtime_method.cpp
JavaScriptCore/bindings/runtime_method.h
JavaScriptCore/bindings/runtime_object.cpp
JavaScriptCore/bindings/test.js [new file with mode: 0644]
JavaScriptCore/bindings/testbindings.mm [new file with mode: 0644]

index c3de56f8ba29fc79044158ea8cf3d81392805c2b..45ceae1bebfc2f8dbcd1e79718b11cdbd321dbfe 100644 (file)
@@ -1,3 +1,109 @@
+2004-02-13  Richard Williamson   <rjw@apple.com>
+
+       Work towards the JavaScript ObjC bindings.  The bindings now work for 
+       simple scalar types.  testbindings.mm is an illustration of how the 
+       bindings work.
+
+        Reviewed by Ken.
+
+        * JavaScriptCore.pbproj/project.pbxproj:
+        * Makefile.am:
+        * bindings/jni/jni_class.cpp:
+        (JavaClass::methodsNamed):
+        * bindings/jni/jni_class.h:
+        * bindings/jni/jni_instance.cpp:
+        (JavaInstance::invokeMethod):
+        * bindings/jni/jni_instance.h:
+        * bindings/jni/jni_runtime.h:
+        (KJS::Bindings::JavaMethod::returnType):
+        * bindings/make_testbindings: Added.
+        * bindings/objc/objc_class.h: Added.
+        (KJS::Bindings::ObjcClass::~ObjcClass):
+        (KJS::Bindings::ObjcClass::ObjcClass):
+        (KJS::Bindings::ObjcClass::operator=):
+        (KJS::Bindings::ObjcClass::constructorAt):
+        (KJS::Bindings::ObjcClass::numConstructors):
+        * bindings/objc/objc_class.mm: Added.
+        (ObjcClass::_commonDelete):
+        (ObjcClass::_commonCopy):
+        (ObjcClass::_commonInit):
+        (_createClassesByIsAIfNecessary):
+        (ObjcClass::classForIsA):
+        (ObjcClass::ObjcClass):
+        (ObjcClass::name):
+        (ObjcClass::methodsNamed):
+        (ObjcClass::fieldNamed):
+        * bindings/objc/objc_header.h: Added.
+        * bindings/objc/objc_instance.h: Added.
+        (KJS::Bindings::ObjcInstance::getObject):
+        * bindings/objc/objc_instance.mm: Added.
+        (ObjcInstance::ObjcInstance):
+        (ObjcInstance::~ObjcInstance):
+        (ObjcInstance::operator=):
+        (ObjcInstance::begin):
+        (ObjcInstance::end):
+        (ObjcInstance::getClass):
+        (ObjcInstance::invokeMethod):
+        (ObjcInstance::defaultValue):
+        (ObjcInstance::stringValue):
+        (ObjcInstance::numberValue):
+        (ObjcInstance::booleanValue):
+        (ObjcInstance::valueOf):
+        * bindings/objc/objc_jsobject.h: Added.
+        * bindings/objc/objc_jsobject.mm: Added.
+        * bindings/objc/objc_runtime.h:
+        (KJS::Bindings::ObjcField::~ObjcField):
+        (KJS::Bindings::ObjcField::ObjcField):
+        (KJS::Bindings::ObjcField::operator=):
+        (KJS::Bindings::ObjcMethod::ObjcMethod):
+        (KJS::Bindings::ObjcMethod::~ObjcMethod):
+        (KJS::Bindings::ObjcMethod::operator=):
+        * bindings/objc/objc_runtime.mm: Added.
+        (ObjcMethod::ObjcMethod):
+        (ObjcMethod::name):
+        (ObjcMethod::numParameters):
+        (ObjcMethod::getMethodSignature):
+        (ObjcField::ObjcField):
+        (ObjcField::name):
+        (ObjcField::type):
+        (ObjcField::valueFromInstance):
+        (ObjcField::setValueToInstance):
+        * bindings/objc/objc_utility.h: Added.
+        (KJS::Bindings::):
+        * bindings/objc/objc_utility.mm: Added.
+        (KJS::Bindings::JSMethodNameToObjCMethodName):
+        (KJS::Bindings::convertValueToObjcValue):
+        (KJS::Bindings::convertObjcValueToValue):
+        (KJS::Bindings::objcValueTypeForType):
+        * bindings/runtime.cpp:
+        (MethodList::MethodList):
+        (MethodList::operator=):
+        (Instance::setValueOfField):
+        (Instance::createBindingForLanguageInstance):
+        (Instance::createRuntimeObject):
+        * bindings/runtime.h:
+        * bindings/runtime_method.cpp:
+        (RuntimeMethodImp::RuntimeMethodImp):
+        (RuntimeMethodImp::get):
+        (RuntimeMethodImp::call):
+        * bindings/runtime_method.h:
+        * bindings/runtime_object.cpp:
+        (RuntimeObjectImp::get):
+        (RuntimeObjectImp::hasProperty):
+        * bindings/test.js: Added.
+        * bindings/testbindings.mm: Added.
+        (-[MySecondInterface init]):
+        (-[MyFirstInterface init]):
+        (-[MyFirstInterface dealloc]):
+        (+[MyFirstInterface JavaScriptNameForSelector:]):
+        (-[MyFirstInterface getInt]):
+        (-[MyFirstInterface setInt:]):
+        (-[MyFirstInterface getMySecondInterface]):
+        (-[MyFirstInterface logMessage:]):
+        (GlobalImp::className):
+        (readJavaScriptFromFile):
+        (main):
+
 === Safari-128 ===
 
 2004-02-08  Darin Adler  <darin@apple.com>
index 1be0ce7fa0be0b4bba97ad49fa80e94e008db1ec..9eb24841b254ca903d08860169e1041f34808bbf 100644 (file)
@@ -17,8 +17,8 @@
                                GCC_OPTIMIZATION_LEVEL = 0;
                                INSTALL_PATH = "@executable_path/../Frameworks";
                                OPTIMIZATION_CFLAGS = "-O0";
-                               OTHER_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR)";
                                SECTORDER_FLAGS = "";
+                               STYLE_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR)";
                                ZERO_LINK = YES;
                        };
                        isa = PBXBuildStyle;
@@ -32,8 +32,8 @@
                                DEBUGGING_SYMBOLS = NO;
                                GCC_ENABLE_FIX_AND_CONTINUE = NO;
                                INSTALL_PATH = "@executable_path/../Frameworks";
-                               OTHER_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR)";
                                SECTORDER_FLAGS = "";
+                               STYLE_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR)";
                                ZERO_LINK = NO;
                        };
                        isa = PBXBuildStyle;
                };
                0867D69AFE84028FC02AAC07 = {
                        children = (
+                               51F0EC0705C86C9A00E6DF1B,
+                               51F0EB6105C86C6B00E6DF1B,
                                6560A4CF04B3B3E7008AE952,
                                6560A63D04B3B69F008AE952,
                                51856D980562F158008B9D83,
                                MACOSX_DEPLOYMENT_TARGET = 10.2;
                                OPTIMIZATION_CFLAGS = "-Os";
                                OTHER_CFLAGS = "$(DEBUG_CFLAGS) -DAPPLE_CHANGES -DHAVE_CONFIG_H";
-                               OTHER_LDFLAGS = "-umbrella WebKit -allowable_client JavaScriptGlue";
+                               OTHER_LDFLAGS = "$(STYLE_LDFLAGS) -sub_library libobjc";
+                               PREBINDING = NO;
                                PRECOMPILE_PREFIX_HEADER = YES;
                                PREFIX_HEADER = JavaScriptCorePrefix.h;
                                PRODUCT_NAME = JavaScriptCore;
                                SECTORDER_FLAGS = "-sectorder __TEXT __text /AppleInternal/OrderFiles/JavaScriptCore.order";
+                               STYLE_LDFLAGS = "-umbrella WebKit -allowable_client JavaScriptGlue";
                                USE_GCC3_PFE_SUPPORT = YES;
                                WARNING_CFLAGS = "-Werror -Wall -W -Wcast-align -Wchar-subscripts -Wformat-security -Wmissing-format-attribute -Wmissing-prototypes -Wpointer-arith -Wwrite-strings -Wno-format-y2k -Wno-unused-parameter -Wno-long-double";
                                WRAPPER_EXTENSION = framework;
        <key>CFBundleShortVersionString</key>
        <string>1.2</string>
        <key>CFBundleVersion</key>
-       <string>129u</string>
+       <string>128u</string>
 </dict>
 </plist>
 ";
                                7073BE3F0581291E005EE2C9,
                                513DF74305C0861F00F89391,
                                51C4974205C0A5D4006FBFF5,
+                               518CF93905C72271003CF905,
+                               51F0EB0205C85A6300E6DF1B,
+                               51F0EC1105C86F3500E6DF1B,
+                               51F0EC9805C88DC700E6DF1B,
+                               7084D99505DD6211007E4C0E,
                        );
                        isa = PBXHeadersBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                                51A58A8F057D3A6A00A3E942,
                                7073BE3E0581291E005EE2C9,
                                513DF74205C0861F00F89391,
+                               518CF93A05C72271003CF905,
+                               518CF93B05C72271003CF905,
+                               51F0EB0605C85A9000E6DF1B,
+                               51F0EC9905C88DC700E6DF1B,
+                               7084D9BA05DD6CF8007E4C0E,
                        );
                        isa = PBXSourcesBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                                6560A4D004B3B3E7008AE952,
                                6560A63E04B3B69F008AE952,
                                51856D990562F158008B9D83,
+                               51F0EB6205C86C6B00E6DF1B,
+                               51F0EC0805C86C9A00E6DF1B,
                        );
                        isa = PBXFrameworksBuildPhase;
                        runOnlyForDeploymentPostprocessing = 0;
                                51A58A8E057D3A6A00A3E942,
                                70B16A260569A10900DB756D,
                                70B16A270569A10900DB756D,
+                               518CF93605C72271003CF905,
+                               518CF93705C72271003CF905,
+                               51F0EC1005C86F3500E6DF1B,
+                               51F0EB0005C85A6300E6DF1B,
+                               51F0EB0505C85A9000E6DF1B,
+                               7084D99405DD6211007E4C0E,
+                               7084D9B905DD6CF8007E4C0E,
                                51C4974105C0A5D4006FBFF5,
+                               518CF93805C72271003CF905,
+                               51F0EC9605C88DC700E6DF1B,
+                               51F0EC9705C88DC700E6DF1B,
                        );
                        isa = PBXGroup;
                        name = bindings;
                        settings = {
                        };
                };
+               518CF93605C72271003CF905 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = objc_class.h;
+                       path = bindings/objc/objc_class.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               518CF93705C72271003CF905 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.objcpp;
+                       name = objc_class.mm;
+                       path = bindings/objc/objc_class.mm;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               518CF93805C72271003CF905 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.objcpp;
+                       name = objc_runtime.mm;
+                       path = bindings/objc/objc_runtime.mm;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               518CF93905C72271003CF905 = {
+                       fileRef = 518CF93605C72271003CF905;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               518CF93A05C72271003CF905 = {
+                       fileRef = 518CF93705C72271003CF905;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               518CF93B05C72271003CF905 = {
+                       fileRef = 518CF93805C72271003CF905;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
                51A58A8D057D3A6A00A3E942 = {
                        fileEncoding = 30;
                        isa = PBXFileReference;
                        settings = {
                        };
                };
+               51F0EB0005C85A6300E6DF1B = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = objc_instance.h;
+                       path = bindings/objc/objc_instance.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               51F0EB0205C85A6300E6DF1B = {
+                       fileRef = 51F0EB0005C85A6300E6DF1B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               51F0EB0505C85A9000E6DF1B = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.objcpp;
+                       name = objc_instance.mm;
+                       path = bindings/objc/objc_instance.mm;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               51F0EB0605C85A9000E6DF1B = {
+                       fileRef = 51F0EB0505C85A9000E6DF1B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               51F0EB6105C86C6B00E6DF1B = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = wrapper.framework;
+                       name = Foundation.framework;
+                       path = /System/Library/Frameworks/Foundation.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               51F0EB6205C86C6B00E6DF1B = {
+                       fileRef = 51F0EB6105C86C6B00E6DF1B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               51F0EC0705C86C9A00E6DF1B = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = "compiled.mach-o.dylib";
+                       name = libobjc.dylib;
+                       path = /usr/lib/libobjc.dylib;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               51F0EC0805C86C9A00E6DF1B = {
+                       fileRef = 51F0EC0705C86C9A00E6DF1B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               51F0EC1005C86F3500E6DF1B = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = objc_header.h;
+                       path = bindings/objc/objc_header.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               51F0EC1105C86F3500E6DF1B = {
+                       fileRef = 51F0EC1005C86F3500E6DF1B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               51F0EC9605C88DC700E6DF1B = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = objc_utility.h;
+                       path = bindings/objc/objc_utility.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               51F0EC9705C88DC700E6DF1B = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.objcpp;
+                       name = objc_utility.mm;
+                       path = bindings/objc/objc_utility.mm;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               51F0EC9805C88DC700E6DF1B = {
+                       fileRef = 51F0EC9605C88DC700E6DF1B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               51F0EC9905C88DC700E6DF1B = {
+                       fileRef = 51F0EC9705C88DC700E6DF1B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
 //510
 //511
 //512
                        settings = {
                        };
                };
+               7084D99405DD6211007E4C0E = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = objc_jsobject.h;
+                       path = bindings/objc/objc_jsobject.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               7084D99505DD6211007E4C0E = {
+                       fileRef = 7084D99405DD6211007E4C0E;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               7084D9B905DD6CF8007E4C0E = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.cpp.objcpp;
+                       name = objc_jsobject.mm;
+                       path = bindings/objc/objc_jsobject.mm;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               7084D9BA05DD6CF8007E4C0E = {
+                       fileRef = 7084D9B905DD6CF8007E4C0E;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
                70B16A260569A10900DB756D = {
                        fileEncoding = 30;
                        isa = PBXFileReference;
                                COPY_PHASE_STRIP = NO;
                                DEBUG_CFLAGS = "";
                                INSTALL_PATH = "@executable_path/../Frameworks";
-                               OTHER_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR)";
+                               STYLE_LDFLAGS = "-seg1addr $(LOCAL_SEG1_ADDR)";
                        };
                        isa = PBXBuildStyle;
                        name = OptimizedWithSymbols;
index 936547cabee77f59bcb6aaa5a126060cddb6505f..2e6942aab64e848ea134bf74fe2e1fbfdd6e9fa3 100644 (file)
@@ -9,7 +9,7 @@ kjs_testkjs_DEPENDENCIES = JavaScriptCore-stamp
 kjs_testkjs_LDFLAGS = -F$(SYMROOTS) -framework JavaScriptCore
 
 all-am: JavaScriptCore-stamp
-JavaScriptCore-stamp: kjs/*.cpp kjs/*.h pcre/*.c pcre/*.h bindings/*.h bindings/*.cpp bindings/jni/*.cpp bindings/jni/*.h
+JavaScriptCore-stamp: kjs/*.cpp kjs/*.h pcre/*.c pcre/*.h bindings/*.h bindings/*.cpp bindings/jni/*.cpp bindings/jni/*.h bindings/objc/*.h bindings/objc/*.mm
        xcodebuild -buildstyle $(BUILDSTYLE) OBJROOT=$(SYMROOTS) SYMROOT=$(SYMROOTS) DSTROOT=$(SYMROOTS) && touch $@
 clean-am:
        xcodebuild clean OBJROOT=$(SYMROOTS) SYMROOT=$(SYMROOTS) DSTROOT=$(SYMROOTS)
index ea3e0bfd3e9b8611da31b63653f95ed92ab47137..260eff70ff238237dc9467952c9f494ab4f942c5 100644 (file)
@@ -159,12 +159,12 @@ JavaClass *JavaClass::classForInstance (jobject instance)
     return aClass;
 }
 
-MethodList *JavaClass::methodsNamed(const char *name) const
+MethodList JavaClass::methodsNamed(const char *name) const
 {
     CFStringRef methodName = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
     MethodList *methodList = (MethodList *)CFDictionaryGetValue(_methods, methodName);
     CFRelease (methodName);
-    return methodList;
+    return *methodList;
 }
 
 
index 30d60f68efcdf8bb0e98bc634c790c1a5304f648..aff4607f13ba608090006cda488efd83e6e06008 100644 (file)
@@ -32,8 +32,6 @@
 #include <runtime.h>
 #include <jni_runtime.h>
 
-#include <runtime.h>
-
 namespace KJS {
 
 namespace Bindings {
@@ -100,7 +98,7 @@ public:
 
     virtual const char *name() const { return _name; };
     
-    virtual MethodList *methodsNamed(const char *name) const;
+    virtual MethodList methodsNamed(const char *name) const;
     
     virtual Field *fieldNamed(const char *name) const;
     
index 239b354f2c280b34d54b569a91d63102c24b8c1d..0cce229d7e1634e8c8994269d94943b86e0896cc 100644 (file)
@@ -104,13 +104,13 @@ KJS::Value JavaInstance::booleanValue() const
     return v;
 }
 
-Value JavaInstance::invokeMethod (KJS::ExecState *exec, const MethodList *methodList, const List &args)
+Value JavaInstance::invokeMethod (KJS::ExecState *exec, const MethodList &methodList, const List &args)
 {
     int i, count = args.size();
     jvalue *jArgs;
     Value resultValue;
     Method *method = 0;
-    unsigned int numMethods = methodList->length();
+    unsigned int numMethods = methodList.length();
     
     // Try to find a good match for the overloaded method.  The 
     // fundamental problem is that JavaScript doesn have the
@@ -120,7 +120,7 @@ Value JavaInstance::invokeMethod (KJS::ExecState *exec, const MethodList *method
     unsigned int methodIndex;
     Method *aMethod;
     for (methodIndex = 0; methodIndex < numMethods; methodIndex++) {
-        aMethod = methodList->methodAt (methodIndex);
+        aMethod = methodList.methodAt (methodIndex);
         if (aMethod->numParameters() == count) {
             method = aMethod;
             break;
@@ -146,7 +146,7 @@ Value JavaInstance::invokeMethod (KJS::ExecState *exec, const MethodList *method
     }
     
     jvalue result;
-       jobject obj = _instance->_instance;
+    jobject obj = _instance->_instance;
     switch (jMethod->JNIReturnType()){
         case void_type: {
             callJNIVoidMethodIDA (obj, jMethod->methodID(obj), jArgs);
index ad1e03da077497bf62ef09a37b375b7c88a3649e..1c537a1cc9f259b696b9d9f52594af203d9bcb0e 100644 (file)
@@ -93,7 +93,7 @@ public:
     virtual KJS::Value valueOf() const;
     virtual KJS::Value defaultValue (KJS::Type hint) const;
 
-    virtual KJS::Value invokeMethod (KJS::ExecState *exec, const MethodList *method, const KJS::List &args);
+    virtual KJS::Value invokeMethod (KJS::ExecState *exec, const MethodList &method, const KJS::List &args);
 
     jobject javaInstance() const { return _instance->_instance; }
     
index 6dbaeacdf05e1d730e89df32eaf77b0a47c6af07..3c9a40f69fd949331a0941583eb1e90cb05fafa2 100644 (file)
@@ -242,7 +242,7 @@ public:
     };
 
     virtual const char *name() const { return _name.UTF8String(); };
-    virtual RuntimeType returnType() const { return _returnType.UTF8String(); };
+    RuntimeType returnType() const { return _returnType.UTF8String(); };
     virtual Parameter *parameterAt(long i) const { return &_parameters[i]; };
     virtual long numParameters() const { return _numParameters; };
     
diff --git a/JavaScriptCore/bindings/make_testbindings b/JavaScriptCore/bindings/make_testbindings
new file mode 100755 (executable)
index 0000000..6a7a361
--- /dev/null
@@ -0,0 +1 @@
+cc -g -o testbindings testbindings.mm -I../kjs -F$SYMROOTS -framework JavaScriptCore -framework Foundation -lstdc++
diff --git a/JavaScriptCore/bindings/objc/objc_class.h b/JavaScriptCore/bindings/objc/objc_class.h
new file mode 100644 (file)
index 0000000..1ca73e1
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#ifndef _BINDINGS_OBJC_CLASS_H_
+#define _BINDINGS_OBJC_CLASS_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+
+#include <runtime.h>
+#include <objc_header.h>
+#include <objc_runtime.h>
+
+namespace KJS {
+
+namespace Bindings {
+
+class ObjcClass : public KJS::Bindings::Class
+{
+    // Use the public static factory methods to get instances of JavaClass.
+    
+protected:
+    void _commonInit (ClassStructPtr aClass);
+    void _commonCopy(const ObjcClass &other);
+    void _commonDelete();
+    
+    ObjcClass (ClassStructPtr aClass);
+    
+public:
+    // Return the cached ObjC of the specified name.
+    //static ObjcClass *classForName (const char *name);
+    static ObjcClass *classForIsA (ClassStructPtr aClass);
+            
+    ~ObjcClass () {
+        _commonDelete();
+    }
+    
+    ObjcClass (const ObjcClass &other) : Class() {
+        _commonCopy (other);
+    };
+
+    ObjcClass &operator=(const ObjcClass &other)
+    {
+        if (this == &other)
+            return *this;
+            
+        _commonDelete();
+        _commonCopy (other);
+        
+        return *this;
+    }
+
+    virtual const char *name() const;
+    
+    virtual MethodList methodsNamed(const char *name) const;
+    
+    virtual Field *fieldNamed(const char *name) const;
+    
+    virtual Constructor *constructorAt(long i) const {
+        return 0;
+    };
+    
+    virtual long numConstructors() const { return 0; };
+        
+private:
+    ClassStructPtr _isa;
+    CFDictionaryRef _methods;
+    CFDictionaryRef _fields;
+};
+
+} // namespace Bindings
+
+} // namespace KJS
+
+#endif
\ No newline at end of file
diff --git a/JavaScriptCore/bindings/objc/objc_class.mm b/JavaScriptCore/bindings/objc/objc_class.mm
new file mode 100644 (file)
index 0000000..b980f05
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#include <Foundation/Foundation.h>
+
+#include <objc_class.h>
+#include <objc_jsobject.h>
+#include <objc_utility.h>
+
+using namespace KJS::Bindings;
+
+void ObjcClass::_commonDelete() {
+    CFRelease (_fields);
+    CFRelease (_methods);
+}
+    
+
+void ObjcClass::_commonCopy(const ObjcClass &other) {
+    _isa = other._isa;
+    _methods = CFDictionaryCreateCopy (NULL, other._methods);
+    _fields = CFDictionaryCreateCopy (NULL, other._fields);
+}
+    
+
+void ObjcClass::_commonInit (ClassStructPtr aClass)
+{
+    _isa = aClass;
+    _methods = CFDictionaryCreateMutable(NULL, 16, &kCFTypeDictionaryKeyCallBacks, NULL);
+    _fields = CFDictionaryCreateMutable(NULL, 16, &kCFTypeDictionaryKeyCallBacks, NULL);
+}
+
+
+static CFMutableDictionaryRef classesByIsA = 0;
+
+static void _createClassesByIsAIfNecessary()
+{
+    if (classesByIsA == 0)
+        classesByIsA = CFDictionaryCreateMutable (NULL, 0, NULL, NULL);
+}
+
+ObjcClass *ObjcClass::classForIsA (ClassStructPtr isa)
+{
+    _createClassesByIsAIfNecessary();
+    
+    ObjcClass *aClass = (ObjcClass *)CFDictionaryGetValue(classesByIsA, isa);
+    if (aClass == NULL) {
+        aClass = new ObjcClass (isa);
+        CFDictionaryAddValue (classesByIsA, isa, aClass);
+    }
+    
+    return aClass;
+}
+
+
+ObjcClass::ObjcClass (ClassStructPtr isa)
+{
+    _commonInit (isa);
+}
+
+const char *ObjcClass::name() const
+{
+    return _isa->name;
+}
+
+MethodList ObjcClass::methodsNamed(const char *_name) const
+{
+    MethodList methodList;
+    char name[4096];
+    
+    JSMethodNameToObjCMethodName (_name, name, 4096);
+    
+    if (*name == 0) {
+        return methodList;
+    }
+        
+    CFStringRef methodName = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
+    Method *method = (Method *)CFDictionaryGetValue (_methods, methodName);
+    if (method) {
+        CFRelease (methodName);
+        methodList.addMethod(method);
+        return methodList;
+    }
+    
+    ClassStructPtr thisClass = _isa;
+    while (thisClass != 0 && methodList.length() < 1) {
+        void *iterator = 0;
+        struct objc_method_list *objcMethodList;
+        while ( (objcMethodList = class_nextMethodList( thisClass, &iterator )) ) {
+            int i, numMethodsInClass = objcMethodList->method_count;
+            for (i = 0; i < numMethodsInClass; i++) {
+                struct objc_method *objcMethod = &objcMethodList->method_list[i];
+                NSString *mappedName = 0;
+            
+                if ([(id)thisClass respondsToSelector:@selector(JavaScriptNameForSelector:)]){
+                    mappedName = [(id)thisClass JavaScriptNameForSelector: objcMethod->method_name];
+                }
+
+                if ((mappedName && [mappedName isEqual:(NSString *)methodName]) ||
+                    strcmp ((const char *)objcMethod->method_name, name) == 0) {
+                    Method *aMethod = new ObjcMethod (thisClass, (const char *)objcMethod->method_name);
+                    CFDictionaryAddValue ((CFMutableDictionaryRef)_methods, methodName, aMethod);
+                    methodList.addMethod (aMethod);
+                    break;
+                }
+            }
+        } 
+        thisClass = thisClass->super_class;
+    }
+
+    CFRelease (methodName);
+    
+    return methodList;
+}
+
+
+Field *ObjcClass::fieldNamed(const char *name) const
+{
+    ClassStructPtr thisClass = _isa;
+
+    CFStringRef fieldName = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
+    Field *aField = (Field *)CFDictionaryGetValue (_fields, fieldName);
+    if (aField) {
+        CFRelease (fieldName);
+        return aField;
+    }
+
+    while (thisClass != 0) {
+        struct objc_ivar_list *fieldsInClass = thisClass->ivars;
+        if (fieldsInClass) {
+            int i, numFieldsInClass = fieldsInClass->ivar_count;
+            for (i = 0; i < numFieldsInClass; i++) {
+                Ivar objcIVar = &fieldsInClass->ivar_list[i];
+                if (strcmp(objcIVar->ivar_name,name) == 0) {
+                    aField = new ObjcField (objcIVar);
+                    CFDictionaryAddValue ((CFMutableDictionaryRef)_fields, fieldName, aField);
+                    break;
+                }
+            }
+        }
+        thisClass = thisClass->super_class;
+    }
+
+    CFRelease (fieldName);
+
+    return aField;
+};
diff --git a/JavaScriptCore/bindings/objc/objc_header.h b/JavaScriptCore/bindings/objc/objc_header.h
new file mode 100644 (file)
index 0000000..2dd7a26
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#ifndef _BINDINGS_OBJC_HEADER_H_
+#define _BINDINGS_OBJC_HEADER_H_
+
+#ifdef __OBJC__
+#include <objc/objc-class.h>
+#include <objc/objc-runtime.h>
+
+typedef struct objc_class *ClassStructPtr;
+typedef struct objc_object *ObjectStructPtr;
+
+@class NSMethodSignature;
+
+#else
+
+typedef struct objc_ivar {} *Ivar;
+typedef struct objc_class {} *ClassStructPtr;
+typedef struct objc_object {} *ObjectStructPtr;
+
+class NSMethodSignature;
+
+#endif
+
+#endif
\ No newline at end of file
diff --git a/JavaScriptCore/bindings/objc/objc_instance.h b/JavaScriptCore/bindings/objc/objc_instance.h
new file mode 100644 (file)
index 0000000..9ac1f8b
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#ifndef _BINDINGS_OBJC_INSTANCE_H_
+#define _BINDINGS_OBJC_INSTANCE_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <objc_class.h>
+#include <objc_runtime.h>
+#include <objc_utility.h>
+
+namespace KJS {
+
+namespace Bindings {
+
+class ObjcClass;
+
+class ObjcInstance : public Instance
+{
+public:
+    ObjcInstance (ObjectStructPtr instance);
+        
+    ~ObjcInstance ();
+    
+    virtual Class *getClass() const;
+    
+    ObjcInstance (const ObjcInstance &other);
+
+    ObjcInstance &operator=(const ObjcInstance &other);
+    
+    virtual void begin();
+    virtual void end();
+    
+    virtual KJS::Value valueOf() const;
+    virtual KJS::Value defaultValue (KJS::Type hint) const;
+
+    virtual KJS::Value invokeMethod (KJS::ExecState *exec, const MethodList &method, const KJS::List &args);
+
+    ObjectStructPtr getObject() const { return _instance; }
+    
+    KJS::Value stringValue() const;
+    KJS::Value numberValue() const;
+    KJS::Value booleanValue() const;
+    
+private:
+    ObjectStructPtr _instance;
+    mutable ObjcClass *_class;
+    ObjectStructPtr _pool;
+    long _beginCount;
+};
+
+} // namespace Bindings
+
+} // namespace KJS
+
+#endif
diff --git a/JavaScriptCore/bindings/objc/objc_instance.mm b/JavaScriptCore/bindings/objc/objc_instance.mm
new file mode 100644 (file)
index 0000000..c9336fc
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#include <Foundation/Foundation.h>
+
+#include <objc_instance.h>
+
+#ifdef NDEBUG
+#define OBJC_LOG(formatAndArgs...) ((void)0)
+#else
+#define OBJC_LOG(formatAndArgs...) { \
+    fprintf (stderr, "%s:%d -- %s:  ", __FILE__, __LINE__, __FUNCTION__); \
+    fprintf(stderr, formatAndArgs); \
+}
+#endif
+
+using namespace KJS::Bindings;
+using namespace KJS;
+
+ObjcInstance::ObjcInstance (ObjectStructPtr instance) 
+{
+    _instance = [instance retain];
+    _class = 0;
+    _pool = 0;
+    _beginCount = 0;
+};
+
+ObjcInstance::~ObjcInstance () 
+{
+    [_instance release];
+}
+
+
+ObjcInstance::ObjcInstance (const ObjcInstance &other) : Instance() 
+{
+    _instance = [other._instance retain];
+    _class = other._class;
+    _pool = 0;
+    _beginCount = 0;
+};
+
+ObjcInstance &ObjcInstance::operator=(const ObjcInstance &other){
+    if (this == &other)
+        return *this;
+    
+    ObjectStructPtr _oldInstance = _instance;
+    _instance = [(id)other._instance retain];
+    [(id)_oldInstance release];
+    
+    // Classes are kept around forever.
+    _class = other._class;
+    
+    return *this;
+};
+
+void ObjcInstance::begin()
+{
+    if (!_pool) {
+        _pool = [[NSAutoreleasePool alloc] init];
+    }
+    _beginCount++;
+}
+
+void ObjcInstance::end()
+{
+    _beginCount--;
+    assert (_beginCount >= 0);
+    if (_beginCount == 0) {
+        [_pool release];
+    }
+    _pool = 0;
+}
+
+Bindings::Class *ObjcInstance::getClass() const 
+{
+    if (_class == 0) {
+        _class = ObjcClass::classForIsA(_instance->isa);
+    }
+    return static_cast<Bindings::Class*>(_class);
+}
+
+Value ObjcInstance::invokeMethod (KJS::ExecState *exec, const MethodList &methodList, const List &args)
+{
+    Value resultValue;
+
+    // Overloading methods is not allowed in ObjectiveC.  Should only be one
+    // name match for a particular method.
+    assert (methodList.length() == 1);
+
+NS_DURING
+    
+    ObjcMethod *method = 0;
+    method = static_cast<ObjcMethod*>(methodList.methodAt(0));
+    NSMethodSignature *signature = method->getMethodSignature();
+    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
+    [invocation setSelector:(SEL)method->name()];
+    [invocation setTarget:_instance];
+    unsigned i, count = args.size();
+    
+    if (count != [signature numberOfArguments] - 2){
+        return Undefined();
+    }
+    
+    for (i = 2; i < count+2; i++) {
+        const char *type = [signature getArgumentTypeAtIndex:i];
+        ObjcValueType objcValueType = objcValueTypeForType (type);
+
+        // Must have a valid argument type.  This method signature should have
+        // been filtered already to ensure that it has acceptable argument
+        // types.
+        assert (objcValueType != ObjcInvalidType && objcValueType != ObjcVoidType);
+        
+        ObjcValue value = convertValueToObjcValue (exec, args.at(i-2), objcValueType);
+        
+        switch (objcValueType) {
+            case ObjcObjectType:
+                [invocation setArgument:&value.objectValue atIndex:i];
+                break;
+            case ObjcCharType:
+                [invocation setArgument:&value.charValue atIndex:i];
+                break;
+            case ObjcShortType:
+                [invocation setArgument:&value.shortValue atIndex:i];
+                break;
+            case ObjcIntType:
+                [invocation setArgument:&value.intValue atIndex:i];
+                break;
+            case ObjcLongType:
+                [invocation setArgument:&value.longValue atIndex:i];
+                break;
+            case ObjcFloatType:
+                [invocation setArgument:&value.floatValue atIndex:i];
+                break;
+            case ObjcDoubleType:
+                [invocation setArgument:&value.doubleValue atIndex:i];
+                break;
+            default:
+                // Should never get here.  Argument types are filtered (and
+                // the assert above should have fired in the impossible case
+                // of an invalid type anyway).
+                fprintf (stderr, "%s:  invalid type (%d)\n", __PRETTY_FUNCTION__, (int)objcValueType);
+                assert (true);
+        }
+    }
+
+    // Invoke the ObjectiveC method.
+    [invocation invoke];
+
+    // Get the return value type.
+    const char *type = [signature methodReturnType];
+    ObjcValueType objcValueType = objcValueTypeForType (type);
+    
+    // Must have a valid return type.  This method signature should have
+    // been filtered already to ensure that it have an acceptable return
+    // type.
+    assert (objcValueType != ObjcInvalidType);
+    
+    // Get the return value and convert it to a KJS::Value.  Length
+    // of return value will never exceed the size of largest scalar
+    // or a pointer.
+    char buffer[1024];
+    assert ([signature methodReturnLength] < 1024);
+    [invocation getReturnValue:buffer];
+    resultValue = convertObjcValueToValue (exec, buffer, objcValueType);
+    
+NS_HANDLER
+    
+    resultValue = Undefined();
+    
+NS_ENDHANDLER
+    
+    return resultValue;
+}
+
+
+KJS::Value ObjcInstance::defaultValue (KJS::Type hint) const
+{
+    if (hint == KJS::StringType) {
+        return stringValue();
+    }
+    else if (hint == KJS::NumberType) {
+        return numberValue();
+    }
+    else if (hint == KJS::BooleanType) {
+        return booleanValue();
+    }
+    else if (hint == KJS::UnspecifiedType) {
+        if ([_instance isKindOfClass:[NSString class]]) {
+            return stringValue();
+        }
+        else if ([_instance isKindOfClass:[NSNumber class]]) {
+            return numberValue();
+        }
+        else if ([_instance isKindOfClass:[NSNumber class]]) {
+            return booleanValue();
+        }
+    }
+    
+    return valueOf();
+}
+
+KJS::Value ObjcInstance::stringValue() const
+{
+    // FIXME:  Implement something sensible, like calling toString...
+    KJS::String v("");
+    return v;
+}
+
+KJS::Value ObjcInstance::numberValue() const
+{
+    // FIXME:  Implement something sensible
+    KJS::Number v(0);
+    return v;
+}
+
+KJS::Value ObjcInstance::booleanValue() const
+{
+    // FIXME:  Implement something sensible
+    KJS::Boolean v((bool)0);
+    return v;
+}
+
+KJS::Value ObjcInstance::valueOf() const 
+{
+    return stringValue();
+};
diff --git a/JavaScriptCore/bindings/objc/objc_jsobject.h b/JavaScriptCore/bindings/objc/objc_jsobject.h
new file mode 100644 (file)
index 0000000..4eb68f4
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#ifndef _BINDINGS_OBJC_JSOBJECT_H_
+#define _BINDINGS_OBJC_JSOBJECT_H_
+
+#include <Foundation/Foundation.h>
+
+#include <value.h>
+
+/*
+    ObjC      to    JavaScript
+    char            Number
+    short
+    int
+    long
+    float
+    double
+    NSString        string
+    NSArray         []
+    id              wrapper
+    other           exception
+    
+    JavaScript to   ObjC
+    Number          coerced char, short, int, long, float, or double
+    String          NSString
+    wrapper         id
+    Object          JavaScriptObject
+    [], other       exception
+*/
+
+
+@interface NSObject (JavaScriptMethods)
+
++ (NSString *)JavaScriptNameForSelector:(SEL)aSelector;
++ (BOOL)excludeSelectorFromJavaScript:(SEL)aSelector;
+
+@end
+
+
+@interface JavaScriptValueConverter
+
++ (void)registerConverter:(JavaScriptValueConverter *)aConverter;
++ (void)unregisterConverter:(JavaScriptValueConverter *)aConverter;
++ (NSArray *)converters;
+
+- (id)objectForValue:(KJS::Value)aValue;
+
+@end
+
+
+@interface JavaScriptObject
+@end
+
+#endif
\ No newline at end of file
diff --git a/JavaScriptCore/bindings/objc/objc_jsobject.mm b/JavaScriptCore/bindings/objc/objc_jsobject.mm
new file mode 100644 (file)
index 0000000..19a5f78
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#include <objc_jsobject.h>
\ No newline at end of file
index d9330395c7f59f101b5e0de592e0c37abc8870a9..78a5952ec1f32629ed0e63ae87cf10ac1d0d03fb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
-#ifndef _OBJC_RUNTIME_H_
-#define _OBJC_RUNTIME_H_
+#ifndef _BINDINGS_OBJC_RUNTIME_H_
+#define _BINDINGS_OBJC_RUNTIME_H_
 
 #include <CoreFoundation/CoreFoundation.h>
 
 #include <runtime.h>
 #include <ustring.h>
 
+#include <objc_header.h>
+
 namespace KJS
 {
 class Value;
@@ -37,83 +39,25 @@ class Value;
 namespace Bindings
 {
 
-class ObjcParameter : public Parameter
+class ObjcField : public Field
 {
 public:
-    ObjcParameter () {};
-    
-    ~ObjcParameter() {
-    };
-
-    ObjcParameter(const ObjcParameter &other) : Parameter() {
-    };
-
-    ObjcParameter &operator=(const ObjcParameter &other)
-    {
-        if (this == &other)
-            return *this;
-                    
-        return *this;
-    }
+    ObjcField(Ivar ivar);
     
-    virtual RuntimeType type() {}
-    
-private:
-};
-
+    ~ObjcField() {};
 
-class ObjcConstructor : public Constructor
-{
-public:
-    ObjcConstructor() : _parameters (0), _numParameters(0) {};
-        
-    ~ObjcConstructor() {
-        delete [] _parameters;
+    ObjcField(const ObjcField &other) : Field() {
+        _ivar = other._ivar;
     };
-
-    void _commonCopy(const ObjcConstructor &other) {
-        _numParameters = other._numParameters;
-        _parameters = new ObjcParameter[_numParameters];
-        long i;
-        for (i = 0; i < _numParameters; i++) {
-            _parameters[i] = other._parameters[i];
-        }
-    }
     
-    ObjcConstructor(const ObjcConstructor &other) : Constructor() {
-        _commonCopy (other);
-    };
-
-    ObjcConstructor &operator=(const ObjcConstructor &other)
-    {
+    ObjcField &operator=(const ObjcField &other) {
         if (this == &other)
             return *this;
-            
-        delete [] _parameters;
-        
-        _commonCopy (other);
 
+        _ivar = other._ivar;
+        
         return *this;
-    }
-
-    virtual KJS::Value value() const { return KJS::Value(0); }
-    virtual Parameter *parameterAt(long i) const { return &_parameters[i]; };
-    virtual long numParameters() const { return _numParameters; };
-    
-private:
-    ObjcParameter *_parameters;
-    long _numParameters;
-};
-
-
-class ObjcField : public Field
-{
-public:
-    ObjcField() {};
-    ~ObjcField() {};
-
-    ObjcField(const ObjcField &other);
-    ObjcField &operator=(const ObjcField &other);
+    };
         
     virtual KJS::Value valueFromInstance(const Instance *instance) const;
     virtual void setValueToInstance(KJS::ExecState *exec, const Instance *instance, const KJS::Value &aValue) const;
@@ -122,41 +66,43 @@ public:
     virtual RuntimeType type() const;
     
 private:
+    Ivar _ivar;
 };
 
 
 class ObjcMethod : public Method
 {
 public:
-    ObjcMethod() : Method();
-    ~ObjcMethod ();
+    ObjcMethod() : Method(), _objcClass(0), _selector(0) {};
 
-    ObjcMethod(const ObjcMethod &other) : Method();
-    ObjcMethod &operator=(const ObjcMethod &other);
+    ObjcMethod(struct objc_class *aClass, const char *_selector);
+    ~ObjcMethod () {
+    };
 
-    virtual const char *name() const;
-    virtual RuntimeType returnType() const;
-    virtual Parameter *parameterAt(long i) const;
-    virtual long numParameters() const;
+    ObjcMethod(const ObjcMethod &other) : Method() {
+        _objcClass = other._objcClass;
+        _selector = other._selector;
+    };
     
-private:
-};
+    ObjcMethod &operator=(const ObjcMethod &other) {
+        if (this == &other)
+            return *this;
 
-class ObjcArray : public Array
-{
-public:
-    ObjcArray (jobject a, const char *type);
-    virtual ~ObjcArray();
+        _objcClass = other._objcClass;
+        _selector = other._selector;
+        
+        return *this;
+    }
 
-    ObjcArray (const ObjcArray &other);
-    ObjcArray &operator=(const ObjcArray &other);
+    virtual const char *name() const;
 
-    virtual void setValueAt(KJS::ExecState *exec, unsigned int index, const KJS::Value &aValue) const;
-    virtual KJS::Value valueAt(unsigned int index) const;
-    virtual unsigned int getLength() const;
+    virtual long numParameters() const;
+    
+    NSMethodSignature *getMethodSignature() const;
     
-
 private:
+    struct objc_class *_objcClass;
+    const char *_selector;
 };
 
 } // namespace Bindings
diff --git a/JavaScriptCore/bindings/objc/objc_runtime.mm b/JavaScriptCore/bindings/objc/objc_runtime.mm
new file mode 100644 (file)
index 0000000..89de8f6
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#include <Foundation/Foundation.h>
+
+#include <objc_instance.h>
+
+#include <runtime_array.h>
+#include <runtime_object.h>
+
+
+using namespace KJS;
+using namespace KJS::Bindings;
+
+
+ObjcMethod::ObjcMethod(ClassStructPtr aClass, const char *name)
+{
+    _objcClass = aClass;
+    _selector = name;   // Assume ObjC runtime keeps these around forever.
+}
+
+const char *ObjcMethod::name() const
+{
+    return (const char *)_selector;
+}
+
+long ObjcMethod::numParameters() const
+{
+    return [getMethodSignature() numberOfArguments] - 2;
+}
+
+
+NSMethodSignature *ObjcMethod::getMethodSignature() const
+{
+    return [(id)_objcClass instanceMethodSignatureForSelector:(SEL)_selector];
+}
+
+
+ObjcField::ObjcField(Ivar ivar) 
+{
+    _ivar = ivar;    // Assume ObjectiveC runtime will keep this alive forever
+}
+
+const char *ObjcField::name() const 
+{
+    return _ivar->ivar_name;
+}
+
+RuntimeType ObjcField::type() const 
+{
+    return _ivar->ivar_type;
+}
+
+Value ObjcField::valueFromInstance(const Instance *instance) const
+{
+    Value aValue;
+    char *ivarValuePtr = ((char *)(static_cast<const ObjcInstance*>(instance))->getObject() + _ivar->ivar_offset);
+
+    ObjcValueType ctype = objcValueTypeForType(_ivar->ivar_type);
+    switch (ctype){
+        case ObjcVoidType: {
+            aValue = Undefined();
+        }
+        break;
+        
+        case ObjcObjectType: {
+            ObjectStructPtr obj = *(ObjectStructPtr *)(ivarValuePtr);
+            Instance *anInstance = Instance::createBindingForLanguageInstance (Instance::ObjectiveCLanguage, (void *)obj);
+            aValue = Object(new RuntimeObjectImp(anInstance,true));
+        }
+        break;
+        
+        case ObjcCharType: {
+            char aChar = *(char *)(ivarValuePtr);
+            aValue = Number(aChar);
+        }
+        break;
+        
+        case ObjcShortType: {
+            short aShort = *(short *)(ivarValuePtr);
+            aValue = Number(aShort);
+        }
+        break;
+        
+        case ObjcIntType: {
+            int anInt = *(int *)(ivarValuePtr);
+            aValue = Number(anInt);
+        }
+        break;
+        
+        case ObjcLongType: {
+            long aLong = *(long *)(ivarValuePtr);
+            aValue = Number(aLong);
+        }
+        break;
+        
+        case ObjcFloatType: {
+            float aFloat = *(float *)(ivarValuePtr);
+            aValue = Number(aFloat);
+        }
+        break;
+        
+        case ObjcDoubleType: {
+            double aDouble = *(double *)(ivarValuePtr);
+            aValue = Number(aDouble);
+        }
+        break;
+        
+        
+        case ObjcInvalidType:
+        default: {
+            aValue = Undefined();
+        }
+        break;
+    }
+    return aValue;
+}
+
+void ObjcField::setValueToInstance(KJS::ExecState *exec, const Instance *instance, const KJS::Value &aValue) const
+{
+    char *ivarValuePtr = ((char *)(static_cast<const ObjcInstance*>(instance))->getObject() + _ivar->ivar_offset);
+
+    ObjcValueType ctype = objcValueTypeForType(_ivar->ivar_type);
+    ObjcValue result = convertValueToObjcValue(exec, aValue, ctype);
+    switch (ctype){
+        case ObjcVoidType: {
+        }
+        break;
+        
+        case ObjcObjectType: {
+            // First see if we have an ObjC instance.
+            if (aValue.type() == KJS::ObjectType){
+                ObjcValue result = convertValueToObjcValue(exec, aValue, objcValueTypeForType(_ivar->ivar_type));
+                *(ObjectStructPtr *)(ivarValuePtr) = result.objectValue;
+            }
+            
+            // FIXME.  Deal with arrays.
+            
+            // FIXME.  Deal with strings.
+        }
+        break;
+        
+        case ObjcCharType: {
+            *(char *)(ivarValuePtr) = result.charValue;
+        }
+        break;
+        
+        case ObjcShortType: {
+            *(short *)(ivarValuePtr) = result.shortValue;
+        }
+        break;
+        
+        case ObjcIntType: {
+            *(int *)(ivarValuePtr) = result.intValue;
+        }
+        break;
+        
+        case ObjcLongType: {
+            *(long *)(ivarValuePtr) = result.longValue;
+        }
+        break;
+        
+        case ObjcFloatType: {
+            *(float *)(ivarValuePtr) = result.floatValue;
+        }
+        break;
+        
+        case ObjcDoubleType: {
+            *(double *)(ivarValuePtr) = result.doubleValue;
+        }
+        break;
+        
+        case ObjcInvalidType:
+        default: {
+            // FIXME:  Throw an exception?
+        }
+        break;
+    }
+}
+
+
diff --git a/JavaScriptCore/bindings/objc/objc_utility.h b/JavaScriptCore/bindings/objc/objc_utility.h
new file mode 100644 (file)
index 0000000..ac43421
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#ifndef _BINDINGS_OBJC_UTILITY_H_
+#define _BINDINGS_OBJC_UTILITY_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <value.h>
+
+#include <objc_header.h>
+
+namespace KJS
+{
+
+namespace Bindings 
+{
+
+typedef union {
+    ObjectStructPtr objectValue;
+    bool booleanValue;
+    char charValue;
+    short shortValue;
+    int intValue;
+    long longValue;
+    float floatValue;
+    double doubleValue;
+} ObjcValue;
+
+typedef enum {
+    ObjcVoidType,
+    ObjcObjectType,
+    ObjcCharType,
+    ObjcShortType,
+    ObjcIntType,
+    ObjcLongType,
+    ObjcFloatType,
+    ObjcDoubleType,
+    ObjcInvalidType
+} ObjcValueType;
+
+ObjcValue convertValueToObjcValue (KJS::ExecState *exec, KJS::Value value, ObjcValueType type);
+Value convertObjcValueToValue (KJS::ExecState *exec, void *buffer, ObjcValueType type);
+ObjcValueType objcValueTypeForType (const char *type);
+
+void JSMethodNameToObjCMethodName(const char *name, char *name, unsigned int length);
+
+} // namespace Bindings
+
+} // namespace KJS
+
+#endif
diff --git a/JavaScriptCore/bindings/objc/objc_utility.mm b/JavaScriptCore/bindings/objc/objc_utility.mm
new file mode 100644 (file)
index 0000000..4c0d776
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2004 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+#include <runtime_object.h>
+#include <objc_instance.h>
+#include <objc_utility.h>
+
+using namespace KJS;
+using namespace KJS::Bindings;
+
+/*
+    Convert ObjectiveC method names to palatable JavaScript names.  ":" in
+    ObjectiveC names are converted to "_".  "_" are escaped.
+    
+    For example:
+    
+    logLevel:message:
+    
+    would turn into
+    
+    logLevel_message_
+    
+    This name mapping can be overriden by the ObjectiveC class by implementing
+
+    + (NSString *)JavaScriptNameForSelector:(SEL)aSelector;
+    
+    See objc_jsobject.h for more details.
+*/
+void KJS::Bindings::JSMethodNameToObjCMethodName(const char *name, char *buffer, unsigned int len)
+{
+    const char *np = name;
+    char *bp;
+
+    if (strlen(name)*2+1 > len){
+        *buffer = 0;
+    }
+
+    bp = buffer;
+    while (*np) {
+        if (*np == '_') {
+            if (*(np+1) == '_') {
+                *bp++ = '_';
+                np += 2;
+            }
+            else {
+                *bp++ = ':';
+                np++;
+            }
+        }
+        else
+            *bp++ = *np++;
+    }
+    *bp++ = 0;
+}
+
+/*
+
+    JavaScript to   ObjC
+    Number          coerced to char, short, int, long, float, or double as appropriate
+    String          NSString
+    wrapper         id
+    Object          JavaScriptObject
+    [], other       exception
+
+*/
+ObjcValue KJS::Bindings::convertValueToObjcValue (KJS::ExecState *exec, KJS::Value value, ObjcValueType type)
+{
+    ObjcValue result;
+    double d = 0;
+   
+    d = value.toNumber(exec);
+    switch (type){
+        case ObjcObjectType: {
+            result.objectValue = 0;
+            
+            // First see if we have a ObjC instance.
+            if (value.type() == KJS::ObjectType){
+                KJS::ObjectImp *objectImp = static_cast<KJS::ObjectImp*>(value.imp());
+                if (strcmp(objectImp->classInfo()->className, "RuntimeObject") == 0) {
+                    KJS::RuntimeObjectImp *imp = static_cast<KJS::RuntimeObjectImp *>(value.imp());
+                    ObjcInstance *instance = static_cast<ObjcInstance*>(imp->getInternalInstance());
+                    if (instance)
+                        result.objectValue = instance->getObject();
+                }
+            }
+            
+            // FIXME:  Deal with String to NSString conversion.
+            
+            // FIXME:  Deal with other Object types by creating a JavaScriptObjects
+        }
+        break;
+        
+        
+        case ObjcCharType: {
+            result.charValue = (char)d;
+        }
+        break;
+
+        case ObjcShortType: {
+            result.shortValue = (short)d;
+        }
+        break;
+
+        case ObjcIntType: {
+            result.intValue = (int)d;
+        }
+        break;
+
+        case ObjcLongType: {
+            result.longValue = (long)d;
+        }
+        break;
+
+        case ObjcFloatType: {
+            result.floatValue = (float)d;
+        }
+        break;
+
+        case ObjcDoubleType: {
+            result.doubleValue = (double)d;
+        }
+        break;
+            
+        break;
+
+        case ObjcVoidType: {
+            bzero (&result, sizeof(ObjcValue));
+        }
+        break;
+
+        case ObjcInvalidType:
+        default:
+        {
+            // FIXME:  throw an exception
+        }
+        break;
+    }
+    return result;
+}
+
+/*
+
+    ObjC      to    JavaScript
+    char            Number
+    short
+    int
+    long
+    float
+    double
+    NSString        string
+    NSArray         []
+    id              wrapper
+    other           should not happen
+
+*/
+Value KJS::Bindings::convertObjcValueToValue (KJS::ExecState *exec, void *buffer, ObjcValueType type)
+{
+    Value aValue;
+
+    switch (type) {
+        case ObjcObjectType:
+            {
+                ObjectStructPtr *obj = (ObjectStructPtr *)buffer;
+                aValue = Object(new RuntimeObjectImp(new ObjcInstance (*obj)));
+                
+                // FIXME:  Deal with NSString to String conversions.
+                
+                // FIXME:  Deal with NSArray to Array conversions.
+            }
+            break;
+        case ObjcCharType:
+            {
+                char *objcVal = (char *)buffer;
+                aValue = Number ((short)*objcVal);
+            }
+            break;
+        case ObjcShortType:
+            {
+                short *objcVal = (short *)buffer;
+                aValue = Number ((short)*objcVal);
+            }
+            break;
+        case ObjcIntType:
+            {
+                int *objcVal = (int *)buffer;
+                aValue = Number ((int)*objcVal);
+            }
+            break;
+        case ObjcLongType:
+            {
+                long *objcVal = (long *)buffer;
+                aValue = Number ((long)*objcVal);
+            }
+            break;
+        case ObjcFloatType:
+            {
+                float *objcVal = (float *)buffer;
+                aValue = Number ((float)*objcVal);
+            }
+            break;
+        case ObjcDoubleType:
+            {
+                double *objcVal = (double *)buffer;
+                aValue = Number ((double)*objcVal);
+            }
+            break;
+        default:
+            // Should never get here.  Argument types are filtered (and
+            // the assert above should have fired in the impossible case
+            // of an invalid type anyway).
+            fprintf (stderr, "%s:  invalid type (%d)\n", __PRETTY_FUNCTION__, (int)type);
+            assert (true);
+    }
+    
+    return aValue;
+}
+
+
+ObjcValueType KJS::Bindings::objcValueTypeForType (const char *type)
+{
+    int typeLength = strlen(type);
+    ObjcValueType objcValueType = ObjcInvalidType;
+    
+    if (typeLength == 1) {
+        char typeChar = type[0];
+        switch (typeChar){
+            case _C_ID: {
+                objcValueType = ObjcObjectType;
+            }
+            break;
+            case _C_CHR: {
+                objcValueType = ObjcCharType;
+            }
+            break;
+            case _C_SHT: {
+                objcValueType = ObjcShortType;
+            }
+            break;
+            case _C_INT: {
+                objcValueType = ObjcIntType;
+            }
+            break;
+            case _C_LNG: {
+                objcValueType = ObjcLongType;
+            }
+            break;
+            case _C_FLT: {
+                objcValueType = ObjcFloatType;
+            }
+            break;
+            case _C_DBL: {
+                objcValueType = ObjcDoubleType;
+            }
+            break;
+            case _C_VOID: {
+                objcValueType = ObjcVoidType;
+            }
+            break;
+        }
+    }
+    return objcValueType;
+}
+
+
index 83062e7655b110d765faece33ada0b9e5867ae11..bab211a1d2ef0a04301c835b5f756c9349f09258 100644 (file)
@@ -24,8 +24,9 @@
  */
 #include <value.h>
 
-#include <runtime.h>
+#include <runtime_object.h>
 #include <jni_instance.h>
+#include <objc_instance.h>
 
 using namespace KJS;
 using namespace KJS::Bindings;
@@ -58,14 +59,29 @@ MethodList::~MethodList()
     delete [] _methods;
 }
 
+MethodList::MethodList (const MethodList &other) {
+    _length = other._length;
+    _methods = new Method *[_length];
+    if (_length > 0)
+        memcpy (_methods, other._methods, sizeof(Method *) * _length);
+}
 
-Instance *Instance::createBindingForLanguageInstance (BindingLanguage language, void *instance)
+MethodList &MethodList::operator=(const MethodList &other)
 {
-    if (language == Instance::JavaLanguage)
-        return new Bindings::JavaInstance ((jobject)instance);
-    return 0;
+    if (this == &other)
+        return *this;
+            
+    delete [] _methods;
+    
+    _length = other._length;
+    _methods = new Method *[_length];
+    if (_length > 0)
+        memcpy (_methods, other._methods, sizeof(Method *) * _length);
+
+    return *this;
 }
 
+
 Value Instance::getValueOfField (const Field *aField) const {  
     return aField->valueFromInstance (this);
 }
@@ -73,3 +89,18 @@ Value Instance::getValueOfField (const Field *aField) const {
 void Instance::setValueOfField (KJS::ExecState *exec, const Field *aField, const Value &aValue) const {  
     return aField->setValueToInstance (exec, this, aValue);
 }
+
+Instance *Instance::createBindingForLanguageInstance (BindingLanguage language, void *instance)
+{
+    if (language == Instance::JavaLanguage)
+        return new Bindings::JavaInstance ((jobject)instance);
+    if (language == Instance::ObjectiveCLanguage)
+        return new Bindings::ObjcInstance ((struct objc_object *)instance);
+    return 0;
+}
+
+Object Instance::createRuntimeObject (BindingLanguage language, void *myInterface)
+{
+    Instance *interfaceObject = Instance::createBindingForLanguageInstance (language, (void *)myInterface);
+    return Object(new RuntimeObjectImp(interfaceObject,true));
+}
index 92816a02627b89c3b554adbf714e20f4f406fe1a..67b752e6be8bccf10f1cd727e29c6197271bf32b 100644 (file)
@@ -26,6 +26,7 @@
 #define _RUNTIME_H_
 
 #include "list.h"
+#include "object.h"
 #include "value.h"
 
 namespace KJS 
@@ -40,6 +41,7 @@ class Method;
 // For now just use Java style type descriptors.
 typedef const char * RuntimeType;
 
+// FIXME:  Parameter should be removed from abstract runtime classes.
 class Parameter
 {
 public:
@@ -47,6 +49,9 @@ public:
     virtual ~Parameter() {};
 };
 
+// FIXME:  Constructor should be removed from abstract runtime classes
+// unless we want to support instantiation of runtime objects from
+// JavaScript.
 class Constructor
 {
 public:
@@ -80,6 +85,9 @@ public:
     
     ~MethodList();
     
+    MethodList (const MethodList &other);
+    MethodList &operator=(const MethodList &other);
+
 private:
     Method **_methods;
     unsigned int _length;
@@ -90,8 +98,7 @@ class Method
 {
 public:
     virtual const char *name() const = 0;
-    virtual RuntimeType returnType() const = 0;
-    virtual Parameter *parameterAt(long i) const = 0;
+
     virtual long numParameters() const = 0;
         
     virtual ~Method() {};
@@ -102,7 +109,7 @@ class Class
 public:
     virtual const char *name() const = 0;
     
-    virtual MethodList *methodsNamed(const char *name) const = 0;
+    virtual MethodList methodsNamed(const char *name) const = 0;
     
     virtual Constructor *constructorAt(long i) const = 0;
     virtual long numConstructors() const = 0;
@@ -122,6 +129,8 @@ public:
 
     static Instance *createBindingForLanguageInstance (BindingLanguage language, void *instance);
 
+    static Object createRuntimeObject (BindingLanguage language, void *myInterface);
+
     // These functions are called before and after the main entry points into
     // the native implementations.  They can be used to establish and cleanup
     // any needed state.
@@ -133,7 +142,7 @@ public:
     virtual KJS::Value getValueOfField (const Field *aField) const;
     virtual void setValueOfField (KJS::ExecState *exec, const Field *aField, const KJS::Value &aValue) const;
     
-    virtual KJS::Value invokeMethod (KJS::ExecState *exec, const MethodList *method, const KJS::List &args) = 0;
+    virtual KJS::Value invokeMethod (KJS::ExecState *exec, const MethodList &method, const KJS::List &args) = 0;
     
     virtual KJS::Value defaultValue (KJS::Type hint) const = 0;
     
index 48d35387797fb5bb421f186f42c6f3e29f5441c2..308db7707e00739ce966f7ade911a4a3acc427da 100644 (file)
@@ -31,7 +31,7 @@
 using namespace KJS::Bindings;
 using namespace KJS;
 
-RuntimeMethodImp::RuntimeMethodImp(ExecState *exec, const Identifier &ident, Bindings::MethodList *m) : FunctionImp (exec, ident)
+RuntimeMethodImp::RuntimeMethodImp(ExecState *exec, const Identifier &ident, Bindings::MethodList &m) : FunctionImp (exec, ident)
 {
     _methodList = m;
 }
@@ -60,7 +60,7 @@ Value RuntimeMethodImp::get(ExecState *exec, const Identifier &propertyName) con
         // just pick the first method.  The fundamental problem here is that 
         // JavaScript doesn't have the notion of method overloading and
         // Java does.
-        return Number(_methodList->methodAt(0)->numParameters());
+        return Number(_methodList.methodAt(0)->numParameters());
     }
     
     return FunctionImp::get(exec, propertyName);
@@ -73,7 +73,7 @@ bool RuntimeMethodImp::implementsCall() const
 
 Value RuntimeMethodImp::call(ExecState *exec, Object &thisObj, const List &args)
 {
-    if (_methodList) {
+    if (_methodList.length() > 0) {
         RuntimeObjectImp *imp = static_cast<RuntimeObjectImp*>(thisObj.imp());
         if (imp) {
             Instance *instance = imp->getInternalInstance();
index 51bded75ee35d29fa90e8dd23ad0b5d047ff3787..6cfc5a5e44e38044269110bfe01f8efacca8a74f 100644 (file)
@@ -34,7 +34,7 @@ namespace KJS {
 class RuntimeMethodImp : public FunctionImp 
 {
 public:
-    RuntimeMethodImp(ExecState *exec, const Identifier &n = Identifier::null(), Bindings::MethodList *methodList = 0);
+    RuntimeMethodImp(ExecState *exec, const Identifier &n, Bindings::MethodList &methodList);
     
     virtual ~RuntimeMethodImp();
 
@@ -48,7 +48,7 @@ public:
     virtual Completion execute(ExecState *exec);
 
 private:
-    Bindings::MethodList *_methodList;
+    Bindings::MethodList _methodList;
 };
 
 } // namespace KJS
index 6cd5395a44fc113acef2d9a188d174f59ef72784..784f09f729a31166cd064ab3f7efb8fcfe1773f4 100644 (file)
@@ -71,8 +71,8 @@ Value RuntimeObjectImp::get(ExecState *exec, const Identifier &propertyName) con
     
     // Now check if a method with specified name exists, if so return a function object for
     // that method.
-    MethodList *methodList = instance->getClass()->methodsNamed(propertyName.ascii());
-    if (methodList) {
+    MethodList methodList = instance->getClass()->methodsNamed(propertyName.ascii());
+    if (methodList.length() > 0) {
         instance->end();
         return Object (new RuntimeMethodImp(exec, propertyName, methodList));
     }
@@ -118,11 +118,11 @@ bool RuntimeObjectImp::hasProperty(ExecState *exec,
         return true;
     }
         
-    MethodList *methodList = instance->getClass()->methodsNamed(propertyName.ascii());
+    MethodList methodList = instance->getClass()->methodsNamed(propertyName.ascii());
 
     instance->end();
 
-    if (methodList)
+    if (methodList.length() > 0)
         return true;
         
     return false;
diff --git a/JavaScriptCore/bindings/test.js b/JavaScriptCore/bindings/test.js
new file mode 100644 (file)
index 0000000..89a6c8e
--- /dev/null
@@ -0,0 +1,12 @@
+myInterface.logMessage ("starting test");
+
+myInterface.logMessage ("myInterface.getInt() = " + myInterface.getInt());
+
+myInterface.logMessage ("myInterface.setInt_(666) = " + myInterface.setInt_(666));
+myInterface.logMessage ("myInterface.getInt() = " + myInterface.getInt());
+myInterface.logMessage ("myInterface.myInt = " + myInterface.myInt);
+myInterface.logMessage ("setting myInterface.myInt = 777");
+myInterface.myInt = 777;
+myInterface.logMessage ("myInterface.myInt = " + myInterface.myInt);
+myInterface.logMessage ("myInterface.getMySecondInterface().doubleValue = " + myInterface.getMySecondInterface().doubleValue);
+myInterface.logMessage ("myInterface.getMySecondInterface() = " + myInterface.getMySecondInterface());
diff --git a/JavaScriptCore/bindings/testbindings.mm b/JavaScriptCore/bindings/testbindings.mm
new file mode 100644 (file)
index 0000000..8c4d298
--- /dev/null
@@ -0,0 +1,212 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ *  This file is part of the KDE libraries
+ *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *  Boston, MA 02111-1307, USA.
+ *
+ */
+#include <Foundation/Foundation.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "value.h"
+#include "object.h"
+#include "types.h"
+#include "interpreter.h"
+
+#include "runtime.h"
+#include "runtime_object.h"
+
+
+#define LOG(formatAndArgs...) { \
+    fprintf (stderr, "%s:  ", __PRETTY_FUNCTION__); \
+    fprintf(stderr, formatAndArgs); \
+}
+
+@interface MySecondInterface : NSObject
+{
+    double doubleValue;
+}
+
+- init;
+
+@end
+
+@implementation MySecondInterface
+
+- init
+{
+    LOG ("\n");
+    doubleValue = 666.666;
+    return self;
+}
+
+@end
+
+@interface MyFirstInterface : NSObject
+{
+       int myInt;
+       MySecondInterface *mySecondInterface;
+}
+
+- (int)getInt;
+- (void)setInt: (int)anInt;
+- (MySecondInterface *)getMySecondInterface;
+- (void)logMessage:(NSString *)message;
+
+@end
+
+@implementation MyFirstInterface
+
+- init
+{
+    LOG ("\n");
+    mySecondInterface = [[MySecondInterface alloc] init];
+    return self;
+}
+
+- (void)dealloc
+{
+    LOG ("\n");
+    [mySecondInterface release];
+    [super dealloc];
+}
+
++ (NSString *)JavaScriptNameForSelector:(SEL)aSelector
+{
+    if (aSelector == @selector(logMessage:))
+        return @"logMessage";
+    return nil;
+}
+
+- (int)getInt 
+{
+    LOG ("myInt = %d\n", myInt);
+    return myInt;
+}
+
+- (void)setInt: (int)anInt 
+{
+    LOG ("anInt = %d\n", anInt);
+    myInt = anInt;
+}
+
+- (MySecondInterface *)getMySecondInterface 
+{
+    LOG ("\n");
+    return mySecondInterface;
+}
+
+- (void)logMessage:(NSString *)message
+{
+    printf ("%s\n", [message lossyCString]);
+}
+
+@end
+
+
+using namespace KJS;
+using namespace KJS::Bindings;
+
+class GlobalImp : public ObjectImp {
+public:
+  virtual UString className() const { return "global"; }
+};
+
+#define BufferSize 200000
+static char code[BufferSize];
+
+const char *readJavaScriptFromFile (const char *file)
+{
+    FILE *f = fopen(file, "r");
+    if (!f) {
+        fprintf(stderr, "Error opening %s.\n", file);
+        return 0;
+    }
+    
+    int num = fread(code, 1, BufferSize, f);
+    code[num] = '\0';
+    if(num >= BufferSize)
+        fprintf(stderr, "Warning: File may have been too long.\n");
+
+    fclose(f);
+    
+    return code;
+}
+
+int main(int argc, char **argv)
+{
+    // expecting a filename
+    if (argc < 2) {
+        fprintf(stderr, "You have to specify at least one filename\n");
+        return -1;
+    }
+    
+    bool ret = true;
+    {
+        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+        
+        Interpreter::lock();
+        
+        // create interpreter w/ global object
+        Object global(new GlobalImp());
+        Interpreter interp(global);
+        ExecState *exec = interp.globalExec();
+        
+        MyFirstInterface *myInterface = [[MyFirstInterface alloc] init];
+        
+        global.put(exec, Identifier("myInterface"), Instance::createRuntimeObject(Instance::ObjectiveCLanguage, (void *)myInterface));
+        
+        for (int i = 1; i < argc; i++) {
+            const char *code = readJavaScriptFromFile(argv[i]);
+            
+            if (code) {
+                // run
+                Completion comp(interp.evaluate(code));
+                
+                if (comp.complType() == Throw) {
+                    Value exVal = comp.value();
+                    char *msg = exVal.toString(exec).ascii();
+                    int lineno = -1;
+                    if (exVal.type() == ObjectType) {
+                        Value lineVal = Object::dynamicCast(exVal).get(exec,Identifier("line"));
+                        if (lineVal.type() == NumberType)
+                            lineno = int(lineVal.toNumber(exec));
+                    }
+                    if (lineno != -1)
+                        fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
+                    else
+                        fprintf(stderr,"Exception: %s\n",msg);
+                    ret = false;
+                }
+                else if (comp.complType() == ReturnValue) {
+                    char *msg = comp.value().toString(interp.globalExec()).ascii();
+                    fprintf(stderr,"Return value: %s\n",msg);
+                }
+            }
+        }
+        
+        [myInterface release];
+        
+        Interpreter::unlock();
+        
+        [pool release];
+    } // end block, so that Interpreter and global get deleted
+    
+    return ret ? 0 : 3;
+}