mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 01:59:58 +00:00
!10331 修复Lazy import场景下,异步任务执行时序不对的问题
Merge pull request !10331 from wangchen/LdLazyModuleVar
This commit is contained in:
commit
973daf8287
@ -124,6 +124,23 @@ public:
|
||||
|
||||
bool ExecutePromisePendingJob();
|
||||
|
||||
bool IsInPendingJob() const
|
||||
{
|
||||
return pendingJobEnterCount > 0;
|
||||
}
|
||||
|
||||
void AddPendingJobEnterCount()
|
||||
{
|
||||
ASSERT(pendingJobEnterCount < std::numeric_limits<uint64_t>::max());
|
||||
++pendingJobEnterCount;
|
||||
}
|
||||
|
||||
void MinusPendingJobEnterCount()
|
||||
{
|
||||
ASSERT(IsInPendingJob());
|
||||
--pendingJobEnterCount;
|
||||
}
|
||||
|
||||
static EcmaContext *ConstCast(const EcmaContext *context)
|
||||
{
|
||||
return const_cast<EcmaContext *>(context);
|
||||
@ -780,6 +797,8 @@ private:
|
||||
|
||||
bool hasKeptObjects_ {false};
|
||||
|
||||
uint64_t pendingJobEnterCount {0};
|
||||
|
||||
friend class EcmaHandleScope;
|
||||
friend class JSPandaFileExecutor;
|
||||
friend class ObjectFactory;
|
||||
|
@ -20,8 +20,19 @@
|
||||
#include "ecmascript/js_tagged_value-inl.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/tagged_queue.h"
|
||||
#include "ecmascript/ecma_context.h"
|
||||
|
||||
namespace panda::ecmascript::job {
|
||||
MicroJobScope::MicroJobScope(JSThread* thread) : thread_(thread)
|
||||
{
|
||||
thread_->GetCurrentEcmaContext()->AddPendingJobEnterCount();
|
||||
}
|
||||
|
||||
MicroJobScope::~MicroJobScope()
|
||||
{
|
||||
thread_->GetCurrentEcmaContext()->MinusPendingJobEnterCount();
|
||||
}
|
||||
|
||||
uint32_t MicroJobQueue::GetPromiseQueueSize(JSThread *thread, JSHandle<MicroJobQueue> jobQueue)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
@ -58,6 +69,7 @@ void MicroJobQueue::EnqueueJob(JSThread *thread, JSHandle<MicroJobQueue> jobQueu
|
||||
void MicroJobQueue::ExecutePendingJob(JSThread *thread, JSHandle<MicroJobQueue> jobQueue)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
[[maybe_unused]] MicroJobScope microJobScope(thread);
|
||||
JSMutableHandle<TaggedQueue> promiseQueue(thread, jobQueue->GetPromiseJobQueue());
|
||||
JSMutableHandle<PendingJob> pendingJob(thread, JSTaggedValue::Undefined());
|
||||
while (!promiseQueue->Empty()) {
|
||||
|
@ -23,7 +23,13 @@
|
||||
#include "ecmascript/tagged_array.h"
|
||||
|
||||
namespace panda::ecmascript::job {
|
||||
|
||||
class MicroJobScope {
|
||||
public:
|
||||
explicit MicroJobScope(JSThread *thread);
|
||||
~MicroJobScope();
|
||||
private:
|
||||
JSThread *thread_;
|
||||
};
|
||||
class MicroJobQueue final : public Record {
|
||||
public:
|
||||
static MicroJobQueue *Cast(TaggedObject *object)
|
||||
|
@ -181,7 +181,7 @@ JSTaggedValue ModuleManager::GetLazyModuleValueOutterInternal(int32_t index, JST
|
||||
if (resolvedBinding.IsResolvedIndexBinding()) {
|
||||
JSHandle<ResolvedIndexBinding> binding(thread, resolvedBinding);
|
||||
JSTaggedValue resolvedModule = binding->GetModule();
|
||||
JSHandle<SourceTextModule> module(thread, resolvedModule);
|
||||
JSMutableHandle<SourceTextModule> module(thread, resolvedModule);
|
||||
ASSERT(resolvedModule.IsSourceTextModule());
|
||||
// Support for only modifying var value of HotReload.
|
||||
// Cause patchFile exclude the record of importing modifying var. Can't reresolve moduleRecord.
|
||||
@ -191,13 +191,12 @@ JSTaggedValue ModuleManager::GetLazyModuleValueOutterInternal(int32_t index, JST
|
||||
context->FindPatchModule(module->GetEcmaModuleRecordNameString());
|
||||
if (!resolvedModuleOfHotReload->IsHole()) {
|
||||
resolvedModule = resolvedModuleOfHotReload.GetTaggedValue();
|
||||
JSHandle<SourceTextModule> moduleOfHotReload(thread, resolvedModule);
|
||||
SourceTextModule::Evaluate(thread, moduleOfHotReload, nullptr);
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
|
||||
return ModuleManagerHelper::GetModuleValue(thread, moduleOfHotReload, binding->GetIndex());
|
||||
module.Update(resolvedModule);
|
||||
}
|
||||
}
|
||||
SourceTextModule::Evaluate(thread, module, nullptr);
|
||||
if (module->GetStatus() != ModuleStatus::EVALUATED) {
|
||||
SourceTextModule::Evaluate(thread, module, nullptr, 0, context->IsInPendingJob());
|
||||
}
|
||||
RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
|
||||
return ModuleManagerHelper::GetModuleValue(thread, module, binding->GetIndex());
|
||||
}
|
||||
|
60
test/moduletest/moduleLazyImport/asyncUseLazyImport.ts
Normal file
60
test/moduletest/moduleLazyImport/asyncUseLazyImport.ts
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @tc.name:asyncUseLazyImport
|
||||
* @tc.desc:test asyncUseLazyImport
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issue#IB2HNC
|
||||
*/
|
||||
|
||||
// @ts-nocheck
|
||||
import lazy { TestLazy } from './lazyExport';
|
||||
export class Test {
|
||||
async start() {
|
||||
this.log(` Test start`)
|
||||
let a = await this.mapAsync([1, 2], async (t) => {
|
||||
await this.bindRawData(t)
|
||||
})
|
||||
this.log(` Test end ${new Error().stack}`)
|
||||
return a
|
||||
}
|
||||
private async bindRawData(t: number) {
|
||||
await this.mapAsync([1, 2], async (k, b) => {
|
||||
this.onBindRawData(t, k)
|
||||
})
|
||||
await this.mapAsync([4, 5], async (k, b) => {
|
||||
this.onBindRawData(t, k)
|
||||
})
|
||||
await this.mapAsync([7, 8], async (k, b) => {
|
||||
this.onBindRawData(t, k)
|
||||
})
|
||||
}
|
||||
async mapAsync<T, U>(array: T[], map: (t: T, index: number) => Promise<U>) {
|
||||
return await Promise.all(array.map(map))
|
||||
}
|
||||
private async onBindRawData(t: number, k: number) {
|
||||
this.log(` onBindRawData start ${t} ${k}`)
|
||||
await this.isSelf()
|
||||
this.log(` onBindRawData end ${t} ${k}`)
|
||||
}
|
||||
private async isSelf(): Promise<boolean> {
|
||||
return "1" == "1"
|
||||
}
|
||||
log(msg: string) {
|
||||
TestLazy
|
||||
print(msg)
|
||||
}
|
||||
}
|
@ -30,3 +30,30 @@ this is dynamicLazySequence
|
||||
this is dynamicSubFile
|
||||
this is dynamicLazySequence2
|
||||
dynamicSubFile
|
||||
Test start
|
||||
onBindRawData start 1 1
|
||||
onBindRawData start 1 2
|
||||
onBindRawData start 2 1
|
||||
onBindRawData start 2 2
|
||||
onBindRawData end 1 1
|
||||
onBindRawData end 1 2
|
||||
onBindRawData end 2 1
|
||||
onBindRawData end 2 2
|
||||
onBindRawData start 1 4
|
||||
onBindRawData start 1 5
|
||||
onBindRawData start 2 4
|
||||
onBindRawData start 2 5
|
||||
onBindRawData end 1 4
|
||||
onBindRawData end 1 5
|
||||
onBindRawData end 2 4
|
||||
onBindRawData end 2 5
|
||||
onBindRawData start 1 7
|
||||
onBindRawData start 1 8
|
||||
onBindRawData start 2 7
|
||||
onBindRawData start 2 8
|
||||
onBindRawData end 1 7
|
||||
onBindRawData end 1 8
|
||||
onBindRawData end 2 7
|
||||
onBindRawData end 2 8
|
||||
Test end at start (asyncUseLazyImport.ts:31:1)
|
||||
|
||||
|
24
test/moduletest/moduleLazyImport/lazyExport.js
Normal file
24
test/moduletest/moduleLazyImport/lazyExport.js
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @tc.name:asyncUseLazyImport
|
||||
* @tc.desc:test asyncUseLazyImport
|
||||
* @tc.type: FUNC
|
||||
* @tc.require: issue#IB2HNC
|
||||
*/
|
||||
|
||||
// @ts-nocheck
|
||||
export class TestLazy {}
|
@ -25,6 +25,7 @@ import { aaa } from "./E"
|
||||
import lazy {func1} from './F'
|
||||
import lazy {dynamicLazySequence} from './dynamicLazySequence'
|
||||
import lazy {dynamicLazySequence2} from './dynamicLazySequence2'
|
||||
import {Test} from './asyncUseLazyImport'
|
||||
|
||||
print("this is entry");
|
||||
func1();
|
||||
@ -35,4 +36,5 @@ print(h);
|
||||
import("./dynamicLazySequence").then((ns) => {
|
||||
print(ns.dynamicLazySequence);
|
||||
})
|
||||
import("./dynamicLazySequence2");
|
||||
import("./dynamicLazySequence2");
|
||||
new Test().start()
|
@ -9,4 +9,6 @@ H.js;H;esm;H.js;xxHxx
|
||||
dynamicLazySequence.js;dynamicLazySequence;esm;dynamicLazySequence.js;xxdynamicLazySequencexx
|
||||
dynamicLazySequence2.js;dynamicLazySequence2;esm;dynamicLazySequence2.js;xxdynamicLazySequence2xx
|
||||
dynamicSubFile.js;dynamicSubFile;esm;dynamicSubFile.js;xxdynamicSubFilexx
|
||||
moduleLazyImport.js;moduleLazyImport;esm;moduleLazyImport.js;xxmoduleLazyImportxx
|
||||
moduleLazyImport.js;moduleLazyImport;esm;moduleLazyImport.js;xxmoduleLazyImportxx
|
||||
asyncUseLazyImport.ts;asyncUseLazyImport;esm;asyncUseLazyImport.ts;xxasyncUseLazyImportxx
|
||||
lazyExport.js;lazyExport;esm;lazyExport.js;xxlazyExportxx
|
Loading…
Reference in New Issue
Block a user