2011-01-07 Adam Barth <abarth@webkit.org>
[WebKit-https.git] / Source / WebCore / bridge / testbindings.mm
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 }