|
1 /* |
|
2 * Copyright (C) 2004 Apple Computer, Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions |
|
6 * are met: |
|
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. |
|
12 * |
|
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. |
|
24 */ |
|
25 |
|
26 #include "config.h" |
|
27 |
|
28 #include "Bridge.h" |
|
29 #include <Foundation/Foundation.h> |
|
30 #include "JSObject.h" |
|
31 #include "JSValue.h" |
|
32 #import <WebKit/WebScriptObject.h> |
|
33 #include "interpreter.h" |
|
34 #include "runtime_object.h" |
|
35 #include <stdio.h> |
|
36 #include <string.h> |
|
37 #include "types.h" |
|
38 |
|
39 |
|
40 #define LOG(formatAndArgs...) { \ |
|
41 fprintf (stderr, "%s: ", __PRETTY_FUNCTION__); \ |
|
42 fprintf(stderr, formatAndArgs); \ |
|
43 } |
|
44 |
|
45 @interface MySecondInterface : NSObject |
|
46 { |
|
47 double doubleValue; |
|
48 } |
|
49 |
|
50 - init; |
|
51 |
|
52 @end |
|
53 |
|
54 @implementation MySecondInterface |
|
55 |
|
56 - init |
|
57 { |
|
58 LOG ("\n"); |
|
59 doubleValue = 666.666; |
|
60 return self; |
|
61 } |
|
62 |
|
63 @end |
|
64 |
|
65 @interface MyFirstInterface : NSObject |
|
66 { |
|
67 int myInt; |
|
68 MySecondInterface *mySecondInterface; |
|
69 id jsobject; |
|
70 NSString *string; |
|
71 } |
|
72 |
|
73 - (int)getInt; |
|
74 - (void)setInt: (int)anInt; |
|
75 - (MySecondInterface *)getMySecondInterface; |
|
76 - (void)logMessage:(NSString *)message; |
|
77 - (void)setJSObject:(id)jsobject; |
|
78 @end |
|
79 |
|
80 @implementation MyFirstInterface |
|
81 |
|
82 + (NSString *)webScriptNameForSelector:(SEL)aSelector |
|
83 { |
|
84 if (aSelector == @selector(logMessage:)) |
|
85 return @"logMessage"; |
|
86 if (aSelector == @selector(logMessages:)) |
|
87 return @"logMessages"; |
|
88 if (aSelector == @selector(logMessage:prefix:)) |
|
89 return @"logMessageWithPrefix"; |
|
90 return nil; |
|
91 } |
|
92 |
|
93 + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector |
|
94 { |
|
95 return NO; |
|
96 } |
|
97 |
|
98 + (BOOL)isKeyExcludedFromWebScript:(const char *)name |
|
99 { |
|
100 return NO; |
|
101 } |
|
102 |
|
103 /* |
|
104 - (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args |
|
105 { |
|
106 NSLog (@"Call to undefined method %@", name); |
|
107 NSLog (@"%d args\n", [args count]); |
|
108 int i; |
|
109 for (i = 0; i < [args count]; i++) { |
|
110 NSLog (@"%d: %@\n", i, [args objectAtIndex:i]); |
|
111 } |
|
112 return @"success"; |
|
113 } |
|
114 */ |
|
115 |
|
116 /* |
|
117 - (id)valueForUndefinedKey:(NSString *)key |
|
118 { |
|
119 NSLog (@"%s: key = %@", __PRETTY_FUNCTION__, key); |
|
120 return @"aValue"; |
|
121 } |
|
122 */ |
|
123 |
|
124 - (void)setValue:(id)value forUndefinedKey:(NSString *)key |
|
125 { |
|
126 NSLog (@"%s: key = %@", __PRETTY_FUNCTION__, key); |
|
127 } |
|
128 |
|
129 - init |
|
130 { |
|
131 LOG ("\n"); |
|
132 mySecondInterface = [[MySecondInterface alloc] init]; |
|
133 return self; |
|
134 } |
|
135 |
|
136 - (void)dealloc |
|
137 { |
|
138 LOG ("\n"); |
|
139 [mySecondInterface release]; |
|
140 [super dealloc]; |
|
141 } |
|
142 |
|
143 - (int)getInt |
|
144 { |
|
145 LOG ("myInt = %d\n", myInt); |
|
146 return myInt; |
|
147 } |
|
148 |
|
149 - (void)setInt: (int)anInt |
|
150 { |
|
151 LOG ("anInt = %d\n", anInt); |
|
152 myInt = anInt; |
|
153 } |
|
154 |
|
155 - (NSString *)getString |
|
156 { |
|
157 return string; |
|
158 } |
|
159 |
|
160 - (MySecondInterface *)getMySecondInterface |
|
161 { |
|
162 LOG ("\n"); |
|
163 return mySecondInterface; |
|
164 } |
|
165 |
|
166 - (void)logMessage:(NSString *)message |
|
167 { |
|
168 printf ("%s\n", [message lossyCString]); |
|
169 } |
|
170 |
|
171 - (void)logMessages:(id)messages |
|
172 { |
|
173 int i, count = [[messages valueForKey:@"length"] intValue]; |
|
174 for (i = 0; i < count; i++) |
|
175 printf ("%s\n", [[messages webScriptValueAtIndex:i] lossyCString]); |
|
176 } |
|
177 |
|
178 - (void)logMessage:(NSString *)message prefix:(NSString *)prefix |
|
179 { |
|
180 printf ("%s:%s\n", [prefix lossyCString], [message lossyCString]); |
|
181 } |
|
182 |
|
183 - (void)setJSObject:(id)jso |
|
184 { |
|
185 [jsobject autorelease]; |
|
186 jsobject = [jso retain]; |
|
187 } |
|
188 |
|
189 - (void)callJSObject:(int)arg1 :(int)arg2 |
|
190 { |
|
191 id foo1 = [jsobject callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObjects:jsobject, [NSNumber numberWithInt:arg1], [NSNumber numberWithInt:arg2], nil]]; |
|
192 printf ("foo (via call) = %s\n", [[foo1 description] lossyCString] ); |
|
193 id foo2 = [jsobject callWebScriptMethod:@"apply" withArguments:[NSArray arrayWithObjects:jsobject, [NSArray arrayWithObjects:[NSNumber numberWithInt:arg1], [NSNumber numberWithInt:arg2], nil], nil]]; |
|
194 printf ("foo (via apply) = %s\n", [[foo2 description] lossyCString] ); |
|
195 } |
|
196 |
|
197 @end |
|
198 |
|
199 |
|
200 using namespace JSC; |
|
201 using namespace JSC::Bindings; |
|
202 |
|
203 class GlobalImp : public ObjectImp { |
|
204 public: |
|
205 virtual UString className() const { return "global"; } |
|
206 }; |
|
207 |
|
208 #define BufferSize 200000 |
|
209 static char code[BufferSize]; |
|
210 |
|
211 const char *readJavaScriptFromFile (const char *file) |
|
212 { |
|
213 FILE *f = fopen(file, "r"); |
|
214 if (!f) { |
|
215 fprintf(stderr, "Error opening %s.\n", file); |
|
216 return 0; |
|
217 } |
|
218 |
|
219 int num = fread(code, 1, BufferSize, f); |
|
220 code[num] = '\0'; |
|
221 if(num >= BufferSize) |
|
222 fprintf(stderr, "Warning: File may have been too long.\n"); |
|
223 |
|
224 fclose(f); |
|
225 |
|
226 return code; |
|
227 } |
|
228 |
|
229 int main(int argc, char **argv) |
|
230 { |
|
231 // expecting a filename |
|
232 if (argc < 2) { |
|
233 fprintf(stderr, "You have to specify at least one filename\n"); |
|
234 return -1; |
|
235 } |
|
236 |
|
237 bool ret = true; |
|
238 { |
|
239 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
|
240 |
|
241 JSLock lock; |
|
242 |
|
243 // create interpreter w/ global object |
|
244 Object global(new GlobalImp()); |
|
245 Interpreter interp; |
|
246 interp.setGlobalObject(global); |
|
247 ExecState *exec = interp.globalExec(); |
|
248 |
|
249 MyFirstInterface *myInterface = [[MyFirstInterface alloc] init]; |
|
250 |
|
251 global.put(exec, Identifier("myInterface"), Instance::createRuntimeObject(Instance::ObjectiveCLanguage, (void *)myInterface)); |
|
252 |
|
253 for (int i = 1; i < argc; i++) { |
|
254 const char *code = readJavaScriptFromFile(argv[i]); |
|
255 |
|
256 if (code) { |
|
257 // run |
|
258 Completion comp(interp.evaluate(code)); |
|
259 |
|
260 if (comp.complType() == Throw) { |
|
261 Value exVal = comp.value(); |
|
262 char *msg = exVal.toString(exec).ascii(); |
|
263 int lineno = -1; |
|
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)); |
|
268 } |
|
269 if (lineno != -1) |
|
270 fprintf(stderr,"Exception, line %d: %s\n",lineno,msg); |
|
271 else |
|
272 fprintf(stderr,"Exception: %s\n",msg); |
|
273 ret = false; |
|
274 } |
|
275 else if (comp.complType() == ReturnValue) { |
|
276 char *msg = comp.value().toString(interp.globalExec()).ascii(); |
|
277 fprintf(stderr,"Return value: %s\n",msg); |
|
278 } |
|
279 } |
|
280 } |
|
281 |
|
282 [myInterface release]; |
|
283 [pool drain]; |
|
284 } // end block, so that Interpreter and global get deleted |
|
285 |
|
286 return ret ? 0 : 3; |
|
287 } |