Commit 8c4e21b9 authored by ap@apple.com's avatar ap@apple.com

Reviewed by Anders Carlsson.

        https://bugs.webkit.org/show_bug.cgi?id=35406
        <rdar://problem/6945502> Make generic array methods work with JavaArray

        Test: java/array-sort.html

        Made RuntimeArray inherit from JSArray, keeping the promise given in ClassInfo.

        * bridge/runtime_array.cpp:
        (JSC::RuntimeArray::RuntimeArray):
        (JSC::RuntimeArray::~RuntimeArray):
        * bridge/runtime_array.h:
        (JSC::RuntimeArray::classInfo):
        (JSC::RuntimeArray::getConcreteArray):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55262 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 0ac226a2
2010-02-25 Alexey Proskuryakov <ap@apple.com>
Reviewed by Anders Carlsson.
https://bugs.webkit.org/show_bug.cgi?id=35406
<rdar://problem/6945502> Make generic array methods work with JavaArray
Renamed lazyCreationData to subclassData. This is extra data that can be used by JSArray
subclasses (you can't add new data members, because it wouldn't fit in JSCell otherwise).
* JavaScriptCore.exp:
* runtime/JSArray.cpp:
(JSC::JSArray::JSArray):
(JSC::JSArray::subclassData):
(JSC::JSArray::setSubclassData):
* runtime/JSArray.h:
* runtime/RegExpConstructor.cpp:
(JSC::RegExpMatchesArray::RegExpMatchesArray):
(JSC::RegExpMatchesArray::~RegExpMatchesArray):
(JSC::RegExpMatchesArray::fillArrayInstance):
* runtime/RegExpMatchesArray.h:
(JSC::RegExpMatchesArray::getOwnPropertySlot):
(JSC::RegExpMatchesArray::getOwnPropertyDescriptor):
(JSC::RegExpMatchesArray::put):
(JSC::RegExpMatchesArray::deleteProperty):
(JSC::RegExpMatchesArray::getOwnPropertyNames):
2010-02-25 Oliver Hunt <oliver@apple.com>
Reviewed by Geoff Garen.
......
......@@ -226,6 +226,10 @@ __ZN3JSC6JSLockC1EPNS_9ExecStateE
__ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
__ZN3JSC7CStringD1Ev
__ZN3JSC7CStringaSERKS0_
__ZN3JSC7JSArrayC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
__ZN3JSC7JSArrayD2Ev
__ZN3JSC7JSArray12markChildrenERNS_9MarkStackE
__ZN3JSC7JSArray15setSubclassDataEPv
__ZN3JSC7JSArray4infoE
__ZN3JSC7JSArray9setLengthEj
__ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
......@@ -384,6 +388,7 @@ __ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE
__ZNK3JSC6JSCell9getUInt32ERj
__ZNK3JSC6JSCell9toBooleanEPNS_9ExecStateE
__ZNK3JSC7ArgList8getSliceEiRS0_
__ZNK3JSC7JSArray12subclassDataEv
__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE
__ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE
__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
......
......@@ -151,7 +151,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength)
m_vectorLength = initialCapacity;
m_storage->m_numValuesInVector = 0;
m_storage->m_sparseValueMap = 0;
m_storage->lazyCreationData = 0;
m_storage->subclassData = 0;
m_storage->reportedMapCapacity = 0;
JSValue* vector = m_storage->m_vector;
......@@ -173,7 +173,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list)
m_vectorLength = initialCapacity;
m_storage->m_numValuesInVector = initialCapacity;
m_storage->m_sparseValueMap = 0;
m_storage->lazyCreationData = 0;
m_storage->subclassData = 0;
m_storage->reportedMapCapacity = 0;
size_t i = 0;
......@@ -1022,14 +1022,14 @@ unsigned JSArray::compactForSorting()
return numDefined;
}
void* JSArray::lazyCreationData()
void* JSArray::subclassData() const
{
return m_storage->lazyCreationData;
return m_storage->subclassData;
}
void JSArray::setLazyCreationData(void* d)
void JSArray::setSubclassData(void* d)
{
m_storage->lazyCreationData = d;
m_storage->subclassData = d;
}
#if CHECK_ARRAY_CONSISTENCY
......
......@@ -31,7 +31,7 @@ namespace JSC {
unsigned m_length;
unsigned m_numValuesInVector;
SparseArrayValueMap* m_sparseValueMap;
void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily.
void* subclassData; // A JSArray subclass can use this to fill the vector lazily.
size_t reportedMapCapacity;
JSValue m_vector[1];
};
......@@ -101,8 +101,8 @@ namespace JSC {
virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual void markChildren(MarkStack&);
void* lazyCreationData();
void setLazyCreationData(void*);
void* subclassData() const;
void setSubclassData(void*);
private:
virtual const ClassInfo* classInfo() const { return &info; }
......
......@@ -113,17 +113,17 @@ RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate
memcpy(d->lastOvector().data(), data->lastOvector().data(), offsetVectorSize * sizeof(int));
// d->multiline is not needed, and remains uninitialized
setLazyCreationData(d);
setSubclassData(d);
}
RegExpMatchesArray::~RegExpMatchesArray()
{
delete static_cast<RegExpConstructorPrivate*>(lazyCreationData());
delete static_cast<RegExpConstructorPrivate*>(subclassData());
}
void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
{
RegExpConstructorPrivate* d = static_cast<RegExpConstructorPrivate*>(lazyCreationData());
RegExpConstructorPrivate* d = static_cast<RegExpConstructorPrivate*>(subclassData());
ASSERT(d);
unsigned lastNumSubpatterns = d->lastNumSubPatterns;
......@@ -141,7 +141,7 @@ void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input), slot);
delete d;
setLazyCreationData(0);
setSubclassData(0);
}
JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
......
......@@ -32,56 +32,56 @@ namespace JSC {
private:
virtual bool getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
if (lazyCreationData())
if (subclassData())
fillArrayInstance(exec);
return JSArray::getOwnPropertySlot(exec, propertyName, slot);
}
virtual bool getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
if (lazyCreationData())
if (subclassData())
fillArrayInstance(exec);
return JSArray::getOwnPropertySlot(exec, propertyName, slot);
}
virtual bool getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
if (lazyCreationData())
if (subclassData())
fillArrayInstance(exec);
return JSArray::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
virtual void put(ExecState* exec, const Identifier& propertyName, JSValue v, PutPropertySlot& slot)
{
if (lazyCreationData())
if (subclassData())
fillArrayInstance(exec);
JSArray::put(exec, propertyName, v, slot);
}
virtual void put(ExecState* exec, unsigned propertyName, JSValue v)
{
if (lazyCreationData())
if (subclassData())
fillArrayInstance(exec);
JSArray::put(exec, propertyName, v);
}
virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName)
{
if (lazyCreationData())
if (subclassData())
fillArrayInstance(exec);
return JSArray::deleteProperty(exec, propertyName);
}
virtual bool deleteProperty(ExecState* exec, unsigned propertyName)
{
if (lazyCreationData())
if (subclassData())
fillArrayInstance(exec);
return JSArray::deleteProperty(exec, propertyName);
}
virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
{
if (lazyCreationData())
if (subclassData())
fillArrayInstance(exec);
JSArray::getOwnPropertyNames(exec, arr, mode);
}
......
2010-02-25 Alexey Proskuryakov <ap@apple.com>
Reviewed by Anders Carlsson.
https://bugs.webkit.org/show_bug.cgi?id=35406
<rdar://problem/6945502> Make generic array methods work with JavaArray
* java/array-sort-expected.txt: Added.
* java/array-sort.html: Added.
2010-02-25 Dirk Schulze <krit@webkit.org>
Reviewed by Nikolas Zimmermann.
......
Test that Java arrays work with generic JS array methods.
Also test that they work when passed as the second argument to apply(). This may or may not be correct behavior per LiveConnect spec.
call
PASS array[0] + '' is 'One'
PASS array[1] + '' is 'Three'
PASS array[2] + '' is 'Two'
apply
PASS array[0] + '' is 'One'
PASS array[1] + '' is 'Three'
PASS array[2] + '' is 'Two'
passing array as function arguments, potentially parser-optimized apply
PASS concat.apply({}, array) is 'OneTwoThree'
passing array as function arguments, unoptimized apply
PASS concat["apply"]({}, array) is 'OneTwoThree'
PASS array.length = 5 threw exception RangeError: Range error.
PASS successfullyParsed is true
TEST COMPLETE
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../fast/js/resources/js-test-style.css">
<script src="../fast/js/resources/js-test-pre.js"></script>
<script>
if (window.layoutTestController)
layoutTestController.overridePreference("WebKitJavaEnabled", "1");
</script>
</head>
<body>
<p>Test that Java arrays work with generic JS array methods.</p>
<p>Also test that they work when passed as the second argument to apply(). This may or may not be correct behavior per LiveConnect spec.</p>
<div id="console"></div>
<applet CODE="SharedApplet.class" NAME="javaTest" WIDTH=150 HEIGHT=25 MAYSCRIPT></applet>
<script>
debug("call");
var array = document.javaTest.stringArray();
Array.prototype.sort.call(array);
shouldBe("array[0] + ''", "'One'");
shouldBe("array[1] + ''", "'Three'");
shouldBe("array[2] + ''", "'Two'");
debug("apply");
array = document.javaTest.stringArray();
Array.prototype.sort.apply(array, []);
shouldBe("array[0] + ''", "'One'");
shouldBe("array[1] + ''", "'Three'");
shouldBe("array[2] + ''", "'Two'");
function concat()
{
var result = "";
for (i = 0; i < arguments.length; ++i)
result += arguments[i];
return result;
}
debug("passing array as function arguments, potentially parser-optimized apply");
array = document.javaTest.stringArray();
shouldBe("concat.apply({}, array)", "'OneTwoThree'");
debug("passing array as function arguments, unoptimized apply");
array = document.javaTest.stringArray();
shouldBe('concat["apply"]({}, array)', "'OneTwoThree'");
shouldThrow("array.length = 5");
successfullyParsed = true;
</script>
<script src="../fast/js/resources/js-test-post.js"></script>
</body>
</html>
2010-02-25 Alexey Proskuryakov <ap@apple.com>
Reviewed by Anders Carlsson.
https://bugs.webkit.org/show_bug.cgi?id=35406
<rdar://problem/6945502> Make generic array methods work with JavaArray
Test: java/array-sort.html
Made RuntimeArray inherit from JSArray, keeping the promise given in ClassInfo.
* bridge/runtime_array.cpp:
(JSC::RuntimeArray::RuntimeArray):
(JSC::RuntimeArray::~RuntimeArray):
* bridge/runtime_array.h:
(JSC::RuntimeArray::classInfo):
(JSC::RuntimeArray::getConcreteArray):
2010-02-25 Dan Bernstein <mitz@apple.com>
Reviewed by Alexey Proskuryakov.
......
......@@ -40,9 +40,14 @@ const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &JSArray::info, 0, 0 };
RuntimeArray::RuntimeArray(ExecState* exec, Bindings::Array* array)
// FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object
// We need to pass in the right global object for "array".
: JSObject(deprecatedGetDOMStructure<RuntimeArray>(exec))
, _array(array)
: JSArray(deprecatedGetDOMStructure<RuntimeArray>(exec))
{
setSubclassData(array);
}
RuntimeArray::~RuntimeArray()
{
delete getConcreteArray();
}
JSValue RuntimeArray::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
......
......@@ -27,29 +27,30 @@
#define RUNTIME_ARRAY_H_
#include "Bridge.h"
#include <runtime/JSGlobalObject.h>
#include <runtime/ArrayPrototype.h>
namespace JSC {
class RuntimeArray : public JSObject {
class RuntimeArray : public JSArray {
public:
RuntimeArray(ExecState*, Bindings::Array*);
virtual ~RuntimeArray();
virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState *, unsigned, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState *, const Identifier&, PropertyDescriptor&);
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&);
virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
virtual void put(ExecState*, unsigned propertyName, JSValue);
virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
virtual bool deleteProperty(ExecState *exec, unsigned propertyName);
virtual bool deleteProperty(ExecState* exec, const Identifier &propertyName);
virtual bool deleteProperty(ExecState* exec, unsigned propertyName);
virtual const ClassInfo *classInfo() const { return &s_info; }
virtual const ClassInfo* classInfo() const { return &s_info; }
unsigned getLength() const { return getConcreteArray()->getLength(); }
Bindings::Array *getConcreteArray() const { return _array.get(); }
Bindings::Array* getConcreteArray() const { return static_cast<Bindings::Array*>(subclassData()); }
static const ClassInfo s_info;
......@@ -58,17 +59,10 @@ public:
return globalObject->arrayPrototype();
}
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
}
private:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags;
static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue indexGetter(ExecState*, const Identifier&, const PropertySlot&);
OwnPtr<Bindings::Array> _array;
};
} // namespace JSC
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment