Reviewed by Geoff Garen.
authorap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Aug 2008 07:43:48 +0000 (07:43 +0000)
committerap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Aug 2008 07:43:48 +0000 (07:43 +0000)
        JSStringRef is created context-free, but can get linked to one via an identifier table,
        breaking an implicit API contract.

        Made JSStringRef point to OpaqueJSString, which is a new string object separate from UString.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@35775 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
JavaScriptCore/API/APICast.h
JavaScriptCore/API/JSBase.cpp
JavaScriptCore/API/JSCallbackObjectFunctions.h
JavaScriptCore/API/JSObjectRef.cpp
JavaScriptCore/API/JSStringRef.cpp
JavaScriptCore/API/JSStringRefCF.cpp
JavaScriptCore/API/JSValueRef.cpp
JavaScriptCore/API/OpaqueJSString.cpp [new file with mode: 0644]
JavaScriptCore/API/OpaqueJSString.h [new file with mode: 0644]
JavaScriptCore/ChangeLog
JavaScriptCore/GNUmakefile.am
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/JavaScriptCore.pri
JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/JavaScriptCoreSources.bkl
JavaScriptCore/kjs/identifier.cpp
JavaScriptCore/kjs/identifier.h
WebCore/ChangeLog
WebCore/page/InspectorController.cpp
WebCore/page/JavaScriptProfile.cpp

index 76947f0..5b5417c 100644 (file)
@@ -40,7 +40,6 @@ namespace KJS {
 typedef const struct OpaqueJSContextGroup* JSContextGroupRef;
 typedef const struct OpaqueJSContext* JSContextRef;
 typedef struct OpaqueJSContext* JSGlobalContextRef;
-typedef struct OpaqueJSString* JSStringRef;
 typedef struct OpaqueJSPropertyNameAccumulator* JSPropertyNameAccumulatorRef;
 typedef const struct OpaqueJSValue* JSValueRef;
 typedef struct OpaqueJSValue* JSObjectRef;
@@ -62,11 +61,6 @@ inline KJS::JSValue* toJS(JSValueRef v)
     return reinterpret_cast<KJS::JSValue*>(const_cast<OpaqueJSValue*>(v));
 }
 
-inline KJS::UString::Rep* toJS(JSStringRef b)
-{
-    return reinterpret_cast<KJS::UString::Rep*>(b);
-}
-
 inline KJS::JSObject* toJS(JSObjectRef o)
 {
     return reinterpret_cast<KJS::JSObject*>(o);
@@ -92,11 +86,6 @@ inline JSValueRef* toRef(KJS::JSValue** v)
     return reinterpret_cast<JSValueRef*>(const_cast<const KJS::JSValue**>(v));
 }
 
-inline JSStringRef toRef(KJS::UString::Rep* s)
-{
-    return reinterpret_cast<JSStringRef>(s);
-}
-
 inline JSObjectRef toRef(KJS::JSObject* o)
 {
     return reinterpret_cast<JSObjectRef>(o);
index 2eb12e1..b8afc52 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "APICast.h"
 #include "completion.h"
+#include "OpaqueJSString.h"
 #include <kjs/ExecState.h>
 #include <kjs/InitializeThreading.h>
 #include <kjs/interpreter.h>
@@ -43,12 +44,10 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
     exec->globalData().heap->registerThread();
 
     JSObject* jsThisObject = toJS(thisObject);
-    UString::Rep* scriptRep = toJS(script);
-    UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
 
     // Interpreter::evaluate sets "this" to the global object if it is NULL
     JSGlobalObject* globalObject = exec->dynamicGlobalObject();
-    Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), UString(sourceURLRep), startingLineNumber, UString(scriptRep), jsThisObject);
+    Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), sourceURL->ustring(), startingLineNumber, script->ustring(), jsThisObject);
 
     if (completion.complType() == Throw) {
         if (exception)
@@ -68,9 +67,7 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
     ExecState* exec = toJS(ctx);
     exec->globalData().heap->registerThread();
 
-    UString::Rep* scriptRep = toJS(script);
-    UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
-    Completion completion = Interpreter::checkSyntax(exec->dynamicGlobalObject()->globalExec(), UString(sourceURLRep), startingLineNumber, UString(scriptRep));
+    Completion completion = Interpreter::checkSyntax(exec->dynamicGlobalObject()->globalExec(), sourceURL->ustring(), startingLineNumber, script->ustring());
     if (completion.complType() == Throw) {
         if (exception)
             *exception = toRef(completion.value());
index d9ea429..9ac5a62 100644 (file)
@@ -33,6 +33,7 @@
 #include "JSObjectRef.h"
 #include "JSString.h"
 #include "JSStringRef.h"
+#include "OpaqueJSString.h"
 #include "PropertyNameArray.h"
 #include <wtf/Vector.h>
 
@@ -105,17 +106,21 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie
 {
     JSContextRef ctx = toRef(exec);
     JSObjectRef thisRef = toRef(this);
-    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
+    RefPtr<OpaqueJSString> propertyNameRef;
     
     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
         // optional optimization to bypass getProperty in cases when we only need to know if the property exists
         if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
-            if (hasProperty(ctx, thisRef, propertyNameRef)) {
+            if (!propertyNameRef)
+                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
+            if (hasProperty(ctx, thisRef, propertyNameRef.get())) {
                 slot.setCustom(this, callbackGetter);
                 return true;
             }
         } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
-            if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef, toRef(exec->exceptionSlot()))) {
+            if (!propertyNameRef)
+                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
+            if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot()))) {
                 // cache the value so we don't have to compute it again
                 // FIXME: This violates the PropertySlot design a little bit.
                 // We should either use this optimization everywhere, or nowhere.
@@ -153,12 +158,14 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
 {
     JSContextRef ctx = toRef(exec);
     JSObjectRef thisRef = toRef(this);
-    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
+    RefPtr<OpaqueJSString> propertyNameRef;
     JSValueRef valueRef = toRef(value);
     
     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
         if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
-            if (setProperty(ctx, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot())))
+            if (!propertyNameRef)
+                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
+            if (setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, toRef(exec->exceptionSlot())))
                 return;
         }
         
