source: webkit/trunk/JavaScriptCore/API/testapi.c@ 14951

Last change on this file since 14951 was 14951, checked in by ggaren, 19 years ago

JavaScriptCore:

Reviewed by Anders.


  • First cut at C API to JavaScript. Includes a unit test, 'testapi.c', and the outline of a test app, 'minidom.c'.


Includes one change to JSC internals: Rename propList to getPropertyList and have it
take its target property list by reference so that subclasses can
add properties to the list before calling through to their superclasses.


Also, I just ran prepare-ChangeLog in about 10 seconds, and I would like
to give a shout-out to that.


  • API/APICast.h: Added. (toJS): (toRef):
  • API/JSBase.h: Added.
  • API/JSCallbackObject.cpp: Added. (KJS::): (KJS::JSCallbackObject::JSCallbackObject): (KJS::JSCallbackObject::~JSCallbackObject): (KJS::JSCallbackObject::className): (KJS::JSCallbackObject::getOwnPropertySlot): (KJS::JSCallbackObject::put): (KJS::JSCallbackObject::deleteProperty): (KJS::JSCallbackObject::implementsConstruct): (KJS::JSCallbackObject::construct): (KJS::JSCallbackObject::implementsCall): (KJS::JSCallbackObject::callAsFunction): (KJS::JSCallbackObject::getPropertyList): (KJS::JSCallbackObject::toBoolean): (KJS::JSCallbackObject::toNumber): (KJS::JSCallbackObject::toString): (KJS::JSCallbackObject::setPrivate): (KJS::JSCallbackObject::getPrivate): (KJS::JSCallbackObject::cachedValueGetter): (KJS::JSCallbackObject::callbackGetter):
  • API/JSCallbackObject.h: Added. (KJS::JSCallbackObject::classInfo):
  • API/JSCharBufferRef.cpp: Added. (JSStringMake): (JSCharBufferCreate): (JSCharBufferCreateUTF8): (JSCharBufferRetain): (JSCharBufferRelease): (JSValueCopyStringValue): (JSCharBufferGetLength): (JSCharBufferGetCharactersPtr): (JSCharBufferGetCharacters): (JSCharBufferGetMaxLengthUTF8): (JSCharBufferGetCharactersUTF8): (JSCharBufferIsEqual): (JSCharBufferIsEqualUTF8): (JSCharBufferCreateWithCFString): (CFStringCreateWithJSCharBuffer):
  • API/JSCharBufferRef.h: Added.
  • API/JSContextRef.cpp: Added. (JSContextCreate): (JSContextDestroy): (JSContextGetGlobalObject): (JSEvaluate): (JSCheckSyntax): (JSContextHasException): (JSContextGetException): (JSContextClearException): (JSContextSetException):
  • API/JSContextRef.h: Added.
  • API/JSObjectRef.cpp: Added. (JSValueToObject): (JSObjectMake): (JSFunctionMake): (JSObjectGetDescription): (JSObjectGetPrototype): (JSObjectSetPrototype): (JSObjectHasProperty): (JSObjectGetProperty): (JSObjectSetProperty): (JSObjectDeleteProperty): (JSObjectGetPrivate): (JSObjectSetPrivate): (JSObjectIsFunction): (JSObjectCallAsFunction): (JSObjectIsConstructor): (JSObjectCallAsConstructor): (JSPropertyListEnumerator::JSPropertyListEnumerator): (JSObjectCreatePropertyEnumerator): (JSPropertyEnumeratorGetNext): (JSPropertyEnumeratorRetain): (JSPropertyEnumeratorRelease): (JSPropertyListAdd):
  • API/JSObjectRef.h: Added.
  • API/JSValueRef.cpp: Added. (JSValueGetType): (JSValueIsUndefined): (JSValueIsNull): (JSValueIsBoolean): (JSValueIsNumber): (JSValueIsString): (JSValueIsObject): (JSValueIsEqual): (JSValueIsStrictEqual): (JSUndefinedMake): (JSNullMake): (JSBooleanMake): (JSNumberMake): (JSValueToBoolean): (JSValueToNumber): (JSGCProtect): (JSGCUnprotect): (JSGCCollect):
  • API/JSValueRef.h: Added.
  • API/JavaScriptCore.h: Added.
  • API/minidom.c: Added. (main):
  • API/minidom.html: Added.
  • API/minidom.js: Added.
  • API/testapi.c: Added. (assertEqualsAsBoolean): (assertEqualsAsNumber): (assertEqualsAsUTF8String): (assertEqualsAsCharactersPtr): (assertEqualsAsCharacters): (MyObject_initialize): (MyObject_copyDescription): (MyObject_hasProperty): (MyObject_getProperty): (MyObject_setProperty): (MyObject_deleteProperty): (MyObject_getPropertyList): (MyObject_callAsFunction): (MyObject_callAsConstructor): (MyObject_convertToType): (MyObject_finalize): (print_callAsFunction): (main): (createStringWithContentsOfFile):
  • API/testapi.js: Added.
  • ChangeLog:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bindings/npruntime_impl.h:
  • kjs/array_instance.h:
  • kjs/array_object.cpp: (ArrayInstance::getPropertyList):
  • kjs/interpreter.cpp: (KJS::Interpreter::evaluate):
  • kjs/nodes.cpp: (ForInNode::execute):
  • kjs/object.cpp: (KJS::JSObject::put): (KJS::JSObject::canPut): (KJS::JSObject::deleteProperty): (KJS::JSObject::propertyIsEnumerable): (KJS::JSObject::getPropertyAttributes): (KJS::JSObject::getPropertyList):
  • kjs/object.h:
  • kjs/property_map.cpp: (KJS::PropertyMap::get):
  • kjs/property_map.h:
  • kjs/scope_chain.cpp: (KJS::ScopeChain::print):
  • kjs/string_object.cpp: (StringInstance::getPropertyList):
  • kjs/string_object.h:
  • kjs/ustring.h: (KJS::UString::Rep::ref):

