void updateFuncExprNodeProfilerIdent(ExpressionNode* node, const ExpressionNode* base, const Identifier& ident) { ASSERT(node); ASSERT(node->isFuncExprNode()); FuncExprNode* funcExprNode = static_cast<FuncExprNode*>(node); if (base) { UString name(ident.ustring()); const UString dotString("."); const ExpressionNode* baseIterator = base; while (baseIterator && baseIterator->isDotAccessorNode()) { const DotAccessorNode* const dotAccessorNode = static_cast<const DotAccessorNode*>(baseIterator); name = makeString(dotAccessorNode->identifier().ustring(), dotString, name); baseIterator = dotAccessorNode->base(); } if (baseIterator && baseIterator->isResolveNode()) { const ResolveNode* const resolveNode = static_cast<const ResolveNode*>(baseIterator); name = makeString(resolveNode->identifier().ustring(), dotString, name); } funcExprNode->body()->setContextualName(name); } else { funcExprNode->body()->setContextualName(ident.ustring()); } }
MethodList BalClass::methodsNamed(const Identifier& identifier, Instance* instance) const { MethodList methodList; Method* method = m_methods.get(identifier.ustring().rep()); if (method) { methodList.append(method); return methodList; } const UChar* ident16 = identifier.ustring().data(); char ident[256]; sprintf(ident,"%S",ident16); ident[identifier.ustring().size()] = '\0'; const BalInstance* inst = static_cast<const BalInstance*>(instance); BalObject* obj = inst->getObject(); if( obj->hasMethod( ident ) ) { BalMethod *aMethod= new BalMethod(obj, 0, ident, 0); m_methods.set(identifier.ustring().rep(), aMethod); methodList.append(aMethod); } return methodList; }
MethodList BalClass::methodsNamed(const Identifier& identifier, Instance* instance) const { MethodList methodList; Method* method = m_methods.get(identifier.ustring().rep()); if (method) { methodList.append(method); return methodList; } const char *ident = identifier.ascii(); const BalInstance* inst = static_cast<const BalInstance*>(instance); BalObject* obj = inst->getObject(); if( obj->hasMethod( ident ) ) { Method* aMethod = new BalMethod(ident); // deleted in the CClass destructor { JSLock lock(false); m_methods.set(identifier.ustring().rep(), aMethod); } methodList.append(aMethod); } return methodList; }
PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset) { ASSERT(!structure->isDictionary()); ASSERT(structure->typeInfo().type() == ObjectType); ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset)); if (structure->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount) specificValue = 0; if (structure->transitionCount() > s_maxTransitionLength) { RefPtr<Structure> transition = toCacheableDictionaryTransition(structure); ASSERT(structure != transition); offset = transition->put(propertyName, attributes, specificValue); ASSERT(offset >= structure->m_anonymousSlotCount); ASSERT(structure->m_anonymousSlotCount == transition->m_anonymousSlotCount); if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) transition->growPropertyStorageCapacity(); return transition.release(); } RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo(), structure->anonymousSlotCount()); transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain; transition->m_previous = structure; transition->m_nameInPrevious = propertyName.ustring().rep(); transition->m_attributesInPrevious = attributes; transition->m_specificValueInPrevious = specificValue; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount; if (structure->m_propertyTable) { if (structure->m_isPinnedPropertyTable) transition->m_propertyTable = structure->copyPropertyTable(); else { transition->m_propertyTable = structure->m_propertyTable; structure->m_propertyTable = 0; } } else { if (structure->m_previous) transition->materializePropertyMap(); else transition->createPropertyMapHashTable(); } offset = transition->put(propertyName, attributes, specificValue); ASSERT(offset >= structure->m_anonymousSlotCount); ASSERT(structure->m_anonymousSlotCount == transition->m_anonymousSlotCount); if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) transition->growPropertyStorageCapacity(); transition->m_offset = offset - structure->m_anonymousSlotCount; ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount()); structure->transitionTableAdd(make_pair(propertyName.ustring().rep(), attributes), transition.get(), specificValue); return transition.release(); }
PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset) { ASSERT(!structure->m_isDictionary); ASSERT(structure->typeInfo().type() == ObjectType); ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, offset)); if (structure->transitionCount() > s_maxTransitionLength) { RefPtr<Structure> transition = toDictionaryTransition(structure); offset = transition->put(propertyName, attributes); if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) transition->growPropertyStorageCapacity(); return transition.release(); } RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo()); transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain; transition->m_previous = structure; transition->m_nameInPrevious = propertyName.ustring().rep(); transition->m_attributesInPrevious = attributes; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; if (structure->m_propertyTable) { if (structure->m_isPinnedPropertyTable) transition->m_propertyTable = structure->copyPropertyTable(); else { transition->m_propertyTable = structure->m_propertyTable; structure->m_propertyTable = 0; } } else { if (structure->m_previous) transition->materializePropertyMap(); else transition->createPropertyMapHashTable(); } offset = transition->put(propertyName, attributes); if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) transition->growPropertyStorageCapacity(); transition->m_offset = offset; if (structure->m_usingSingleTransitionSlot) { if (!structure->m_transitions.singleTransition) { structure->m_transitions.singleTransition = transition.get(); return transition.release(); } Structure* existingTransition = structure->m_transitions.singleTransition; structure->m_usingSingleTransitionSlot = false; StructureTransitionTable* transitionTable = new StructureTransitionTable; structure->m_transitions.table = transitionTable; transitionTable->add(make_pair(existingTransition->m_nameInPrevious.get(), +existingTransition->m_attributesInPrevious), existingTransition); } structure->m_transitions.table->add(make_pair(propertyName.ustring().rep(), attributes), transition.get()); return transition.release(); }
void write(const Identifier& ident) { UString str = ident.ustring(); pair<StringConstantPool::iterator, bool> iter = m_constantPool.add(str.impl(), m_constantPool.size()); if (!iter.second) { write(StringPoolTag); writeStringIndex(iter.first->second); return; } // This condition is unlikely to happen as they would imply an ~8gb // string but we should guard against it anyway if (str.length() >= StringPoolTag) { fail(); return; } // Guard against overflow if (str.length() > (numeric_limits<uint32_t>::max() - sizeof(uint32_t)) / sizeof(UChar)) { fail(); return; } writeLittleEndian<uint32_t>(m_buffer, str.length()); if (!writeLittleEndian<uint16_t>(m_buffer, reinterpret_cast<const uint16_t*>(str.characters()), str.length())) fail(); }
int Lookup::find(const struct HashTable *table, const Identifier &s) { const HashEntry *entry = KJS::findEntry(table, s.ustring().rep()->hash(), s.data(), s.size()); if (entry) return entry->value; return -1; }
void PropertyNameArray::add(const Identifier& ident) { if (!m_set.add(ident.ustring().rep()).second) return; m_vector.append(ident); }
bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propertyName) { if (symbolTable().contains(propertyName.ustring().rep())) return false; return JSObject::deleteProperty(exec, propertyName); }
MethodList JavaClass::methodsNamed(const Identifier& identifier, Instance*) const { MethodList* methodList = m_methods.get(identifier.ustring().rep()); if (methodList) return *methodList; return MethodList(); }
bool JSVariableObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const { SymbolTableEntry entry = symbolTable().get(propertyName.ustring().rep()); if (!entry.isNull()) { attributes = entry.getAttributes() | DontDelete; return true; } return JSObject::getPropertyAttributes(exec, propertyName, attributes); }
bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertyDescriptor& descriptor) { SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); if (!entry.isNull()) { descriptor.setDescriptor(registerAt(entry.getIndex()).jsValue(), entry.getAttributes() | DontDelete); return true; } return false; }
JSValue PropertyNameForFunctionCall::value(ExecState* exec) const { if (!m_value) { if (m_identifier) m_value = jsString(exec, m_identifier->ustring()); else m_value = jsNumber(m_number); } return m_value; }
JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock) { int startOffset = 0; int endOffset = 0; int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); UString message(makeUString("Can't find variable: ", ident.ustring())); JSObject* exception = addErrorInfo(exec, createReferenceError(exec, message), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset); return exception; }
PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, TiCell* specificValue, size_t& offset) { ASSERT(!structure->isDictionary()); ASSERT(structure->typeInfo().type() == ObjectType); if (Structure* existingTransition = structure->table.get(make_pair(propertyName.ustring().rep(), attributes), specificValue)) { ASSERT(existingTransition->m_offset != noOffset); offset = existingTransition->m_offset; return existingTransition; } return 0; }
void ScopeChainNode::print() const { ScopeChainIterator scopeEnd = end(); for (ScopeChainIterator scopeIter = begin(); scopeIter != scopeEnd; ++scopeIter) { JSObject* o = *scopeIter; PropertyNameArray propertyNames(globalObject->globalExec()); o->getPropertyNames(globalObject->globalExec(), propertyNames); PropertyNameArray::const_iterator propEnd = propertyNames.end(); fprintf(stderr, "----- [scope %p] -----\n", o); for (PropertyNameArray::const_iterator propIter = propertyNames.begin(); propIter != propEnd; propIter++) { Identifier name = *propIter; fprintf(stderr, "%s, ", name.ustring().utf8().data()); } fprintf(stderr, "\n"); } }
void ScopeChainNode::print() { ScopeChainIterator scopeEnd = end(); for (ScopeChainIterator scopeIter = begin(); scopeIter != scopeEnd; ++scopeIter) { JSObject* o = scopeIter->get(); PropertyNameArray propertyNames(globalObject->globalExec()); o->methodTable()->getPropertyNames(o, globalObject->globalExec(), propertyNames, ExcludeDontEnumProperties); PropertyNameArray::const_iterator propEnd = propertyNames.end(); dataLog("----- [scope %p] -----\n", o); for (PropertyNameArray::const_iterator propIter = propertyNames.begin(); propIter != propEnd; propIter++) { Identifier name = *propIter; dataLog("%s, ", name.ustring().utf8().data()); } dataLog("\n"); } }
Value RegExpObjectImp::get(ExecState *exec, const Identifier &p) const { UString s = p.ustring(); if (s[0] == '$' && lastOvector) { bool ok; unsigned long i = s.substr(1).toULong(&ok); if (ok) { if (i < lastNrSubPatterns + 1) { UString substring = lastString.substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] ); return String(substring); } return String(""); } } return InternalFunctionImp::get(exec, p); }
PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset) { ASSERT(!structure->m_isDictionary); ASSERT(structure->typeInfo().type() == ObjectType); if (structure->m_usingSingleTransitionSlot) { Structure* existingTransition = structure->m_transitions.singleTransition; if (existingTransition && existingTransition->m_nameInPrevious.get() == propertyName.ustring().rep() && existingTransition->m_attributesInPrevious == attributes) { ASSERT(structure->m_transitions.singleTransition->m_offset != noOffset); offset = structure->m_transitions.singleTransition->m_offset; return existingTransition; } } else { if (Structure* existingTransition = structure->m_transitions.table->get(make_pair(propertyName.ustring().rep(), attributes))) { ASSERT(existingTransition->m_offset != noOffset); offset = existingTransition->m_offset; return existingTransition; } } return 0; }
String::String(const Identifier& str) { if (str.isNull()) return; m_impl = StringImpl::create(str.ustring()); }
InternalFunction::InternalFunction(JSGlobalData* globalData, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const Identifier& name) : JSObjectWithGlobalObject(globalObject, structure) { putDirect(globalData->propertyNames->name, jsString(globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); }
static CString idName(int id0, const Identifier& ident) { return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String(); }
static NPIdentifier npIdentifierFromIdentifier(const Identifier& identifier) { return static_cast<NPIdentifier>(IdentifierRep::get(identifier.ustring().utf8().data())); }
JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock) { int startOffset = 0; int endOffset = 0; int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); JSObject* exception = Error::create(exec, ReferenceError, makeString("Can't find variable: ", ident.ustring()), line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete); return exception; }
void InternalFunction::finishCreation(JSGlobalData& globalData, const Identifier& name) { Base::finishCreation(globalData); ASSERT(inherits(&s_info)); putDirect(globalData, globalData.propertyNames->name, jsString(&globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); }
JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, PassRefPtr<NativeExecutable> thunk) : Base(globalObject, structure) , m_executable(thunk) , m_scopeChain(globalObject->globalScopeChain()) { putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum); }
//-------------------------------------------------------------------------- // KJSValueToCFTypeInternal //-------------------------------------------------------------------------- // Caller is responsible for releasing the returned CFTypeRef CFTypeRef KJSValueToCFTypeInternal(JSValue inValue, ExecState *exec, ObjectImpList* inImps) { if (!inValue) return 0; CFTypeRef result = 0; JSGlueAPIEntry entry; if (inValue.isBoolean()) { result = inValue.toBoolean(exec) ? kCFBooleanTrue : kCFBooleanFalse; RetainCFType(result); return result; } if (inValue.isString()) { UString uString = inValue.toString(exec); result = UStringToCFString(uString); return result; } if (inValue.isNumber()) { double number1 = inValue.toNumber(exec); double number2 = (double)inValue.toInteger(exec); if (number1 == number2) { int intValue = (int)number2; result = CFNumberCreate(0, kCFNumberIntType, &intValue); } else { result = CFNumberCreate(0, kCFNumberDoubleType, &number1); } return result; } if (inValue.isObject()) { if (inValue.inherits(&UserObjectImp::info)) { UserObjectImp* userObjectImp = static_cast<UserObjectImp *>(asObject(inValue)); JSUserObject* ptr = userObjectImp->GetJSUserObject(); if (ptr) { result = ptr->CopyCFValue(); } } else { JSObject *object = inValue.toObject(exec); UInt8 isArray = false; // if two objects reference each JSObject* imp = object; ObjectImpList* temp = inImps; while (temp) { if (imp == temp->imp) { return CFRetain(GetCFNull()); } temp = temp->next; } ObjectImpList imps; imps.next = inImps; imps.imp = imp; //[...] HACK since we do not have access to the class info we use class name instead #if 0 if (object->inherits(&ArrayInstanceImp::info)) #else if (object->className() == "Array") #endif { isArray = true; JSGlueGlobalObject* globalObject = static_cast<JSGlueGlobalObject*>(exec->dynamicGlobalObject()); if (globalObject && (globalObject->Flags() & kJSFlagConvertAssociativeArray)) { PropertyNameArray propNames(exec); object->getPropertyNames(exec, propNames); PropertyNameArray::const_iterator iter = propNames.begin(); PropertyNameArray::const_iterator end = propNames.end(); while(iter != end && isArray) { Identifier propName = *iter; UString ustr = propName.ustring(); const UniChar* uniChars = (const UniChar*)ustr.characters(); int size = ustr.length(); while (size--) { if (uniChars[size] < '0' || uniChars[size] > '9') { isArray = false; break; } } iter++; } } } if (isArray) { // This is an KJS array unsigned int length = object->get(exec, Identifier(exec, "length")).toUInt32(exec); result = CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks); if (result) { for (unsigned i = 0; i < length; i++) { CFTypeRef cfValue = KJSValueToCFTypeInternal(object->get(exec, i), exec, &imps); CFArrayAppendValue((CFMutableArrayRef)result, cfValue); ReleaseCFType(cfValue); } } } else { // Not an array, just treat it like a dictionary which contains (property name, property value) pairs PropertyNameArray propNames(exec); object->getPropertyNames(exec, propNames); { result = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (result) { PropertyNameArray::const_iterator iter = propNames.begin(); PropertyNameArray::const_iterator end = propNames.end(); while(iter != end) { Identifier propName = *iter; if (object->hasProperty(exec, propName)) { CFStringRef cfKey = IdentifierToCFString(propName); CFTypeRef cfValue = KJSValueToCFTypeInternal(object->get(exec, propName), exec, &imps); if (cfKey && cfValue) { CFDictionaryAddValue((CFMutableDictionaryRef)result, cfKey, cfValue); } ReleaseCFType(cfKey); ReleaseCFType(cfValue); } iter++; } } } } } return result; } if (inValue.isUndefinedOrNull()) { result = RetainCFType(GetCFNull()); return result; } ASSERT_NOT_REACHED(); return 0; }
JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func) : Base(globalObject, structure) #if ENABLE(JIT) , m_executable(exec->globalData().getHostFunction(func)) #endif , m_scopeChain(globalObject->globalScopeChain()) { putDirect(exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); #if ENABLE(JIT) putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum); #else UNUSED_PARAM(length); UNUSED_PARAM(func); ASSERT_NOT_REACHED(); #endif }
//-------------------------------------------------------------------------- // IdentifierToCFString //-------------------------------------------------------------------------- // Caller is responsible for releasing the returned CFStringRef CFStringRef IdentifierToCFString(const Identifier& inIdentifier) { return UStringToCFString(inIdentifier.ustring()); }
void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const Identifier& name) { Base::finishCreation(exec->globalData()); ASSERT(inherits(&s_info)); m_executable.set(exec->globalData(), this, executable); putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum); }