@@ -167,7 +174,9 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
                 if (entry->attributes & kJSPropertyAttributeReadOnly)
                     return;
                 if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
-                    if (setProperty(ctx, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot())))
+                    if (!propertyNameRef)
+                        propertyNameRef = OpaqueJSString::create(propertyName.ustring());
+                    if (setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, toRef(exec->exceptionSlot())))
                         return;
                 } else
                     throwError(exec, ReferenceError, "Attempt to set a property that is not settable.");
@@ -198,11 +207,13 @@ bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& p
 {
     JSContextRef ctx = toRef(exec);
     JSObjectRef thisRef = toRef(this);
-    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
+    RefPtr<OpaqueJSString> propertyNameRef;
     
     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
         if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
-            if (deleteProperty(ctx, thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
+            if (!propertyNameRef)
+                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
+            if (deleteProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
                 return true;
         }
         
@@ -430,13 +441,15 @@ JSValue* JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identi
     JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
     
     JSObjectRef thisRef = toRef(thisObj);
-    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
+    RefPtr<OpaqueJSString> propertyNameRef;
     
     for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
         if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec))
             if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep()))
                 if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
-                    if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
+                    if (!propertyNameRef)
+                        propertyNameRef = OpaqueJSString::create(propertyName.ustring());
+                    if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
                         return toJS(value);
                 }
                     
@@ -476,11 +489,13 @@ JSValue* JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifie
     JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
     
     JSObjectRef thisRef = toRef(thisObj);
-    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
+    RefPtr<OpaqueJSString> propertyNameRef;
     
     for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
         if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
-            if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
+            if (!propertyNameRef)
+                propertyNameRef = OpaqueJSString::create(propertyName.ustring());
+            if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
                 return toJS(value);
         }
             
index 81fac2e..5bb09c0 100644 (file)
@@ -36,6 +36,7 @@
 #include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSObject.h"
+#include "JSRetainPtr.h"
 #include "JSString.h"
 #include "JSValueRef.h"
 #include "ObjectPrototype.h"
@@ -85,7 +86,7 @@ JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name,
     ExecState* exec = toJS(ctx);
     exec->globalData().heap->registerThread();
 
-    Identifier nameID = name ? Identifier(exec, toJS(name)) : Identifier(exec, "anonymous");
+    Identifier nameID = name ? name->identifier(exec) : Identifier(exec, "anonymous");
     
     return toRef(new (exec) JSCallbackFunction(exec, callAsFunction, nameID));
 }
@@ -109,17 +110,14 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
     ExecState* exec = toJS(ctx);
     exec->globalData().heap->registerThread();
 
-    UString::Rep* bodyRep = toJS(body);
-    UString::Rep* sourceURLRep = sourceURL ? toJS(sourceURL) : &UString::Rep::null;
-    
-    Identifier nameID = name ? Identifier(exec, toJS(name)) : Identifier(exec, "anonymous");
+    Identifier nameID = name ? name->identifier(exec) : Identifier(exec, "anonymous");
     
     ArgList args;
     for (unsigned i = 0; i < parameterCount; i++)
-        args.append(jsString(exec, UString(toJS(parameterNames[i]))));
-    args.append(jsString(exec, UString(bodyRep)));
+        args.append(jsString(exec, UString(parameterNames[i]->ustring())));
+    args.append(jsString(exec, body->ustring()));
 
