2 * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include <Foundation/Foundation.h>
28 #import <WebKit/WebScriptObject.h>
36 #include "interpreter.h"
39 #include "runtime_object.h"
41 #define LOG(formatAndArgs...) { \
42 fprintf (stderr, "%s: ", __PRETTY_FUNCTION__); \
43 fprintf(stderr, formatAndArgs); \
46 @interface MySecondInterface : NSObject
55 @implementation MySecondInterface
60 doubleValue = 666.666;
66 @interface MyFirstInterface : NSObject
69 MySecondInterface *mySecondInterface;
75 - (void)setInt: (int)anInt;
76 - (MySecondInterface *)getMySecondInterface;
77 - (void)logMessage:(NSString *)message;
78 - (void)setJSObject:(id)jsobject;
81 @implementation MyFirstInterface
83 + (NSString *)webScriptNameForSelector:(SEL)aSelector
85 if (aSelector == @selector(logMessage:))
87 if (aSelector == @selector(logMessages:))
88 return @"logMessages";
89 if (aSelector == @selector(logMessage:prefix:))
90 return @"logMessageWithPrefix";
94 + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
99 + (BOOL)isKeyExcludedFromWebScript:(const char *)name
105 - (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args;
107 NSLog (@"Call to undefined method %@", name);
108 NSLog (@"%d args\n", [args count]);
110 for (i = 0; i < [args count]; i++) {
111 NSLog (@"%d: %@\n", i, [args objectAtIndex:i]);
118 - (id)valueForUndefinedKey:(NSString *)key
120 NSLog (@"%s: key = %@", __PRETTY_FUNCTION__, key);
125 - (void)setValue:(id)value forUndefinedKey:(NSString *)key
127 NSLog (@"%s: key = %@", __PRETTY_FUNCTION__, key);
133 mySecondInterface = [[MySecondInterface alloc] init];
140 [mySecondInterface release];
146 LOG ("myInt = %d\n", myInt);
150 - (void)setInt: (int)anInt
152 LOG ("anInt = %d\n", anInt);
156 - (NSString *)getString
161 - (MySecondInterface *)getMySecondInterface
164 return mySecondInterface;
167 - (void)logMessage:(NSString *)message
169 printf ("%s\n", [message lossyCString]);
172 - (void)logMessages:(id)messages
174 int i, count = [[messages valueForKey:@"length"] intValue];
175 for (i = 0; i < count; i++)
176 printf ("%s\n", [[messages webScriptValueAtIndex:i] lossyCString]);
179 - (void)logMessage:(NSString *)message prefix:(NSString *)prefix
181 printf ("%s:%s\n", [prefix lossyCString], [message lossyCString]);
184 - (void)setJSObject:(id)jso
186 [jsobject autorelease];
187 jsobject = [jso retain];
190 - (void)callJSObject:(int)arg1 :(int)arg2
192 id foo1 = [jsobject callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObjects:jsobject, [NSNumber numberWithInt:arg1], [NSNumber numberWithInt:arg2], nil]];
193 printf ("foo (via call) = %s\n", [[foo1 description] lossyCString] );
194 id foo2 = [jsobject callWebScriptMethod:@"apply" withArguments:[NSArray arrayWithObjects:jsobject, [NSArray arrayWithObjects:[NSNumber numberWithInt:arg1], [NSNumber numberWithInt:arg2], nil], nil]];
195 printf ("foo (via apply) = %s\n", [[foo2 description] lossyCString] );
202 using namespace KJS::Bindings;
204 class GlobalImp : public ObjectImp {
206 virtual UString className() const { return "global"; }
209 #define BufferSize 200000
210 static char code[BufferSize];
212 const char *readJavaScriptFromFile (const char *file)
214 FILE *f = fopen(file, "r");
216 fprintf(stderr, "Error opening %s.\n", file);
220 int num = fread(code, 1, BufferSize, f);
222 if(num >= BufferSize)
223 fprintf(stderr, "Warning: File may have been too long.\n");
230 int main(int argc, char **argv)
232 // expecting a filename
234 fprintf(stderr, "You have to specify at least one filename\n");
240 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
244 // create interpreter w/ global object
245 Object global(new GlobalImp());
246 Interpreter interp(global);
247 ExecState *exec = interp.globalExec();
249 MyFirstInterface *myInterface = [[MyFirstInterface alloc] init];
251 global.put(exec, Identifier("myInterface"), Instance::createRuntimeObject(Instance::ObjectiveCLanguage, (void *)myInterface));
253 for (int i = 1; i < argc; i++) {
254 const char *code = readJavaScriptFromFile(argv[i]);
258 Completion comp(interp.evaluate(code));
260 if (comp.complType() == Throw) {
261 Value exVal = comp.value();
262 char *msg = exVal.toString(exec).ascii();
264 if (exVal.type() == ObjectType) {
265 Value lineVal = Object::dynamicCast(exVal).get(exec,Identifier("line"));
266 if (lineVal.type() == NumberType)
267 lineno = int(lineVal.toNumber(exec));
270 fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
272 fprintf(stderr,"Exception: %s\n",msg);
275 else if (comp.complType() == ReturnValue) {
276 char *msg = comp.value().toString(interp.globalExec()).ascii();
277 fprintf(stderr,"Return value: %s\n",msg);
282 [myInterface release];
284 Interpreter::unlock();
286 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3
291 } // end block, so that Interpreter and global get deleted