]> git.saurik.com Git - apple/javascriptcore.git/blob - bindings/testbindings.cpp
JavaScriptCore-461.tar.gz
[apple/javascriptcore.git] / bindings / testbindings.cpp
1 // -*- c-basic-offset: 2 -*-
2 /*
3 * This file is part of the KDE libraries
4 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22 #include "config.h"
23 #include <assert.h>
24 #include <stdio.h>
25 #include <string.h>
26
27 #include "value.h"
28 #include "object.h"
29 #include "types.h"
30 #include "interpreter.h"
31
32 #include "npruntime_internal.h"
33
34 #include "runtime.h"
35 #include "runtime_object.h"
36
37
38 #define LOG(formatAndArgs...) { \
39 fprintf (stderr, "%s: ", __PRETTY_FUNCTION__); \
40 fprintf(stderr, formatAndArgs); \
41 }
42
43
44 // ------------------ NP Interface definition --------------------
45 typedef struct
46 {
47 NPObject object;
48 double doubleValue;
49 int intValue;
50 NPVariant stringValue;
51 bool boolValue;
52 } MyObject;
53
54
55 static bool identifiersInitialized = false;
56
57 #define ID_DOUBLE_VALUE 0
58 #define ID_INT_VALUE 1
59 #define ID_STRING_VALUE 2
60 #define ID_BOOLEAN_VALUE 3
61 #define ID_NULL_VALUE 4
62 #define ID_UNDEFINED_VALUE 5
63 #define NUM_PROPERTY_IDENTIFIERS 6
64
65 static NPIdentifier myPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
66 static const NPUTF8 *myPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
67 "doubleValue",
68 "intValue",
69 "stringValue",
70 "booleanValue",
71 "nullValue",
72 "undefinedValue"
73 };
74
75 #define ID_LOG_MESSAGE 0
76 #define ID_SET_DOUBLE_VALUE 1
77 #define ID_SET_INT_VALUE 2
78 #define ID_SET_STRING_VALUE 3
79 #define ID_SET_BOOLEAN_VALUE 4
80 #define ID_GET_DOUBLE_VALUE 5
81 #define ID_GET_INT_VALUE 6
82 #define ID_GET_STRING_VALUE 7
83 #define ID_GET_BOOLEAN_VALUE 8
84 #define NUM_METHOD_IDENTIFIERS 9
85
86 static NPIdentifier myMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
87 static const NPUTF8 *myMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
88 "logMessage",
89 "setDoubleValue",
90 "setIntValue",
91 "setStringValue",
92 "setBooleanValue",
93 "getDoubleValue",
94 "getIntValue",
95 "getStringValue",
96 "getBooleanValue"
97 };
98
99 static void initializeIdentifiers()
100 {
101 NPN_GetStringIdentifiers (myPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, myPropertyIdentifiers);
102 NPN_GetStringIdentifiers (myMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, myMethodIdentifiers);
103 };
104
105 bool myHasProperty (NPClass *theClass, NPIdentifier name)
106 {
107 int i;
108 for (i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++) {
109 if (name == myPropertyIdentifiers[i]){
110 return true;
111 }
112 }
113 return false;
114 }
115
116 bool myHasMethod (NPClass *theClass, NPIdentifier name)
117 {
118 int i;
119 for (i = 0; i < NUM_METHOD_IDENTIFIERS; i++) {
120 if (name == myMethodIdentifiers[i]){
121 return true;
122 }
123 }
124 return false;
125 }
126
127
128 void logMessage (const NPVariant *message)
129 {
130 if (message->type == NPVariantStringType) {
131 char msgBuf[1024];
132 strncpy (msgBuf, message->value.stringValue.UTF8Characters, message->value.stringValue.UTF8Length);
133 msgBuf[message->value.stringValue.UTF8Length] = 0;
134 printf ("%s\n", msgBuf);
135 }
136 else if (message->type == NPVariantDoubleType)
137 printf ("%f\n", (float)message->value.doubleValue);
138 else if (message->type == NPVariantInt32Type)
139 printf ("%d\n", message->value.intValue);
140 else if (message->type == NPVariantObjectType)
141 printf ("%p\n", message->value.objectValue);
142 }
143
144 void setDoubleValue (MyObject *obj, const NPVariant *variant)
145 {
146 if (!NPN_VariantToDouble (variant, &obj->doubleValue)) {
147 NPUTF8 *msg = "Attempt to set double value with invalid type.";
148 NPString aString;
149 aString.UTF8Characters = msg;
150 aString.UTF8Length = strlen (msg);
151 NPN_SetException ((NPObject *)obj, &aString);
152 }
153 }
154
155 void setIntValue (MyObject *obj, const NPVariant *variant)
156 {
157 if (!NPN_VariantToInt32 (variant, &obj->intValue)) {
158 NPUTF8 *msg = "Attempt to set int value with invalid type.";
159 NPString aString;
160 aString.UTF8Characters = msg;
161 aString.UTF8Length = strlen (msg);
162 NPN_SetException ((NPObject *)obj, &aString);
163 }
164 }
165
166 void setStringValue (MyObject *obj, const NPVariant *variant)
167 {
168 NPN_ReleaseVariantValue (&obj->stringValue);
169 NPN_InitializeVariantWithVariant (&obj->stringValue, variant);
170 }
171
172 void setBooleanValue (MyObject *obj, const NPVariant *variant)
173 {
174 if (!NPN_VariantToBool (variant, (NPBool *)&obj->boolValue)) {
175 NPUTF8 *msg = "Attempt to set bool value with invalid type.";
176 NPString aString;
177 aString.UTF8Characters = msg;
178 aString.UTF8Length = strlen (msg);
179 NPN_SetException ((NPObject *)obj, &aString);
180 }
181 }
182
183 void getDoubleValue (MyObject *obj, NPVariant *variant)
184 {
185 NPN_InitializeVariantWithDouble (variant, obj->doubleValue);
186 }
187
188 void getIntValue (MyObject *obj, NPVariant *variant)
189 {
190 NPN_InitializeVariantWithInt32 (variant, obj->intValue);
191 }
192
193 void getStringValue (MyObject *obj, NPVariant *variant)
194 {
195 NPN_InitializeVariantWithVariant (variant, &obj->stringValue);
196 }
197
198 void getBooleanValue (MyObject *obj, NPVariant *variant)
199 {
200 NPN_InitializeVariantWithBool (variant, obj->boolValue);
201 }
202
203 void myGetProperty (MyObject *obj, NPIdentifier name, NPVariant *variant)
204 {
205 if (name == myPropertyIdentifiers[ID_DOUBLE_VALUE]){
206 getDoubleValue (obj, variant);
207 }
208 else if (name == myPropertyIdentifiers[ID_INT_VALUE]){
209 getIntValue (obj, variant);
210 }
211 else if (name == myPropertyIdentifiers[ID_STRING_VALUE]){
212 getStringValue (obj, variant);
213 }
214 else if (name == myPropertyIdentifiers[ID_BOOLEAN_VALUE]){
215 getBooleanValue (obj, variant);
216 }
217 else if (name == myPropertyIdentifiers[ID_NULL_VALUE]){
218 return NPN_InitializeVariantAsNull (variant);
219 }
220 else if (name == myPropertyIdentifiers[ID_UNDEFINED_VALUE]){
221 return NPN_InitializeVariantAsUndefined (variant);
222 }
223 else
224 NPN_InitializeVariantAsUndefined(variant);
225 }
226
227 void mySetProperty (MyObject *obj, NPIdentifier name, const NPVariant *variant)
228 {
229 if (name == myPropertyIdentifiers[ID_DOUBLE_VALUE]) {
230 setDoubleValue (obj, variant);
231 }
232 else if (name == myPropertyIdentifiers[ID_INT_VALUE]) {
233 setIntValue (obj, variant);
234 }
235 else if (name == myPropertyIdentifiers[ID_STRING_VALUE]) {
236 setStringValue (obj, variant);
237 }
238 else if (name == myPropertyIdentifiers[ID_BOOLEAN_VALUE]) {
239 setBooleanValue (obj, variant);
240 }
241 else if (name == myPropertyIdentifiers[ID_NULL_VALUE]) {
242 // Do nothing!
243 }
244 else if (name == myPropertyIdentifiers[ID_UNDEFINED_VALUE]) {
245 // Do nothing!
246 }
247 }
248
249 void myInvoke (MyObject *obj, NPIdentifier name, NPVariant *args, unsigned argCount, NPVariant *result)
250 {
251 if (name == myMethodIdentifiers[ID_LOG_MESSAGE]) {
252 if (argCount == 1 && NPN_VariantIsString(&args[0]))
253 logMessage (&args[0]);
254 NPN_InitializeVariantAsVoid (result);
255 }
256 else if (name == myMethodIdentifiers[ID_SET_DOUBLE_VALUE]) {
257 if (argCount == 1 && NPN_VariantIsDouble (&args[0]))
258 setDoubleValue (obj, &args[0]);
259 NPN_InitializeVariantAsVoid (result);
260 }
261 else if (name == myMethodIdentifiers[ID_SET_INT_VALUE]) {
262 if (argCount == 1 && (NPN_VariantIsDouble (&args[0]) || NPN_VariantIsInt32 (&args[0])))
263 setIntValue (obj, &args[0]);
264 NPN_InitializeVariantAsVoid (result);
265 }
266 else if (name == myMethodIdentifiers[ID_SET_STRING_VALUE]) {
267 if (argCount == 1 && NPN_VariantIsString (&args[0]))
268 setStringValue (obj, &args[0]);
269 NPN_InitializeVariantAsVoid (result);
270 }
271 else if (name == myMethodIdentifiers[ID_SET_BOOLEAN_VALUE]) {
272 if (argCount == 1 && NPN_VariantIsBool (&args[0]))
273 setBooleanValue (obj, &args[0]);
274 NPN_InitializeVariantAsVoid (result);
275 }
276 else if (name == myMethodIdentifiers[ID_GET_DOUBLE_VALUE]) {
277 getDoubleValue (obj, result);
278 }
279 else if (name == myMethodIdentifiers[ID_GET_INT_VALUE]) {
280 getIntValue (obj, result);
281 }
282 else if (name == myMethodIdentifiers[ID_GET_STRING_VALUE]) {
283 getStringValue (obj, result);
284 }
285 else if (name == myMethodIdentifiers[ID_GET_BOOLEAN_VALUE]) {
286 getBooleanValue (obj, result);
287 }
288 else
289 NPN_InitializeVariantAsUndefined (result);
290 }
291
292 NPObject *myAllocate ()
293 {
294 MyObject *newInstance = (MyObject *)malloc (sizeof(MyObject));
295
296 if (!identifiersInitialized) {
297 identifiersInitialized = true;
298 initializeIdentifiers();
299 }
300
301
302 newInstance->doubleValue = 666.666;
303 newInstance->intValue = 1234;
304 newInstance->boolValue = true;
305 newInstance->stringValue.type = NPVariantType_String;
306 newInstance->stringValue.value.stringValue.UTF8Length = strlen ("Hello world");
307 newInstance->stringValue.value.stringValue.UTF8Characters = strdup ("Hello world");
308
309 return (NPObject *)newInstance;
310 }
311
312 void myInvalidate ()
313 {
314 // Make sure we've released any remaining references to JavaScript objects.
315 }
316
317 void myDeallocate (MyObject *obj)
318 {
319 free ((void *)obj);
320 }
321
322 static NPClass _myFunctionPtrs = {
323 kNPClassStructVersionCurrent,
324 (NPAllocateFunctionPtr) myAllocate,
325 (NPDeallocateFunctionPtr) myDeallocate,
326 (NPInvalidateFunctionPtr) myInvalidate,
327 (NPHasMethodFunctionPtr) myHasMethod,
328 (NPInvokeFunctionPtr) myInvoke,
329 (NPHasPropertyFunctionPtr) myHasProperty,
330 (NPGetPropertyFunctionPtr) myGetProperty,
331 (NPSetPropertyFunctionPtr) mySetProperty,
332 };
333 static NPClass *myFunctionPtrs = &_myFunctionPtrs;
334
335 // --------------------------------------------------------
336
337 using namespace KJS;
338 using namespace KJS::Bindings;
339
340 class GlobalImp : public ObjectImp {
341 public:
342 virtual UString className() const { return "global"; }
343 };
344
345 #define BufferSize 200000
346 static char code[BufferSize];
347
348 const char *readJavaScriptFromFile (const char *file)
349 {
350 FILE *f = fopen(file, "r");
351 if (!f) {
352 fprintf(stderr, "Error opening %s.\n", file);
353 return 0;
354 }
355
356 int num = fread(code, 1, BufferSize, f);
357 code[num] = '\0';
358 if(num >= BufferSize)
359 fprintf(stderr, "Warning: File may have been too long.\n");
360
361 fclose(f);
362
363 return code;
364 }
365
366 int main(int argc, char **argv)
367 {
368 // expecting a filename
369 if (argc < 2) {
370 fprintf(stderr, "You have to specify at least one filename\n");
371 return -1;
372 }
373
374 bool ret = true;
375 {
376 JSLock lock;
377
378 // create interpreter w/ global object
379 Object global(new GlobalImp());
380 Interpreter interp;
381 interp.setGlobalObject(global);
382 ExecState *exec = interp.globalExec();
383
384 MyObject *myObject = (MyObject *)NPN_CreateObject (myFunctionPtrs);
385
386 global.put(exec, Identifier("myInterface"), Instance::createRuntimeObject(Instance::CLanguage, (void *)myObject));
387
388 for (int i = 1; i < argc; i++) {
389 const char *code = readJavaScriptFromFile(argv[i]);
390
391 if (code) {
392 // run
393 Completion comp(interp.evaluate(code));
394
395 if (comp.complType() == Throw) {
396 Value exVal = comp.value();
397 char *msg = exVal.toString(exec).ascii();
398 int lineno = -1;
399 if (exVal.type() == ObjectType) {
400 Value lineVal = Object::dynamicCast(exVal).get(exec,Identifier("line"));
401 if (lineVal.type() == NumberType)
402 lineno = int(lineVal.toNumber(exec));
403 }
404 if (lineno != -1)
405 fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
406 else
407 fprintf(stderr,"Exception: %s\n",msg);
408 ret = false;
409 }
410 else if (comp.complType() == ReturnValue) {
411 char *msg = comp.value().toString(interp.globalExec()).ascii();
412 fprintf(stderr,"Return value: %s\n",msg);
413 }
414 }
415 }
416
417 NPN_ReleaseObject ((NPObject *)myObject);
418
419 } // end block, so that Interpreter and global get deleted
420
421 return ret ? 0 : 3;
422 }