зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central. a=merge
This commit is contained in:
Коммит
df9ab52a72
|
@ -112,6 +112,7 @@ struct BlobItemData
|
|||
Matrix mMatrix; // updated to track the current transform to device space
|
||||
Matrix4x4Flagged mTransform; // only used with nsDisplayTransform items to detect transform changes
|
||||
float mOpacity; // only used with nsDisplayOpacity items to detect change to opacity
|
||||
RefPtr<BasicLayerManager> mLayerManager;
|
||||
|
||||
IntRect mImageRect;
|
||||
LayerIntPoint mGroupOffset;
|
||||
|
@ -449,7 +450,7 @@ struct DIGroup
|
|||
GP("mRect %d %d %d %d\n", aData->mRect.x, aData->mRect.y, aData->mRect.width, aData->mRect.height);
|
||||
InvalidateRect(aData->mRect);
|
||||
aData->mInvalid = true;
|
||||
} else if (/*aData->mIsInvalid || XXX: handle image load invalidation */ (aItem->IsInvalid(invalid) && invalid.IsEmpty())) {
|
||||
} else if (aData->mInvalid || /* XXX: handle image load invalidation */ (aItem->IsInvalid(invalid) && invalid.IsEmpty())) {
|
||||
MOZ_RELEASE_ASSERT(imageRect.IsEqualEdges(aData->mImageRect));
|
||||
MOZ_RELEASE_ASSERT(mLayerBounds.TopLeft() == aData->mGroupOffset);
|
||||
UniquePtr<nsDisplayItemGeometry> geometry(aItem->AllocateGeometry(aBuilder));
|
||||
|
@ -806,6 +807,32 @@ struct DIGroup
|
|||
}
|
||||
};
|
||||
|
||||
// If we have an item we need to make sure it matches the current group
|
||||
// otherwise it means the item switched groups and we need to invalidate
|
||||
// it and recreate the data.
|
||||
static BlobItemData*
|
||||
GetBlobItemDataForGroup(nsDisplayItem* aItem, DIGroup* aGroup)
|
||||
{
|
||||
BlobItemData* data = GetBlobItemData(aItem);
|
||||
if (data) {
|
||||
MOZ_RELEASE_ASSERT(data->mGroup->mDisplayItems.Contains(data));
|
||||
if (data->mGroup != aGroup) {
|
||||
GP("group don't match %p %p\n", data->mGroup, aGroup);
|
||||
data->ClearFrame();
|
||||
// the item is for another group
|
||||
// it should be cleared out as being unused at the end of this paint
|
||||
data = nullptr;
|
||||
}
|
||||
}
|
||||
if (!data) {
|
||||
GP("Allocating blob data\n");
|
||||
data = new BlobItemData(aGroup, aItem);
|
||||
aGroup->mDisplayItems.PutEntry(data);
|
||||
}
|
||||
data->mUsed = true;
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
Grouper::PaintContainerItem(DIGroup* aGroup, nsDisplayItem* aItem, const IntRect& aItemBounds,
|
||||
nsDisplayList* aChildren, gfxContext* aContext,
|
||||
|
@ -872,26 +899,32 @@ Grouper::PaintContainerItem(DIGroup* aGroup, nsDisplayItem* aItem, const IntRect
|
|||
GP("Paint Mask\n");
|
||||
// We don't currently support doing invalidation inside nsDisplayMask
|
||||
// for now just paint it as a single item
|
||||
gfx::Size scale(1, 1);
|
||||
RefPtr<BasicLayerManager> blm = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
|
||||
PaintByLayer(aItem, mDisplayListBuilder, blm, aContext, scale, [&]() {
|
||||
static_cast<nsDisplayMask*>(aItem)->PaintAsLayer(mDisplayListBuilder,
|
||||
aContext, blm);
|
||||
});
|
||||
aContext->GetDrawTarget()->FlushItem(aItemBounds);
|
||||
BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
|
||||
if (data->mLayerManager->GetRoot()) {
|
||||
data->mLayerManager->BeginTransaction();
|
||||
static_cast<nsDisplayMask*>(aItem)->PaintAsLayer(mDisplayListBuilder,
|
||||
aContext, data->mLayerManager);
|
||||
if (data->mLayerManager->InTransaction()) {
|
||||
data->mLayerManager->AbortTransaction();
|
||||
}
|
||||
aContext->GetDrawTarget()->FlushItem(aItemBounds);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DisplayItemType::TYPE_FILTER: {
|
||||
GP("Paint Filter\n");
|
||||
// We don't currently support doing invalidation inside nsDisplayFilter
|
||||
// for now just paint it as a single item
|
||||
RefPtr<BasicLayerManager> blm = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
|
||||
gfx::Size scale(1, 1);
|
||||
PaintByLayer(aItem, mDisplayListBuilder, blm, aContext, scale, [&]() {
|
||||
static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(mDisplayListBuilder,
|
||||
aContext, blm);
|
||||
});
|
||||
aContext->GetDrawTarget()->FlushItem(aItemBounds);
|
||||
BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
|
||||
if (data->mLayerManager->GetRoot()) {
|
||||
data->mLayerManager->BeginTransaction();
|
||||
static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(mDisplayListBuilder,
|
||||
aContext, data->mLayerManager);
|
||||
if (data->mLayerManager->InTransaction()) {
|
||||
data->mLayerManager->AbortTransaction();
|
||||
}
|
||||
aContext->GetDrawTarget()->FlushItem(aItemBounds);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -965,32 +998,6 @@ IsItemProbablyActive(nsDisplayItem* aItem, nsDisplayListBuilder* aDisplayListBui
|
|||
}
|
||||
}
|
||||
|
||||
// If we have an item we need to make sure it matches the current group
|
||||
// otherwise it means the item switched groups and we need to invalidate
|
||||
// it and recreate the data.
|
||||
static BlobItemData*
|
||||
GetBlobItemDataForGroup(nsDisplayItem* aItem, DIGroup* aGroup)
|
||||
{
|
||||
BlobItemData* data = GetBlobItemData(aItem);
|
||||
if (data) {
|
||||
MOZ_RELEASE_ASSERT(data->mGroup->mDisplayItems.Contains(data));
|
||||
if (data->mGroup != aGroup) {
|
||||
GP("group don't match %p %p\n", data->mGroup, aGroup);
|
||||
data->ClearFrame();
|
||||
// the item is for another group
|
||||
// it should be cleared out as being unused at the end of this paint
|
||||
data = nullptr;
|
||||
}
|
||||
}
|
||||
if (!data) {
|
||||
GP("Allocating blob data\n");
|
||||
data = new BlobItemData(aGroup, aItem);
|
||||
aGroup->mDisplayItems.PutEntry(data);
|
||||
}
|
||||
data->mUsed = true;
|
||||
return data;
|
||||
}
|
||||
|
||||
// This does a pass over the display lists and will join the display items
|
||||
// into groups as well as paint them
|
||||
void
|
||||
|
@ -1076,6 +1083,10 @@ Grouper::ConstructGroupInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
|
|||
}
|
||||
}
|
||||
|
||||
bool BuildLayer(nsDisplayItem* aItem, BlobItemData* aData,
|
||||
nsDisplayListBuilder* aDisplayListBuilder,
|
||||
const gfx::Size& aScale);
|
||||
|
||||
void
|
||||
Grouper::ConstructItemInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
|
@ -1084,8 +1095,15 @@ Grouper::ConstructItemInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
|
|||
const StackingContextHelper& aSc)
|
||||
{
|
||||
nsDisplayList* children = aItem->GetChildren();
|
||||
BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
|
||||
|
||||
if (aItem->GetType() == DisplayItemType::TYPE_TRANSFORM) {
|
||||
if (aItem->GetType() == DisplayItemType::TYPE_FILTER ||
|
||||
aItem->GetType() == DisplayItemType::TYPE_MASK) {
|
||||
gfx::Size scale(1, 1);
|
||||
// If ComputeDifferences finds any change, we invalidate the entire container item.
|
||||
// This is needed because blob merging requires the entire item to be within the invalid region.
|
||||
data->mInvalid = BuildLayer(aItem, data, mDisplayListBuilder, scale);
|
||||
} else if (aItem->GetType() == DisplayItemType::TYPE_TRANSFORM) {
|
||||
nsDisplayTransform* transformItem = static_cast<nsDisplayTransform*>(aItem);
|
||||
const Matrix4x4Flagged& t = transformItem->GetTransform();
|
||||
Matrix t2d;
|
||||
|
@ -1101,12 +1119,13 @@ Grouper::ConstructItemInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
|
|||
|
||||
mTransform = m;
|
||||
} else if (children) {
|
||||
sIndent++;
|
||||
ConstructGroupInsideInactive(aCommandBuilder, aBuilder, aResources, aGroup, children, aSc);
|
||||
sIndent--;
|
||||
}
|
||||
|
||||
GP("Including %s of %d\n", aItem->Name(), aGroup->mDisplayItems.Count());
|
||||
|
||||
BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
|
||||
aGroup->ComputeGeometryChange(aItem, data, mTransform, mDisplayListBuilder); // we compute the geometry change here because we have the transform around still
|
||||
}
|
||||
|
||||
|
@ -1556,6 +1575,50 @@ WebRenderCommandBuilder::PushImage(nsDisplayItem* aItem,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BuildLayer(nsDisplayItem* aItem,
|
||||
BlobItemData* aData,
|
||||
nsDisplayListBuilder* aDisplayListBuilder,
|
||||
const gfx::Size& aScale)
|
||||
{
|
||||
if (!aData->mLayerManager) {
|
||||
aData->mLayerManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
|
||||
}
|
||||
RefPtr<BasicLayerManager> blm = aData->mLayerManager;
|
||||
UniquePtr<LayerProperties> props;
|
||||
if (blm->GetRoot()) {
|
||||
props = LayerProperties::CloneFrom(blm->GetRoot());
|
||||
}
|
||||
FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
|
||||
layerBuilder->Init(aDisplayListBuilder, blm, nullptr, true);
|
||||
layerBuilder->DidBeginRetainedLayerTransaction(blm);
|
||||
|
||||
blm->BeginTransaction();
|
||||
bool isInvalidated = false;
|
||||
|
||||
ContainerLayerParameters param(aScale.width, aScale.height);
|
||||
RefPtr<Layer> root = aItem->BuildLayer(aDisplayListBuilder, blm, param);
|
||||
|
||||
if (root) {
|
||||
blm->SetRoot(root);
|
||||
layerBuilder->WillEndTransaction();
|
||||
|
||||
// Check if there is any invalidation region.
|
||||
nsIntRegion invalid;
|
||||
if (props) {
|
||||
props->ComputeDifferences(root, invalid, nullptr);
|
||||
if (!invalid.IsEmpty()) {
|
||||
isInvalidated = true;
|
||||
}
|
||||
} else {
|
||||
isInvalidated = true;
|
||||
}
|
||||
}
|
||||
blm->AbortTransaction();
|
||||
|
||||
return isInvalidated;
|
||||
}
|
||||
|
||||
static bool
|
||||
PaintByLayer(nsDisplayItem* aItem,
|
||||
nsDisplayListBuilder* aDisplayListBuilder,
|
||||
|
|
|
@ -239,6 +239,8 @@ DeleteBlobFont(WrFontInstanceKey aKey)
|
|||
}
|
||||
}
|
||||
|
||||
} // extern
|
||||
|
||||
static RefPtr<UnscaledFont>
|
||||
GetUnscaledFont(Translator* aTranslator, WrFontKey aKey)
|
||||
{
|
||||
|
@ -455,6 +457,11 @@ static bool Moz2DRenderCallback(const Range<const uint8_t> aBlob,
|
|||
return ret;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
bool wr_moz2d_render_cb(const mozilla::wr::ByteSlice blob,
|
||||
uint32_t width, uint32_t height,
|
||||
mozilla::wr::ImageFormat aFormat,
|
||||
|
@ -474,6 +481,3 @@ bool wr_moz2d_render_cb(const mozilla::wr::ByteSlice blob,
|
|||
|
||||
} // extern
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -107,29 +107,29 @@ BinASTParserBase::~BinASTParserBase()
|
|||
// ------------- Toplevel constructions
|
||||
|
||||
template<typename Tok> JS::Result<ParseNode*>
|
||||
BinASTParser<Tok>::parse(const Vector<uint8_t>& data)
|
||||
BinASTParser<Tok>::parse(GlobalSharedContext* globalsc, const Vector<uint8_t>& data)
|
||||
{
|
||||
return parse(data.begin(), data.length());
|
||||
return parse(globalsc, data.begin(), data.length());
|
||||
}
|
||||
|
||||
template<typename Tok> JS::Result<ParseNode*>
|
||||
BinASTParser<Tok>::parse(const uint8_t* start, const size_t length)
|
||||
BinASTParser<Tok>::parse(GlobalSharedContext* globalsc, const uint8_t* start, const size_t length)
|
||||
{
|
||||
auto result = parseAux(start, length);
|
||||
auto result = parseAux(globalsc, start, length);
|
||||
poison(); // Make sure that the parser is never used again accidentally.
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<typename Tok> JS::Result<ParseNode*>
|
||||
BinASTParser<Tok>::parseAux(const uint8_t* start, const size_t length)
|
||||
BinASTParser<Tok>::parseAux(GlobalSharedContext* globalsc,
|
||||
const uint8_t* start, const size_t length)
|
||||
{
|
||||
MOZ_ASSERT(globalsc);
|
||||
|
||||
tokenizer_.emplace(cx_, start, length);
|
||||
|
||||
Directives directives(options().strictOption);
|
||||
GlobalSharedContext globalsc(cx_, ScopeKind::Global,
|
||||
directives, options().extraWarningsOption);
|
||||
BinParseContext globalpc(cx_, this, &globalsc, /* newDirectives = */ nullptr);
|
||||
BinParseContext globalpc(cx_, this, globalsc, /* newDirectives = */ nullptr);
|
||||
if (!globalpc.init())
|
||||
return cx_->alreadyReportedError();
|
||||
|
||||
|
@ -146,7 +146,7 @@ BinASTParser<Tok>::parseAux(const uint8_t* start, const size_t length)
|
|||
parseContext_);
|
||||
if (!bindings)
|
||||
return cx_->alreadyReportedError();
|
||||
globalsc.bindings = *bindings;
|
||||
globalsc->bindings = *bindings;
|
||||
|
||||
return result; // Magic conversion to Ok.
|
||||
}
|
||||
|
|
|
@ -124,11 +124,13 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
|
|||
*
|
||||
* In case of error, the parser reports the JS error.
|
||||
*/
|
||||
JS::Result<ParseNode*> parse(const uint8_t* start, const size_t length);
|
||||
JS::Result<ParseNode*> parse(const Vector<uint8_t>& data);
|
||||
JS::Result<ParseNode*> parse(GlobalSharedContext* globalsc,
|
||||
const uint8_t* start, const size_t length);
|
||||
JS::Result<ParseNode*> parse(GlobalSharedContext* globalsc, const Vector<uint8_t>& data);
|
||||
|
||||
private:
|
||||
MOZ_MUST_USE JS::Result<ParseNode*> parseAux(const uint8_t* start, const size_t length);
|
||||
MOZ_MUST_USE JS::Result<ParseNode*> parseAux(GlobalSharedContext* globalsc,
|
||||
const uint8_t* start, const size_t length);
|
||||
|
||||
// --- Raise errors.
|
||||
//
|
||||
|
|
|
@ -641,16 +641,17 @@ frontend::CompileGlobalBinASTScript(JSContext* cx, LifoAlloc& alloc, const ReadO
|
|||
if (!script)
|
||||
return nullptr;
|
||||
|
||||
Directives directives(options.strictOption);
|
||||
GlobalSharedContext globalsc(cx, ScopeKind::Global, directives, options.extraWarningsOption);
|
||||
|
||||
frontend::BinASTParser<BinTokenReaderMultipart> parser(cx, alloc, usedNames, options);
|
||||
|
||||
auto parsed = parser.parse(src, len);
|
||||
auto parsed = parser.parse(&globalsc, src, len);
|
||||
|
||||
if (parsed.isErr())
|
||||
return nullptr;
|
||||
|
||||
Directives dir(false);
|
||||
GlobalSharedContext sc(cx, ScopeKind::Global, dir, false);
|
||||
BytecodeEmitter bce(nullptr, &parser, &sc, script, nullptr, 0);
|
||||
BytecodeEmitter bce(nullptr, &parser, &globalsc, script, nullptr, 0);
|
||||
|
||||
if (!bce.init())
|
||||
return nullptr;
|
||||
|
|
|
@ -36,6 +36,8 @@ testBinASTReaderInit(int *argc, char ***argv) {
|
|||
|
||||
static int
|
||||
testBinASTReaderFuzz(const uint8_t* buf, size_t size) {
|
||||
using namespace js::frontend;
|
||||
|
||||
auto gcGuard = mozilla::MakeScopeExit([&] {
|
||||
JS::PrepareForFullGC(gCx);
|
||||
JS::NonIncrementalGC(gCx, GC_NORMAL, JS::gcreason::API);
|
||||
|
@ -53,12 +55,16 @@ testBinASTReaderFuzz(const uint8_t* buf, size_t size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
js::frontend::UsedNameTracker binUsedNames(gCx);
|
||||
UsedNameTracker binUsedNames(gCx);
|
||||
|
||||
js::frontend::BinASTParser<js::frontend::BinTokenReaderTester> reader(gCx, gCx->tempLifoAlloc(), binUsedNames, options);
|
||||
Directives directives(false);
|
||||
GlobalSharedContext globalsc(gCx, ScopeKind::Global, directives, false);
|
||||
|
||||
BinASTParser<js::frontend::BinTokenReaderTester> reader(gCx, gCx->tempLifoAlloc(),
|
||||
binUsedNames, options);
|
||||
|
||||
// Will be deallocated once `reader` goes out of scope.
|
||||
auto binParsed = reader.parse(binSource);
|
||||
auto binParsed = reader.parse(&globalsc, binSource);
|
||||
RootedValue binExn(gCx);
|
||||
if (binParsed.isErr()) {
|
||||
js::GetAndClearException(gCx, &binExn);
|
||||
|
|
|
@ -202,11 +202,14 @@ runTestFromPath(JSContext* cx, const char* path)
|
|||
CompileOptions binOptions(cx);
|
||||
binOptions.setFileAndLine(binPath.begin(), 0);
|
||||
|
||||
js::frontend::UsedNameTracker binUsedNames(cx);
|
||||
frontend::UsedNameTracker binUsedNames(cx);
|
||||
|
||||
js::frontend::BinASTParser<Tok> binParser(cx, allocScope.alloc(), binUsedNames, binOptions);
|
||||
frontend::Directives directives(false);
|
||||
frontend::GlobalSharedContext globalsc(cx, ScopeKind::Global, directives, false);
|
||||
|
||||
auto binParsed = binParser.parse(binSource); // Will be deallocated once `reader` goes out of scope.
|
||||
frontend::BinASTParser<Tok> binParser(cx, allocScope.alloc(), binUsedNames, binOptions);
|
||||
|
||||
auto binParsed = binParser.parse(&globalsc, binSource); // Will be deallocated once `reader` goes out of scope.
|
||||
RootedValue binExn(cx);
|
||||
if (binParsed.isErr()) {
|
||||
// Save exception for more detailed error message, if necessary.
|
||||
|
|
|
@ -4697,11 +4697,39 @@ GetModuleObject(JSContext* cx, unsigned argc, Value* vp)
|
|||
|
||||
#if defined(JS_BUILD_BINAST)
|
||||
|
||||
using js::frontend::BinASTParser;
|
||||
using js::frontend::Directives;
|
||||
using js::frontend::GlobalSharedContext;
|
||||
using js::frontend::ParseNode;
|
||||
using js::frontend::UsedNameTracker;
|
||||
|
||||
template <typename Tok>
|
||||
static bool
|
||||
ParseBinASTData(JSContext* cx, uint8_t* buf_data, uint32_t buf_length,
|
||||
GlobalSharedContext* globalsc, UsedNameTracker& usedNames,
|
||||
const JS::ReadOnlyCompileOptions& options)
|
||||
{
|
||||
MOZ_ASSERT(globalsc);
|
||||
|
||||
// Note: We need to keep `reader` alive as long as we can use `parsed`.
|
||||
BinASTParser<Tok> reader(cx, cx->tempLifoAlloc(), usedNames, options);
|
||||
|
||||
JS::Result<ParseNode*> parsed = reader.parse(globalsc, buf_data, buf_length);
|
||||
|
||||
if (parsed.isErr())
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
Fprinter out(stderr);
|
||||
DumpParseTree(parsed.unwrap(), out);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
BinParse(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
using namespace js::frontend;
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (args.length() < 1) {
|
||||
|
@ -4782,35 +4810,13 @@ BinParse(JSContext* cx, unsigned argc, Value* vp)
|
|||
|
||||
UsedNameTracker usedNames(cx);
|
||||
|
||||
JS::Result<ParseNode*> parsed(nullptr);
|
||||
if (useMultipart) {
|
||||
// Note: We need to keep `reader` alive as long as we can use `parsed`.
|
||||
BinASTParser<BinTokenReaderMultipart> reader(cx, cx->tempLifoAlloc(), usedNames, options);
|
||||
Directives directives(false);
|
||||
GlobalSharedContext globalsc(cx, ScopeKind::Global, directives, false);
|
||||
|
||||
parsed = reader.parse(buf_data, buf_length);
|
||||
|
||||
if (parsed.isErr())
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
Fprinter out(stderr);
|
||||
DumpParseTree(parsed.unwrap(), out);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
// Note: We need to keep `reader` alive as long as we can use `parsed`.
|
||||
BinASTParser<BinTokenReaderTester> reader(cx, cx->tempLifoAlloc(), usedNames, options);
|
||||
|
||||
parsed = reader.parse(buf_data, buf_length);
|
||||
|
||||
if (parsed.isErr())
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
Fprinter out(stderr);
|
||||
DumpParseTree(parsed.unwrap(), out);
|
||||
#endif
|
||||
}
|
||||
auto parseFunc = useMultipart ? ParseBinASTData<frontend::BinTokenReaderMultipart>
|
||||
: ParseBinASTData<frontend::BinTokenReaderTester>;
|
||||
if (!parseFunc(cx, buf_data, buf_length, &globalsc, usedNames, options))
|
||||
return false;
|
||||
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
|
|
|
@ -172,7 +172,7 @@ def check_nsmodules(target, binary):
|
|||
raise Skip()
|
||||
symbols = []
|
||||
if buildconfig.substs.get('_MSC_VER'):
|
||||
for line in get_output('dumpbin', '-exports', binary):
|
||||
for line in get_output('dumpbin.exe', '-exports', binary):
|
||||
data = line.split(None, 3)
|
||||
if data and len(data) == 4 and data[0].isdigit() and \
|
||||
ishex(data[1]) and ishex(data[2]):
|
||||
|
|
|
@ -425,7 +425,9 @@ class Linkable(ContextDerived):
|
|||
# The '$' check is here as a special temporary rule, allowing the
|
||||
# inherited use of make variables, most notably in TK_LIBS.
|
||||
if not lib.startswith('$') and not lib.startswith('-'):
|
||||
if self.config.substs.get('GNU_CC'):
|
||||
type_var = 'HOST_CC_TYPE' if self.KIND == 'host' else 'CC_TYPE'
|
||||
compiler_type = self.config.substs.get(type_var)
|
||||
if compiler_type in ('gcc', 'clang'):
|
||||
lib = '-l%s' % lib
|
||||
else:
|
||||
lib = '%s%s%s' % (
|
||||
|
|
Загрузка…
Ссылка в новой задаче