-    JSObject* result = constructFunction(exec, args, nameID, UString(sourceURLRep), startingLineNumber);
+    JSObject* result = constructFunction(exec, args, nameID, sourceURL->ustring(), startingLineNumber);
     if (exec->hadException()) {
         if (exception)
             *exception = toRef(exec->exception());
@@ -149,9 +147,8 @@ bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
     exec->globalData().heap->registerThread();
 
     JSObject* jsObject = toJS(object);
-    UString::Rep* nameRep = toJS(propertyName);
     
-    return jsObject->hasProperty(exec, Identifier(exec, nameRep));
+    return jsObject->hasProperty(exec, propertyName->identifier(exec));
 }
 
 JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
@@ -160,9 +157,8 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
     exec->globalData().heap->registerThread();
 
     JSObject* jsObject = toJS(object);
-    UString::Rep* nameRep = toJS(propertyName);
 
-    JSValue* jsValue = jsObject->get(exec, Identifier(exec, nameRep));
+    JSValue* jsValue = jsObject->get(exec, propertyName->identifier(exec));
     if (exec->hadException()) {
         if (exception)
             *exception = toRef(exec->exception());
@@ -177,7 +173,7 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
     exec->globalData().heap->registerThread();
 
     JSObject* jsObject = toJS(object);
-    Identifier name(exec, toJS(propertyName));
+    Identifier name(propertyName->identifier(exec));
     JSValue* jsValue = toJS(value);
 
     if (attributes && !jsObject->hasProperty(exec, name))
@@ -231,9 +227,8 @@ bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
     exec->globalData().heap->registerThread();
 
     JSObject* jsObject = toJS(object);
-    UString::Rep* nameRep = toJS(propertyName);
 
-    bool result = jsObject->deleteProperty(exec, Identifier(exec, nameRep));
+    bool result = jsObject->deleteProperty(exec,  propertyName->identifier(exec));
     if (exec->hadException()) {
         if (exception)
             *exception = toRef(exec->exception());
@@ -337,14 +332,16 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
     return result;
 }
 
-struct OpaqueJSPropertyNameArray
-{
-    OpaqueJSPropertyNameArray(JSGlobalData* globalData) : refCount(0), array(globalData)
+struct OpaqueJSPropertyNameArray {
+    OpaqueJSPropertyNameArray(JSGlobalData* globalData)
+        : refCount(0)
+        , globalData(globalData)
     {
     }
     
     unsigned refCount;
-    PropertyNameArray array;
+    JSGlobalData* globalData;
+    Vector<JSRetainPtr<JSStringRef> > array;
 };
 
 JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object)
@@ -353,8 +350,16 @@ JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef o
     ExecState* exec = toJS(ctx);
     exec->globalData().heap->registerThread();
 
-    JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(&exec->globalData());
-    jsObject->getPropertyNames(exec, propertyNames->array);
+    JSGlobalData* globalData = &exec->globalData();
+
+    JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(globalData);
+    PropertyNameArray array(globalData);
+    jsObject->getPropertyNames(exec, array);
+
+    size_t size = array.size();
+    propertyNames->array.reserveCapacity(size);
+    for (size_t i = 0; i < size; ++i)
+        propertyNames->array.append(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].ustring()).releaseRef()));
     
     return JSPropertyNameArrayRetain(propertyNames);
 }
@@ -378,15 +383,14 @@ size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array)
 
 JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index)
 {
-    return toRef(array->array[static_cast<unsigned>(index)].ustring().rep());
+    return array->array[static_cast<unsigned>(index)].get();
 }
 
 void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStringRef propertyName)
 {
     PropertyNameArray* propertyNames = toJS(array);
-    UString::Rep* rep = toJS(propertyName);
 
     propertyNames->globalData()->heap->registerThread();
 
-    propertyNames->add(Identifier(propertyNames->globalData(), rep));
+    propertyNames->add(propertyName->identifier(propertyNames->globalData()));
 }
index 302da8d..e65292a 100644 (file)
 #include "config.h"
 #include "JSStringRef.h"
 
-#include <wtf/Platform.h>
-
-#include "APICast.h"
-#include <kjs/JSType.h>
-#include <kjs/JSString.h>
-#include <kjs/operations.h>
-#include <kjs/ustring.h>
-#include <kjs/JSValue.h>
+#include "OpaqueJSString.h"
 #include <wtf/unicode/UTF8.h>
 
 using namespace KJS;
