]> git.saurik.com Git - apple/javascriptcore.git/blame - bindings/testbindings.cpp
JavaScriptCore-461.tar.gz
[apple/javascriptcore.git] / bindings / testbindings.cpp
CommitLineData
b37bf2e1
A
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 --------------------
45typedef struct
46{
47 NPObject object;
48 double doubleValue;
49 int intValue;
50 NPVariant stringValue;
51 bool boolValue;
52} MyObject;
53
54
55static 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
65static NPIdentifier myPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
66static 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
86static NPIdentifier myMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
87static 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
99static void initializeIdentifiers()
100{
101 NPN_GetStringIdentifiers (myPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, myPropertyIdentifiers);
102 NPN_GetStringIdentifiers (myMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, myMethodIdentifiers);
103};
104
105bool 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
116bool 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
128void 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
144void 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
155void 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
166void setStringValue (MyObject *obj, const NPVariant *variant)
167{
168 NPN_ReleaseVariantValue (&obj->stringValue);
169 NPN_InitializeVariantWithVariant (&obj->stringValue, variant);
170}
171
172void 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
183void getDoubleValue (MyObject *obj, NPVariant *variant)
184{
185 NPN_InitializeVariantWithDouble (variant, obj->doubleValue);
186}
187
188void getIntValue (MyObject *obj, NPVariant *variant)
189{
190 NPN_InitializeVariantWithInt32 (variant, obj->intValue);
191}
192
193void getStringValue (MyObject *obj, NPVariant *variant)
194{
195 NPN_InitializeVariantWithVariant (variant, &obj->stringValue);
196}
197
198void getBooleanValue (MyObject *obj, NPVariant *variant)
199{
200 NPN_InitializeVariantWithBool (variant, obj->boolValue);
201}
202
203void 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
227void 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
249void 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
292NPObject *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
312void myInvalidate ()
313{
314 // Make sure we've released any remaining references to JavaScript objects.
315}
316
317void myDeallocate (MyObject *obj)
318{
319 free ((void *)obj);
320}
321
322static 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};
333static NPClass *myFunctionPtrs = &_myFunctionPtrs;
334
335// --------------------------------------------------------
336
337using namespace KJS;
338using namespace KJS::Bindings;
339
340class GlobalImp : public ObjectImp {
341public:
342 virtual UString className() const { return "global"; }
343};
344
345#define BufferSize 200000
346static char code[BufferSize];
347
348const 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
366int 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}