Merge remote-tracking branch 'openharmony/master' into HEAD

Change-Id: I1b6b4e641d78a8d98ef7cf8328b9c3ec3a40c0ac
This commit is contained in:
wengchangcheng 2024-03-18 15:29:39 +08:00
commit 56792fb937
17 changed files with 156 additions and 10 deletions

View File

@ -1490,7 +1490,7 @@ JSTaggedValue BuiltinsArray::Map(EcmaRuntimeCallInfo *argv)
// e. Increase k by 1.
uint32_t k = 0;
uint32_t len = static_cast<uint32_t>(rawLen);
if (thisObjVal->IsStableJSArray(thread) && !thisObjHandle->GetJSHClass()->HasConstructor()) {
if (thisObjVal->IsStableJSArray(thread)) {
JSStableArray::Map(newArrayHandle, thisObjHandle, argv, k, len);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
}

View File

@ -275,7 +275,7 @@ JSTaggedValue BuiltinsArrayBuffer::CloneArrayBuffer(JSThread *thread, const JSHa
{
BUILTINS_API_TRACE(thread, ArrayBuffer, CloneArrayBuffer);
// 1. Assert: Type(srcBuffer) is Object and it has an [[ArrayBufferData]] internal slot.
ASSERT(srcBuffer->IsArrayBuffer() || srcBuffer->IsSharedArrayBuffer());
ASSERT(srcBuffer->IsArrayBuffer() || srcBuffer->IsSharedArrayBuffer() || srcBuffer->IsByteArray());
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
// 2. If cloneConstructor is not present
if (constructor->IsUndefined()) {

View File

@ -17,6 +17,7 @@
#include "ecmascript/base/string_helper.h"
#include "ecmascript/ecma_macros.h"
#include "ecmascript/ecma_string_table.h"
#include "ecmascript/js_iterator.h"
#include "ecmascript/js_string_iterator.h"
#include "ecmascript/js_tagged_number.h"
@ -72,8 +73,13 @@ JSTaggedValue BuiltinsStringIterator::NextInternal(JSThread *thread, JSHandle<JS
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
if (position + 1 == len || first < base::utf_helper::DECODE_LEAD_LOW ||
first > base::utf_helper::DECODE_LEAD_HIGH) {
std::vector<uint16_t> resultString {first, 0x0};
result.Update(factory->NewFromUtf16(resultString.data(), 1).GetTaggedValue());
if (EcmaStringAccessor::CanBeCompressed(&first, 1)) {
JSHandle<SingleCharTable> singleCharTable(thread, thread->GetSingleCharTable());
result.Update(singleCharTable->GetStringFromSingleCharTable(first));
} else {
std::vector<uint16_t> resultString {first, 0x0};
result.Update(factory->NewFromUtf16(resultString.data(), 1).GetTaggedValue());
}
} else {
// 11. Else,
// a. Let second be the code unit value at index position+1 in the String S.

View File

@ -1110,7 +1110,7 @@ JSTaggedValue BuiltinsTypedArray::Set(EcmaRuntimeCallInfo *argv)
}
}
// 9. Let targetBuffer be the value of targets [[ViewedArrayBuffer]] internal slot.
JSHandle<JSTaggedValue> targetBuffer(thread, JSTypedArray::FastGetOffHeapBuffer(thread, targetObj));
JSHandle<JSTaggedValue> targetBuffer(thread, targetObj->GetViewedArrayBufferOrByteArray());
// 10. If IsDetachedBuffer(targetBuffer) is true, throw a TypeError exception.
if (BuiltinsArrayBuffer::IsDetachedBuffer(targetBuffer.GetTaggedValue())) {
THROW_TYPE_ERROR_AND_RETURN(thread, "The targetBuffer of This value is detached buffer.",

View File

@ -114,6 +114,7 @@ namespace panda::ecmascript::kungfu {
#define AOT_AND_BUILTINS_STUB_LIST(V) \
V(LocaleCompare) \
V(STRING_ITERATOR_PROTO_NEXT) \
V(SORT)
#define AOT_BUILTINS_STUB_LIST(V) \
@ -127,7 +128,6 @@ namespace panda::ecmascript::kungfu {
V(TYPED_ARRAY_PROTO_ITERATOR) \
V(MAP_ITERATOR_PROTO_NEXT) \
V(SET_ITERATOR_PROTO_NEXT) \
V(STRING_ITERATOR_PROTO_NEXT) \
V(ARRAY_ITERATOR_PROTO_NEXT) \
V(ITERATOR_PROTO_RETURN)
@ -208,6 +208,7 @@ public:
static bool IsTypedBuiltin(ID builtinId)
{
return (BuiltinsStubCSigns::ID::LocaleCompare == builtinId) ||
(BuiltinsStubCSigns::ID::STRING_ITERATOR_PROTO_NEXT == builtinId) ||
(BuiltinsStubCSigns::ID::SORT == builtinId) ||
((BuiltinsStubCSigns::ID::TYPED_BUILTINS_FIRST <= builtinId) &&
(builtinId <= BuiltinsStubCSigns::ID::TYPED_BUILTINS_LAST));
@ -359,6 +360,7 @@ public:
{"pow", MathPow},
{"floor", FLOOR},
{"localeCompare", LocaleCompare},
{"next", STRING_ITERATOR_PROTO_NEXT},
{"sort", SORT},
{"stringify", STRINGIFY},
};

View File

@ -18,6 +18,7 @@
#include "ecmascript/builtins/builtins_number.h"
#include "ecmascript/compiler/builtins/builtins_stubs.h"
#include "ecmascript/compiler/new_object_stub_builder.h"
#include "ecmascript/js_iterator.h"
#include "ecmascript/js_string_iterator.h"
namespace panda::ecmascript::kungfu {
@ -2170,6 +2171,86 @@ void BuiltinsStringStubBuilder::GetStringIterator(GateRef glue, GateRef thisValu
}
}
void BuiltinsStringStubBuilder::StringIteratorNext(GateRef glue, GateRef thisValue, [[maybe_unused]] GateRef numArgs,
Variable *res, Label *exit, Label *slowPath)
{
auto env = GetEnvironment();
DEFVARIABLE(result, VariableType::JS_POINTER(), Undefined());
Label thisIsHeapObj(env);
Label thisIsStringIterator(env);
Label strNotUndefined(env);
Label strIsHeapObj(env);
Label strIsString(env);
Label iterDone(env);
Branch(TaggedIsHeapObject(thisValue), &thisIsHeapObj, slowPath);
Bind(&thisIsHeapObj);
Branch(TaggedIsStringIterator(thisValue), &thisIsStringIterator, slowPath);
Bind(&thisIsStringIterator);
GateRef str = Load(VariableType::JS_POINTER(), thisValue, IntPtr(JSStringIterator::ITERATED_STRING_OFFSET));
Branch(TaggedIsUndefined(str), &iterDone, &strNotUndefined);
Bind(&strNotUndefined);
Branch(TaggedIsHeapObject(str), &strIsHeapObj, slowPath);
Bind(&strIsHeapObj);
Branch(TaggedIsString(str), &strIsString, slowPath);
Bind(&strIsString);
{
Label getFirst(env);
Label afterFlat(env);
Label getStringFromSingleCharTable(env);
GateRef position = Load(VariableType::INT32(), thisValue,
IntPtr(JSStringIterator::STRING_ITERATOR_NEXT_INDEX_OFFSET));
GateRef len = GetLengthFromString(str);
Branch(Int32GreaterThanOrEqual(position, len), &iterDone, &getFirst);
Bind(&getFirst);
FlatStringStubBuilder strFlat(this);
strFlat.FlattenString(glue, str, &afterFlat);
Bind(&afterFlat);
StringInfoGateRef strInfo(&strFlat);
GateRef first = StringAt(strInfo, position);
GateRef canStoreAsUtf8 = IsASCIICharacter(first);
Branch(canStoreAsUtf8, &getStringFromSingleCharTable, slowPath);
Bind(&getStringFromSingleCharTable);
GateRef singleCharTable = GetSingleCharTable(glue);
GateRef firstStr = GetValueFromTaggedArray(singleCharTable, ZExtInt16ToInt32(first));
Store(VariableType::INT32(), glue, thisValue, IntPtr(JSStringIterator::STRING_ITERATOR_NEXT_INDEX_OFFSET),
Int32Add(position, Int32(1)));
// CreateIterResultObject(firstStr, false)
GateRef iterResultClass = GetGlobalConstantValue(VariableType::JS_POINTER(), glue,
ConstantIndex::ITERATOR_RESULT_CLASS);
Label afterNew(env);
NewObjectStubBuilder newBuilder(this);
newBuilder.SetParameters(glue, 0);
newBuilder.NewJSObject(&result, &afterNew, iterResultClass);
Bind(&afterNew);
SetPropertyInlinedProps(glue, *result, iterResultClass, firstStr,
Int32(JSIterator::VALUE_INLINE_PROPERTY_INDEX));
SetPropertyInlinedProps(glue, *result, iterResultClass, TaggedFalse(),
Int32(JSIterator::DONE_INLINE_PROPERTY_INDEX));
res->WriteVariable(*result);
Jump(exit);
}
Bind(&iterDone);
{
Store(VariableType::JS_POINTER(), glue, thisValue, IntPtr(JSStringIterator::ITERATED_STRING_OFFSET),
Undefined());
// CreateIterResultObject(undefined, true)
GateRef iterResultClass = GetGlobalConstantValue(VariableType::JS_POINTER(), glue,
ConstantIndex::ITERATOR_RESULT_CLASS);
Label afterNew(env);
NewObjectStubBuilder newBuilder(this);
newBuilder.SetParameters(glue, 0);
newBuilder.NewJSObject(&result, &afterNew, iterResultClass);
Bind(&afterNew);
SetPropertyInlinedProps(glue, *result, iterResultClass, Undefined(),
Int32(JSIterator::VALUE_INLINE_PROPERTY_INDEX));
SetPropertyInlinedProps(glue, *result, iterResultClass, TaggedTrue(),
Int32(JSIterator::DONE_INLINE_PROPERTY_INDEX));
res->WriteVariable(*result);
Jump(exit);
}
}
GateRef BuiltinsStringStubBuilder::EcmaStringTrim(GateRef glue, GateRef thisValue, GateRef trimMode)
{
auto env = GetEnvironment();

View File

@ -48,6 +48,8 @@ public:
void EndsWith(GateRef glue, GateRef thisValue, GateRef numArgs, Variable *res, Label *exit, Label *slowPath);
void GetStringIterator(GateRef glue, GateRef thisValue, GateRef numArgs,
Variable *res, Label *exit, Label *slowPath);
void StringIteratorNext(GateRef glue, GateRef thisValue, GateRef numArgs,
Variable *res, Label *exit, Label *slowPath);
GateRef ConvertAndClampRelativeIndex(GateRef index, GateRef length);
GateRef StringAt(const StringInfoGateRef &stringInfoGate, GateRef index);

View File

@ -222,6 +222,24 @@ DECLARE_BUILTINS(GetStringIterator)
Return(*res);
}
DECLARE_BUILTINS(STRING_ITERATOR_PROTO_NEXT)
{
auto env = GetEnvironment();
DEFVARIABLE(res, VariableType::JS_ANY(), Undefined());
Label exit(env);
Label slowPath(env);
BuiltinsStringStubBuilder stringStubBuilder(this);
stringStubBuilder.StringIteratorNext(glue, thisValue, numArgs, &res, &exit, &slowPath);
Bind(&slowPath);
{
auto name = BuiltinsStubCSigns::GetName(BUILTINS_STUB_ID(STRING_ITERATOR_PROTO_NEXT));
res = CallSlowPath(nativeCode, glue, thisValue, numArgs, func, newTarget, name.c_str());
Jump(&exit);
}
Bind(&exit);
Return(*res);
}
BUILTINS_WITH_STRING_STUB_BUILDER(DECLARE_BUILTINS_WITH_STRING_STUB_BUILDER)
#undef DECLARE_BUILTINS_WITH_STRING_STUB_BUILDER

View File

@ -649,6 +649,7 @@ public:
inline GateRef TaggedIsBoolean(GateRef x);
inline GateRef TaggedIsBigInt(GateRef obj);
inline GateRef TaggedIsString(GateRef obj);
inline GateRef TaggedIsStringIterator(GateRef obj);
inline GateRef TaggedIsShared(GateRef obj);
inline GateRef TaggedIsStringOrSymbol(GateRef obj);
inline GateRef TaggedIsSymbol(GateRef obj);

View File

@ -147,6 +147,26 @@ GateRef CircuitBuilder::TaggedIsString(GateRef obj)
return ret;
}
GateRef CircuitBuilder::TaggedIsStringIterator(GateRef obj)
{
Label entry(env_);
SubCfgEntry(&entry);
Label exit(env_);
DEFVALUE(result, env_, VariableType::BOOL(), False());
Label isHeapObject(env_);
Branch(TaggedIsHeapObject(obj), &isHeapObject, &exit);
Bind(&isHeapObject);
{
result = Int32Equal(GetObjectType(LoadHClass(obj)),
Int32(static_cast<int32_t>(JSType::JS_STRING_ITERATOR)));
Jump(&exit);
}
Bind(&exit);
auto ret = *result;
SubCfgExit();
return ret;
}
GateRef CircuitBuilder::TaggedIsShared(GateRef obj)
{
Label entry(env_);

View File

@ -604,6 +604,11 @@ inline GateRef StubBuilder::TaggedIsString(GateRef obj)
return env_->GetBuilder()->TaggedIsString(obj);
}
inline GateRef StubBuilder::TaggedIsStringIterator(GateRef obj)
{
return env_->GetBuilder()->TaggedIsStringIterator(obj);
}
inline GateRef StubBuilder::TaggedIsShared(GateRef obj)
{
return env_->GetBuilder()->TaggedIsShared(obj);

View File

@ -239,6 +239,7 @@ public:
GateRef TaggedIsTransWithProtoHandler(GateRef x);
GateRef TaggedIsTransitionHandler(GateRef x);
GateRef TaggedIsString(GateRef obj);
GateRef TaggedIsStringIterator(GateRef obj);
GateRef TaggedIsShared(GateRef obj);
GateRef BothAreString(GateRef x, GateRef y);
GateRef TaggedIsStringOrSymbol(GateRef obj);

View File

@ -804,7 +804,7 @@ JSTaggedValue JSStableArray::Map(JSHandle<JSObject> newArrayHandle, JSHandle<JSO
JSTaggedValue mapResult = JSFunction::Call(info);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
mapResultHandle.Update(mapResult);
ElementAccessor::Set(thread, newArrayHandle, k, mapResultHandle, true);
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, k, mapResultHandle);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
if (ElementAccessor::GetElementsLength(thisObjHandle) < len) {
len = ElementAccessor::GetElementsLength(thisObjHandle);

View File

@ -89,7 +89,8 @@ void PageProtect(void *mem, size_t size, int prot)
{
int ret = mprotect(mem, size, prot);
if (ret != 0) {
LOG_ECMA(ERROR) << "PageProtect change to " << prot << " failed, error code is " << errno;
LOG_ECMA(ERROR) << "PageProtect mem = " << mem << ", size = " << size <<
", change to " << prot << " failed, ret = " << ret << ", error code is " << errno;
}
}

View File

@ -101,7 +101,8 @@ void PageProtect(void *mem, size_t size, int prot)
[[maybe_unused]] DWORD oldProtect;
if (!VirtualProtect(mem, size, prot, &oldProtect)) {
int errCode = GetLastError();
LOG_ECMA(ERROR) << "PageProtect change to " << prot << " failed, error code is " << errCode;
LOG_ECMA(ERROR) << "PageProtect mem = " << mem << ", size = " << size <<
", change to " << prot << " failed, error code is " << errCode;
}
}

View File

@ -87,6 +87,7 @@ false
true
undefined
true
true
false
@ -94,3 +95,4 @@ true
false
true
true
sub_string test success!

View File

@ -248,6 +248,7 @@ const iter = str7[Symbol.iterator]();
print(iter.next().value);
print(iter.next().value);
print(iter.next().done);
print(iter.next().value);
const str_endsWith1 = 'this is a test for string endsWith!';
print(str_endsWith1.endsWith('string', '25')); // true
@ -256,4 +257,9 @@ print(str_endsWith1.endsWith('endsWith!', 25)); // false
print(str_endsWith1.endsWith('endsWith!')); // true
print(str_endsWith1.endsWith('endsWith!', -1)); // false
print(str_endsWith1.endsWith('endsWith!', 100)); // true
print(str_endsWith1.endsWith('string', 25.3)); // true
print(str_endsWith1.endsWith('string', 25.3)); // true
let arr = Array(14);
let tree_str = arr + 512;
tree_str.substring(0,arr.length);
print("sub_string test success!");