@@ -42,72 +35,69 @@ using namespace WTF::Unicode;
 
 JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars)
 {
-    return toRef(UString(chars, static_cast<int>(numChars)).rep()->ref());
+    return OpaqueJSString::create(chars, numChars).releaseRef();
 }
 
 JSStringRef JSStringCreateWithUTF8CString(const char* string)
 {
-    RefPtr<UString::Rep> result = UString::Rep::createFromUTF8(string);
-    if (result.get() == &UString::Rep::null)
-        return 0;
-
-    return toRef(result.release().releaseRef());
+    if (string) {
+        size_t length = strlen(string);
+        Vector<UChar, 1024> buffer(length);
+        UChar* p = buffer.data();
+        if (conversionOK == convertUTF8ToUTF16(&string, string + length, &p, p + length))
+            return OpaqueJSString::create(buffer.data(), p - buffer.data()).releaseRef();
+    }
+
+    // Null string.
+    return OpaqueJSString::create().releaseRef();
 }
 
 JSStringRef JSStringRetain(JSStringRef string)
 {
-    UString::Rep* rep = toJS(string);
-    return toRef(rep->ref());
+    string->ref();
+    return string;
 }
 
 void JSStringRelease(JSStringRef string)
 {
-    UString::Rep* rep = toJS(string);
-    bool needsLocking = rep->identifierTable();
-    if (needsLocking) {
-        // It is wasteful to take the lock for non-shared contexts, but we don't have a good way
-        // to determine what the context is.
-        rep->deref();
-    } else
-        rep->deref();
+    string->deref();
 }
 
 size_t JSStringGetLength(JSStringRef string)
 {
-    UString::Rep* rep = toJS(string);
-    return rep->size();
+    return string->length();
 }
 
 const JSChar* JSStringGetCharactersPtr(JSStringRef string)
 {
-    UString::Rep* rep = toJS(string);
-    return reinterpret_cast<const JSChar*>(rep->data());
+    return string->characters();
 }
 
 size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string)
 {
-    UString::Rep* rep = toJS(string);
-    
     // Any UTF8 character > 3 bytes encodes as a UTF16 surrogate pair.
-    return rep->size() * 3 + 1; // + 1 for terminating '\0'
+    return string->length() * 3 + 1; // + 1 for terminating '\0'
 }
 
 size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSize)
 {
-    UString::Rep* rep = toJS(string);
-    CString cString = UString(rep).UTF8String();
+    if (!bufferSize)
+        return 0;
 
-    size_t length = std::min(bufferSize, cString.size() + 1); // + 1 for terminating '\0'
-    memcpy(buffer, cString.c_str(), length);
-    return length;
+    char* p = buffer;
+    const UChar* d = string->characters();
+    ConversionResult result = convertUTF16ToUTF8(&d, d + string->length(), &p, p + bufferSize - 1, true);
+    *p++ = '\0';
+    if (result != conversionOK && result != targetExhausted)
+        return 0;
+
+    return p - buffer;
 }
 
 bool JSStringIsEqual(JSStringRef a, JSStringRef b)
 {
-    UString::Rep* aRep = toJS(a);
-    UString::Rep* bRep = toJS(b);
-    
-    return UString(aRep) == UString(bRep);
+    unsigned len = a->length();
+    return len == b->length() && 0 == memcmp(a->characters(), b->characters(), len * sizeof(UChar));
 }
 
 bool JSStringIsEqualToUTF8CString(JSStringRef a, const char* b)
index a822768..d527816 100644 (file)
 
 #include "APICast.h"
 #include "JSStringRef.h"
+#include "OpaqueJSString.h"
 #include <kjs/ustring.h>
 #include <kjs/JSValue.h>
-
-using namespace KJS;
+#include <wtf/OwnArrayPtr.h>
 
 JSStringRef JSStringCreateWithCFString(CFStringRef string)
 {
     CFIndex length = CFStringGetLength(string);
-    UString::Rep* rep;
-    if (!length)
-        rep = UString("").rep()->ref();
-    else {
-        UniChar* buffer = static_cast<UniChar*>(fastMalloc(sizeof(UniChar) * length));
-        CFStringGetCharacters(string, CFRangeMake(0, length), buffer);
+    if (length) {
+        OwnArrayPtr<UniChar> buffer(new UniChar[length]);
+        CFStringGetCharacters(string, CFRangeMake(0, length), buffer.get());
         COMPILE_ASSERT(sizeof(UniChar) == sizeof(UChar), unichar_and_uchar_must_be_same_size);
-        rep = UString(reinterpret_cast<UChar*>(buffer), length, false).rep()->ref();
+        return OpaqueJSString::create(buffer.get(), length).releaseRef();
+    } else {
+        return OpaqueJSString::create(0, 0).releaseRef();
+    }
     }
-    return toRef(rep);
-}
 
 CFStringRef JSStringCopyCFString(CFAllocatorRef alloc, JSStringRef string)
 {
-    UString::Rep* rep = toJS(string);
-    return CFStringCreateWithCharacters(alloc, reinterpret_cast<const UniChar*>(rep->data()), rep->size());
+    return CFStringCreateWithCharacters(alloc, reinterpret_cast<const UniChar*>(string->characters()), string->length());
 }