JavaScriptGlue:

Reviewed by Anders.


  • Required for JS API: Rename propList to getPropertyList and have it take its target property list by reference so that subclasses can add properties to the list before calling through to their superclasses.
  • JSUtils.cpp: (KJSValueToCFTypeInternal):
  • JSValueWrapper.cpp: (JSValueWrapper::JSObjectCopyPropertyNames):
  • UserObjectImp.cpp: (UserObjectImp::getPropertyList):
  • UserObjectImp.h:
File size: 20.1 KB
Line 
1// -*- mode: c++; c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "JavaScriptCore.h"
28#include <wtf/UnusedParam.h>
29
30#if defined(__APPLE__)
31#include <CoreFoundation/CoreFoundation.h>
32#endif
33
34#include <assert.h>
35#include <math.h>
36
37static JSContextRef context = 0;
38
39static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue)
40{
41 assert(JSValueToBoolean(context, value) == expectedValue);
42}
43
44static void assertEqualsAsNumber(JSValueRef value, double expectedValue)
45{
46 double number = JSValueToNumber(context, value);
47 assert(number == expectedValue || (isnan(number) && isnan(expectedValue)));
48}
49
50static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue)
51{
52 JSCharBufferRef valueAsString = JSValueCopyStringValue(context, value);
53
54 size_t jsSize = JSCharBufferGetMaxLengthUTF8(valueAsString);
55 char jsBuffer[jsSize];
56 JSCharBufferGetCharactersUTF8(valueAsString, jsBuffer, jsSize);
57
58 assert(strcmp(jsBuffer, expectedValue) == 0);
59 assert(jsSize >= strlen(jsBuffer) + 1);
60
61 JSCharBufferRelease(valueAsString);
62}
63
64#if defined(__APPLE__)
65static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedValue)
66{
67 JSCharBufferRef valueAsString = JSValueCopyStringValue(context, value);
68
69 size_t jsLength = JSCharBufferGetLength(valueAsString);
70 const JSChar* jsBuffer = JSCharBufferGetCharactersPtr(valueAsString);
71
72 CFStringRef expectedValueAsCFString = CFStringCreateWithCString(kCFAllocatorDefault,
73 expectedValue,
74 kCFStringEncodingUTF8);
75 CFIndex cfLength = CFStringGetLength(expectedValueAsCFString);
76 UniChar cfBuffer[cfLength];
77 CFStringGetCharacters(expectedValueAsCFString, CFRangeMake(0, cfLength), cfBuffer);
78 CFRelease(expectedValueAsCFString);
79
80 assert(memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) == 0);
81 assert(jsLength == (size_t)cfLength);
82
83 JSCharBufferRelease(valueAsString);
84}
85
86static void assertEqualsAsCharacters(JSValueRef value, const char* expectedValue)
87{
88 JSCharBufferRef valueAsString = JSValueCopyStringValue(context, value);
89
90 size_t jsLength = JSCharBufferGetLength(valueAsString);
91 JSChar jsBuffer[jsLength];
92 JSCharBufferGetCharacters(valueAsString, jsBuffer, jsLength);
93
94 CFStringRef expectedValueAsCFString = CFStringCreateWithCString(kCFAllocatorDefault,
95 expectedValue,
96 kCFStringEncodingUTF8);
97 CFIndex cfLength = CFStringGetLength(expectedValueAsCFString);
98 UniChar cfBuffer[cfLength];
99 CFStringGetCharacters(expectedValueAsCFString, CFRangeMake(0, cfLength), cfBuffer);
100 CFRelease(expectedValueAsCFString);
101
102 assert(memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) == 0);
103 assert(jsLength == (size_t)cfLength);
104
105 JSCharBufferRelease(valueAsString);
106}
107#endif // __APPLE__
108
109static JSValueRef jsGlobalValue; // non-stack value for testing JSGCProtect()
110
111/* MyObject pseudo-class */
112
113static bool didInitialize = false;
114static void MyObject_initialize(JSObjectRef object)
115{
116 UNUSED_PARAM(context);
117 UNUSED_PARAM(object);
118 didInitialize = true;
119}
120
121static JSCharBufferRef MyObject_copyDescription(JSObjectRef object)
122{
123 UNUSED_PARAM(object);
124 return JSCharBufferCreateUTF8("MyObject");
125}
126
127static bool MyObject_hasProperty(JSObjectRef object, JSCharBufferRef propertyName)
128{
129 UNUSED_PARAM(object);
130
131 if (JSCharBufferIsEqualUTF8(propertyName, "alwaysOne")
132 || JSCharBufferIsEqualUTF8(propertyName, "cantFind")
133 || JSCharBufferIsEqualUTF8(propertyName, "myPropertyName")) {
134 return true;
135 }
136
137 return false;
138}
139
140static bool MyObject_getProperty(JSObjectRef object, JSCharBufferRef propertyName, JSValueRef* returnValue)
141{
142 UNUSED_PARAM(object);
143
144 if (JSCharBufferIsEqualUTF8(propertyName, "alwaysOne")) {
145 *returnValue = JSNumberMake(1);
146 return true;
147 }
148
149 if (JSCharBufferIsEqualUTF8(propertyName, "myPropertyName")) {
150 *returnValue = JSNumberMake(1);
151 return true;
152 }
153
154 if (JSCharBufferIsEqualUTF8(propertyName, "cantFind")) {
155 *returnValue = JSUndefinedMake();
156 return true;
157 }
158
159 return false;
160}
161
162static bool MyObject_setProperty(JSObjectRef object, JSCharBufferRef propertyName, JSValueRef value)
163{
164 UNUSED_PARAM(object);
165 UNUSED_PARAM(value);
166
167 if (JSCharBufferIsEqualUTF8(propertyName, "cantSet"))
168 return true; // pretend we set the property in order to swallow it
169
170 return false;
171}
172
173static bool MyObject_deleteProperty(JSObjectRef object, JSCharBufferRef propertyName)
174{
175 UNUSED_PARAM(object);
176
177 if (JSCharBufferIsEqualUTF8(propertyName, "cantDelete"))
178 return true;
179
180 return false;
181}
182
183static void MyObject_getPropertyList(JSObjectRef object, JSPropertyListRef propertyList)
184{
185 JSCharBufferRef propertyNameBuf;
186
187 propertyNameBuf = JSCharBufferCreateUTF8("alwaysOne");
188 JSPropertyListAdd(propertyList, object, propertyNameBuf);
189 JSCharBufferRelease(propertyNameBuf);
190
191 propertyNameBuf = JSCharBufferCreateUTF8("myPropertyName");
192 JSPropertyListAdd(propertyList, object, propertyNameBuf);
193 JSCharBufferRelease(propertyNameBuf);
194}
195
196static JSValueRef MyObject_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argc, JSValueRef argv[])
197{
198 UNUSED_PARAM(context);
199 UNUSED_PARAM(object);
200 UNUSED_PARAM(thisObject);
201
202 if (argc > 0 && JSValueIsStrictEqual(context, argv[0], JSNumberMake(0)))
203 return JSNumberMake(1);
204
205 return JSUndefinedMake();
206}
207
208static JSObjectRef MyObject_callAsConstructor(JSContextRef context, JSObjectRef object, size_t argc, JSValueRef argv[])
209{
210 UNUSED_PARAM(context);
211 UNUSED_PARAM(object);
212
213 if (argc > 0 && JSValueIsStrictEqual(context, argv[0], JSNumberMake(0)))
214 return JSValueToObject(context, JSNumberMake(1));
215
216 return JSValueToObject(context, JSNumberMake(0));
217}
218
219static bool MyObject_convertToType(JSObjectRef object, JSTypeCode typeCode, JSValueRef* returnValue)
220{
221 UNUSED_PARAM(object);
222
223 switch (typeCode) {
224 case kJSTypeBoolean:
225 *returnValue = JSBooleanMake(false); // default object conversion is 'true'
226 return true;
227 case kJSTypeNumber:
228 *returnValue = JSNumberMake(1);
229 return true;
230 default:
231 break;
232 }
233
234 // string
235 return false;
236}
237
238static bool didFinalize = false;
239static void MyObject_finalize(JSObjectRef object)
240{
241 UNUSED_PARAM(context);
242 UNUSED_PARAM(object);
243 didFinalize = true;
244}
245
246JSObjectCallbacks MyObjectCallbacks = {
247 0,
248 0,
249 &MyObject_initialize,
250 &MyObject_finalize,
251 &MyObject_copyDescription,
252 &MyObject_hasProperty,
253 &MyObject_getProperty,
254 &MyObject_setProperty,
255 &MyObject_deleteProperty,
256 &MyObject_getPropertyList,
257 &MyObject_callAsFunction,
258 &MyObject_callAsConstructor,
259 &MyObject_convertToType,
260};
261
262static JSValueRef print_callAsFunction(JSContextRef context, JSObjectRef functionObject, JSObjectRef thisObject, size_t argc, JSValueRef argv[])
263{
264 UNUSED_PARAM(functionObject);
265 UNUSED_PARAM(thisObject);
266
267 if (argc > 0) {
268 JSCharBufferRef string = JSValueCopyStringValue(context, argv[0]);
269 size_t sizeUTF8 = JSCharBufferGetMaxLengthUTF8(string);
270 char stringUTF8[sizeUTF8];
271 JSCharBufferGetCharactersUTF8(string, stringUTF8, sizeUTF8);
272 printf("%s\n", stringUTF8);
273 JSCharBufferRelease(string);
274 }
275
276 return JSUndefinedMake();
277}
278
279static char* createStringWithContentsOfFile(const char* fileName);
280
281int main(int argc, char* argv[])
282{
283 UNUSED_PARAM(argc);
284 UNUSED_PARAM(argv);
285
286 context = JSContextCreate(&kJSObjectCallbacksNone, 0);
287
288 JSValueRef jsUndefined = JSUndefinedMake();
289 JSValueRef jsNull = JSNullMake();
290 JSValueRef jsTrue = JSBooleanMake(true);
291 JSValueRef jsFalse = JSBooleanMake(false);
292 JSValueRef jsZero = JSNumberMake(0);
293 JSValueRef jsOne = JSNumberMake(1);
294 JSValueRef jsOneThird = JSNumberMake(1.0 / 3.0);
295 // FIXME: test funny utf8 characters
296 JSCharBufferRef jsEmptyStringBuf = JSCharBufferCreateUTF8("");
297 JSValueRef jsEmptyString = JSStringMake(jsEmptyStringBuf);
298
299 JSCharBufferRef jsOneStringBuf = JSCharBufferCreateUTF8("1");
300 JSValueRef jsOneString = JSStringMake(jsOneStringBuf);
301
302#if defined(__APPLE__)
303 UniChar singleUniChar = 65; // Capital A
304 CFMutableStringRef cfString =
305 CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault,
306 &singleUniChar,
307 1,
308 1,
309 kCFAllocatorNull);
310
311 JSCharBufferRef jsCFStringBuf = JSCharBufferCreateWithCFString(cfString);
312 JSValueRef jsCFString = JSStringMake(jsCFStringBuf);
313
314 CFStringRef cfEmptyString = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8);
315
316 JSCharBufferRef jsCFEmptyStringBuf = JSCharBufferCreateWithCFString(cfEmptyString);
317 JSValueRef jsCFEmptyString = JSStringMake(jsCFEmptyStringBuf);
318
319 CFIndex cfStringLength = CFStringGetLength(cfString);
320 UniChar buffer[cfStringLength];
321 CFStringGetCharacters(cfString,
322 CFRangeMake(0, cfStringLength),
323 buffer);
324 JSCharBufferRef jsCFStringWithCharactersBuf = JSCharBufferCreate(buffer, cfStringLength);
325 JSValueRef jsCFStringWithCharacters = JSStringMake(jsCFStringWithCharactersBuf);
326
327 JSCharBufferRef jsCFEmptyStringWithCharactersBuf = JSCharBufferCreate(buffer, CFStringGetLength(cfEmptyString));
328 JSValueRef jsCFEmptyStringWithCharacters = JSStringMake(jsCFEmptyStringWithCharactersBuf);
329#endif // __APPLE__
330
331 assert(JSValueGetType(jsUndefined) == kJSTypeUndefined);
332 assert(JSValueGetType(jsNull) == kJSTypeNull);
333 assert(JSValueGetType(jsTrue) == kJSTypeBoolean);
334 assert(JSValueGetType(jsFalse) == kJSTypeBoolean);
335 assert(JSValueGetType(jsZero) == kJSTypeNumber);
336 assert(JSValueGetType(jsOne) == kJSTypeNumber);
337 assert(JSValueGetType(jsOneThird) == kJSTypeNumber);
338 assert(JSValueGetType(jsEmptyString) == kJSTypeString);
339 assert(JSValueGetType(jsOneString) == kJSTypeString);
340#if defined(__APPLE__)
341 assert(JSValueGetType(jsCFString) == kJSTypeString);
342 assert(JSValueGetType(jsCFStringWithCharacters) == kJSTypeString);
343 assert(JSValueGetType(jsCFEmptyString) == kJSTypeString);
344 assert(JSValueGetType(jsCFEmptyStringWithCharacters) == kJSTypeString);
345#endif // __APPLE__
346
347 assertEqualsAsBoolean(jsUndefined, false);
348 assertEqualsAsBoolean(jsNull, false);
349 assertEqualsAsBoolean(jsTrue, true);
350 assertEqualsAsBoolean(jsFalse, false);
351 assertEqualsAsBoolean(jsZero, false);
352 assertEqualsAsBoolean(jsOne, true);
353 assertEqualsAsBoolean(jsOneThird, true);
354 assertEqualsAsBoolean(jsEmptyString, false);
355 assertEqualsAsBoolean(jsOneString, true);
356#if defined(__APPLE__)
357 assertEqualsAsBoolean(jsCFString, true);
358 assertEqualsAsBoolean(jsCFStringWithCharacters, true);
359 assertEqualsAsBoolean(jsCFEmptyString, false);
360 assertEqualsAsBoolean(jsCFEmptyStringWithCharacters, false);
361#endif // __APPLE__
362
363 assertEqualsAsNumber(jsUndefined, nan(""));
364 assertEqualsAsNumber(jsNull, 0);
365 assertEqualsAsNumber(jsTrue, 1);
366 assertEqualsAsNumber(jsFalse, 0);
367 assertEqualsAsNumber(jsZero, 0);
368 assertEqualsAsNumber(jsOne, 1);
369 assertEqualsAsNumber(jsOneThird, 1.0 / 3.0);
370 assertEqualsAsNumber(jsEmptyString, 0);
371 assertEqualsAsNumber(jsOneString, 1);
372#if defined(__APPLE__)
373 assertEqualsAsNumber(jsCFString, nan(""));
374 assertEqualsAsNumber(jsCFStringWithCharacters, nan(""));
375 assertEqualsAsNumber(jsCFEmptyString, 0);
376 assertEqualsAsNumber(jsCFEmptyStringWithCharacters, 0);
377 assert(sizeof(JSChar) == sizeof(UniChar));
378#endif // __APPLE__
379
380 assertEqualsAsCharactersPtr(jsUndefined, "undefined");
381 assertEqualsAsCharactersPtr(jsNull, "null");
382 assertEqualsAsCharactersPtr(jsTrue, "true");
383 assertEqualsAsCharactersPtr(jsFalse, "false");
384 assertEqualsAsCharactersPtr(jsZero, "0");
385 assertEqualsAsCharactersPtr(jsOne, "1");
386 assertEqualsAsCharactersPtr(jsOneThird, "0.3333333333333333");
387 assertEqualsAsCharactersPtr(jsEmptyString, "");
388 assertEqualsAsCharactersPtr(jsOneString, "1");
389#if defined(__APPLE__)
390 assertEqualsAsCharactersPtr(jsCFString, "A");
391 assertEqualsAsCharactersPtr(jsCFStringWithCharacters, "A");
392 assertEqualsAsCharactersPtr(jsCFEmptyString, "");
393 assertEqualsAsCharactersPtr(jsCFEmptyStringWithCharacters, "");
394#endif // __APPLE__
395
396 assertEqualsAsCharacters(jsUndefined, "undefined");
397 assertEqualsAsCharacters(jsNull, "null");
398 assertEqualsAsCharacters(jsTrue, "true");
399 assertEqualsAsCharacters(jsFalse, "false");
400 assertEqualsAsCharacters(jsZero, "0");
401 assertEqualsAsCharacters(jsOne, "1");
402 assertEqualsAsCharacters(jsOneThird, "0.3333333333333333");
403 assertEqualsAsCharacters(jsEmptyString, "");
404 assertEqualsAsCharacters(jsOneString, "1");
405#if defined(__APPLE__)
406 assertEqualsAsCharacters(jsCFString, "A");
407 assertEqualsAsCharacters(jsCFStringWithCharacters, "A");
408 assertEqualsAsCharacters(jsCFEmptyString, "");
409 assertEqualsAsCharacters(jsCFEmptyStringWithCharacters, "");
410#endif // __APPLE__
411
412 assertEqualsAsUTF8String(jsUndefined, "undefined");
413 assertEqualsAsUTF8String(jsNull, "null");
414 assertEqualsAsUTF8String(jsTrue, "true");
415 assertEqualsAsUTF8String(jsFalse, "false");
416 assertEqualsAsUTF8String(jsZero, "0");
417 assertEqualsAsUTF8String(jsOne, "1");
418 assertEqualsAsUTF8String(jsOneThird, "0.3333333333333333");
419 assertEqualsAsUTF8String(jsEmptyString, "");
420 assertEqualsAsUTF8String(jsOneString, "1");
421#if defined(__APPLE__)
422 assertEqualsAsUTF8String(jsCFString, "A");
423 assertEqualsAsUTF8String(jsCFStringWithCharacters, "A");
424 assertEqualsAsUTF8String(jsCFEmptyString, "");
425 assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, "");
426#endif // __APPLE__
427
428 assert(JSValueIsStrictEqual(context, jsTrue, jsTrue));
429 assert(!JSValueIsStrictEqual(context, jsOne, jsOneString));
430
431 assert(JSValueIsEqual(context, jsOne, jsOneString));
432 assert(!JSValueIsEqual(context, jsTrue, jsFalse));
433
434#if defined(__APPLE__)
435 CFStringRef cfJSString = CFStringCreateWithJSCharBuffer(kCFAllocatorDefault, jsCFStringBuf);
436 CFStringRef cfJSEmptyString = CFStringCreateWithJSCharBuffer(kCFAllocatorDefault, jsCFEmptyStringBuf);
437 assert(CFEqual(cfJSString, cfString));
438 assert(CFEqual(cfJSEmptyString, cfEmptyString));
439 CFRelease(cfJSString);
440 CFRelease(cfJSEmptyString);
441
442 CFRelease(cfString);
443 CFRelease(cfEmptyString);
444#endif // __APPLE__
445
446 // GDB says jsGlobalValue actually ends up being marked by the stack crawl, so this
447 // exercise is a bit academic. Not sure why that happens, or how to avoid it.
448 jsGlobalValue = JSObjectMake(context, &kJSObjectCallbacksNone, 0);
449 JSGCCollect();
450 assert(JSValueIsObject(jsGlobalValue));
451 JSGCUnprotect(jsGlobalValue);
452
453 /* JSInterpreter.h */
454
455 JSObjectRef globalObject = JSContextGetGlobalObject(context);
456 assert(JSValueIsObject(globalObject));
457
458 JSCharBufferRef goodSyntaxBuf = JSCharBufferCreateUTF8("x = 1;");
459 JSCharBufferRef badSyntaxBuf = JSCharBufferCreateUTF8("x := 1;");
460 assert(JSCheckSyntax(context, goodSyntaxBuf));
461 assert(!JSCheckSyntax(context, badSyntaxBuf));
462
463 JSValueRef result;
464 assert(JSEvaluate(context, globalObject, goodSyntaxBuf, jsEmptyString, 0, &result));
465 assert(JSValueIsEqual(context, result, jsOne));
466
467 assert(!JSEvaluate(context, globalObject, badSyntaxBuf, jsEmptyString, 0, &result));
468 assert(JSValueIsObject(result));
469
470 JSContextSetException(context, JSNumberMake(1));
471 assert(JSContextHasException(context));
472 assert(JSValueIsEqual(context, jsOne, JSContextGetException(context)));
473 JSContextClearException(context);
474 assert(!JSContextHasException(context));
475
476 JSCharBufferRelease(jsEmptyStringBuf);
477 JSCharBufferRelease(jsOneStringBuf);
478#if defined(__APPLE__)
479 JSCharBufferRelease(jsCFStringBuf);
480 JSCharBufferRelease(jsCFEmptyStringBuf);
481 JSCharBufferRelease(jsCFStringWithCharactersBuf);
482 JSCharBufferRelease(jsCFEmptyStringWithCharactersBuf);
483#endif // __APPLE__
484 JSCharBufferRelease(goodSyntaxBuf);
485 JSCharBufferRelease(badSyntaxBuf);
486
487 JSObjectRef myObject = JSObjectMake(context, &MyObjectCallbacks, 0);
488 assert(didInitialize);
489 JSCharBufferRef myObjectBuf = JSCharBufferCreateUTF8("MyObject");
490 JSObjectSetProperty(context, globalObject, myObjectBuf, myObject, kJSPropertyAttributeNone);
491 JSCharBufferRelease(myObjectBuf);
492
493 JSCharBufferRef printBuf = JSCharBufferCreateUTF8("print");
494 JSObjectSetProperty(context, globalObject, printBuf, JSFunctionMake(context, print_callAsFunction), kJSPropertyAttributeNone);
495 JSCharBufferRelease(printBuf);
496
497 char* script = createStringWithContentsOfFile("testapi.js");
498 JSCharBufferRef scriptBuf = JSCharBufferCreateUTF8(script);
499 JSEvaluate(context, globalObject, scriptBuf, jsEmptyString, 0, &result);
500 if (JSValueIsUndefined(result))
501 printf("PASS: Test script executed successfully.\n");
502 else {
503 printf("FAIL: Test script returned unexcpected value:\n");
504 JSCharBufferRef resultBuf = JSValueCopyStringValue(context, result);
505 CFStringRef resultCF = CFStringCreateWithJSCharBuffer(kCFAllocatorDefault, resultBuf);
506 CFShow(resultCF);
507 CFRelease(resultCF);
508 JSCharBufferRelease(resultBuf);
509 }
510 JSCharBufferRelease(scriptBuf);
511 free(script);
512
513 // Allocate a few dummies so that at least one will be collected
514 JSObjectMake(context, &MyObjectCallbacks, 0);
515 JSObjectMake(context, &MyObjectCallbacks, 0);
516 JSGCCollect();
517 assert(didFinalize);
518
519 JSContextDestroy(context);
520 printf("PASS: All assertions passed.\n");
521 return 0;
522}
523
524static char* createStringWithContentsOfFile(const char* fileName)
525{
526 char* buffer;
527
528 int buffer_size = 0;
529 int buffer_capacity = 1024;
530 buffer = (char*)malloc(buffer_capacity);
531
532 FILE* f = fopen(fileName, "r");
533 if (!f) {
534 fprintf(stderr, "Could not open file: %s\n", fileName);
535 return 0;
536 }
537
538 while (!feof(f) && !ferror(f)) {
539 buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f);
540 if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
541 buffer_capacity *= 2;
542 buffer = (char*)realloc(buffer, buffer_capacity);
543 assert(buffer);
544 }
545
546 assert(buffer_size < buffer_capacity);
547 }
548 fclose(f);
549 buffer[buffer_size] = '\0';
550
551 return buffer;
552}
Note: See TracBrowser for help on using the repository browser.