2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "StringConstructor.h"
25 #include "Executable.h"
27 #include "JSFunction.h"
28 #include "JSGlobalObject.h"
29 #include "JSCInlines.h"
30 #include "StringPrototype.h"
34 static EncodedJSValue JSC_HOST_CALL
stringFromCharCode(ExecState
*);
35 static EncodedJSValue JSC_HOST_CALL
stringFromCodePoint(ExecState
*);
39 #include "StringConstructor.lut.h"
43 const ClassInfo
StringConstructor::s_info
= { "Function", &InternalFunction::s_info
, &stringConstructorTable
, CREATE_METHOD_TABLE(StringConstructor
) };
45 /* Source for StringConstructor.lut.h
46 @begin stringConstructorTable
47 fromCharCode stringFromCharCode DontEnum|Function 1
48 fromCodePoint stringFromCodePoint DontEnum|Function 1
49 raw stringRaw DontEnum|Function 1
53 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(StringConstructor
);
55 StringConstructor::StringConstructor(VM
& vm
, Structure
* structure
)
56 : InternalFunction(vm
, structure
)
60 void StringConstructor::finishCreation(VM
& vm
, StringPrototype
* stringPrototype
)
62 Base::finishCreation(vm
, stringPrototype
->classInfo()->className
);
63 putDirectWithoutTransition(vm
, vm
.propertyNames
->prototype
, stringPrototype
, ReadOnly
| DontEnum
| DontDelete
);
64 putDirectWithoutTransition(vm
, vm
.propertyNames
->length
, jsNumber(1), ReadOnly
| DontEnum
| DontDelete
);
67 bool StringConstructor::getOwnPropertySlot(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertySlot
&slot
)
69 return getStaticFunctionSlot
<InternalFunction
>(exec
, stringConstructorTable
, jsCast
<StringConstructor
*>(object
), propertyName
, slot
);
72 // ------------------------------ Functions --------------------------------
74 static NEVER_INLINE JSValue
stringFromCharCodeSlowCase(ExecState
* exec
)
76 unsigned length
= exec
->argumentCount();
78 PassRefPtr
<StringImpl
> impl
= StringImpl::createUninitialized(length
, buf
);
79 for (unsigned i
= 0; i
< length
; ++i
)
80 buf
[i
] = static_cast<UChar
>(exec
->uncheckedArgument(i
).toUInt32(exec
));
81 return jsString(exec
, impl
);
84 static EncodedJSValue JSC_HOST_CALL
stringFromCharCode(ExecState
* exec
)
86 if (LIKELY(exec
->argumentCount() == 1))
87 return JSValue::encode(jsSingleCharacterString(exec
, exec
->uncheckedArgument(0).toUInt32(exec
)));
88 return JSValue::encode(stringFromCharCodeSlowCase(exec
));
91 JSCell
* JSC_HOST_CALL
stringFromCharCode(ExecState
* exec
, int32_t arg
)
93 return jsSingleCharacterString(exec
, arg
);
96 static EncodedJSValue JSC_HOST_CALL
stringFromCodePoint(ExecState
* exec
)
98 unsigned length
= exec
->argumentCount();
99 StringBuilder builder
;
100 builder
.reserveCapacity(length
);
102 for (unsigned i
= 0; i
< length
; ++i
) {
103 double codePointAsDouble
= exec
->uncheckedArgument(i
).toNumber(exec
);
104 if (exec
->hadException())
105 return JSValue::encode(jsUndefined());
107 uint32_t codePoint
= static_cast<uint32_t>(codePointAsDouble
);
109 if (codePoint
!= codePointAsDouble
|| codePoint
> UCHAR_MAX_VALUE
)
110 return throwVMError(exec
, createRangeError(exec
, ASCIILiteral("Arguments contain a value that is out of range of code points")));
112 if (U_IS_BMP(codePoint
))
113 builder
.append(static_cast<UChar
>(codePoint
));
115 builder
.append(U16_LEAD(codePoint
));
116 builder
.append(U16_TRAIL(codePoint
));
120 return JSValue::encode(jsString(exec
, builder
.toString()));
123 static EncodedJSValue JSC_HOST_CALL
constructWithStringConstructor(ExecState
* exec
)
125 JSGlobalObject
* globalObject
= asInternalFunction(exec
->callee())->globalObject();
128 if (!exec
->argumentCount())
129 return JSValue::encode(StringObject::create(vm
, globalObject
->stringObjectStructure()));
131 return JSValue::encode(StringObject::create(vm
, globalObject
->stringObjectStructure(), exec
->uncheckedArgument(0).toString(exec
)));
134 ConstructType
StringConstructor::getConstructData(JSCell
*, ConstructData
& constructData
)
136 constructData
.native
.function
= constructWithStringConstructor
;
137 return ConstructTypeHost
;
140 JSCell
* stringConstructor(ExecState
* exec
, JSValue argument
)
142 if (argument
.isSymbol())
143 return jsNontrivialString(exec
, asSymbol(argument
)->descriptiveString());
144 return argument
.toString(exec
);
147 static EncodedJSValue JSC_HOST_CALL
callStringConstructor(ExecState
* exec
)
149 if (!exec
->argumentCount())
150 return JSValue::encode(jsEmptyString(exec
));
151 return JSValue::encode(stringConstructor(exec
, exec
->uncheckedArgument(0)));
154 CallType
StringConstructor::getCallData(JSCell
*, CallData
& callData
)
156 callData
.native
.function
= callStringConstructor
;