index 86da2a6..0a6c40f 100644 (file)
@@ -188,8 +188,7 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
     ExecState* exec = toJS(ctx);
     exec->globalData().heap->registerThread();
 
-    UString::Rep* rep = toJS(string);
-    return toRef(jsString(exec, UString(rep)));
+    return toRef(jsString(exec, string->ustring()));
 }
 
 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
@@ -223,14 +222,14 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef*
 
     JSValue* jsValue = toJS(value);
     
-    JSStringRef stringRef = toRef(jsValue->toString(exec).rep()->ref());
+    RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue->toString(exec)));
     if (exec->hadException()) {
         if (exception)
             *exception = toRef(exec->exception());
         exec->clearException();
-        stringRef = 0;
+        stringRef.clear();
     }
-    return stringRef;
+    return stringRef.release().releaseRef();
 }
 
 JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
diff --git a/JavaScriptCore/API/OpaqueJSString.cpp b/JavaScriptCore/API/OpaqueJSString.cpp
new file mode 100644 (file)
index 0000000..d591cf3
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "OpaqueJSString.h"
+
+#include <kjs/ExecState.h>
+#include <kjs/identifier.h>
+
+using namespace KJS;
+
+PassRefPtr<OpaqueJSString> OpaqueJSString::create(const UString& ustring)
+{
+    if (!ustring.isNull())
+        return adoptRef(new OpaqueJSString(ustring.data(), ustring.size()));
+    return 0;
+}
+
+UString OpaqueJSString::ustring() const
+{
+    if (this && m_characters)
+        return UString(m_characters, m_length, true);
+    return UString::null();
+}
+
+Identifier OpaqueJSString::identifier(ExecState* exec) const
+{
+    return identifier(&exec->globalData());
+}
+
+Identifier OpaqueJSString::identifier(JSGlobalData* globalData) const
+{
+    if (!this || !m_characters)
+        return Identifier(globalData, static_cast<const char*>(0));
+
+    return Identifier(globalData, m_characters, m_length);
+}
diff --git a/JavaScriptCore/API/OpaqueJSString.h b/JavaScriptCore/API/OpaqueJSString.h
new file mode 100644 (file)
index 0000000..687f28c
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef OpaqueJSString_h
+#define OpaqueJSString_h
+
+#include <kjs/ustring.h>
+
+namespace KJS {
+    class ExecState;
+    class Identifier;
+    class JSGlobalData;
+};
+
+struct OpaqueJSString : public ThreadSafeShared<OpaqueJSString> {
+
+    static PassRefPtr<OpaqueJSString> create() // null
+    {
+        return adoptRef(new OpaqueJSString);
+    }
+
+    static PassRefPtr<OpaqueJSString> create(const UChar* characters, unsigned length)
+    {
+        return adoptRef(new OpaqueJSString(characters, length));
+    }
+
+    static PassRefPtr<OpaqueJSString> create(const KJS::UString&);
+
+    UChar* characters() { return this ? m_characters : 0; }
+    unsigned length() { return this ? m_length : 0; }
+
+    KJS::UString ustring() const;
+
+    KJS::Identifier identifier(KJS::ExecState*) const;
+    KJS::Identifier identifier(KJS::JSGlobalData*) const;
+
+private:
+    friend class ThreadSafeShared<OpaqueJSString>;
+
+    OpaqueJSString()
+        : m_characters(0)
+        , m_length(0)
+    {
+    }
+
+    OpaqueJSString(const UChar* characters, unsigned length)
+        : m_length(length)
+    {
+        m_characters = new UChar[length];
+        memcpy(m_characters, characters, length * sizeof(UChar));
+    }
+
+    ~OpaqueJSString()
+    {
+        delete[] m_characters;
+    }
+
+    UChar* m_characters;
+    unsigned m_length;
+};
+
+#endif
index 39a8bad..cd44210 100644 (file)
@@ -1,3 +1,73 @@
+2008-08-15  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Geoff Garen.
+
+        JSStringRef is created context-free, but can get linked to one via an identifier table,
+        breaking an implicit API contract.
+
+        Made JSStringRef point to OpaqueJSString, which is a new string object separate from UString.
+
+        * API/APICast.h: Removed toRef/toJS conversions for JSStringRef, as this is no longer a
+        simple typecast.
+
+        * kjs/identifier.cpp:
+        (KJS::Identifier::checkSameIdentifierTable):
+        * kjs/identifier.h:
+        (KJS::Identifier::add):
+        (KJS::UString::checkSameIdentifierTable):
+        Added assertions to verify that an identifier is not being added to a different JSGlobalData.
+
+        * API/JSObjectRef.cpp:
+        (OpaqueJSPropertyNameArray::OpaqueJSPropertyNameArray): Changed OpaqueJSPropertyNameArray to
+        hold JSStringRefs. This is necessary to avoid having to construct (and leak) a new instance
+        in JSPropertyNameArrayGetNameAtIndex(), now that making a JSStringRef is not just a typecast.
+
+        * API/OpaqueJSString.cpp: Added.
+        (OpaqueJSString::create):
+        (OpaqueJSString::ustring):
+        (OpaqueJSString::identifier):
+        * API/OpaqueJSString.h: Added.
+        (OpaqueJSString::create):
+        (OpaqueJSString::characters):
+        (OpaqueJSString::length):
+        (OpaqueJSString::OpaqueJSString):
+        (OpaqueJSString::~OpaqueJSString):
+
+        * API/JSBase.cpp:
+        (JSEvaluateScript):
+        (JSCheckScriptSyntax):
+        * API/JSCallbackObjectFunctions.h:
+        (KJS::::getOwnPropertySlot):
+        (KJS::::put):
+        (KJS::::deleteProperty):
+        (KJS::::staticValueGetter):
+        (KJS::::callbackGetter):
+        * API/JSStringRef.cpp:
+        (JSStringCreateWithCharacters):
+        (JSStringCreateWithUTF8CString):
+        (JSStringRetain):
+        (JSStringRelease):
+        (JSStringGetLength):
+        (JSStringGetCharactersPtr):
+        (JSStringGetMaximumUTF8CStringSize):
+        (JSStringGetUTF8CString):
+        (JSStringIsEqual):
+        * API/JSStringRefCF.cpp:
+        (JSStringCreateWithCFString):
+        (JSStringCopyCFString):
+        * API/JSValueRef.cpp:
+        (JSValueMakeString):
+        (JSValueToStringCopy):
+        Updated to use OpaqueJSString.
+
+        * GNUmakefile.am:
+        * JavaScriptCore.exp:
+        * JavaScriptCore.pri:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * JavaScriptCoreSources.bkl:
+        Added OpaqueJSString.
+
 2008-08-14  Kevin McCullough  <kmccullough@apple.com>
 
         Reviewed by Tim.
