18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JavaScriptCore.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSBasePrivate.h"
28cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "JSContextRefPrivate.h"
29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "JSObjectRefPrivate.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <math.h>
318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define ASSERT_DISABLED 0
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h>
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/UnusedParam.h>
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if OS(WINDOWS)
3681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <windows.h>
3781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif
3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if COMPILER(MSVC)
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/MathExtras.h>
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic double nan(const char*)
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return std::numeric_limits<double>::quiet_NaN();
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockstatic JSGlobalContextRef context;
51cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockstatic int failed;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void assertEqualsAsBoolean(JSValueRef value, bool expectedValue)
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (JSValueToBoolean(context, value) != expectedValue) {
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fprintf(stderr, "assertEqualsAsBoolean failed: %p, %d\n", value, expectedValue);
568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        failed = 1;
578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void assertEqualsAsNumber(JSValueRef value, double expectedValue)
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double number = JSValueToNumber(context, value, NULL);
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME <rdar://4668451> - On i386 the isnan(double) macro tries to map to the isnan(float) function,
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // causing a build break with -Wshorten-64-to-32 enabled.  The issue is known by the appropriate team.
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // After that's resolved, we can remove these casts
678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (number != expectedValue && !(isnan((float)number) && isnan((float)expectedValue))) {
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fprintf(stderr, "assertEqualsAsNumber failed: %p, %lf\n", value, expectedValue);
698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        failed = 1;
708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue)
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef valueAsString = JSValueToStringCopy(context, value, NULL);
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t jsSize = JSStringGetMaximumUTF8CStringSize(valueAsString);
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* jsBuffer = (char*)malloc(jsSize);
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringGetUTF8CString(valueAsString, jsBuffer, jsSize);
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned i;
828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (i = 0; jsBuffer[i]; i++) {
838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (jsBuffer[i] != expectedValue[i]) {
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            fprintf(stderr, "assertEqualsAsUTF8String failed at character %d: %c(%d) != %c(%d)\n", i, jsBuffer[i], jsBuffer[i], expectedValue[i], expectedValue[i]);
858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            failed = 1;
868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (jsSize < strlen(jsBuffer) + 1) {
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fprintf(stderr, "assertEqualsAsUTF8String failed: jsSize was too small\n");
918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        failed = 1;
928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    free(jsBuffer);
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(valueAsString);
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedValue)
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef valueAsString = JSValueToStringCopy(context, value, NULL);
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t jsLength = JSStringGetLength(valueAsString);
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const JSChar* jsBuffer = JSStringGetCharactersPtr(valueAsString);
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFStringRef expectedValueAsCFString = CFStringCreateWithCString(kCFAllocatorDefault,
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                                    expectedValue,
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                                    kCFStringEncodingUTF8);
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFIndex cfLength = CFStringGetLength(expectedValueAsCFString);
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UniChar* cfBuffer = (UniChar*)malloc(cfLength * sizeof(UniChar));
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFStringGetCharacters(expectedValueAsCFString, CFRangeMake(0, cfLength), cfBuffer);
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFRelease(expectedValueAsCFString);
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) != 0) {
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsBuffer != cfBuffer\n");
1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        failed = 1;
1168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (jsLength != (size_t)cfLength) {
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%ld) != cfLength(%ld)\n", jsLength, cfLength);
1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        failed = 1;
1218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    free(cfBuffer);
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(valueAsString);
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic bool timeZoneIsPST()
1285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    char timeZoneName[70];
1305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    struct tm gtm;
1315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    memset(&gtm, 0, sizeof(gtm));
1325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
1335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return 0 == strcmp("PST", timeZoneName);
1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
1365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSValueRef jsGlobalValue; // non-stack value for testing JSValueProtect()
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* MyObject pseudo-class */
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool MyObject_hasProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName)
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne")
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        || JSStringIsEqualToUTF8CString(propertyName, "cantFind")
1488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        || JSStringIsEqualToUTF8CString(propertyName, "throwOnGet")
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        || JSStringIsEqualToUTF8CString(propertyName, "myPropertyName")
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        || JSStringIsEqualToUTF8CString(propertyName, "hasPropertyLie")
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        || JSStringIsEqualToUTF8CString(propertyName, "0")) {
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSValueRef MyObject_getProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne")) {
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return JSValueMakeNumber(context, 1);
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (JSStringIsEqualToUTF8CString(propertyName, "myPropertyName")) {
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return JSValueMakeNumber(context, 1);
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (JSStringIsEqualToUTF8CString(propertyName, "cantFind")) {
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return JSValueMakeUndefined(context);
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
175643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (JSStringIsEqualToUTF8CString(propertyName, "hasPropertyLie")) {
176643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return 0;
177643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
1788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (JSStringIsEqualToUTF8CString(propertyName, "throwOnGet")) {
1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
1818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (JSStringIsEqualToUTF8CString(propertyName, "0")) {
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        *exception = JSValueMakeNumber(context, 1);
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return JSValueMakeNumber(context, 1);
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
188643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return JSValueMakeNull(context);
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool MyObject_setProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(value);
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (JSStringIsEqualToUTF8CString(propertyName, "cantSet"))
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true; // pretend we set the property in order to swallow it
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (JSStringIsEqualToUTF8CString(propertyName, "throwOnSet")) {
2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
2038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool MyObject_deleteProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (JSStringIsEqualToUTF8CString(propertyName, "cantDelete"))
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (JSStringIsEqualToUTF8CString(propertyName, "throwOnDelete")) {
2178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void MyObject_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames)
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef propertyName;
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    propertyName = JSStringCreateWithUTF8CString("alwaysOne");
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(propertyName);
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    propertyName = JSStringCreateWithUTF8CString("myPropertyName");
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSPropertyNameAccumulatorAddName(propertyNames, propertyName);
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(propertyName);
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSValueRef MyObject_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(thisObject);
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (argumentCount > 0 && JSValueIsString(context, arguments[0]) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, arguments[0], 0), "throwOnCall")) {
2488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
2498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return JSValueMakeUndefined(context);
2508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0)))
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return JSValueMakeNumber(context, 1);
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return JSValueMakeUndefined(context);
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSObjectRef MyObject_callAsConstructor(JSContextRef context, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (argumentCount > 0 && JSValueIsString(context, arguments[0]) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, arguments[0], 0), "throwOnConstruct")) {
2648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return object;
2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0)))
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return JSValueToObject(context, JSValueMakeNumber(context, 1), exception);
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return JSValueToObject(context, JSValueMakeNumber(context, 0), exception);
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool MyObject_hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleValue, JSValueRef* exception)
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(constructor);
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (JSValueIsString(context, possibleValue) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, possibleValue, 0), "throwOnHasInstance")) {
2808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), constructor, JSStringCreateWithUTF8CString("test script"), 1, exception);
2818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return false;
2828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef numberString = JSStringCreateWithUTF8CString("Number");
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef numberConstructor = JSValueToObject(context, JSObjectGetProperty(context, JSContextGetGlobalObject(context), numberString, exception), exception);
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(numberString);
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return JSValueIsInstanceOfConstructor(context, possibleValue, numberConstructor, exception);
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSValueRef MyObject_convertToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception)
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (type) {
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case kJSTypeNumber:
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return JSValueMakeNumber(context, 1);
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case kJSTypeString:
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        {
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            JSStringRef string = JSStringCreateWithUTF8CString("MyObjectAsString");
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            JSValueRef result = JSValueMakeString(context, string);
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            JSStringRelease(string);
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return result;
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    default:
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // string conversion -- forward to default object class
311643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return JSValueMakeNull(context);
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSStaticValue evilStaticValues[] = {
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "nullGetSet", 0, 0, kJSPropertyAttributeNone },
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { 0, 0, 0, 0 }
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSStaticFunction evilStaticFunctions[] = {
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "nullCall", 0, kJSPropertyAttributeNone },
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { 0, 0, 0 }
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectJSClassDefinition MyObject_definition = {
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    0,
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    kJSClassAttributeNone,
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    "MyObject",
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NULL,
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    evilStaticValues,
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    evilStaticFunctions,
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NULL,
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NULL,
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MyObject_hasProperty,
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MyObject_getProperty,
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MyObject_setProperty,
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MyObject_deleteProperty,
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MyObject_getPropertyNames,
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MyObject_callAsFunction,
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MyObject_callAsConstructor,
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MyObject_hasInstance,
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MyObject_convertToType,
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSClassRef MyObject_class(JSContextRef context)
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static JSClassRef jsClass;
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!jsClass)
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        jsClass = JSClassCreate(&MyObject_definition);
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsClass;
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic bool EvilExceptionObject_hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleValue, JSValueRef* exception)
3598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
3608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UNUSED_PARAM(context);
3618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UNUSED_PARAM(constructor);
3628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSStringRef hasInstanceName = JSStringCreateWithUTF8CString("hasInstance");
3648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSValueRef hasInstance = JSObjectGetProperty(context, constructor, hasInstanceName, exception);
3658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSStringRelease(hasInstanceName);
3668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!hasInstance)
3678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return false;
3688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSObjectRef function = JSValueToObject(context, hasInstance, exception);
3698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSValueRef result = JSObjectCallAsFunction(context, function, constructor, 1, &possibleValue, exception);
3708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return result && JSValueToBoolean(context, result);
3718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
3728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic JSValueRef EvilExceptionObject_convertToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception)
3748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
3758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UNUSED_PARAM(object);
3768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UNUSED_PARAM(exception);
3778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSStringRef funcName;
3788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    switch (type) {
3798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    case kJSTypeNumber:
3808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        funcName = JSStringCreateWithUTF8CString("toNumber");
3818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        break;
3828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    case kJSTypeString:
3838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        funcName = JSStringCreateWithUTF8CString("toStringExplicit");
3848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        break;
3858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    default:
386643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return JSValueMakeNull(context);
3878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        break;
3888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSValueRef func = JSObjectGetProperty(context, object, funcName, exception);
3918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSStringRelease(funcName);
3928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSObjectRef function = JSValueToObject(context, func, exception);
3938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!function)
394643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return JSValueMakeNull(context);
3958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSValueRef value = JSObjectCallAsFunction(context, function, object, 0, NULL, exception);
3960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!value) {
3970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        JSStringRef errorString = JSStringCreateWithUTF8CString("convertToType failed");
3980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        JSValueRef errorStringRef = JSValueMakeString(context, errorString);
3990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        JSStringRelease(errorString);
4000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return errorStringRef;
4010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
4028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return value;
4038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
4048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianJSClassDefinition EvilExceptionObject_definition = {
4068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    0,
4078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    kJSClassAttributeNone,
4088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    "EvilExceptionObject",
4108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    EvilExceptionObject_hasInstance,
4258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    EvilExceptionObject_convertToType,
4268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian};
4278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic JSClassRef EvilExceptionObject_class(JSContextRef context)
4298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
4308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UNUSED_PARAM(context);
4318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    static JSClassRef jsClass;
4338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!jsClass)
4348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        jsClass = JSClassCreate(&EvilExceptionObject_definition);
4358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return jsClass;
4378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
4388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianJSClassDefinition EmptyObject_definition = {
4408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    0,
4418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    kJSClassAttributeNone,
4428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    NULL,
4608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian};
4618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic JSClassRef EmptyObject_class(JSContextRef context)
4638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
4648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    UNUSED_PARAM(context);
4658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    static JSClassRef jsClass;
4678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!jsClass)
4688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        jsClass = JSClassCreate(&EmptyObject_definition);
4698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return jsClass;
4718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
4728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSValueRef Base_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(propertyName);
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return JSValueMakeNumber(ctx, 1); // distinguish base get form derived get
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool Base_set(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(propertyName);
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(value);
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *exception = JSValueMakeNumber(ctx, 1); // distinguish base set from derived set
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSValueRef Base_callAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(function);
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(thisObject);
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(argumentCount);
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(arguments);
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return JSValueMakeNumber(ctx, 1); // distinguish base call from derived call
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSStaticFunction Base_staticFunctions[] = {
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "baseProtoDup", NULL, kJSPropertyAttributeNone },
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "baseProto", Base_callAsFunction, kJSPropertyAttributeNone },
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { 0, 0, 0 }
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSStaticValue Base_staticValues[] = {
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "baseDup", Base_get, Base_set, kJSPropertyAttributeNone },
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "baseOnly", Base_get, Base_set, kJSPropertyAttributeNone },
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { 0, 0, 0, 0 }
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool TestInitializeFinalize;
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void Base_initialize(JSContextRef context, JSObjectRef object)
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (TestInitializeFinalize) {
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT((void*)1 == JSObjectGetPrivate(object));
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSObjectSetPrivate(object, (void*)2);
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic unsigned Base_didFinalize;
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void Base_finalize(JSObjectRef object)
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (TestInitializeFinalize) {
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT((void*)4 == JSObjectGetPrivate(object));
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Base_didFinalize = true;
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSClassRef Base_class(JSContextRef context)
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static JSClassRef jsClass;
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!jsClass) {
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSClassDefinition definition = kJSClassDefinitionEmpty;
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        definition.staticValues = Base_staticValues;
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        definition.staticFunctions = Base_staticFunctions;
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        definition.initialize = Base_initialize;
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        definition.finalize = Base_finalize;
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        jsClass = JSClassCreate(&definition);
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsClass;
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSValueRef Derived_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(propertyName);
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return JSValueMakeNumber(ctx, 2); // distinguish base get form derived get
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool Derived_set(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(ctx);
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(propertyName);
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(value);
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *exception = JSValueMakeNumber(ctx, 2); // distinguish base set from derived set
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSValueRef Derived_callAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(function);
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(thisObject);
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(argumentCount);
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(arguments);
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return JSValueMakeNumber(ctx, 2); // distinguish base call from derived call
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSStaticFunction Derived_staticFunctions[] = {
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "protoOnly", Derived_callAsFunction, kJSPropertyAttributeNone },
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "protoDup", NULL, kJSPropertyAttributeNone },
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "baseProtoDup", Derived_callAsFunction, kJSPropertyAttributeNone },
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { 0, 0, 0 }
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSStaticValue Derived_staticValues[] = {
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "derivedOnly", Derived_get, Derived_set, kJSPropertyAttributeNone },
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "protoDup", Derived_get, Derived_set, kJSPropertyAttributeNone },
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "baseDup", Derived_get, Derived_set, kJSPropertyAttributeNone },
5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { 0, 0, 0, 0 }
5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void Derived_initialize(JSContextRef context, JSObjectRef object)
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(context);
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (TestInitializeFinalize) {
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT((void*)2 == JSObjectGetPrivate(object));
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSObjectSetPrivate(object, (void*)3);
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void Derived_finalize(JSObjectRef object)
6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (TestInitializeFinalize) {
6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT((void*)3 == JSObjectGetPrivate(object));
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSObjectSetPrivate(object, (void*)4);
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSClassRef Derived_class(JSContextRef context)
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static JSClassRef jsClass;
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!jsClass) {
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSClassDefinition definition = kJSClassDefinitionEmpty;
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        definition.parentClass = Base_class(context);
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        definition.staticValues = Derived_staticValues;
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        definition.staticFunctions = Derived_staticFunctions;
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        definition.initialize = Derived_initialize;
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        definition.finalize = Derived_finalize;
6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        jsClass = JSClassCreate(&definition);
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsClass;
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
631d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic JSClassRef Derived2_class(JSContextRef context)
632d0825bca7fe65beaee391d30da42e937db621564Steve Block{
633d0825bca7fe65beaee391d30da42e937db621564Steve Block    static JSClassRef jsClass;
634d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!jsClass) {
635d0825bca7fe65beaee391d30da42e937db621564Steve Block        JSClassDefinition definition = kJSClassDefinitionEmpty;
636d0825bca7fe65beaee391d30da42e937db621564Steve Block        definition.parentClass = Derived_class(context);
637d0825bca7fe65beaee391d30da42e937db621564Steve Block        jsClass = JSClassCreate(&definition);
638d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
639d0825bca7fe65beaee391d30da42e937db621564Steve Block    return jsClass;
640d0825bca7fe65beaee391d30da42e937db621564Steve Block}
641d0825bca7fe65beaee391d30da42e937db621564Steve Block
642cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockstatic JSValueRef print_callAsFunction(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(functionObject);
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(thisObject);
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
647cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
648cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    ASSERT(JSContextGetGlobalContext(ctx) == context);
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (argumentCount > 0) {
651cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        JSStringRef string = JSValueToStringCopy(ctx, arguments[0], NULL);
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        size_t sizeUTF8 = JSStringGetMaximumUTF8CStringSize(string);
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        char* stringUTF8 = (char*)malloc(sizeUTF8);
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSStringGetUTF8CString(string, stringUTF8, sizeUTF8);
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("%s\n", stringUTF8);
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        free(stringUTF8);
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSStringRelease(string);
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
660cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    return JSValueMakeUndefined(ctx);
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSObjectRef myConstructor_callAsConstructor(JSContextRef context, JSObjectRef constructorObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(constructorObject);
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef result = JSObjectMake(context, NULL, NULL);
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (argumentCount > 0) {
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSStringRef value = JSStringCreateWithUTF8CString("value");
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSObjectSetProperty(context, result, value, arguments[0], kJSPropertyAttributeNone, NULL);
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSStringRelease(value);
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void globalObject_initialize(JSContextRef context, JSObjectRef object)
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Ensure that an execution context is passed in
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(context);
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Ensure that the global object is set to the object that we were passed
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef globalObject = JSContextGetGlobalObject(context);
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(globalObject);
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(object == globalObject);
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Ensure that the standard global properties have been set on the global object
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef array = JSStringCreateWithUTF8CString("Array");
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef arrayConstructor = JSValueToObject(context, JSObjectGetProperty(context, globalObject, array, NULL), NULL);
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(array);
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(arrayConstructor);
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(arrayConstructor);
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSValueRef globalObject_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(propertyName);
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return JSValueMakeNumber(ctx, 3);
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool globalObject_set(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(object);
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(propertyName);
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(value);
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *exception = JSValueMakeNumber(ctx, 3);
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSValueRef globalObject_call(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(function);
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(thisObject);
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(argumentCount);
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(arguments);
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(exception);
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return JSValueMakeNumber(ctx, 3);
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic JSValueRef functionGC(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
7305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
7315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    UNUSED_PARAM(function);
7325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    UNUSED_PARAM(thisObject);
7335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    UNUSED_PARAM(argumentCount);
7345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    UNUSED_PARAM(arguments);
7355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    UNUSED_PARAM(exception);
7365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSGarbageCollect(context);
7375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return JSValueMakeUndefined(context);
7385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
7395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSStaticValue globalObject_staticValues[] = {
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "globalStaticValue", globalObject_get, globalObject_set, kJSPropertyAttributeNone },
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { 0, 0, 0, 0 }
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic JSStaticFunction globalObject_staticFunctions[] = {
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { "globalStaticFunction", globalObject_call, kJSPropertyAttributeNone },
7475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    { "gc", functionGC, kJSPropertyAttributeNone },
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    { 0, 0, 0 }
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic char* createStringWithContentsOfFile(const char* fileName);
7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void testInitializeFinalize()
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef o = JSObjectMake(context, Derived_class(context), (void*)1);
7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UNUSED_PARAM(o);
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSObjectGetPrivate(o) == (void*)3);
7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
760643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic JSValueRef jsNumberValue =  NULL;
761643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
762dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic JSObjectRef aHeapRef = NULL;
763dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
764643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic void makeGlobalNumberValue(JSContextRef context) {
765643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    JSValueRef v = JSValueMakeNumber(context, 420);
766643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    JSValueProtect(context, v);
767643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    jsNumberValue = v;
768643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v = NULL;
769643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
770643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
7715af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkestatic bool assertTrue(bool value, const char* message)
7725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
7735af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!value) {
7745af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (message)
7755af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            fprintf(stderr, "assertTrue failed: '%s'\n", message);
7765af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        else
7775af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            fprintf(stderr, "assertTrue failed.\n");
7785af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        failed = 1;
7795af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
7805af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return value;
7815af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
7825af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
7835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkestatic bool checkForCycleInPrototypeChain()
7845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
7855af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    bool result = true;
7865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSGlobalContextRef context = JSGlobalContextCreate(0);
7875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectRef object1 = JSObjectMake(context, /* jsClass */ 0, /* data */ 0);
7885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectRef object2 = JSObjectMake(context, /* jsClass */ 0, /* data */ 0);
7895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectRef object3 = JSObjectMake(context, /* jsClass */ 0, /* data */ 0);
7905af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
7915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectSetPrototype(context, object1, JSValueMakeNull(context));
7925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    ASSERT(JSValueIsNull(context, JSObjectGetPrototype(context, object1)));
7935af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
7945af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // object1 -> object1
7955af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectSetPrototype(context, object1, object1);
7965af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    result &= assertTrue(JSValueIsNull(context, JSObjectGetPrototype(context, object1)), "It is possible to assign self as a prototype");
7975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
7985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // object1 -> object2 -> object1
7995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectSetPrototype(context, object2, object1);
8005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    ASSERT(JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object2), object1));
8015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectSetPrototype(context, object1, object2);
8025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    result &= assertTrue(JSValueIsNull(context, JSObjectGetPrototype(context, object1)), "It is possible to close a prototype chain cycle");
8035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
8045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    // object1 -> object2 -> object3 -> object1
8055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectSetPrototype(context, object2, object3);
8065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    ASSERT(JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object2), object3));
8075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectSetPrototype(context, object1, object2);
8085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    ASSERT(JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object1), object2));
8095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSObjectSetPrototype(context, object3, object1);
8105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    result &= assertTrue(!JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object3), object1), "It is possible to close a prototype chain cycle");
8115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
8125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSValueRef exception;
8135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSStringRef code = JSStringCreateWithUTF8CString("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
8145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSStringRef file = JSStringCreateWithUTF8CString("");
8155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    result &= assertTrue(!JSEvaluateScript(context, code, /* thisObject*/ 0, file, 1, &exception)
8165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                         , "An exception should be thrown");
8175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
8185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSStringRelease(code);
8195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSStringRelease(file);
8205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    JSGlobalContextRelease(context);
8215af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    return result;
8225af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
8235af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint main(int argc, char* argv[])
8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
82681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if OS(WINDOWS)
82781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
82881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
82981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
83081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ::SetErrorMode(0);
83181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif
83281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const char *scriptPath = "testapi.js";
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (argc > 1) {
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        scriptPath = argv[1];
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Test garbage collection with a fresh context
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context = JSGlobalContextCreateInGroup(NULL, NULL);
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TestInitializeFinalize = true;
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    testInitializeFinalize();
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSGlobalContextRelease(context);
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TestInitializeFinalize = false;
8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(Base_didFinalize);
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSClassDefinition globalObjectClassDefinition = kJSClassDefinitionEmpty;
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    globalObjectClassDefinition.initialize = globalObject_initialize;
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    globalObjectClassDefinition.staticValues = globalObject_staticValues;
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    globalObjectClassDefinition.staticFunctions = globalObject_staticFunctions;
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    globalObjectClassDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSClassRef globalObjectClass = JSClassCreate(&globalObjectClassDefinition);
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context = JSGlobalContextCreateInGroup(NULL, globalObjectClass);
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSGlobalContextRetain(context);
8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSGlobalContextRelease(context);
857cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    ASSERT(JSContextGetGlobalContext(context) == context);
8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSReportExtraMemoryCost(context, 0);
8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSReportExtraMemoryCost(context, 1);
8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSReportExtraMemoryCost(context, 1024);
8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef globalObject = JSContextGetGlobalObject(context);
8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsObject(context, globalObject));
8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsUndefined = JSValueMakeUndefined(context);
8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsNull = JSValueMakeNull(context);
8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsTrue = JSValueMakeBoolean(context, true);
8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsFalse = JSValueMakeBoolean(context, false);
8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsZero = JSValueMakeNumber(context, 0);
8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsOne = JSValueMakeNumber(context, 1);
8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsOneThird = JSValueMakeNumber(context, 1.0 / 3.0);
8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, NULL);
8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectSetPrototype(context, jsObjectNoProto, JSValueMakeNull(context));
8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: test funny utf8 characters
8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef jsEmptyIString = JSStringCreateWithUTF8CString("");
8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsEmptyString = JSValueMakeString(context, jsEmptyIString);
8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef jsOneIString = JSStringCreateWithUTF8CString("1");
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsOneString = JSValueMakeString(context, jsOneIString);
8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UniChar singleUniChar = 65; // Capital A
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFMutableStringRef cfString =
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault,
8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                          &singleUniChar,
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                          1,
8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                          1,
8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                          kCFAllocatorNull);
8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef jsCFIString = JSStringCreateWithCFString(cfString);
8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsCFString = JSValueMakeString(context, jsCFIString);
8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFStringRef cfEmptyString = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8);
8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef jsCFEmptyIString = JSStringCreateWithCFString(cfEmptyString);
8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsCFEmptyString = JSValueMakeString(context, jsCFEmptyIString);
8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFIndex cfStringLength = CFStringGetLength(cfString);
9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    UniChar* buffer = (UniChar*)malloc(cfStringLength * sizeof(UniChar));
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFStringGetCharacters(cfString,
9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                          CFRangeMake(0, cfStringLength),
9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                          buffer);
9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef jsCFIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, cfStringLength);
9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsCFStringWithCharacters = JSValueMakeString(context, jsCFIStringWithCharacters);
9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef jsCFEmptyIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, CFStringGetLength(cfEmptyString));
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    free(buffer);
9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(context, jsCFEmptyIStringWithCharacters);
9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsUndefined) == kJSTypeUndefined);
9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsNull) == kJSTypeNull);
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsTrue) == kJSTypeBoolean);
9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsFalse) == kJSTypeBoolean);
9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsZero) == kJSTypeNumber);
9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsOne) == kJSTypeNumber);
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsOneThird) == kJSTypeNumber);
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsEmptyString) == kJSTypeString);
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsOneString) == kJSTypeString);
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsCFString) == kJSTypeString);
9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsCFStringWithCharacters) == kJSTypeString);
9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsCFEmptyString) == kJSTypeString);
9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString);
9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL);
9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef myObjectIString = JSStringCreateWithUTF8CString("MyObject");
9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone, NULL);
9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(myObjectIString);
9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSObjectRef EvilExceptionObject = JSObjectMake(context, EvilExceptionObject_class(context), NULL);
9318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSStringRef EvilExceptionObjectIString = JSStringCreateWithUTF8CString("EvilExceptionObject");
9328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSObjectSetProperty(context, globalObject, EvilExceptionObjectIString, EvilExceptionObject, kJSPropertyAttributeNone, NULL);
9338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSStringRelease(EvilExceptionObjectIString);
9348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSObjectRef EmptyObject = JSObjectMake(context, EmptyObject_class(context), NULL);
9368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSStringRef EmptyObjectIString = JSStringCreateWithUTF8CString("EmptyObject");
9378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSObjectSetProperty(context, globalObject, EmptyObjectIString, EmptyObject, kJSPropertyAttributeNone, NULL);
9388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSStringRelease(EmptyObjectIString);
9398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
940dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRef lengthStr = JSStringCreateWithUTF8CString("length");
941ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    JSObjectRef aStackRef = JSObjectMakeArray(context, 0, 0, 0);
942ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    aHeapRef = aStackRef;
943dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSObjectSetProperty(context, aHeapRef, lengthStr, JSValueMakeNumber(context, 10), 0, 0);
944dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRef privatePropertyName = JSStringCreateWithUTF8CString("privateProperty");
945dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!JSObjectSetPrivateProperty(context, myObject, privatePropertyName, aHeapRef)) {
946dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Could not set private property.\n");
9475abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        failed = 1;
9485abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    } else
949dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: Set private property.\n");
950ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    aStackRef = 0;
951dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (JSObjectSetPrivateProperty(context, aHeapRef, privatePropertyName, aHeapRef)) {
952dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: JSObjectSetPrivateProperty should fail on non-API objects.\n");
9535abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        failed = 1;
9545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    } else
955dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: Did not allow JSObjectSetPrivateProperty on a non-API object.\n");
956dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (JSObjectGetPrivateProperty(context, myObject, privatePropertyName) != aHeapRef) {
957dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Could not retrieve private property.\n");
958dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
959dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
960dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: Retrieved private property.\n");
961dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (JSObjectGetPrivateProperty(context, aHeapRef, privatePropertyName)) {
962dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: JSObjectGetPrivateProperty should return NULL when called on a non-API object.\n");
963dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
964dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
965dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: JSObjectGetPrivateProperty return NULL.\n");
9665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
967dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (JSObjectGetProperty(context, myObject, privatePropertyName, 0) == aHeapRef) {
968dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Accessed private property through ordinary property lookup.\n");
969dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
970dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
971dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: Cannot access private property through ordinary property lookup.\n");
9725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
973dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSGarbageCollect(context);
9745abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
975dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for (int i = 0; i < 10000; i++)
976dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        JSObjectMake(context, 0, 0);
977dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
978ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    aHeapRef = JSValueToObject(context, JSObjectGetPrivateProperty(context, myObject, privatePropertyName), 0);
979dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (JSValueToNumber(context, JSObjectGetProperty(context, aHeapRef, lengthStr, 0), 0) != 10) {
980dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Private property has been collected.\n");
981dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
982dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
983dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: Private property does not appear to have been collected.\n");
984dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRelease(lengthStr);
9855abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
9865abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (!JSObjectSetPrivateProperty(context, myObject, privatePropertyName, 0)) {
9875abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        printf("FAIL: Could not set private property to NULL.\n");
9885abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        failed = 1;
9895abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    } else
9905abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        printf("PASS: Set private property to NULL.\n");
9915abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    if (JSObjectGetPrivateProperty(context, myObject, privatePropertyName)) {
9925abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        printf("FAIL: Could not retrieve private property.\n");
9935abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        failed = 1;
9945abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    } else
9955abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        printf("PASS: Retrieved private property.\n");
9965abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
997dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRef validJSON = JSStringCreateWithUTF8CString("{\"aProperty\":true}");
998dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSValueRef jsonObject = JSValueMakeFromJSONString(context, validJSON);
999dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRelease(validJSON);
1000dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!JSValueIsObject(context, jsonObject)) {
1001dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Did not parse valid JSON correctly\n");
1002dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
1003dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
1004dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: Parsed valid JSON string.\n");
1005dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRef propertyName = JSStringCreateWithUTF8CString("aProperty");
1006dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    assertEqualsAsBoolean(JSObjectGetProperty(context, JSValueToObject(context, jsonObject, 0), propertyName, 0), true);
1007dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRelease(propertyName);
1008dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRef invalidJSON = JSStringCreateWithUTF8CString("fail!");
1009dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (JSValueMakeFromJSONString(context, invalidJSON)) {
1010dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Should return null for invalid JSON data\n");
1011dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
1012dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
1013dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: Correctly returned null for invalid JSON data.\n");
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef exception;
1015dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRef str = JSValueCreateJSONString(context, jsonObject, 0, 0);
1016dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!JSStringIsEqualToUTF8CString(str, "{\"aProperty\":true}")) {
1017dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Did not correctly serialise with indent of 0.\n");
1018dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
1019dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
1020dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: Correctly serialised with indent of 0.\n");
1021dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRelease(str);
10228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1023dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    str = JSValueCreateJSONString(context, jsonObject, 4, 0);
1024dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!JSStringIsEqualToUTF8CString(str, "{\n    \"aProperty\": true\n}")) {
1025dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Did not correctly serialise with indent of 4.\n");
1026dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
1027dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
1028dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: Correctly serialised with indent of 4.\n");
1029dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRelease(str);
1030dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSStringRef src = JSStringCreateWithUTF8CString("({get a(){ throw '';}})");
1031dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    JSValueRef unstringifiableObj = JSEvaluateScript(context, src, NULL, NULL, 1, NULL);
1032dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1033dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    str = JSValueCreateJSONString(context, unstringifiableObj, 4, 0);
1034dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (str) {
1035dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Didn't return null when attempting to serialize unserializable value.\n");
1036dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        JSStringRelease(str);
1037dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
1038dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
1039dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: returned null when attempting to serialize unserializable value.\n");
1040dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1041dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    str = JSValueCreateJSONString(context, unstringifiableObj, 4, &exception);
1042dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (str) {
1043dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Didn't return null when attempting to serialize unserializable value.\n");
1044dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        JSStringRelease(str);
1045dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
1046dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
1047dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: returned null when attempting to serialize unserializable value.\n");
1048dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!exception) {
1049dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("FAIL: Did not set exception on serialisation error\n");
1050dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        failed = 1;
1051dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    } else
1052dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        printf("PASS: set exception on serialisation error\n");
10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Conversions that throw exceptions
10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(NULL == JSValueToObject(context, jsNull, &exception));
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(exception);
10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
10598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME <rdar://4668451> - On i386 the isnan(double) macro tries to map to the isnan(float) function,
10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // causing a build break with -Wshorten-64-to-32 enabled.  The issue is known by the appropriate team.
10618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // After that's resolved, we can remove these casts
10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(isnan((float)JSValueToNumber(context, jsObjectNoProto, &exception)));
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(exception);
10648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSValueToStringCopy(context, jsObjectNoProto, &exception));
10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(exception);
10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueToBoolean(context, myObject));
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSValueIsEqual(context, jsObjectNoProto, JSValueMakeNumber(context, 1), &exception));
10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(exception);
10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectGetPropertyAtIndex(context, myObject, 0, &exception);
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(1 == JSValueToNumber(context, exception, NULL));
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsUndefined, false);
10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsNull, false);
10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsTrue, true);
10828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsFalse, false);
10838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsZero, false);
10848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsOne, true);
10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsOneThird, true);
10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsEmptyString, false);
10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsOneString, true);
10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsCFString, true);
10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsCFStringWithCharacters, true);
10908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsCFEmptyString, false);
10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsBoolean(jsCFEmptyStringWithCharacters, false);
10928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsUndefined, nan(""));
10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsNull, 0);
10958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsTrue, 1);
10968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsFalse, 0);
10978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsZero, 0);
10988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsOne, 1);
10998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsOneThird, 1.0 / 3.0);
11008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsEmptyString, 0);
11018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsOneString, 1);
11028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsCFString, nan(""));
11038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsCFStringWithCharacters, nan(""));
11048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsCFEmptyString, 0);
11058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(jsCFEmptyStringWithCharacters, 0);
11068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(sizeof(JSChar) == sizeof(UniChar));
11078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsUndefined, "undefined");
11098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsNull, "null");
11108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsTrue, "true");
11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsFalse, "false");
11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsZero, "0");
11138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsOne, "1");
11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsOneThird, "0.3333333333333333");
11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsEmptyString, "");
11168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsOneString, "1");
11178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsCFString, "A");
11188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsCFStringWithCharacters, "A");
11198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsCFEmptyString, "");
11208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsCharactersPtr(jsCFEmptyStringWithCharacters, "");
11218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsUndefined, "undefined");
11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsNull, "null");
11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsTrue, "true");
11258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsFalse, "false");
11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsZero, "0");
11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsOne, "1");
11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsOneThird, "0.3333333333333333");
11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsEmptyString, "");
11308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsOneString, "1");
11318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsCFString, "A");
11328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsCFStringWithCharacters, "A");
11338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsCFEmptyString, "");
11348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, "");
11358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsStrictEqual(context, jsTrue, jsTrue));
11378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSValueIsStrictEqual(context, jsOne, jsOneString));
11388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, jsOne, jsOneString, NULL));
11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSValueIsEqual(context, jsTrue, jsFalse, NULL));
11418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFStringRef cfJSString = JSStringCopyCFString(kCFAllocatorDefault, jsCFIString);
11438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFStringRef cfJSEmptyString = JSStringCopyCFString(kCFAllocatorDefault, jsCFEmptyIString);
11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(CFEqual(cfJSString, cfString));
11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(CFEqual(cfJSEmptyString, cfEmptyString));
11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFRelease(cfJSString);
11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFRelease(cfJSEmptyString);
11488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFRelease(cfString);
11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CFRelease(cfEmptyString);
11518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jsGlobalValue = JSObjectMake(context, NULL, NULL);
1153643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    makeGlobalNumberValue(context);
11548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueProtect(context, jsGlobalValue);
11558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSGarbageCollect(context);
11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsObject(context, jsGlobalValue));
11578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueUnprotect(context, jsGlobalValue);
1158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    JSValueUnprotect(context, jsNumberValue);
11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef goodSyntax = JSStringCreateWithUTF8CString("x = 1;");
11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef badSyntax = JSStringCreateWithUTF8CString("x := 1;");
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSCheckScriptSyntax(context, goodSyntax, NULL, 0, NULL));
11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSCheckScriptSyntax(context, badSyntax, NULL, 0, NULL));
11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef result;
11668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef v;
11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef o;
11688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef string;
11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result = JSEvaluateScript(context, goodSyntax, NULL, NULL, 1, NULL);
11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(result);
11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, result, jsOne, NULL));
11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result = JSEvaluateScript(context, badSyntax, NULL, NULL, 1, &exception);
11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!result);
11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsObject(context, exception));
11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef array = JSStringCreateWithUTF8CString("Array");
11808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef arrayConstructor = JSValueToObject(context, JSObjectGetProperty(context, globalObject, array, NULL), NULL);
11818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(array);
11828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result = JSObjectCallAsConstructor(context, arrayConstructor, 0, NULL, NULL);
11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(result);
11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsObject(context, result));
11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsInstanceOfConstructor(context, result, arrayConstructor, NULL));
11868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSValueIsInstanceOfConstructor(context, JSValueMakeNull(context), arrayConstructor, NULL));
11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    o = JSValueToObject(context, result, NULL);
11898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
11908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsUndefined(context, JSObjectGetPropertyAtIndex(context, o, 0, &exception)));
11918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!exception);
11928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectSetPropertyAtIndex(context, o, 0, JSValueMakeNumber(context, 1), &exception);
11948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!exception);
11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
11978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(1 == JSValueToNumber(context, JSObjectGetPropertyAtIndex(context, o, 0, &exception), &exception));
11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!exception);
11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef functionBody;
12018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef function;
12028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
12048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    functionBody = JSStringCreateWithUTF8CString("rreturn Array;");
12058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef line = JSStringCreateWithUTF8CString("line");
12068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception));
12078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsObject(context, exception));
12088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectGetProperty(context, JSValueToObject(context, exception, NULL), line, NULL);
12098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(v, 1);
12108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(functionBody);
12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(line);
12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
12148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    functionBody = JSStringCreateWithUTF8CString("return Array;");
12158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, &exception);
12168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(functionBody);
12178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!exception);
12188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSObjectIsFunction(context, function));
12198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
12208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(v);
12218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, v, arrayConstructor, NULL));
12228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
12248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    function = JSObjectMakeFunction(context, NULL, 0, NULL, jsEmptyIString, NULL, 0, &exception);
12258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!exception);
12268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, &exception);
12278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(v && !exception);
12288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsUndefined(context, v));
12298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    exception = NULL;
12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = NULL;
12328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef foo = JSStringCreateWithUTF8CString("foo");
12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef argumentNames[] = { foo };
12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    functionBody = JSStringCreateWithUTF8CString("return foo;");
12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    function = JSObjectMakeFunction(context, foo, 1, argumentNames, functionBody, NULL, 1, &exception);
12368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(function && !exception);
12378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef arguments[] = { JSValueMakeNumber(context, 2) };
12388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectCallAsFunction(context, function, NULL, 1, arguments, &exception);
12398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(foo);
12408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(functionBody);
12418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    string = JSValueToStringCopy(context, function, NULL);
12438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) { return foo;\n}");
12448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(string);
12458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef print = JSStringCreateWithUTF8CString("print");
12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef printFunction = JSObjectMakeFunctionWithCallback(context, print, print_callAsFunction);
12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectSetProperty(context, globalObject, print, printFunction, kJSPropertyAttributeNone, NULL);
12498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(print);
12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSObjectSetPrivate(printFunction, (void*)1));
12528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSObjectGetPrivate(printFunction));
12538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef myConstructorIString = JSStringCreateWithUTF8CString("MyConstructor");
12558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef myConstructor = JSObjectMakeConstructor(context, NULL, myConstructor_callAsConstructor);
12568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectSetProperty(context, globalObject, myConstructorIString, myConstructor, kJSPropertyAttributeNone, NULL);
12578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(myConstructorIString);
12588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSObjectSetPrivate(myConstructor, (void*)1));
12608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!JSObjectGetPrivate(myConstructor));
12618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1262d0825bca7fe65beaee391d30da42e937db621564Steve Block    string = JSStringCreateWithUTF8CString("Base");
1263d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSObjectRef baseConstructor = JSObjectMakeConstructor(context, Base_class(context), NULL);
1264d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSObjectSetProperty(context, globalObject, string, baseConstructor, kJSPropertyAttributeNone, NULL);
1265d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSStringRelease(string);
1266d0825bca7fe65beaee391d30da42e937db621564Steve Block
12678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    string = JSStringCreateWithUTF8CString("Derived");
12688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectRef derivedConstructor = JSObjectMakeConstructor(context, Derived_class(context), NULL);
12698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectSetProperty(context, globalObject, string, derivedConstructor, kJSPropertyAttributeNone, NULL);
12708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(string);
12718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1272d0825bca7fe65beaee391d30da42e937db621564Steve Block    string = JSStringCreateWithUTF8CString("Derived2");
1273d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSObjectRef derived2Constructor = JSObjectMakeConstructor(context, Derived2_class(context), NULL);
1274d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSObjectSetProperty(context, globalObject, string, derived2Constructor, kJSPropertyAttributeNone, NULL);
1275d0825bca7fe65beaee391d30da42e937db621564Steve Block    JSStringRelease(string);
1276d0825bca7fe65beaee391d30da42e937db621564Steve Block
12778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    o = JSObjectMake(context, NULL, NULL);
12788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL);
12798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSObjectSetProperty(context, o, jsCFIString,  JSValueMakeNumber(context, 1), kJSPropertyAttributeDontEnum, NULL);
12808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSPropertyNameArrayRef nameArray = JSObjectCopyPropertyNames(context, o);
12818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t expectedCount = JSPropertyNameArrayGetCount(nameArray);
12828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t count;
12838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (count = 0; count < expectedCount; ++count)
12848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSPropertyNameArrayGetNameAtIndex(nameArray, count);
12858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSPropertyNameArrayRelease(nameArray);
12868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(count == 1); // jsCFString should not be enumerated
12878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef argumentsArrayValues[] = { JSValueMakeNumber(context, 10), JSValueMakeNumber(context, 20) };
12898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    o = JSObjectMakeArray(context, sizeof(argumentsArrayValues) / sizeof(JSValueRef), argumentsArrayValues, NULL);
12908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    string = JSStringCreateWithUTF8CString("length");
12918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectGetProperty(context, o, string, NULL);
12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(v, 2);
12938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectGetPropertyAtIndex(context, o, 0, NULL);
12948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(v, 10);
12958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectGetPropertyAtIndex(context, o, 1, NULL);
12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(v, 20);
12978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    o = JSObjectMakeArray(context, 0, NULL, NULL);
12998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectGetProperty(context, o, string, NULL);
13008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsNumber(v, 0);
13018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(string);
13028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef argumentsDateValues[] = { JSValueMakeNumber(context, 0) };
13048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    o = JSObjectMakeDate(context, 1, argumentsDateValues, NULL);
13055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (timeZoneIsPST())
13065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        assertEqualsAsUTF8String(o, "Wed Dec 31 1969 16:00:00 GMT-0800 (PST)");
13078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    string = JSStringCreateWithUTF8CString("an error message");
13098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef argumentsErrorValues[] = { JSValueMakeString(context, string) };
13108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    o = JSObjectMakeError(context, 1, argumentsErrorValues, NULL);
13118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(o, "Error: an error message");
13128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(string);
13138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    string = JSStringCreateWithUTF8CString("foo");
13158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef string2 = JSStringCreateWithUTF8CString("gi");
13168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSValueRef argumentsRegExpValues[] = { JSValueMakeString(context, string), JSValueMakeString(context, string2) };
13178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    o = JSObjectMakeRegExp(context, 2, argumentsRegExpValues, NULL);
13188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    assertEqualsAsUTF8String(o, "/foo/gi");
13198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(string);
13208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(string2);
13218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSClassDefinition nullDefinition = kJSClassDefinitionEmpty;
13238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    nullDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
13248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSClassRef nullClass = JSClassCreate(&nullDefinition);
13258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSClassRelease(nullClass);
13268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    nullDefinition = kJSClassDefinitionEmpty;
13288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    nullClass = JSClassCreate(&nullDefinition);
13298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSClassRelease(nullClass);
13308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    functionBody = JSStringCreateWithUTF8CString("return this;");
13328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, NULL);
13338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(functionBody);
13348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
13358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
13368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
13378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, v, o, NULL));
13388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    functionBody = JSStringCreateWithUTF8CString("return eval(\"this\");");
13408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    function = JSObjectMakeFunction(context, NULL, 0, NULL, functionBody, NULL, 1, NULL);
13418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(functionBody);
13428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL);
13438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
13448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
13458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, v, o, NULL));
13468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRef script = JSStringCreateWithUTF8CString("this;");
13488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
13498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
13508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
13518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, v, o, NULL));
13528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(script);
13538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    script = JSStringCreateWithUTF8CString("eval(this);");
13558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSEvaluateScript(context, script, NULL, NULL, 1, NULL);
13568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, v, globalObject, NULL));
13578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = JSEvaluateScript(context, script, o, NULL, 1, NULL);
13588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(JSValueIsEqual(context, v, o, NULL));
13598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(script);
13608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Verify that creating a constructor for a class with no static functions does not trigger
13625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // an assert inside putDirect or lead to a crash during GC. <https://bugs.webkit.org/show_bug.cgi?id=25785>
13635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    nullDefinition = kJSClassDefinitionEmpty;
13645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    nullClass = JSClassCreate(&nullDefinition);
13655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    myConstructor = JSObjectMakeConstructor(context, nullClass, 0);
13665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    JSClassRelease(nullClass);
13675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* scriptUTF8 = createStringWithContentsOfFile(scriptPath);
13698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!scriptUTF8) {
13708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        printf("FAIL: Test script could not be loaded.\n");
13718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        failed = 1;
13728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else {
13738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        script = JSStringCreateWithUTF8CString(scriptUTF8);
13748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
1375d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (result && JSValueIsUndefined(context, result))
13768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            printf("PASS: Test script executed successfully.\n");
13778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
13788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            printf("FAIL: Test script returned unexpected value:\n");
13798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            JSStringRef exceptionIString = JSValueToStringCopy(context, exception, NULL);
13808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFStringRef exceptionCF = JSStringCopyCFString(kCFAllocatorDefault, exceptionIString);
13818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFShow(exceptionCF);
13828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRelease(exceptionCF);
13838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            JSStringRelease(exceptionIString);
13848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            failed = 1;
13858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
13868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSStringRelease(script);
13878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        free(scriptUTF8);
13888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Clear out local variables pointing at JSObjectRefs to allow their values to be collected
13918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    function = NULL;
13928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    v = NULL;
13938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    o = NULL;
13948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    globalObject = NULL;
13955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    myConstructor = NULL;
13968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(jsEmptyIString);
13988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(jsOneIString);
13998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(jsCFIString);
14008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(jsCFEmptyIString);
14018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(jsCFIStringWithCharacters);
14028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(jsCFEmptyIStringWithCharacters);
14038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(goodSyntax);
14048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSStringRelease(badSyntax);
14058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSGlobalContextRelease(context);
14078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    JSClassRelease(globalObjectClass);
14088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Test for an infinite prototype chain that used to be created. This test
14108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // passes if the call to JSObjectHasProperty() does not hang.
14118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
14128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSClassDefinition prototypeLoopClassDefinition = kJSClassDefinitionEmpty;
14138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    prototypeLoopClassDefinition.staticFunctions = globalObject_staticFunctions;
14148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSClassRef prototypeLoopClass = JSClassCreate(&prototypeLoopClassDefinition);
14158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSGlobalContextRef prototypeLoopContext = JSGlobalContextCreateInGroup(NULL, prototypeLoopClass);
14168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
14178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSStringRef nameProperty = JSStringCreateWithUTF8CString("name");
14188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSObjectHasProperty(prototypeLoopContext, JSContextGetGlobalObject(prototypeLoopContext), nameProperty);
14198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
14208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSGlobalContextRelease(prototypeLoopContext);
14218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    JSClassRelease(prototypeLoopClass);
14228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
14238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    printf("PASS: Infinite prototype chain does not occur.\n");
14248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
14255af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (checkForCycleInPrototypeChain())
14265af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        printf("PASS: A cycle in a prototype chain can't be created.\n");
14275af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    else {
14285af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        printf("FAIL: A cycle in a prototype chain can be created.\n");
14295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        failed = true;
14305af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
14315af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
14328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (failed) {
14338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        printf("FAIL: Some tests failed.\n");
14348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return 1;
14358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
14368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
14378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    printf("PASS: Program exited normally.\n");
14388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return 0;
14398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic char* createStringWithContentsOfFile(const char* fileName)
14428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    char* buffer;
14448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t buffer_size = 0;
14468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t buffer_capacity = 1024;
14478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    buffer = (char*)malloc(buffer_capacity);
14488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FILE* f = fopen(fileName, "r");
14508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!f) {
14518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fprintf(stderr, "Could not open file: %s\n", fileName);
14528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
14538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (!feof(f) && !ferror(f)) {
14568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f);
14578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0'
14588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            buffer_capacity *= 2;
14598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            buffer = (char*)realloc(buffer, buffer_capacity);
14608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(buffer);
14618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
14628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(buffer_size < buffer_capacity);
14648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fclose(f);
14668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    buffer[buffer_size] = '\0';
14678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return buffer;
14698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1470