Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4stringobject.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
5#include "qv4stringobject_p.h"
6#include "qv4regexp_p.h"
7#include "qv4regexpobject_p.h"
8#include <private/qv4mm_p.h>
9#include "qv4scopedvalue_p.h"
10#include "qv4symbol_p.h"
11#include <private/qv4alloca_p.h>
12#include "qv4jscall_p.h"
13#include "qv4stringiterator_p.h"
14#include <QtCore/QDateTime>
15#include <QtCore/QDebug>
16#include <QtCore/QStringList>
17#include <QtQml/private/qv4runtime_p.h>
18
19#include <cassert>
20
21#ifndef Q_OS_WIN
22# include <time.h>
23# ifndef Q_OS_VXWORKS
24# include <sys/time.h>
25# else
26# include "qplatformdefs.h"
27# endif
28#else
29# include <qt_windows.h>
30#endif
31
32using namespace QV4;
33using namespace Qt::Literals::StringLiterals;
34
36
37void Heap::StringObject::init()
38{
39 Object::init();
40 Q_ASSERT(vtable() == QV4::StringObject::staticVTable());
41 string.set(internalClass->engine, internalClass->engine->id_empty()->d());
42 setProperty(internalClass->engine, LengthPropertyIndex, Value::fromInt32(0));
43}
44
45void Heap::StringObject::init(const QV4::String *str)
46{
47 Object::init();
48 string.set(internalClass->engine, str->d());
49 setProperty(internalClass->engine, LengthPropertyIndex, Value::fromInt32(length()));
50}
51
52Heap::String *Heap::StringObject::getIndex(uint index) const
53{
54 QString str = string->toQString();
55 if (index >= (uint)str.size())
56 return nullptr;
57 return internalClass->engine->newString(str.mid(index, 1));
58}
59
60uint Heap::StringObject::length() const
61{
62 return string->length();
63}
64
66{
67 Q_ASSERT(m->as<StringObject>());
68 if (id.isArrayIndex()) {
69 StringObject *o = static_cast<StringObject *>(m);
70 uint index = id.asArrayIndex();
71 if (index < static_cast<uint>(o->d()->string->toQString().size()))
72 return false;
73 }
75}
76
83
85{
86 const StringObject *s = static_cast<const StringObject *>(o);
87 uint slen = s->d()->string->toQString().size();
88 if (arrayIndex < slen) {
89 uint index = arrayIndex;
90 ++arrayIndex;
91 if (attrs)
93 if (pd)
94 pd->value = s->getIndex(index);
96 } else if (arrayIndex == slen) {
97 if (s->arrayData()) {
98 SparseArrayNode *arrayNode = s->sparseBegin();
99 // iterate until we're past the end of the string
100 while (arrayNode && arrayNode->key() < slen)
101 arrayNode = arrayNode->nextNode();
102 }
103 }
104
106}
107
113
115{
117 if (attributes != Attr_Invalid)
118 return attributes;
119
120 if (id.isArrayIndex()) {
121 const uint index = id.asArrayIndex();
122 const auto s = static_cast<const StringObject *>(m);
123 if (index < uint(s->d()->string->toQString().size())) {
124 if (p)
125 p->value = s->getIndex(index);
127 }
128 }
129 return Object::virtualGetOwnProperty(m, id, p);
130}
131
133
135{
136 Heap::FunctionObject::init(engine, QStringLiteral("String"));
137}
138
139ReturnedValue StringCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
140{
141 ExecutionEngine *v4 = static_cast<const Object *>(f)->engine();
142 Scope scope(v4);
143 ScopedString value(scope);
144 if (argc)
145 value = argv[0].toString(v4);
146 else
147 value = v4->newString();
150
151 if (!newTarget)
152 return o;
153 ScopedObject obj(scope, o);
154 obj->setProtoFromNewTarget(newTarget);
155 return obj->asReturnedValue();
156}
157
158ReturnedValue StringCtor::virtualCall(const FunctionObject *m, const Value *, const Value *argv, int argc)
159{
160 ExecutionEngine *v4 = m->engine();
161 if (!argc)
162 return v4->newString()->asReturnedValue();
163 if (argv[0].isSymbol())
164 return v4->newString(argv[0].symbolValue()->descriptiveString())->asReturnedValue();
165 return argv[0].toString(v4)->asReturnedValue();
166}
167
169{
171 QChar *ch = str.data();
172 for (int i = 0, ei = argc; i < ei; ++i) {
173 *ch = QChar(argv[i].toUInt16());
174 ++ch;
175 }
176 return Encode(b->engine()->newString(str));
177}
178
179
180
182{
183 ExecutionEngine *e = f->engine();
184 QString result(argc*2, Qt::Uninitialized); // assume worst case
185 QChar *ch = result.data();
186 for (int i = 0; i < argc; ++i) {
187 double num = argv[i].toNumber();
188 if (e->hasException)
189 return Encode::undefined();
190 int cp = static_cast<int>(num);
191 if (cp != num || cp < 0 || cp > 0x10ffff)
192 return e->throwRangeError(QStringLiteral("String.fromCodePoint: argument out of range."));
193 if (cp > 0xffff) {
194 *ch = QChar::highSurrogate(cp);
195 ++ch;
196 *ch = QChar::lowSurrogate(cp);
197 } else {
198 *ch = QChar(cp);
199 }
200 ++ch;
201 }
202 result.truncate(ch - result.constData());
203 return e->newString(result)->asReturnedValue();
204}
205
206ReturnedValue StringCtor::method_raw(const FunctionObject *f, const Value *, const Value *argv, int argc)
207{
208 Scope scope(f);
209 if (!argc)
210 return scope.engine->throwTypeError();
211
212 ScopedObject cooked(scope, argv[0].toObject(scope.engine));
213 if (!cooked)
214 return scope.engine->throwTypeError();
215 ScopedString rawString(scope, scope.engine->newIdentifier(QStringLiteral("raw")));
216 ScopedValue rawValue(scope, cooked->get(rawString));
217 ScopedObject raw(scope, rawValue->toObject(scope.engine));
218 if (scope.hasException())
219 return Encode::undefined();
220
221 ++argv;
222 --argc;
223
225 uint literalSegments = raw->getLength();
226 if (!literalSegments)
227 return scope.engine->id_empty()->asReturnedValue();
228
229 uint nextIndex = 0;
230 ScopedValue val(scope);
231 while (1) {
232 val = raw->get(nextIndex);
233 result += val->toQString();
234 if (scope.hasException())
235 return Encode::undefined();
236 if (nextIndex + 1 == literalSegments)
237 return scope.engine->newString(result)->asReturnedValue();
238
239 if (nextIndex < static_cast<uint>(argc))
240 result += argv[nextIndex].toQString();
241 if (scope.hasException())
242 return Encode::undefined();
243 ++nextIndex;
244 }
245}
246
248{
249 Scope scope(engine);
250 ScopedObject o(scope);
251
252 // need to set this once again, as these were not fully defined when creating the string proto
254 d()->internalClass.set(scope.engine, ic);
255 d()->string.set(scope.engine, scope.engine->id_empty()->d());
256 setProperty(scope.engine, Heap::StringObject::LengthPropertyIndex, Value::fromInt32(0));
257
258 ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
259 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(1));
260 ctor->defineDefaultProperty(QStringLiteral("fromCharCode"), StringCtor::method_fromCharCode, 1);
261 ctor->defineDefaultProperty(QStringLiteral("fromCodePoint"), StringCtor::method_fromCodePoint, 1);
262 ctor->defineDefaultProperty(QStringLiteral("raw"), StringCtor::method_raw, 1);
263
264 defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
265 defineDefaultProperty(engine->id_toString(), method_toString);
266 defineDefaultProperty(engine->id_valueOf(), method_toString); // valueOf and toString are identical
267 defineDefaultProperty(QStringLiteral("charAt"), method_charAt, 1);
268 defineDefaultProperty(QStringLiteral("charCodeAt"), method_charCodeAt, 1);
269 defineDefaultProperty(QStringLiteral("codePointAt"), method_codePointAt, 1);
270 defineDefaultProperty(QStringLiteral("concat"), method_concat, 1);
271 defineDefaultProperty(QStringLiteral("endsWith"), method_endsWith, 1);
272 defineDefaultProperty(QStringLiteral("indexOf"), method_indexOf, 1);
273 defineDefaultProperty(QStringLiteral("includes"), method_includes, 1);
274 defineDefaultProperty(QStringLiteral("lastIndexOf"), method_lastIndexOf, 1);
275 defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare, 1);
276 defineDefaultProperty(QStringLiteral("match"), method_match, 1);
277 defineDefaultProperty(QStringLiteral("normalize"), method_normalize, 0);
278 defineDefaultProperty(QStringLiteral("padEnd"), method_padEnd, 1);
279 defineDefaultProperty(QStringLiteral("padStart"), method_padStart, 1);
280 defineDefaultProperty(QStringLiteral("repeat"), method_repeat, 1);
281 defineDefaultProperty(QStringLiteral("replace"), method_replace, 2);
282 defineDefaultProperty(QStringLiteral("search"), method_search, 1);
283 defineDefaultProperty(QStringLiteral("slice"), method_slice, 2);
284 defineDefaultProperty(QStringLiteral("split"), method_split, 2);
285 defineDefaultProperty(QStringLiteral("startsWith"), method_startsWith, 1);
286 defineDefaultProperty(QStringLiteral("substr"), method_substr, 2);
287 defineDefaultProperty(QStringLiteral("substring"), method_substring, 2);
288 defineDefaultProperty(QStringLiteral("toLowerCase"), method_toLowerCase);
289 defineDefaultProperty(QStringLiteral("toLocaleLowerCase"), method_toLocaleLowerCase);
290 defineDefaultProperty(QStringLiteral("toUpperCase"), method_toUpperCase);
291 defineDefaultProperty(QStringLiteral("toLocaleUpperCase"), method_toLocaleUpperCase);
292 defineDefaultProperty(QStringLiteral("trim"), method_trim);
293 defineDefaultProperty(engine->symbol_iterator(), method_iterator);
294}
295
297{
298 if (String *s = thisObject->stringValue())
299 return s->d();
300 if (const StringObject *thisString = thisObject->as<StringObject>())
301 return thisString->d()->string;
302 return thisObject->toString(v4);
303}
304
305static QString getThisString(ExecutionEngine *v4, const QV4::Value *thisObject)
306{
307 if (String *s = thisObject->stringValue())
308 return s->toQString();
309 if (const StringObject *thisString = thisObject->as<StringObject>())
310 return thisString->d()->string->toQString();
311 if (thisObject->isUndefined() || thisObject->isNull()) {
312 v4->throwTypeError();
313 return QString();
314 }
315 return thisObject->toQString();
316}
317
319{
320 if (thisObject->isString())
321 return thisObject->asReturnedValue();
322
323 ExecutionEngine *v4 = b->engine();
324 const StringObject *o = thisObject->as<StringObject>();
325 if (!o)
326 return v4->throwTypeError();
327 return o->d()->string->asReturnedValue();
328}
329
330ReturnedValue StringPrototype::method_charAt(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
331{
332 ExecutionEngine *v4 = b->engine();
333 const QString str = getThisString(v4, thisObject);
334 if (v4->hasException)
335 return QV4::Encode::undefined();
336
337 double pos = 0;
338 if (argc > 0)
339 pos = argv[0].toInteger();
340
342 if (pos >= 0 && pos < str.size())
343 result += str.at(pos);
344
345 return Encode(v4->newString(result));
346}
347
348ReturnedValue StringPrototype::method_charCodeAt(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
349{
350 ExecutionEngine *v4 = b->engine();
351 const QString str = getThisString(v4, thisObject);
352 if (v4->hasException)
353 return QV4::Encode::undefined();
354
355 double pos = 0;
356 if (argc > 0)
357 pos = argv[0].toInteger();
358
359
360 if (pos >= 0 && pos < str.size())
361 RETURN_RESULT(Encode(str.at(pos).unicode()));
362
363 return Encode(qt_qnan());
364}
365
366ReturnedValue StringPrototype::method_codePointAt(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
367{
368 ExecutionEngine *v4 = f->engine();
369 QString value = getThisString(v4, thisObject);
370 if (v4->hasException)
371 return QV4::Encode::undefined();
372
373 double index = argc ? argv[0].toInteger() : 0.0;
374 if (v4->hasException)
375 return QV4::Encode::undefined();
376
377 if (index < 0 || index >= value.size())
378 return Encode::undefined();
379
380 uint first = value.at(index).unicode();
381 if (QChar::isHighSurrogate(first) && index + 1 < value.size()) {
382 uint second = value.at(index + 1).unicode();
383 if (QChar::isLowSurrogate(second))
384 return Encode(QChar::surrogateToUcs4(first, second));
385 }
386 return Encode(first);
387}
388
389ReturnedValue StringPrototype::method_concat(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
390{
391 ExecutionEngine *v4 = b->engine();
392 QString value = getThisString(v4, thisObject);
393 if (v4->hasException)
394 return QV4::Encode::undefined();
395
396 Scope scope(v4);
397 ScopedString s(scope);
398 for (int i = 0; i < argc; ++i) {
399 s = argv[i].toString(scope.engine);
400 if (v4->hasException)
401 return QV4::Encode::undefined();
402
403 Q_ASSERT(s->isString());
404 value += s->toQString();
405 }
406
407 return Encode(v4->newString(value));
408}
409
410ReturnedValue StringPrototype::method_endsWith(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
411{
412 ExecutionEngine *v4 = b->engine();
413 const QString value = getThisString(v4, thisObject);
414 if (v4->hasException)
415 return QV4::Encode::undefined();
416
417 if (argc && argv[0].as<RegExpObject>())
418 return v4->throwTypeError();
419 QString searchString = (argc ? argv[0] : Value::undefinedValue()).toQString();
420 if (v4->hasException)
421 return Encode::undefined();
422
423 double pos = value.size();
424 if (argc > 1)
425 pos = argv[1].toInteger();
426
427 if (pos == value.size())
428 RETURN_RESULT(Encode(value.endsWith(searchString)));
429
430 QStringView stringToSearch = QStringView{value}.left(pos);
431 return Encode(stringToSearch.endsWith(searchString));
432}
433
434ReturnedValue StringPrototype::method_indexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
435{
436 ExecutionEngine *v4 = b->engine();
437 const QString value = getThisString(v4, thisObject);
438 if (v4->hasException)
439 return QV4::Encode::undefined();
440
441 QString searchString = (argc ? argv[0] : Value::undefinedValue()).toQString();
442 if (v4->hasException)
443 return Encode::undefined();
444
445 double pos = 0;
446 if (argc > 1)
447 pos = argv[1].toInteger();
448
449 int index = -1;
450 if (!value.isEmpty())
451 index = value.indexOf(searchString, qMin(qMax(pos, 0.0), double(value.size())));
452
453 return Encode(index);
454}
455
456ReturnedValue StringPrototype::method_includes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
457{
458 ExecutionEngine *v4 = b->engine();
459 const QString value = getThisString(v4, thisObject);
460 if (v4->hasException)
461 return QV4::Encode::undefined();
462
463 if (argc && argv[0].as<RegExpObject>())
464 return v4->throwTypeError();
465 QString searchString = (argc ? argv[0] : Value::undefinedValue()).toQString();
466 if (v4->hasException)
467 return Encode::undefined();
468
469 double pos = 0;
470 if (argc > 1) {
471 const Value &posArg = argv[1];
472 pos = posArg.toInteger();
473 if (!posArg.isInteger() && posArg.isNumber() && qIsInf(posArg.toNumber()))
474 pos = value.size();
475 }
476
477 if (pos == 0)
478 RETURN_RESULT(Encode(value.contains(searchString)));
479
480 QStringView stringToSearch = QStringView{value}.mid(pos);
481 return Encode(stringToSearch.contains(searchString));
482}
483
484ReturnedValue StringPrototype::method_lastIndexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
485{
486 ExecutionEngine *v4 = b->engine();
487 const QString value = getThisString(v4, thisObject);
488 if (v4->hasException)
489 return QV4::Encode::undefined();
490
491 QString searchString = (argc ? argv[0] : Value::undefinedValue()).toQString();
492 if (v4->hasException)
493 return Encode::undefined();
494
495 double position = argc > 1 ? RuntimeHelpers::toNumber(argv[1]) : +qInf();
496 if (std::isnan(position))
497 position = +qInf();
498 else
499 position = std::trunc(position);
500
501 int pos = std::trunc(qMin(qMax(position, 0.0), double(value.size())));
502 if (!searchString.isEmpty() && pos == value.size())
503 --pos;
504 if (searchString.isNull() && pos == 0)
506 int index = value.lastIndexOf(searchString, pos);
507 return Encode(index);
508}
509
510ReturnedValue StringPrototype::method_localeCompare(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
511{
512 ExecutionEngine *v4 = b->engine();
513 const QString value = getThisString(v4, thisObject);
514 if (v4->hasException)
515 return QV4::Encode::undefined();
516
517 const QString that = (argc ? argv[0] : Value::undefinedValue()).toQString();
519}
520
521ReturnedValue StringPrototype::method_match(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
522{
523 ExecutionEngine *v4 = b->engine();
524 if (thisObject->isNullOrUndefined())
525 return v4->throwTypeError();
526
527 Scope scope(v4);
528 if (argc && !argv[0].isNullOrUndefined()) {
529 ScopedObject r(scope, argv[0].toObject(scope.engine));
530 if (scope.hasException())
531 return Encode::undefined();
532 ScopedValue f(scope, r->get(scope.engine->symbol_match()));
533 if (!f->isNullOrUndefined()) {
534 ScopedFunctionObject fo(scope, f);
535 if (!fo)
536 return scope.engine->throwTypeError();
537 return checkedResult(scope.engine, fo->call(r, thisObject, 1));
538 }
539 }
540
541 ScopedString s(scope, thisObject->toString(v4));
542 if (v4->hasException)
543 return Encode::undefined();
544
545 Scoped<RegExpObject> that(scope, argc ? argv[0] : Value::undefinedValue());
546 if (!that) {
547 // convert args[0] to a regexp
548 that = RegExpCtor::virtualCallAsConstructor(b, argv, argc, b);
549 if (v4->hasException)
550 return Encode::undefined();
551 }
552 Q_ASSERT(!!that);
553
554 ScopedFunctionObject match(scope, that->get(scope.engine->symbol_match()));
555 if (!match)
556 return scope.engine->throwTypeError();
557 return checkedResult(scope.engine, match->call(that, s, 1));
558}
559
560ReturnedValue StringPrototype::method_normalize(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
561{
562 ExecutionEngine *v4 = f->engine();
563 const QString value = getThisString(v4, thisObject);
564 if (v4->hasException)
565 return Encode::undefined();
566
568 if (argc >= 1 && !argv[0].isUndefined()) {
569 QString f = argv[0].toQString();
570 if (v4->hasException)
571 return Encode::undefined();
572 if (f == QLatin1String("NFC"))
574 else if (f == QLatin1String("NFD"))
576 else if (f == QLatin1String("NFKC"))
578 else if (f == QLatin1String("NFKD"))
580 else
581 return v4->throwRangeError(QLatin1String("String.prototype.normalize: Invalid normalization form."));
582 }
584 return v4->newString(normalized)->asReturnedValue();
585}
586
587ReturnedValue StringPrototype::method_padEnd(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
588{
589 ExecutionEngine *v4 = f->engine();
590 if (thisObject->isNullOrUndefined())
591 return v4->throwTypeError();
592
593 Scope scope(v4);
594 ScopedString s(scope, thisAsString(v4, thisObject));
595 if (v4->hasException)
596 return Encode::undefined();
597 if (!argc)
598 return s->asReturnedValue();
599
600 double maxLen = argv[0].toInteger();
601 if (maxLen <= s->d()->length())
602 return s->asReturnedValue();
603 QString fillString = (argc > 1 && !argv[1].isUndefined()) ? argv[1].toQString() : u" "_s;
604 if (v4->hasException)
605 return Encode::undefined();
606
607 if (fillString.isEmpty())
608 return s->asReturnedValue();
609
610 QString padded = s->toQString();
611 int oldLength = padded.size();
612 int toFill = maxLen - oldLength;
613 padded.resize(maxLen);
614 QChar *ch = padded.data() + oldLength;
615 while (toFill) {
616 int copy = qMin(fillString.size(), toFill);
617 memcpy(ch, fillString.constData(), copy*sizeof(QChar));
618 toFill -= copy;
619 ch += copy;
620 }
621 *ch = QChar::Null;
622
623 return v4->newString(padded)->asReturnedValue();
624}
625
626ReturnedValue StringPrototype::method_padStart(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
627{
628 ExecutionEngine *v4 = f->engine();
629 if (thisObject->isNullOrUndefined())
630 return v4->throwTypeError();
631
632 Scope scope(v4);
633 ScopedString s(scope, thisAsString(v4, thisObject));
634 if (v4->hasException)
635 return Encode::undefined();
636 if (!argc)
637 return s->asReturnedValue();
638
639 double maxLen = argv[0].toInteger();
640 if (maxLen <= s->d()->length())
641 return s->asReturnedValue();
642 QString fillString = (argc > 1 && !argv[1].isUndefined()) ? argv[1].toQString() : u" "_s;
643 if (v4->hasException)
644 return Encode::undefined();
645
646 if (fillString.isEmpty())
647 return s->asReturnedValue();
648
649 QString original = s->toQString();
650 int oldLength = original.size();
651 int toFill = maxLen - oldLength;
652 QString padded;
653 padded.resize(maxLen);
654 QChar *ch = padded.data();
655 while (toFill) {
656 int copy = qMin(fillString.size(), toFill);
657 memcpy(ch, fillString.constData(), copy*sizeof(QChar));
658 toFill -= copy;
659 ch += copy;
660 }
661 memcpy(ch, original.constData(), oldLength*sizeof(QChar));
662 ch += oldLength;
663 *ch = QChar::Null;
664
665 return v4->newString(padded)->asReturnedValue();
666}
667
668
669ReturnedValue StringPrototype::method_repeat(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
670{
671 ExecutionEngine *v4 = b->engine();
672 const QString value = getThisString(v4, thisObject);
673 if (v4->hasException)
674 return QV4::Encode::undefined();
675
676 double repeats = (argc ? argv[0] : Value::undefinedValue()).toInteger();
677
678 if (repeats < 0 || qIsInf(repeats))
679 return v4->throwRangeError(QLatin1String("Invalid count value"));
680
681 return Encode(v4->newString(value.repeated(int(repeats))));
682}
683
684static void appendReplacementString(QString *result, const QString &input, const QString& replaceValue, uint* matchOffsets, int captureCount)
685{
686 result->reserve(result->size() + replaceValue.size());
687 for (int i = 0; i < replaceValue.size(); ++i) {
688 if (replaceValue.at(i) == QLatin1Char('$') && i < replaceValue.size() - 1) {
689 ushort ch = replaceValue.at(i + 1).unicode();
690 uint substStart = JSC::Yarr::offsetNoMatch;
691 uint substEnd = JSC::Yarr::offsetNoMatch;
692 int skip = 0;
693 if (ch == '$') {
694 *result += QChar(ch);
695 ++i;
696 continue;
697 } else if (ch == '&') {
698 substStart = matchOffsets[0];
699 substEnd = matchOffsets[1];
700 skip = 1;
701 } else if (ch == '`') {
702 substStart = 0;
703 substEnd = matchOffsets[0];
704 skip = 1;
705 } else if (ch == '\'') {
706 substStart = matchOffsets[1];
707 substEnd = input.size();
708 skip = 1;
709 } else if (ch >= '0' && ch <= '9') {
710 uint capture = ch - '0';
711 skip = 1;
712 if (i < replaceValue.size() - 2) {
713 ch = replaceValue.at(i + 2).unicode();
714 if (ch >= '0' && ch <= '9') {
715 uint c = capture*10 + ch - '0';
716 if (c < static_cast<uint>(captureCount)) {
717 capture = c;
718 skip = 2;
719 }
720 }
721 }
722 if (capture > 0 && capture < static_cast<uint>(captureCount)) {
723 substStart = matchOffsets[capture * 2];
724 substEnd = matchOffsets[capture * 2 + 1];
725 } else {
726 skip = 0;
727 }
728 }
729 i += skip;
730 if (substStart != JSC::Yarr::offsetNoMatch && substEnd != JSC::Yarr::offsetNoMatch)
731 *result += QStringView{input}.mid(substStart, substEnd - substStart);
732 else if (skip == 0) // invalid capture reference. Taken as literal value
733 *result += replaceValue.at(i);
734 } else {
735 *result += replaceValue.at(i);
736 }
737 }
738}
739
740ReturnedValue StringPrototype::method_replace(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
741{
743 if (const StringObject *thisString = thisObject->as<StringObject>())
744 string = thisString->d()->string->toQString();
745 else
746 string = thisObject->toQString();
747
748 int numCaptures = 0;
749 int numStringMatches = 0;
750
751 uint allocatedMatchOffsets = 64;
752 uint _matchOffsets[64];
753 uint *matchOffsets = _matchOffsets;
754
755 Scope scope(b);
756 ScopedValue searchValue(scope, argc ? argv[0] : Value::undefinedValue());
757 Scoped<RegExpObject> regExp(scope, searchValue);
758 if (regExp) {
759 uint offset = 0;
760 uint nMatchOffsets = 0;
761
762 // We extract the pointer here to work around a compiler bug on Android.
763 Scoped<RegExp> re(scope, regExp->value());
764 while (true) {
765 int oldSize = nMatchOffsets;
766 if (allocatedMatchOffsets < nMatchOffsets + re->captureCount() * 2) {
767 allocatedMatchOffsets = qMax(allocatedMatchOffsets * 2, nMatchOffsets + re->captureCount() * 2);
768 uint *newOffsets = (uint *)malloc(allocatedMatchOffsets*sizeof(uint));
769 memcpy(newOffsets, matchOffsets, nMatchOffsets*sizeof(uint));
770 if (matchOffsets != _matchOffsets)
771 free(matchOffsets);
772 matchOffsets = newOffsets;
773 }
774 if (re->match(string, offset, matchOffsets + oldSize) == JSC::Yarr::offsetNoMatch) {
775 nMatchOffsets = oldSize;
776 break;
777 }
778 nMatchOffsets += re->captureCount() * 2;
779 if (!regExp->global())
780 break;
781 offset = qMax(offset + 1, matchOffsets[oldSize + 1]);
782 }
783 if (regExp->global()) {
784 regExp->setLastIndex(0);
785 if (scope.hasException())
786 return Encode::undefined();
787 }
788 numStringMatches = nMatchOffsets / (regExp->value()->captureCount() * 2);
789 numCaptures = regExp->value()->captureCount();
790 } else {
791 numCaptures = 1;
792 QString searchString = searchValue->toQString();
793 int idx = string.indexOf(searchString);
794 if (idx != -1) {
795 numStringMatches = 1;
796 matchOffsets[0] = idx;
797 matchOffsets[1] = idx + searchString.size();
798 }
799 }
800
802 ScopedValue replacement(scope);
803 ScopedValue replaceValue(scope, argc > 1 ? argv[1] : Value::undefinedValue());
804 ScopedFunctionObject searchCallback(scope, replaceValue);
805 if (!!searchCallback) {
806 result.reserve(string.size() + 10*numStringMatches);
807 ScopedValue entry(scope);
808 Value *arguments = scope.alloc(numCaptures + 2);
809 int lastEnd = 0;
810 for (int i = 0; i < numStringMatches; ++i) {
811 for (int k = 0; k < numCaptures; ++k) {
812 int idx = (i * numCaptures + k) * 2;
813 uint start = matchOffsets[idx];
814 uint end = matchOffsets[idx + 1];
816 if (start != JSC::Yarr::offsetNoMatch && end != JSC::Yarr::offsetNoMatch)
817 entry = scope.engine->newString(string.mid(start, end - start));
818 arguments[k] = entry;
819 }
820 uint matchStart = matchOffsets[i * numCaptures * 2];
821 Q_ASSERT(matchStart >= static_cast<uint>(lastEnd));
822 uint matchEnd = matchOffsets[i * numCaptures * 2 + 1];
823 arguments[numCaptures] = Value::fromUInt32(matchStart);
824 arguments[numCaptures + 1] = scope.engine->newString(string);
825
827 replacement = searchCallback->call(&that, arguments, numCaptures + 2);
829 result += QStringView{string}.mid(lastEnd, matchStart - lastEnd);
830 result += replacement->toQString();
831 lastEnd = matchEnd;
832 }
833 result += QStringView{string}.mid(lastEnd);
834 } else {
835 QString newString = replaceValue->toQString();
836 result.reserve(string.size() + numStringMatches*newString.size());
837
838 int lastEnd = 0;
839 for (int i = 0; i < numStringMatches; ++i) {
840 int baseIndex = i * numCaptures * 2;
841 uint matchStart = matchOffsets[baseIndex];
842 uint matchEnd = matchOffsets[baseIndex + 1];
843 if (matchStart == JSC::Yarr::offsetNoMatch)
844 continue;
845
846 result += QStringView{string}.mid(lastEnd, matchStart - lastEnd);
847 appendReplacementString(&result, string, newString, matchOffsets + baseIndex, numCaptures);
848 lastEnd = matchEnd;
849 }
850 result += QStringView{string}.mid(lastEnd);
851 }
852
853 if (matchOffsets != _matchOffsets)
854 free(matchOffsets);
855
856 return Encode(scope.engine->newString(result));
857}
858
859ReturnedValue StringPrototype::method_search(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
860{
861 Scope scope(b);
862 QString string = getThisString(scope.engine, thisObject);
863 if (scope.hasException())
864 return QV4::Encode::undefined();
865
866 Scoped<RegExpObject> regExp(scope, argc ? argv[0] : Value::undefinedValue());
867 if (!regExp) {
868 regExp = scope.engine->regExpCtor()->callAsConstructor(argv, 1);
869 if (scope.hasException())
870 return QV4::Encode::undefined();
871
872 Q_ASSERT(regExp);
873 }
874 Scoped<RegExp> re(scope, regExp->value());
875 Q_ALLOCA_VAR(uint, matchOffsets, regExp->value()->captureCount() * 2 * sizeof(uint));
876 uint result = re->match(string, /*offset*/0, matchOffsets);
877 if (result == JSC::Yarr::offsetNoMatch)
878 return Encode(-1);
879 else
880 return Encode(result);
881}
882
883ReturnedValue StringPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
884{
885 ExecutionEngine *v4 = b->engine();
886 Scope scope(v4);
887 ScopedString s(scope, thisAsString(v4, thisObject));
888 if (v4->hasException)
889 return QV4::Encode::undefined();
890 Q_ASSERT(s);
891
892 const double length = s->d()->length();
893
894 double start = argc ? argv[0].toInteger() : 0;
895 double end = (argc < 2 || argv[1].isUndefined())
896 ? length : argv[1].toInteger();
897
898 if (start < 0)
899 start = qMax(length + start, 0.);
900 else
902
903 if (end < 0)
904 end = qMax(length + end, 0.);
905 else
906 end = qMin(end, length);
907
908 const int intStart = int(start);
909 const int intEnd = int(end);
910
911 int count = qMax(0, intEnd - intStart);
912 return Encode(v4->memoryManager->alloc<ComplexString>(s->d(), intStart, count));
913}
914
915ReturnedValue StringPrototype::method_split(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
916{
917 ExecutionEngine *v4 = b->engine();
918 QString text = getThisString(v4, thisObject);
919 if (v4->hasException)
920 return QV4::Encode::undefined();
921
922 Scope scope(v4);
923 ScopedValue separatorValue(scope, argc ? argv[0] : Value::undefinedValue());
924 ScopedValue limitValue(scope, argc > 1 ? argv[1] : Value::undefinedValue());
925
927
928 if (separatorValue->isUndefined()) {
929 if (limitValue->isUndefined()) {
930 ScopedString s(scope, scope.engine->newString(text));
931 array->push_back(s);
932 return array.asReturnedValue();
933 }
934 RETURN_RESULT(scope.engine->newString(text.left(limitValue->toInteger())));
935 }
936
937 uint limit = limitValue->isUndefined() ? UINT_MAX : limitValue->toUInt32();
938
939 if (limit == 0)
940 return array.asReturnedValue();
941
942 Scoped<RegExpObject> re(scope, separatorValue);
943 if (re) {
944 if (re->value()->pattern->isEmpty()) {
945 re = (RegExpObject *)nullptr;
946 separatorValue = scope.engine->newString();
947 }
948 }
949
950 ScopedString s(scope);
951 if (re) {
952 uint offset = 0;
953 Q_ALLOCA_VAR(uint, matchOffsets, re->value()->captureCount() * 2 * sizeof(uint));
954 while (true) {
955 Scoped<RegExp> regexp(scope, re->value());
956 uint result = regexp->match(text, offset, matchOffsets);
957 if (result == JSC::Yarr::offsetNoMatch)
958 break;
959
960 array->push_back((s = scope.engine->newString(text.mid(offset, matchOffsets[0] - offset))));
961 offset = qMax(offset + 1, matchOffsets[1]);
962
963 if (array->getLength() >= limit)
964 break;
965
966 for (int i = 1; i < re->value()->captureCount(); ++i) {
967 uint start = matchOffsets[i * 2];
968 uint end = matchOffsets[i * 2 + 1];
969 array->push_back((s = scope.engine->newString(text.mid(start, end - start))));
970 if (array->getLength() >= limit)
971 break;
972 }
973 }
974 if (array->getLength() < limit)
975 array->push_back((s = scope.engine->newString(text.mid(offset))));
976 } else {
977 QString separator = separatorValue->toQString();
978 if (separator.isEmpty()) {
979 for (uint i = 0; i < qMin(limit, uint(text.size())); ++i)
980 array->push_back((s = scope.engine->newString(text.mid(i, 1))));
981 return array.asReturnedValue();
982 }
983
984 int start = 0;
985 int end;
986 while ((end = text.indexOf(separator, start)) != -1) {
987 array->push_back((s = scope.engine->newString(text.mid(start, end - start))));
988 start = end + separator.size();
989 if (array->getLength() >= limit)
990 break;
991 }
992 if (array->getLength() < limit && start != -1)
993 array->push_back((s = scope.engine->newString(text.mid(start))));
994 }
995 return array.asReturnedValue();
996}
997
998ReturnedValue StringPrototype::method_startsWith(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
999{
1000 ExecutionEngine *v4 = b->engine();
1001 const QString value = getThisString(v4, thisObject);
1002 if (v4->hasException)
1003 return QV4::Encode::undefined();
1004
1005 if (argc && argv[0].as<RegExpObject>())
1006 return v4->throwTypeError();
1007 QString searchString = (argc ? argv[0] : Value::undefinedValue()).toQString();
1008 if (v4->hasException)
1009 return Encode::undefined();
1010
1011 double pos = 0;
1012 if (argc > 1)
1013 pos = argv[1].toInteger();
1014
1015 if (pos == 0)
1016 return Encode(value.startsWith(searchString));
1017
1018 QStringView stringToSearch = QStringView{value}.mid(pos);
1019 RETURN_RESULT(Encode(stringToSearch.startsWith(searchString)));
1020}
1021
1022ReturnedValue StringPrototype::method_substr(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1023{
1024 ExecutionEngine *v4 = b->engine();
1025 const QString value = getThisString(v4, thisObject);
1026 if (v4->hasException)
1027 return QV4::Encode::undefined();
1028
1029 double start = 0;
1030 if (argc > 0)
1031 start = argv[0].toInteger();
1032
1033 double length = +qInf();
1034 if (argc > 1)
1035 length = argv[1].toInteger();
1036
1037 double count = value.size();
1038 if (start < 0)
1039 start = qMax(count + start, 0.0);
1040
1041 length = qMin(qMax(length, 0.0), count - start);
1042
1045 return Encode(v4->newString(value.mid(x, y)));
1046}
1047
1048ReturnedValue StringPrototype::method_substring(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1049{
1050 ExecutionEngine *v4 = b->engine();
1051 const QString value = getThisString(v4, thisObject);
1052 if (v4->hasException)
1053 return QV4::Encode::undefined();
1054
1055 int length = value.size();
1056
1057 double start = 0;
1058 double end = length;
1059
1060 if (argc > 0)
1061 start = argv[0].toInteger();
1062
1063 if (argc > 1 && !argv[1].isUndefined())
1064 end = argv[1].toInteger();
1065
1066 if (std::isnan(start) || start < 0)
1067 start = 0;
1068
1069 if (std::isnan(end) || end < 0)
1070 end = 0;
1071
1072 if (start > length)
1073 start = length;
1074
1075 if (end > length)
1076 end = length;
1077
1078 if (start > end) {
1079 double was = start;
1080 start = end;
1081 end = was;
1082 }
1083
1084 qint32 x = (int)start;
1085 qint32 y = (int)(end - start);
1086 return Encode(v4->newString(value.mid(x, y)));
1087}
1088
1090{
1091 ExecutionEngine *v4 = b->engine();
1092 const QString value = getThisString(v4, thisObject);
1093 if (v4->hasException)
1094 return QV4::Encode::undefined();
1095
1096 return Encode(v4->newString(value.toLower()));
1097}
1098
1100{
1101 return method_toLowerCase(b, thisObject, argv, argc);
1102}
1103
1105{
1106 ExecutionEngine *v4 = b->engine();
1107 const QString value = getThisString(v4, thisObject);
1108 if (v4->hasException)
1109 return QV4::Encode::undefined();
1110
1111 return Encode(v4->newString(value.toUpper()));
1112}
1113
1115{
1116 return method_toUpperCase(b, thisObject, argv, argc);
1117}
1118
1120{
1121 ExecutionEngine *v4 = b->engine();
1122 QString s = getThisString(v4, thisObject);
1123 if (v4->hasException)
1124 return QV4::Encode::undefined();
1125
1126 const QChar *chars = s.constData();
1127 int start, end;
1128 for (start = 0; start < s.size(); ++start) {
1129 if (!chars[start].isSpace() && chars[start].unicode() != 0xfeff)
1130 break;
1131 }
1132 for (end = s.size() - 1; end >= start; --end) {
1133 if (!chars[end].isSpace() && chars[end].unicode() != 0xfeff)
1134 break;
1135 }
1136
1137 return Encode(v4->newString(QString(chars + start, end - start + 1)));
1138}
1139
1140
1141
1143{
1144 Scope scope(b);
1145 ScopedString s(scope, thisObject->toString(scope.engine));
1146 if (!s || thisObject->isNullOrUndefined())
1147 return scope.engine->throwTypeError();
1148
1149 Scoped<StringIteratorObject> si(scope, scope.engine->memoryManager->allocate<StringIteratorObject>(s->d(), scope.engine));
1150 return si->asReturnedValue();
1151}
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
constexpr QStringView left(qsizetype n) const noexcept
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString left(qsizetype n) const &
Definition qstring.h:363
qsizetype indexOf(QLatin1StringView s, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4517
void reserve(qsizetype size)
Ensures the string has space for at least size characters.
Definition qstring.h:1325
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition qstring.h:1246
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition qstring.h:994
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
void push_back(QChar c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.h:957
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1226
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1240
int localeAwareCompare(const QString &s) const
Definition qstring.cpp:6907
NormalizationForm
This enum describes the various normalized forms of Unicode text.
Definition qstring.h:617
@ NormalizationForm_KC
Definition qstring.h:621
@ NormalizationForm_KD
Definition qstring.h:620
@ NormalizationForm_C
Definition qstring.h:619
@ NormalizationForm_D
Definition qstring.h:618
QString normalized(NormalizationForm mode, QChar::UnicodeVersion version=QChar::Unicode_Unassigned) const
Returns the string in the given Unicode normalization mode, according to the given version of the Uni...
Definition qstring.cpp:8475
qsizetype length() const noexcept
Returns the number of characters in this string.
Definition qstring.h:191
void resize(qsizetype size)
Sets the size of the string to size characters.
Definition qstring.cpp:2668
ObjectType::Data * allocate(Args &&... args)
Definition qv4mm_p.h:298
ManagedType::Data * alloc(Args &&... args)
Definition qv4mm_p.h:307
QString str
[2]
QString text
QList< QVariant > arguments
short next
Definition keywords.cpp:445
Scoped< FunctionObject > ScopedFunctionObject
quint64 ReturnedValue
ReturnedValue checkedResult(QV4::ExecutionEngine *v4, ReturnedValue result)
Scoped< String > ScopedString
@ Attr_Invalid
@ Attr_NotConfigurable
@ Attr_NotWritable
constexpr Initialization Uninitialized
static jboolean copy(JNIEnv *, jobject)
static const QCssKnownValue repeats[NumKnownRepeats - 1]
static struct AttrInfo attrs[]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qIsInf(qfloat16 f) noexcept
Definition qfloat16.h:283
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf()
constexpr static Q_DECL_CONST_FUNCTION double qt_qnan() noexcept
Definition qnumeric_p.h:100
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
const GLfloat * m
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLenum target
GLuint start
GLenum GLuint GLintptr offset
GLint first
GLint y
GLhandleARB obj
[2]
GLdouble s
[6]
Definition qopenglext.h:235
const GLubyte * c
GLuint GLfloat * val
GLuint entry
GLenum array
GLint limit
GLint GLenum GLboolean normalized
Definition qopenglext.h:752
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLuint num
GLenum GLenum GLenum input
GLsizei const GLchar *const * string
[0]
Definition qopenglext.h:694
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
int qint32
Definition qtypes.h:49
unsigned int uint
Definition qtypes.h:34
unsigned short ushort
Definition qtypes.h:33
#define Q_ALLOCA_VAR(type, name, size)
Definition qv4alloca_p.h:36
#define CHECK_EXCEPTION()
#define RETURN_RESULT(r)
static Heap::String * thisAsString(ExecutionEngine *v4, const QV4::Value *thisObject)
static QString getThisString(ExecutionEngine *v4, const QV4::Value *thisObject)
static void appendReplacementString(QString *result, const QString &input, const QString &replaceValue, uint *matchOffsets, int captureCount)
#define DEFINE_OBJECT_VTABLE(classname)
args<< 1<< 2;QJSValue threeAgain=fun.call(args);QString fileName="helloworld.qs";QFile scriptFile(fileName);if(!scriptFile.open(QIODevice::ReadOnly)) QTextStream stream(&scriptFile);QString contents=stream.readAll();scriptFile.close();myEngine.evaluate(contents, fileName);myEngine.globalObject().setProperty("myNumber", 123);...QJSValue myNumberPlusOne=myEngine.evaluate("myNumber + 1");QJSValue result=myEngine.evaluate(...);if(result.isError()) qDebug()<< "Uncaught exception at line"<< result.property("lineNumber").toInt()<< ":"<< result.toString();QPushButton *button=new QPushButton;QJSValue scriptButton=myEngine.newQObject(button);myEngine.globalObject().setProperty("button", scriptButton);myEngine.evaluate("button.checkable = true");qDebug()<< scriptButton.property("checkable").toBool();scriptButton.property("show").call();QJSEngine engine;QObject *myQObject=new QObject();myQObject- setProperty)("dynamicProperty", 3)
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
static constexpr ReturnedValue undefined()
Heap::InternalClass * classes[NClasses]
MemoryManager * memoryManager
FunctionObject * regExpCtor() const
ReturnedValue throwRangeError(const Value &value)
Heap::String * newString(char16_t c)
Heap::String * newIdentifier(const QString &text)
String * id_empty() const
Object * objectPrototype() const
Symbol * symbol_match() const
Heap::ArrayObject * newArrayObject(int count=0)
Heap::Object * newStringObject(const String *string)
ReturnedValue throwTypeError()
ReturnedValue callAsConstructor(const Value *argv, int argc, const Value *newTarget=nullptr) const
ReturnedValue asReturnedValue() const
Definition qv4value_p.h:342
Pointer< InternalClass *, 0 > internalClass
Definition qv4heap_p.h:63
Q_REQUIRED_RESULT InternalClass * changePrototype(Heap::Object *proto)
void init(QV4::ExecutionEngine *engine)
ExecutionEngine * engine() const
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
static PropertyKey fromArrayIndex(uint idx)
static double toNumber(const Value &value)
Value * alloc(qint64 nValues) const =delete
bool hasException() const
ExecutionEngine * engine
const SparseArrayNode * nextNode() const
QV4_NEARLY_ALWAYS_INLINE constexpr quint64 rawValue() const
constexpr ReturnedValue asReturnedValue() const
QV4_NEARLY_ALWAYS_INLINE constexpr quint32 value() const
bool isNullOrUndefined() const
bool isUndefined() const
static ReturnedValue method_raw(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_fromCharCode(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_fromCodePoint(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static bool virtualDeleteProperty(Managed *m, PropertyKey id)
static ReturnedValue method_localeCompare(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_concat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleUpperCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_indexOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_includes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_repeat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleLowerCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_padEnd(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLowerCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toUpperCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_charAt(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_replace(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_normalize(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_substr(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_slice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_match(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_codePointAt(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_search(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_split(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_substring(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_trim(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void init(ExecutionEngine *engine, Object *ctor)
static ReturnedValue method_lastIndexOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_charCodeAt(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_startsWith(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_endsWith(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_padStart(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_iterator(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static constexpr VTable::OwnPropertyKeys virtualOwnPropertyKeys
static constexpr VTable::GetOwnProperty virtualGetOwnProperty
static constexpr VTable::CallAsConstructor virtualCallAsConstructor
static constexpr VTable::Call virtualCall
static constexpr VTable::DeleteProperty virtualDeleteProperty
int toUInt16() const
Definition qv4value.cpp:16
static constexpr Value fromInt32(int i)
Definition qv4value_p.h:187
Heap::String * toString(ExecutionEngine *e) const
Definition qv4value_p.h:114
bool isString() const
Definition qv4value_p.h:284
int toInt32() const
Definition qv4value_p.h:353
QML_NEARLY_ALWAYS_INLINE String * stringValue() const
Definition qv4value_p.h:55
static constexpr Value undefinedValue()
Definition qv4value_p.h:191
double toNumber() const
Definition qv4value_p.h:323
const T * as() const
Definition qv4value_p.h:132
QString toQString() const
Definition qv4value.cpp:158
QML_NEARLY_ALWAYS_INLINE Symbol * symbolValue() const
Definition qv4value_p.h:65
bool isSymbol() const
Definition qv4value_p.h:296
double toInteger() const
Definition qv4value_p.h:394
Heap::Object * toObject(ExecutionEngine *e) const
Definition qv4value_p.h:122
static Value fromUInt32(uint i)
Definition qv4value_p.h:203
~StringObjectOwnPropertyKeyIterator() override=default
PropertyKey next(const QV4::Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override