index 691cba5..ed41e23 100644 (file)
@@ -47,6 +47,7 @@ javascriptcore_sources += \
        JavaScriptCore/API/JSRetainPtr.h \
        JavaScriptCore/API/JSStringRef.cpp \
        JavaScriptCore/API/JSValueRef.cpp \
+       JavaScriptCore/API/OpaqueJSString.cpp \
        JavaScriptCore/ForwardingHeaders/JavaScriptCore/APICast.h \
        JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSBase.h \
        JavaScriptCore/ForwardingHeaders/JavaScriptCore/JSContextRef.h \
index e7503ce..169b0f9 100644 (file)
@@ -76,8 +76,11 @@ _WTFReportFatalError
 __Z12jsRegExpFreeP8JSRegExp
 __Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
 __Z15jsRegExpExecutePK8JSRegExpPKtiiPii
+__ZN14OpaqueJSStringD1Ev
 __ZN3KJS10Identifier11addSlowCaseEPNS_12JSGlobalDataEPNS_7UString3RepE
 __ZN3KJS10Identifier11addSlowCaseEPNS_9ExecStateEPNS_7UString3RepE
+__ZN3KJS10Identifier24checkSameIdentifierTableEPNS_12JSGlobalDataEPNS_7UString3RepE
+__ZN3KJS10Identifier24checkSameIdentifierTableEPNS_9ExecStateEPNS_7UString3RepE
 __ZN3KJS10Identifier3addEPNS_9ExecStateEPKc
 __ZN3KJS10Identifier5equalEPKNS_7UString3RepEPKc
 __ZN3KJS10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
index 16f36b1..03169fd 100644 (file)
@@ -45,6 +45,7 @@ SOURCES += \
     API/JSObjectRef.cpp \
     API/JSStringRef.cpp \
     API/JSValueRef.cpp \
+    API/OpaqueJSString.cpp \
     kjs/InitializeThreading.cpp \
     kjs/JSGlobalData.cpp \
     kjs/JSGlobalObject.cpp \
index a05d900..27c902d 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\..\API\OpaqueJSString.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\API\OpaqueJSString.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\..\API\WebKitAvailability.h"\r
                                >\r
                        </File>\r
