1 /* 2 * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "runtime_array.h" 28 29 #include <runtime/ArrayPrototype.h> 30 #include <runtime/Error.h> 31 #include <runtime/PropertyNameArray.h> 32 #include "JSDOMBinding.h" 33 34 using namespace WebCore; 35 36 namespace JSC { 37 38 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &JSArray::info, 0, 0 }; 39 40 RuntimeArray::RuntimeArray(ExecState* exec, Bindings::Array* array) 41 // FIXME: deprecatedGetDOMStructure uses the prototype off of the wrong global object 42 // We need to pass in the right global object for "array". 43 : JSObject(deprecatedGetDOMStructure<RuntimeArray>(exec)) 44 , _array(array) 45 { 46 } 47 48 JSValue RuntimeArray::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) 49 { 50 RuntimeArray* thisObj = static_cast<RuntimeArray*>(asObject(slot.slotBase())); 51 return jsNumber(exec, thisObj->getLength()); 52 } 53 54 JSValue RuntimeArray::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) 55 { 56 RuntimeArray* thisObj = static_cast<RuntimeArray*>(asObject(slot.slotBase())); 57 return thisObj->getConcreteArray()->valueAt(exec, slot.index()); 58 } 59 60 void RuntimeArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) 61 { 62 unsigned length = getLength(); 63 for (unsigned i = 0; i < length; ++i) 64 propertyNames.add(Identifier::from(exec, i)); 65 66 if (mode == IncludeDontEnumProperties) 67 propertyNames.add(exec->propertyNames().length); 68 69 JSObject::getOwnPropertyNames(exec, propertyNames, mode); 70 } 71 72 bool RuntimeArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) 73 { 74 if (propertyName == exec->propertyNames().length) { 75 slot.setCustom(this, lengthGetter); 76 return true; 77 } 78 79 bool ok; 80 unsigned index = propertyName.toArrayIndex(&ok); 81 if (ok) { 82 if (index < getLength()) { 83 slot.setCustomIndex(this, index, indexGetter); 84 return true; 85 } 86 } 87 88 return JSObject::getOwnPropertySlot(exec, propertyName, slot); 89 } 90 91 bool RuntimeArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 92 { 93 if (propertyName == exec->propertyNames().length) { 94 PropertySlot slot; 95 slot.setCustom(this, lengthGetter); 96 descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); 97 return true; 98 } 99 100 bool ok; 101 unsigned index = propertyName.toArrayIndex(&ok); 102 if (ok) { 103 if (index < getLength()) { 104 PropertySlot slot; 105 slot.setCustomIndex(this, index, indexGetter); 106 descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | DontEnum); 107 return true; 108 } 109 } 110 111 return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); 112 } 113 114 bool RuntimeArray::getOwnPropertySlot(ExecState *exec, unsigned index, PropertySlot& slot) 115 { 116 if (index < getLength()) { 117 slot.setCustomIndex(this, index, indexGetter); 118 return true; 119 } 120 121 return JSObject::getOwnPropertySlot(exec, index, slot); 122 } 123 124 void RuntimeArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 125 { 126 if (propertyName == exec->propertyNames().length) { 127 throwError(exec, RangeError); 128 return; 129 } 130 131 bool ok; 132 unsigned index = propertyName.toArrayIndex(&ok); 133 if (ok) { 134 getConcreteArray()->setValueAt(exec, index, value); 135 return; 136 } 137 138 JSObject::put(exec, propertyName, value, slot); 139 } 140 141 void RuntimeArray::put(ExecState* exec, unsigned index, JSValue value) 142 { 143 if (index >= getLength()) { 144 throwError(exec, RangeError); 145 return; 146 } 147 148 getConcreteArray()->setValueAt(exec, index, value); 149 } 150 151 bool RuntimeArray::deleteProperty(ExecState*, const Identifier&) 152 { 153 return false; 154 } 155 156 bool RuntimeArray::deleteProperty(ExecState*, unsigned) 157 { 158 return false; 159 } 160 161 } 162