index 3d4c7fb..58bdf2d 100644 (file)
                BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */; };
                BCF605140E203EF800B9A64D /* ArgList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF605120E203EF800B9A64D /* ArgList.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C0A272630E50A06300E96E15 /* NotFound.h in Headers */ = {isa = PBXBuildFile; fileRef = C0A2723F0E509F1E00E96E15 /* NotFound.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; };
+               E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E124A8F60E555775003091F1 /* OpaqueJSString.cpp */; };
                E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */; };
                E18E3A590DF9278C00D90B34 /* JSGlobalData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18E3A570DF9278C00D90B34 /* JSGlobalData.cpp */; };
                E1A862A90D7EBB76001EC6AA /* CollatorICU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A862A80D7EBB76001EC6AA /* CollatorICU.cpp */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; };
                D21202280AD4310C00ED79B6 /* DateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateMath.cpp; sourceTree = "<group>"; };
                D21202290AD4310C00ED79B6 /* DateMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateMath.h; sourceTree = "<group>"; };
                E11D51750B2E798D0056C188 /* StringExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringExtras.h; sourceTree = "<group>"; };
+               E124A8F50E555775003091F1 /* OpaqueJSString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueJSString.h; sourceTree = "<group>"; };
+               E124A8F60E555775003091F1 /* OpaqueJSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpaqueJSString.cpp; sourceTree = "<group>"; };
                E178633F0D9BEC0000D74E75 /* InitializeThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeThreading.h; sourceTree = "<group>"; };
                E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeThreading.cpp; sourceTree = "<group>"; };
                E18E3A560DF9278C00D90B34 /* JSGlobalData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalData.h; sourceTree = "<group>"; };
                                146AAB2A0B66A84900E55F16 /* JSStringRefCF.h */,
                                14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */,
                                1482B6EA0A4300B300517CFC /* JSValueRef.h */,
+                               E124A8F60E555775003091F1 /* OpaqueJSString.cpp */,
+                               E124A8F50E555775003091F1 /* OpaqueJSString.h */,
                                5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */,
                        );
                        path = API;
                                95FDFA160E2299980006FB00 /* HeavyProfile.h in Headers */,
                                8613F45B0E3A433E00C948FD /* SamplingTool.h in Headers */,
                                C0A272630E50A06300E96E15 /* NotFound.h in Headers */,
+                               E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
                        projectDirPath = "";
                        projectRoot = "";
-                       projectRoots = (
-                               "",
-                       );
                        targets = (
                                932F5BE30822A1C700736975 /* All */,
                                932F5B3E0822A1C700736975 /* JavaScriptCore */,
                                95FDFA140E22998F0006FB00 /* HeavyProfile.cpp in Sources */,
                                905B02AE0E28640F006DF882 /* RefCountedLeakCounter.cpp in Sources */,
                                8613F45A0E3A433E00C948FD /* SamplingTool.cpp in Sources */,
+                               E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index f16fd6a..99c4466 100644 (file)
@@ -39,6 +39,7 @@ Source files for JSCore.
         API/JSObjectRef.cpp
         API/JSStringRef.cpp
         API/JSValueRef.cpp
+        API/OpaqueJSString.cpp
     </set>
     
     <set append="1" var="JSCORE_SOURCES_KJS">
index 9085f3f..ad29486 100644 (file)
@@ -223,4 +223,17 @@ void Identifier::remove(UString::Rep *r)
     r->identifierTable()->remove(r);
 }
 
+#ifndef NDEBUG
+void Identifier::checkSameIdentifierTable(ExecState* exec, UString::Rep* rep)
+{
+    ASSERT(rep->identifierTable() == exec->identifierTable());
+}
+
+void Identifier::checkSameIdentifierTable(JSGlobalData* globalData, UString::Rep* rep)
+{
+    ASSERT(rep->identifierTable() == globalData->identifierTable);
+}
+
+#endif
+
 } // namespace KJS
index fecb80f..a23a5f9 100644 (file)
@@ -91,19 +91,26 @@ namespace KJS {
 
         static PassRefPtr<UString::Rep> add(ExecState* exec, UString::Rep* r)
         {
-            if (r->identifierTable())
+            if (r->identifierTable()) {
+                checkSameIdentifierTable(exec, r);
                 return r;
+            }
             return addSlowCase(exec, r);
         }
         static PassRefPtr<UString::Rep> add(JSGlobalData* globalData, UString::Rep* r)
         {
-            if (r->identifierTable())
+            if (r->identifierTable()) {
+                checkSameIdentifierTable(globalData, r);
                 return r;
+            }
             return addSlowCase(globalData, r);
         }
 
         static PassRefPtr<UString::Rep> addSlowCase(ExecState*, UString::Rep* r);
         static PassRefPtr<UString::Rep> addSlowCase(JSGlobalData*, UString::Rep* r);
+
+        static void checkSameIdentifierTable(ExecState*, UString::Rep*);
+        static void checkSameIdentifierTable(JSGlobalData*, UString::Rep*);
     };
     
     inline bool operator==(const Identifier& a, const Identifier& b)
@@ -121,6 +128,11 @@ namespace KJS {
         return Identifier::equal(a, b);
     }
 
+#ifdef NDEBUG
+    void UString::checkSameIdentifierTable(ExecState*, UString::Rep*) {}
+    void UString::checkSameIdentifierTable(JSGlobalData*, UString::Rep*) {}
+#endif
+
     IdentifierTable* createIdentifierTable();
     void deleteIdentifierTable(IdentifierTable*);
 
index c2f0b9e..b662646 100644 (file)
@@ -1,3 +1,18 @@
+2008-08-15  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Geoff Garen.
+
+        JSStringRef is created context-free, but can get linked to one via an identifier table,
+        breaking an implicit API contract.
+
+        * page/InspectorController.cpp:
+        (WebCore::jsStringRef):
+        (WebCore::InspectorController::didParseSource):
+        (WebCore::InspectorController::failedToParseSource):
+        * page/JavaScriptProfile.cpp:
+        (WebCore::getTitleCallback):
+        Updated for JavaScriptCore changes.
+
 2008-08-14  Kevin Ollivier  <kevino@theolliviers.com>
 
         wx !USE(WXGC) build fix. This is necessary until we find a way to replace GDI with
index 0ec8f19..5f3b083 100644 (file)
@@ -68,6 +68,7 @@
 #include <JavaScriptCore/APICast.h>
 #include <JavaScriptCore/JSRetainPtr.h>
 #include <JavaScriptCore/JSStringRef.h>
+#include <JavaScriptCore/OpaqueJSString.h>
 #include <kjs/ustring.h>
 #include <profiler/Profile.h>
 #include <profiler/Profiler.h>
@@ -102,7 +103,7 @@ static JSRetainPtr<JSStringRef> jsStringRef(const String& str)
 
 static JSRetainPtr<JSStringRef> jsStringRef(const UString& str)
 {
-    return JSRetainPtr<JSStringRef>(toRef(str.rep()));
+    return JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(str).releaseRef());
 }
 
 static String toString(JSContextRef context, JSValueRef value, JSValueRef* exception)
@@ -2610,7 +2611,7 @@ bool InspectorController::handleException(JSContextRef context, JSValueRef excep
 
 // JavaScriptDebugListener functions
 
-void InspectorController::didParseSource(ExecState*, const SourceProvider& source, int startingLineNumber, const UString& sourceURL, int sourceID)
+void InspectorController::didParseSource(ExecState* exec, const SourceProvider& source, int startingLineNumber, const UString& sourceURL, int sourceID)
 {
     JSValueRef sourceIDValue = JSValueMakeNumber(m_scriptContext, sourceID);
     JSValueRef sourceURLValue = JSValueMakeString(m_scriptContext, jsStringRef(sourceURL).get());
@@ -2622,7 +2623,7 @@ void InspectorController::didParseSource(ExecState*, const SourceProvider& sourc
     callFunction(m_scriptContext, m_scriptObject, "parsedScriptSource", 4, arguments, exception);
 }
 
-void InspectorController::failedToParseSource(ExecState*, const SourceProvider& source, int startingLineNumber, const UString& sourceURL, int errorLine, const UString& errorMessage)
+void InspectorController::failedToParseSource(ExecState* exec, const SourceProvider& source, int startingLineNumber, const UString& sourceURL, int errorLine, const UString& errorMessage)
 {
     JSValueRef sourceURLValue = JSValueMakeString(m_scriptContext, jsStringRef(sourceURL).get());
     JSValueRef sourceValue = JSValueMakeString(m_scriptContext, jsStringRef(source.data()).get());
index d6895e2..c1abc13 100644 (file)
@@ -31,6 +31,7 @@
 #include <JavaScriptCore/APICast.h>
 #include <JavaScriptCore/JSObjectRef.h>
 #include <JavaScriptCore/JSStringRef.h>
+#include <JavaScriptCore/OpaqueJSString.h>
 #include <kjs/JSObject.h>
 #include <kjs/JSValue.h>
 
@@ -58,7 +59,7 @@ static JSValueRef getTitleCallback(JSContextRef ctx, JSObjectRef thisObject, JSS
         return JSValueMakeUndefined(ctx);
 
     Profile* profile = static_cast<Profile*>(JSObjectGetPrivate(thisObject));
-    return JSValueMakeString(ctx, toRef(profile->title().rep()));
+    return JSValueMakeString(ctx, OpaqueJSString::create(profile->title()).get());
 }
 
 static JSValueRef getHeadCallback(JSContextRef ctx, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)